ITK  4.9.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 "dcdict.h" // For DcmDataDictionary
28 #include "dcdicent.h"
29 #include "dcxfer.h"
30 #include "dcvrds.h"
31 #include "dcstack.h"
32 #include "dcdatset.h"
33 #include "dcitem.h"
34 #include "dcvrobow.h"
35 #include "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 class ITKIODCMTK_EXPORT DCMTKSequence;
61 
62 class ITKIODCMTK_EXPORT DCMTKItem
63 {
64 public:
65  DCMTKItem() : m_DcmItem(ITK_NULLPTR)
66  {
67  }
68  void SetDcmItem(DcmItem *item);
69  int GetElementSQ(const unsigned short group,
70  const unsigned short entry,
71  DCMTKSequence &sequence,
72  const bool throwException = true) const;
73 
74 private:
75  DcmItem *m_DcmItem;
76 };
77 
78 class ITKIODCMTK_EXPORT DCMTKSequence
79 {
80 public:
81  DCMTKSequence() : m_DcmSequenceOfItems(ITK_NULLPTR) {}
82  void SetDcmSequenceOfItems(DcmSequenceOfItems *seq);
83  int card() const;
84  int GetSequence(unsigned long index,
85  DCMTKSequence &target,const bool throwException = true) const;
86  int GetStack(const unsigned short group,
87  const unsigned short element,
88  DcmStack &resultStack, const bool throwException = true) const;
89  int GetElementCS(const unsigned short group,
90  const unsigned short element,
91  std::string &target,
92  const bool throwException = true) const;
93 
94  int GetElementOB(const unsigned short group,
95  const unsigned short element,
96  std::string &target,
97  const bool throwException = true) const;
98 
99  int GetElementCSorOB(const unsigned short group,
100  const unsigned short element,
101  std::string &target,
102  const bool throwException = true) const;
103 
104  template <typename TType>
105  int GetElementDSorOB(const unsigned short group,
106  const unsigned short element,
107  TType &target,
108  const bool throwException = true) const
109  {
110  if(this->GetElementDS<TType>(group,element,1,&target,false) == EXIT_SUCCESS)
111  {
112  return EXIT_SUCCESS;
113  }
114  std::string val;
115  if(this->GetElementOB(group,element,val,throwException) != EXIT_SUCCESS)
116  {
117  DCMTKExceptionOrErrorReturn(<< "Cant find DecimalString element " << std::hex
118  << group << " " << std::hex
119  << element << std::dec);
120  }
121  const char *data = val.c_str();
122  const TType *fptr = reinterpret_cast<const TType *>(data);
123  target = *fptr;
124  return EXIT_SUCCESS;
125 
126  }
127 
128  template <typename TType>
129  int GetElementDSorOB(const unsigned short group,
130  const unsigned short element,
131  int count,
132  TType *target,
133  const bool throwException = true) const
134  {
135  if(this->GetElementDS<TType>(group,element,count,target,false) == EXIT_SUCCESS)
136  {
137  return EXIT_SUCCESS;
138  }
139  std::string val;
140  if(this->GetElementOB(group,element,val,throwException) != EXIT_SUCCESS)
141  {
142  DCMTKExceptionOrErrorReturn(<< "Cant find DecimalString element " << std::hex
143  << group << " " << std::hex
144  << element << std::dec);
145  }
146  const char *data = val.c_str();
147  const TType *fptr = reinterpret_cast<const TType *>(data);
148  for(int i = 0; i < count; ++i)
149  {
150  target[i] = fptr[i];
151  }
152  return EXIT_SUCCESS;
153  }
154 
155 
156  int GetElementFD(const unsigned short group,
157  const unsigned short element,
158  int count,
159  double *target,
160  const bool throwException = true) const;
161  int GetElementFD(const unsigned short group,
162  const unsigned short element,
163  double &target,
164  const bool throwException = true) const;
165  int GetElementDS(const unsigned short group,
166  const unsigned short element,
167  std::string &target,
168  const bool throwException = true) const;
169  int GetElementTM(const unsigned short group,
170  const unsigned short element,
171  std::string &target,
172  const bool throwException = true) const;
176  template <typename TType>
177  int GetElementDS(const unsigned short group,
178  const unsigned short element,
179  unsigned short count,
180  TType *target,
181  const bool throwException = true) const
182  {
183  DcmStack resultStack;
184  if(this->GetStack(group,element,resultStack,throwException) != EXIT_SUCCESS)
185  {
186  return EXIT_FAILURE;
187  }
188  DcmDecimalString *dsItem =
189  dynamic_cast<DcmDecimalString *>(resultStack.top());
190  if(dsItem == ITK_NULLPTR)
191  {
192  DCMTKExceptionOrErrorReturn(<< "Can't get DecimalString Element at tag "
193  << std::hex << group << " "
194  << element << std::dec);
195  }
197 
198  OFVector<Float64> doubleVals;
199  if(dsItem->getFloat64Vector(doubleVals) != EC_Normal)
200  {
201  DCMTKExceptionOrErrorReturn(<< "Cant extract Array from DecimalString " << std::hex
202  << group << " " << std::hex
203  << element << std::dec);
204  }
205  if(doubleVals.size() != count)
206  {
207  DCMTKExceptionOrErrorReturn(<< "DecimalString " << std::hex
208  << group << " " << std::hex
209  << element << " expected "
210  << count << "items, but found "
211  << doubleVals.size() << std::dec);
212 
213  }
214  for(unsigned i = 0; i < count; i++)
215  {
216  target[i] = static_cast<TType>(doubleVals[i]);
217  }
218  return EXIT_SUCCESS;
219  }
220  int GetElementSQ(const unsigned short group,
221  const unsigned short element,
222  DCMTKSequence &target,
223  const bool throwException = true) const;
224  int GetElementItem(unsigned short itemIndex,
225  DCMTKItem &target,
226  const bool throwException = true) const;
227 
228  void print(std::ostream &out) const
229  {
230  this->m_DcmSequenceOfItems->print(out);
231  }
232 private:
233  DcmSequenceOfItems *m_DcmSequenceOfItems;
234 };
235 
236 class ITKIODCMTK_EXPORT DCMTKFileReader
237 {
238 public:
240 
241  DCMTKFileReader() : m_DFile(ITK_NULLPTR),
242  m_Dataset(ITK_NULLPTR),
243  m_Xfer(EXS_Unknown),
244  m_FrameCount(0),
245  m_FileNumber(-1L)
246  {}
247  ~DCMTKFileReader();
248 
249  void SetFileName(const std::string &fileName);
250 
251  const std::string &GetFileName() const;
252 
253  void LoadFile();
254 
255  int GetElementLO(const unsigned short group,
256  const unsigned short element,
257  std::string &target,
258  const bool throwException = true) const;
259  int GetElementLO(const unsigned short group,
260  const unsigned short element,
261  std::vector<std::string> &target,
262  const bool throwException = true) const;
263 
267  template <typename TType>
268  int GetElementDS(const unsigned short group,
269  const unsigned short element,
270  unsigned short count,
271  TType *target,
272  const bool throwException = true) const
273  {
274  DcmTagKey tagkey(group,element);
275  DcmElement *el;
276  if(this->m_Dataset->findAndGetElement(tagkey,el) != EC_Normal)
277  {
278  DCMTKExceptionOrErrorReturn(<< "Cant find tag " << std::hex
279  << group << " " << std::hex
280  << element << std::dec);
281  }
282  DcmDecimalString *dsItem = dynamic_cast<DcmDecimalString *>(el);
283  if(dsItem == ITK_NULLPTR)
284  {
285  DCMTKExceptionOrErrorReturn(<< "Cant find DecimalString element " << std::hex
286  << group << " " << std::hex
287  << element << std::dec);
288  }
289  OFVector<Float64> doubleVals;
290  if(dsItem->getFloat64Vector(doubleVals) != EC_Normal)
291  {
292  DCMTKExceptionOrErrorReturn(<< "Cant extract Array from DecimalString " << std::hex
293  << group << " " << std::hex
294  << element << std::dec);
295  }
296  if(doubleVals.size() != count)
297  {
298  DCMTKExceptionOrErrorReturn(<< "DecimalString " << std::hex
299  << group << " " << std::hex
300  << element << " expected "
301  << count << "items, but found "
302  << doubleVals.size() << std::dec);
304 
305  }
306  for(unsigned i = 0; i < count; i++)
307  {
308  target[i] = static_cast<TType>(doubleVals[i]);
309  }
310  return EXIT_SUCCESS;
311  }
312 
313  template <typename TType>
314  int GetElementDSorOB(const unsigned short group,
315  const unsigned short element,
316  TType &target,
317  const bool throwException = true) const
318  {
319  if(this->GetElementDS<TType>(group,element,1,&target,false) == EXIT_SUCCESS)
320  {
321  return EXIT_SUCCESS;
322  }
323  std::string val;
324  if(this->GetElementOB(group,element,val) != EXIT_SUCCESS)
325  {
326  DCMTKExceptionOrErrorReturn(<< "Cant find DecimalString element " << std::hex
327  << group << " " << std::hex
328  << element << std::dec);
329  }
330  const char *data = val.c_str();
331  const TType *fptr = reinterpret_cast<const TType *>(data);
332  target = *fptr;
333  switch(this->GetTransferSyntax())
334  {
335  case EXS_LittleEndianImplicit:
336  case EXS_LittleEndianExplicit:
338  break;
339  case EXS_BigEndianImplicit:
340  case EXS_BigEndianExplicit:
342  break;
343  default:
344  break;
345  }
346  return EXIT_SUCCESS;
347 
348  }
351  int GetElementDS(const unsigned short group,
352  const unsigned short element,
353  std::string &target,
354  const bool throwException = true) const;
355  int GetElementFD(const unsigned short group,
356  const unsigned short element,
357  double &target,
358  const bool throwException = true) const;
359  int GetElementFD(const unsigned short group,
360  const unsigned short element,
361  int count,
362  double * target,
363  const bool throwException = true) const;
364  int GetElementFL(const unsigned short group,
365  const unsigned short element,
366  float &target,
367  const bool throwException = true) const;
368  int GetElementFLorOB(const unsigned short group,
369  const unsigned short element,
370  float &target,
371  const bool throwException = true) const;
373 
374  int GetElementUS(const unsigned short group,
375  const unsigned short element,
376  unsigned short &target,
377  const bool throwException = true) const;
378  int GetElementUS(const unsigned short group,
379  const unsigned short element,
380  unsigned short *&target,
381  const bool throwException = true) const;
384  int GetElementCS(const unsigned short group,
385  const unsigned short element,
386  std::string &target,
387  const bool throwException = true) const;
388 
391  int GetElementPN(const unsigned short group,
392  const unsigned short element,
393  std::string &target,
394  const bool throwException = true) const;
395 
398  int GetElementIS(const unsigned short group,
399  const unsigned short element,
400  ::itk::int32_t &target,
401  const bool throwException = true) const;
402 
403  int GetElementSL(const unsigned short group,
404  const unsigned short element,
405  ::itk::int32_t &target,
406  const bool throwException = true) const;
407 
408  int GetElementISorOB(const unsigned short group,
409  const unsigned short element,
410  ::itk::int32_t &target,
411  const bool throwException = true) const;
412 
413  int GetElementCSorOB(const unsigned short group,
414  const unsigned short element,
415  std::string &target,
416  const bool throwException = true) const;
417 
420  int GetElementOB(const unsigned short group,
421  const unsigned short element,
422  std::string &target,
423  const bool throwException = true) const;
424 
425  int GetElementSQ(const unsigned short group,
426  unsigned short entry,
427  DCMTKSequence &sequence,
428  const bool throwException = true) const;
429 
430  int GetElementUI(const unsigned short group,
431  unsigned short entry,
432  std::string &target,
433  const bool throwException = true) const;
434 
435  int GetElementDA(const unsigned short group,
436  const unsigned short element,
437  std::string &target,
438  const bool throwException = true) const;
439 
440  int GetElementTM(const unsigned short group,
441  const unsigned short element,
442  std::string &target,
443  const bool throwException = true) const;
444 
445  int GetDirCosines(vnl_vector<double> &dir1,
446  vnl_vector<double> &dir2,
447  vnl_vector<double> &dir3) const;
448 
449  int GetDirCosArray(double * const dircos) const;
450 
451  int GetFrameCount() const;
452 
453  int GetSlopeIntercept(double &slope, double &intercept) const;
454 
455  int GetDimensions(unsigned short &rows, unsigned short &columns) const;
456 
457  ImageIOBase::IOComponentType GetImageDataType() const;
458  ImageIOBase::IOPixelType GetImagePixelType() const;
459 
460  int GetSpacing(double * const spacing) const;
461  int GetOrigin(double * const origin) const;
462 
463  bool HasPixelData() const;
464 
465  E_TransferSyntax GetTransferSyntax() const;
466 
467  long GetFileNumber() const;
468  static void
469  AddDictEntry(DcmDictEntry *entry);
470 
471  static bool CanReadFile(const std::string &filename);
472  static bool IsImageFile(const std::string &filename);
473 
474 private:
475 
476  std::string m_FileName;
477  DcmFileFormat* m_DFile;
478  DcmDataset * m_Dataset;
479  E_TransferSyntax m_Xfer;
480  Sint32 m_FrameCount;
482 };
483 
485 }
486 
487 #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