ITK  4.13.0
Insight Segmentation and Registration Toolkit
itkDCMTKFileReader.h
Go to the documentation of this file.
1 /*=========================================================================
2  *
3  * Copyright Insight Software Consortium
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef itkDCMTKFileReader_h
19 #define itkDCMTKFileReader_h
20 
21 #include "ITKIODCMTKExport.h"
22 #include <stack>
23 #include <vector>
24 #include "itkByteSwapper.h"
25 #include "itkIntTypes.h"
26 #include "vnl/vnl_vector.h"
27 #include "dcmtk/dcmdata/dcdict.h" // For DcmDataDictionary
28 #include "dcmtk/dcmdata/dcdicent.h"
29 #include "dcmtk/dcmdata/dcxfer.h"
30 #include "dcmtk/dcmdata/dcvrds.h"
31 #include "dcmtk/dcmdata/dcstack.h"
32 #include "dcmtk/dcmdata/dcdatset.h"
33 #include "dcmtk/dcmdata/dcitem.h"
34 #include "dcmtk/dcmdata/dcvrobow.h"
35 #include "dcmtk/dcmdata/dcsequen.h"
36 #include "itkMacro.h"
37 #include "itkImageIOBase.h"
38 
39 class DcmSequenceOfItems;
40 class DcmFileFormat;
41 class DcmDictEntry;
42 
43 // Don't print error messages if you're not throwing
44 // an exception
45 // std::cerr body;
46 #define DCMTKExceptionOrErrorReturn(body) \
47  { \
48  if(throwException) \
49  { \
50  itkGenericExceptionMacro(body); \
51  } \
52  else \
53  { \
54  return EXIT_FAILURE; \
55  } \
56  }
57 
58 namespace itk
59 {
60 // Forward reference because of circular dependencies
61 class ITK_FORWARD_EXPORT DCMTKSequence;
62 
63 class ITKIODCMTK_EXPORT DCMTKItem
64 {
65 public:
66  DCMTKItem() : m_DcmItem(ITK_NULLPTR)
67  {
68  }
69  void SetDcmItem(DcmItem *item);
70  int GetElementSQ(const unsigned short group,
71  const unsigned short entry,
72  DCMTKSequence &sequence,
73  const bool throwException = true) const;
74 
75 private:
76  DcmItem *m_DcmItem;
77 };
78 
79 class ITKIODCMTK_EXPORT DCMTKSequence
80 {
81 public:
82  DCMTKSequence() : m_DcmSequenceOfItems(ITK_NULLPTR) {}
83  void SetDcmSequenceOfItems(DcmSequenceOfItems *seq);
84  int card() const;
85  int GetSequence(unsigned long index,
86  DCMTKSequence &target,const bool throwException = true) const;
87  int GetStack(const unsigned short group,
88  const unsigned short element,
89  DcmStack &resultStack, const bool throwException = true) const;
90  int GetElementCS(const unsigned short group,
91  const unsigned short element,
92  std::string &target,
93  const bool throwException = true) const;
94 
95  int GetElementOB(const unsigned short group,
96  const unsigned short element,
97  std::string &target,
98  const bool throwException = true) const;
99 
100  int GetElementCSorOB(const unsigned short group,
101  const unsigned short element,
102  std::string &target,
103  const bool throwException = true) const;
104 
105  template <typename TType>
106  int GetElementDSorOB(const unsigned short group,
107  const unsigned short element,
108  TType &target,
109  const bool throwException = true) const
110  {
111  if(this->GetElementDS<TType>(group,element,1,&target,false) == EXIT_SUCCESS)
112  {
113  return EXIT_SUCCESS;
114  }
115  std::string val;
116  if(this->GetElementOB(group,element,val,throwException) != EXIT_SUCCESS)
117  {
118  DCMTKExceptionOrErrorReturn(<< "Cant find DecimalString element " << std::hex
119  << group << " " << std::hex
120  << element << std::dec);
121  }
122  const char *data = val.c_str();
123  const TType *fptr = reinterpret_cast<const TType *>(data);
124  target = *fptr;
125  return EXIT_SUCCESS;
126 
127  }
128 
129  template <typename TType>
130  int GetElementDSorOB(const unsigned short group,
131  const unsigned short element,
132  int count,
133  TType *target,
134  const bool throwException = true) const
135  {
136  if(this->GetElementDS<TType>(group,element,count,target,false) == EXIT_SUCCESS)
137  {
138  return EXIT_SUCCESS;
139  }
140  std::string val;
141  if(this->GetElementOB(group,element,val,throwException) != EXIT_SUCCESS)
142  {
143  DCMTKExceptionOrErrorReturn(<< "Cant find DecimalString element " << std::hex
144  << group << " " << std::hex
145  << element << std::dec);
146  }
147  const char *data = val.c_str();
148  const TType *fptr = reinterpret_cast<const TType *>(data);
149  for(int i = 0; i < count; ++i)
150  {
151  target[i] = fptr[i];
152  }
153  return EXIT_SUCCESS;
154  }
155 
156 
157  int GetElementFD(const unsigned short group,
158  const unsigned short element,
159  int count,
160  double *target,
161  const bool throwException = true) const;
162  int GetElementFD(const unsigned short group,
163  const unsigned short element,
164  double &target,
165  const bool throwException = true) const;
166  int GetElementDS(const unsigned short group,
167  const unsigned short element,
168  std::string &target,
169  const bool throwException = true) const;
170  int GetElementTM(const unsigned short group,
171  const unsigned short element,
172  std::string &target,
173  const bool throwException = true) const;
177  template <typename TType>
178  int GetElementDS(const unsigned short group,
179  const unsigned short element,
180  unsigned short count,
181  TType *target,
182  const bool throwException = true) const
183  {
184  DcmStack resultStack;
185  if(this->GetStack(group,element,resultStack,throwException) != EXIT_SUCCESS)
186  {
187  return EXIT_FAILURE;
188  }
189  DcmDecimalString *dsItem =
190  dynamic_cast<DcmDecimalString *>(resultStack.top());
191  if(dsItem == ITK_NULLPTR)
192  {
193  DCMTKExceptionOrErrorReturn(<< "Can't get DecimalString Element at tag "
194  << std::hex << group << " "
195  << element << std::dec);
196  }
198 
199  OFVector<Float64> doubleVals;
200  if(dsItem->getFloat64Vector(doubleVals) != EC_Normal)
201  {
202  DCMTKExceptionOrErrorReturn(<< "Cant extract Array from DecimalString " << std::hex
203  << group << " " << std::hex
204  << element << std::dec);
205  }
206  if(doubleVals.size() != count)
207  {
208  DCMTKExceptionOrErrorReturn(<< "DecimalString " << std::hex
209  << group << " " << std::hex
210  << element << " expected "
211  << count << "items, but found "
212  << doubleVals.size() << std::dec);
213 
214  }
215  for(unsigned i = 0; i < count; i++)
216  {
217  target[i] = static_cast<TType>(doubleVals[i]);
218  }
219  return EXIT_SUCCESS;
220  }
221  int GetElementSQ(const unsigned short group,
222  const unsigned short element,
223  DCMTKSequence &target,
224  const bool throwException = true) const;
225  int GetElementItem(unsigned short itemIndex,
226  DCMTKItem &target,
227  const bool throwException = true) const;
228 
229  void print(std::ostream &out) const
230  {
231  this->m_DcmSequenceOfItems->print(out);
232  }
233 private:
234  DcmSequenceOfItems *m_DcmSequenceOfItems;
235 };
236 
237 class ITKIODCMTK_EXPORT DCMTKFileReader
238 {
239 public:
241 
242  DCMTKFileReader() : m_DFile(ITK_NULLPTR),
243  m_Dataset(ITK_NULLPTR),
244  m_Xfer(EXS_Unknown),
245  m_FrameCount(0),
246  m_FileNumber(-1L)
247  {}
248  ~DCMTKFileReader();
249 
250  void SetFileName(const std::string &fileName);
251 
252  const std::string &GetFileName() const;
253 
254  void LoadFile();
255 
256  int GetElementLO(const unsigned short group,
257  const unsigned short element,
258  std::string &target,
259  const bool throwException = true) const;
260  int GetElementLO(const unsigned short group,
261  const unsigned short element,
262  std::vector<std::string> &target,
263  const bool throwException = true) const;
264 
268  template <typename TType>
269  int GetElementDS(const unsigned short group,
270  const unsigned short element,
271  unsigned short count,
272  TType *target,
273  const bool throwException = true) const
274  {
275  DcmTagKey tagkey(group,element);
276  DcmElement *el;
277  if(this->m_Dataset->findAndGetElement(tagkey,el) != EC_Normal)
278  {
279  DCMTKExceptionOrErrorReturn(<< "Cant find tag " << std::hex
280  << group << " " << std::hex
281  << element << std::dec);
282  }
283  DcmDecimalString *dsItem = dynamic_cast<DcmDecimalString *>(el);
284  if(dsItem == ITK_NULLPTR)
285  {
286  DCMTKExceptionOrErrorReturn(<< "Cant find DecimalString element " << std::hex
287  << group << " " << std::hex
288  << element << std::dec);
289  }
290  OFVector<Float64> doubleVals;
291  if(dsItem->getFloat64Vector(doubleVals) != EC_Normal)
292  {
293  DCMTKExceptionOrErrorReturn(<< "Cant extract Array from DecimalString " << std::hex
294  << group << " " << std::hex
295  << element << std::dec);
296  }
297  if(doubleVals.size() != count)
298  {
299  DCMTKExceptionOrErrorReturn(<< "DecimalString " << std::hex
300  << group << " " << std::hex
301  << element << " expected "
302  << count << "items, but found "
303  << doubleVals.size() << std::dec);
305 
306  }
307  for(unsigned i = 0; i < count; i++)
308  {
309  target[i] = static_cast<TType>(doubleVals[i]);
310  }
311  return EXIT_SUCCESS;
312  }
313 
314  template <typename TType>
315  int GetElementDSorOB(const unsigned short group,
316  const unsigned short element,
317  TType &target,
318  const bool throwException = true) const
319  {
320  if(this->GetElementDS<TType>(group,element,1,&target,false) == EXIT_SUCCESS)
321  {
322  return EXIT_SUCCESS;
323  }
324  std::string val;
325  if(this->GetElementOB(group,element,val) != EXIT_SUCCESS)
326  {
327  DCMTKExceptionOrErrorReturn(<< "Cant find DecimalString element " << std::hex
328  << group << " " << std::hex
329  << element << std::dec);
330  }
331  const char *data = val.c_str();
332  const TType *fptr = reinterpret_cast<const TType *>(data);
333  target = *fptr;
334  switch(this->GetTransferSyntax())
335  {
336  case EXS_LittleEndianImplicit:
337  case EXS_LittleEndianExplicit:
339  break;
340  case EXS_BigEndianImplicit:
341  case EXS_BigEndianExplicit:
343  break;
344  default:
345  break;
346  }
347  return EXIT_SUCCESS;
348 
349  }
352  int GetElementDS(const unsigned short group,
353  const unsigned short element,
354  std::string &target,
355  const bool throwException = true) const;
356  int GetElementFD(const unsigned short group,
357  const unsigned short element,
358  double &target,
359  const bool throwException = true) const;
360  int GetElementFD(const unsigned short group,
361  const unsigned short element,
362  int count,
363  double * target,
364  const bool throwException = true) const;
365  int GetElementFL(const unsigned short group,
366  const unsigned short element,
367  float &target,
368  const bool throwException = true) const;
369  int GetElementFLorOB(const unsigned short group,
370  const unsigned short element,
371  float &target,
372  const bool throwException = true) const;
374 
375  int GetElementUS(const unsigned short group,
376  const unsigned short element,
377  unsigned short &target,
378  const bool throwException = true) const;
379  int GetElementUS(const unsigned short group,
380  const unsigned short element,
381  unsigned short *&target,
382  const bool throwException = true) const;
385  int GetElementCS(const unsigned short group,
386  const unsigned short element,
387  std::string &target,
388  const bool throwException = true) const;
389 
392  int GetElementPN(const unsigned short group,
393  const unsigned short element,
394  std::string &target,
395  const bool throwException = true) const;
396 
399  int GetElementIS(const unsigned short group,
400  const unsigned short element,
401  ::itk::int32_t &target,
402  const bool throwException = true) const;
403 
404  int GetElementSL(const unsigned short group,
405  const unsigned short element,
406  ::itk::int32_t &target,
407  const bool throwException = true) const;
408 
409  int GetElementISorOB(const unsigned short group,
410  const unsigned short element,
411  ::itk::int32_t &target,
412  const bool throwException = true) const;
413 
414  int GetElementCSorOB(const unsigned short group,
415  const unsigned short element,
416  std::string &target,
417  const bool throwException = true) const;
418 
421  int GetElementOB(const unsigned short group,
422  const unsigned short element,
423  std::string &target,
424  const bool throwException = true) const;
425 
426  int GetElementSQ(const unsigned short group,
427  unsigned short entry,
428  DCMTKSequence &sequence,
429  const bool throwException = true) const;
430 
431  int GetElementUI(const unsigned short group,
432  unsigned short entry,
433  std::string &target,
434  const bool throwException = true) const;
435 
436  int GetElementDA(const unsigned short group,
437  const unsigned short element,
438  std::string &target,
439  const bool throwException = true) const;
440 
441  int GetElementTM(const unsigned short group,
442  const unsigned short element,
443  std::string &target,
444  const bool throwException = true) const;
445 
446  int GetDirCosines(vnl_vector<double> &dir1,
447  vnl_vector<double> &dir2,
448  vnl_vector<double> &dir3) const;
449 
450  int GetDirCosArray(double * const dircos) const;
451 
452  int GetFrameCount() const;
453 
454  int GetSlopeIntercept(double &slope, double &intercept) const;
455 
456  int GetDimensions(unsigned short &rows, unsigned short &columns) const;
457 
458  ImageIOBase::IOComponentType GetImageDataType() const;
459  ImageIOBase::IOPixelType GetImagePixelType() const;
460 
461  int GetSpacing(double * const spacing) const;
462  int GetOrigin(double * const origin) const;
463 
464  bool HasPixelData() const;
465 
466  E_TransferSyntax GetTransferSyntax() const;
467 
468  long GetFileNumber() const;
469  static void
470  AddDictEntry(DcmDictEntry *entry);
471 
472  static bool CanReadFile(const std::string &filename);
473  static bool IsImageFile(const std::string &filename);
474 
475 private:
476 
477  std::string m_FileName;
478  DcmFileFormat* m_DFile;
479  DcmDataset * m_Dataset;
480  E_TransferSyntax m_Xfer;
481  Sint32 m_FrameCount;
483 };
484 
486 }
487 
488 #endif // itkDCMTKFileReader_h
static void SwapFromSystemToBigEndian(T *p)
int GetElementDSorOB(const unsigned short group, const unsigned short element, int count, TType *target, const bool throwException=true) const
int GetElementDSorOB(const unsigned short group, const unsigned short element, TType &target, const bool throwException=true) const
bool CompareDCMTKFileReaders(DCMTKFileReader *a, DCMTKFileReader *b)
int GetElementDS(const unsigned short group, const unsigned short element, unsigned short count, TType *target, const bool throwException=true) const
DcmSequenceOfItems * m_DcmSequenceOfItems
E_TransferSyntax m_Xfer
static void SwapFromSystemToLittleEndian(T *p)
int GetElementDSorOB(const unsigned short group, const unsigned short element, TType &target, const bool throwException=true) const
void print(std::ostream &out) const
KWIML_INT_int32_t int32_t
Definition: itkIntTypes.h:86
#define DCMTKExceptionOrErrorReturn(body)
int GetElementDS(const unsigned short group, const unsigned short element, unsigned short count, TType *target, const bool throwException=true) const