ITK  4.6.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 
20 #define __itkDCMTKFileReader_h
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(0)
66  {
67  }
68  void SetDcmItem(DcmItem *item);
69  int GetElementSQ(unsigned short group,
70  unsigned short entry,
71  DCMTKSequence &sequence,
72  bool throwException = true);
73 
74 private:
75  DcmItem *m_DcmItem;
76 };
77 
78 class ITKIODCMTK_EXPORT DCMTKSequence
79 {
80 public:
81  DCMTKSequence() : m_DcmSequenceOfItems(0) {}
82  void SetDcmSequenceOfItems(DcmSequenceOfItems *seq);
83  int card();
84  int GetSequence(unsigned long index,
85  DCMTKSequence &target,bool throwException = true);
86  int GetStack(unsigned short group,
87  unsigned short element,
88  DcmStack &resultStack, bool throwException = true);
89  int GetElementCS(unsigned short group,
90  unsigned short element,
91  std::string &target,
92  bool throwException = true);
93 
94  int GetElementOB(unsigned short group,
95  unsigned short element,
96  std::string &target,
97  bool throwException = true);
98 
99  int GetElementCSorOB(unsigned short group,
100  unsigned short element,
101  std::string &target,
102  bool throwException = true);
103 
104  template <typename TType>
105  int GetElementDSorOB(unsigned short group,
106  unsigned short element,
107  TType &target,
108  bool throwException = true)
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(unsigned short group,
130  unsigned short element,
131  int count,
132  TType *target,
133  bool throwException = true)
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(unsigned short group,
157  unsigned short element,
158  int count,
159  double *target,
160  bool throwException = true);
161  int GetElementFD(unsigned short group,
162  unsigned short element,
163  double &target,
164  bool throwException = true);
165  int GetElementDS(unsigned short group,
166  unsigned short element,
167  std::string &target,
168  bool throwException = true);
169  int GetElementTM(unsigned short group,
170  unsigned short element,
171  std::string &target,
172  bool throwException = true);
176  template <typename TType>
177  int GetElementDS(unsigned short group,
178  unsigned short element,
179  unsigned short count,
180  TType *target,
181  bool throwException = true)
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 == 0)
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(unsigned short group,
221  unsigned short element,
222  DCMTKSequence &target,
223  bool throwException = true);
224  int GetElementItem(unsigned short itemIndex,
225  DCMTKItem &target,
226  bool throwException = true);
227 
228  void print(std::ostream &out)
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(0),
242  m_Dataset(0),
243  m_Xfer(EXS_Unknown),
244  m_FrameCount(0),
245  m_FileNumber(-1L)
246  {
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(unsigned short group,
257  unsigned short element,
258  std::string &target,
259  bool throwException = true);
260  int GetElementLO(unsigned short group,
261  unsigned short element,
262  std::vector<std::string> &target,
263  bool throwException = true);
264 
268  template <typename TType>
269  int GetElementDS(unsigned short group,
270  unsigned short element,
271  unsigned short count,
272  TType *target,
273  bool throwException = true)
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 == 0)
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(unsigned short group,
316  unsigned short element,
317  TType &target,
318  bool throwException = true)
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(unsigned short group,
353  unsigned short element,
354  std::string &target,
355  bool throwException = true);
356  int GetElementFD(unsigned short group,
357  unsigned short element,
358  double &target,
359  bool throwException = true);
360  int GetElementFD(unsigned short group,
361  unsigned short element,
362  int count,
363  double * target,
364  bool throwException = true);
365  int GetElementFL(unsigned short group,
366  unsigned short element,
367  float &target,
368  bool throwException = true);
369  int GetElementFLorOB(unsigned short group,
370  unsigned short element,
371  float &target,
372  bool throwException = true);
374 
375  int GetElementUS(unsigned short group,
376  unsigned short element,
377  unsigned short &target,
378  bool throwException = true);
379  int GetElementUS(unsigned short group,
380  unsigned short element,
381  unsigned short *&target,
382  bool throwException = true);
385  int GetElementCS(unsigned short group,
386  unsigned short element,
387  std::string &target,
388  bool throwException = true);
389 
392  int GetElementPN(unsigned short group,
393  unsigned short element,
394  std::string &target,
395  bool throwException = true);
396 
399  int GetElementIS(unsigned short group,
400  unsigned short element,
401  ::itk::int32_t &target,
402  bool throwException = true);
403 
404  int GetElementSL(unsigned short group,
405  unsigned short element,
406  ::itk::int32_t &target,
407  bool throwException = true);
408 
409  int GetElementISorOB(unsigned short group,
410  unsigned short element,
411  ::itk::int32_t &target,
412  bool throwException = true);
413 
414  int GetElementCSorOB(unsigned short group,
415  unsigned short element,
416  std::string &target,
417  bool throwException = true);
418 
421  int GetElementOB(unsigned short group,
422  unsigned short element,
423  std::string &target,
424  bool throwException = true);
425 
426  int GetElementSQ(unsigned short group,
427  unsigned short entry,
428  DCMTKSequence &sequence,
429  bool throwException = true);
430 
431  int GetElementUI(unsigned short group,
432  unsigned short entry,
433  std::string &target,
434  bool throwException = true);
435 
436  int GetElementDA(unsigned short group,
437  unsigned short element,
438  std::string &target,
439  bool throwException = true);
440 
441  int GetElementTM(unsigned short group,
442  unsigned short element,
443  std::string &target,
444  bool throwException = true);
445 
446  int GetDirCosines(vnl_vector<double> &dir1,
447  vnl_vector<double> &dir2,
448  vnl_vector<double> &dir3);
449 
450  int GetDirCosArray(double *dircos);
451 
452  int GetFrameCount() const;
453 
454  int GetSlopeIntercept(double &slope, double &intercept);
455 
456  int GetDimensions(unsigned short &rows, unsigned short &columns);
457 
458  ImageIOBase::IOComponentType GetImageDataType();
459  ImageIOBase::IOPixelType GetImagePixelType();
460 
461  int GetSpacing(double *spacing);
462  int GetOrigin(double *origin);
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(unsigned short group, unsigned short element, TType &target, bool throwException=true)
int GetElementDSorOB(unsigned short group, unsigned short element, TType &target, bool throwException=true)
bool CompareDCMTKFileReaders(DCMTKFileReader *a, DCMTKFileReader *b)
int GetElementDS(unsigned short group, unsigned short element, unsigned short count, TType *target, bool throwException=true)
int GetElementDSorOB(unsigned short group, unsigned short element, int count, TType *target, bool throwException=true)
void print(std::ostream &out)
DcmSequenceOfItems * m_DcmSequenceOfItems
E_TransferSyntax m_Xfer
static void SwapFromSystemToLittleEndian(T *p)
typedef::itksysFundamentalType_Int32 int32_t
Definition: itkIntTypes.h:86
int GetElementDS(unsigned short group, unsigned short element, unsigned short count, TType *target, bool throwException=true)
#define DCMTKExceptionOrErrorReturn(body)