ITK  5.4.0
Insight Toolkit
itkDCMTKFileReader.h
Go to the documentation of this file.
1 /*=========================================================================
2  *
3  * Copyright NumFOCUS
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  * https://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() = default;
67 
68  void
69  SetDcmItem(DcmItem * item);
70  int
71  GetElementSQ(const unsigned short group,
72  const unsigned short entry,
73  DCMTKSequence & sequence,
74  const bool throwException = true) const;
75 
76 private:
77  DcmItem * m_DcmItem{ nullptr };
78 };
79 
80 class ITKIODCMTK_EXPORT DCMTKSequence
81 {
82 public:
83  DCMTKSequence() = default;
84  void
85  SetDcmSequenceOfItems(DcmSequenceOfItems * seq);
86  int
87  card() const;
88  int
89  GetSequence(unsigned long index, DCMTKSequence & target, const bool throwException = true) const;
90  int
91  GetStack(const unsigned short group,
92  const unsigned short element,
93  DcmStack & resultStack,
94  const bool throwException = true) const;
95  int
96  GetElementCS(const unsigned short group,
97  const unsigned short element,
98  std::string & target,
99  const bool throwException = true) const;
100 
101  int
102  GetElementOB(const unsigned short group,
103  const unsigned short element,
104  std::string & target,
105  const bool throwException = true) const;
106 
107  int
108  GetElementCSorOB(const unsigned short group,
109  const unsigned short element,
110  std::string & target,
111  const bool throwException = true) const;
112 
113  template <typename TType>
114  int
115  GetElementDSorOB(const unsigned short group,
116  const unsigned short element,
117  TType & target,
118  const bool throwException = true) const
119  {
120  if (this->GetElementDS<TType>(group, element, 1, &target, false) == EXIT_SUCCESS)
121  {
122  return EXIT_SUCCESS;
123  }
124  std::string val;
125  if (this->GetElementOB(group, element, val, throwException) != EXIT_SUCCESS)
126  {
127  DCMTKExceptionOrErrorReturn(<< "Cant find DecimalString element " << std::hex << group << ' ' << std::hex
128  << element << std::dec);
129  }
130  const char * data = val.c_str();
131  const auto * fptr = reinterpret_cast<const TType *>(data);
132  target = *fptr;
133  return EXIT_SUCCESS;
134  }
135 
136  template <typename TType>
137  int
138  GetElementDSorOB(const unsigned short group,
139  const unsigned short element,
140  int count,
141  TType * target,
142  const bool throwException = true) const
143  {
144  if (this->GetElementDS<TType>(group, element, count, target, false) == EXIT_SUCCESS)
145  {
146  return EXIT_SUCCESS;
147  }
148  std::string val;
149  if (this->GetElementOB(group, element, val, throwException) != EXIT_SUCCESS)
150  {
151  DCMTKExceptionOrErrorReturn(<< "Cant find DecimalString element " << std::hex << group << ' ' << std::hex
152  << element << std::dec);
153  }
154  const char * data = val.c_str();
155  const auto * fptr = reinterpret_cast<const TType *>(data);
156  for (int i = 0; i < count; ++i)
157  {
158  target[i] = fptr[i];
159  }
160  return EXIT_SUCCESS;
161  }
162 
163 
164  int
165  GetElementFD(const unsigned short group,
166  const unsigned short element,
167  int count,
168  double * target,
169  const bool throwException = true) const;
170  int
171  GetElementFD(const unsigned short group,
172  const unsigned short element,
173  double & target,
174  const bool throwException = true) const;
175  int
176  GetElementDS(const unsigned short group,
177  const unsigned short element,
178  std::string & target,
179  const bool throwException = true) const;
180  int
181  GetElementTM(const unsigned short group,
182  const unsigned short element,
183  std::string & target,
184  const bool throwException = true) const;
188  template <typename TType>
189  int
190  GetElementDS(const unsigned short group,
191  const unsigned short element,
192  unsigned short count,
193  TType * target,
194  const bool throwException = true) const
195  {
196  DcmStack resultStack;
197  if (this->GetStack(group, element, resultStack, throwException) != EXIT_SUCCESS)
198  {
199  return EXIT_FAILURE;
200  }
201  auto * dsItem = dynamic_cast<DcmDecimalString *>(resultStack.top());
202  if (dsItem == nullptr)
203  {
204  DCMTKExceptionOrErrorReturn(<< "Can't get DecimalString Element at tag " << std::hex << group << ' ' << element
205  << std::dec);
206  }
209  OFVector<Float64> doubleVals;
210  if (dsItem->getFloat64Vector(doubleVals) != EC_Normal)
211  {
212  DCMTKExceptionOrErrorReturn(<< "Cant extract Array from DecimalString " << std::hex << group << ' ' << std::hex
213  << element << std::dec);
214  }
215  if (doubleVals.size() != count)
216  {
217  DCMTKExceptionOrErrorReturn(<< "DecimalString " << std::hex << group << ' ' << std::hex << element << " expected "
218  << count << "items, but found " << doubleVals.size() << std::dec);
219  }
220  for (unsigned int i = 0; i < count; ++i)
221  {
222  target[i] = static_cast<TType>(doubleVals[i]);
223  }
224  return EXIT_SUCCESS;
225  }
226  int
227  GetElementSQ(const unsigned short group,
228  const unsigned short element,
229  DCMTKSequence & target,
230  const bool throwException = true) const;
231  int
232  GetElementItem(unsigned short itemIndex, DCMTKItem & target, const bool throwException = true) const;
233 
234  void
235  print(std::ostream & out) const
236  {
237  this->m_DcmSequenceOfItems->print(out);
238  }
239 
240 private:
241  DcmSequenceOfItems * m_DcmSequenceOfItems{ nullptr };
242 };
243 
244 class ITKIODCMTK_EXPORT DCMTKFileReader
245 {
246 public:
248 
249  DCMTKFileReader() = default;
250  ~DCMTKFileReader();
251 
252  void
253  SetFileName(const std::string & fileName);
254 
255  const std::string &
256  GetFileName() const;
257 
258  void
259  LoadFile();
260 
261  int
262  GetElementLO(const unsigned short group,
263  const unsigned short element,
264  std::string & target,
265  const bool throwException = true) const;
266  int
267  GetElementLO(const unsigned short group,
268  const unsigned short element,
269  std::vector<std::string> & target,
270  const bool throwException = true) const;
271 
275  template <typename TType>
276  int
277  GetElementDS(const unsigned short group,
278  const unsigned short element,
279  unsigned short count,
280  TType * target,
281  const bool throwException = true) const
282  {
283  DcmTagKey tagkey(group, element);
284  DcmElement * el;
285  if (this->m_Dataset->findAndGetElement(tagkey, el) != EC_Normal)
286  {
287  DCMTKExceptionOrErrorReturn(<< "Cant find tag " << std::hex << group << ' ' << std::hex << element << std::dec);
288  }
289  auto * dsItem = dynamic_cast<DcmDecimalString *>(el);
290  if (dsItem == nullptr)
291  {
292  DCMTKExceptionOrErrorReturn(<< "Cant find DecimalString element " << std::hex << group << ' ' << std::hex
293  << element << std::dec);
294  }
295  OFVector<Float64> doubleVals;
296  if (dsItem->getFloat64Vector(doubleVals) != EC_Normal)
297  {
298  DCMTKExceptionOrErrorReturn(<< "Cant extract Array from DecimalString " << std::hex << group << ' ' << std::hex
299  << element << std::dec);
300  }
301  if (doubleVals.size() != count)
302  {
303  DCMTKExceptionOrErrorReturn(<< "DecimalString " << std::hex << group << ' ' << std::hex << element << " expected "
304  << count << "items, but found " << doubleVals.size() << std::dec);
305  }
306  for (unsigned int i = 0; i < count; ++i)
307  {
308  target[i] = static_cast<TType>(doubleVals[i]);
309  }
310  return EXIT_SUCCESS;
311  }
314  template <typename TType>
315  int
316  GetElementDSorOB(const unsigned short group,
317  const unsigned short element,
318  TType & target,
319  const bool throwException = true) const
320  {
321  if (this->GetElementDS<TType>(group, element, 1, &target, false) == EXIT_SUCCESS)
322  {
323  return EXIT_SUCCESS;
324  }
325  std::string val;
326  if (this->GetElementOB(group, element, val, throwException) != EXIT_SUCCESS)
327  {
328  DCMTKExceptionOrErrorReturn(<< "Cant find DecimalString element " << std::hex << group << ' ' << std::hex
329  << element << std::dec);
330  }
331  const char * data = val.c_str();
332  const auto * 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  }
351  int
352  GetElementDS(const unsigned short group,
353  const unsigned short element,
354  std::string & target,
355  const bool throwException = true) const;
356  int
357  GetElementFD(const unsigned short group,
358  const unsigned short element,
359  double & target,
360  const bool throwException = true) const;
361  int
362  GetElementFD(const unsigned short group,
363  const unsigned short element,
364  int count,
365  double * target,
366  const bool throwException = true) const;
367  int
368  GetElementFL(const unsigned short group,
369  const unsigned short element,
370  float & target,
371  const bool throwException = true) const;
372  int
373  GetElementFLorOB(const unsigned short group,
374  const unsigned short element,
375  float & target,
376  const bool throwException = true) const;
379  int
380  GetElementUS(const unsigned short group,
381  const unsigned short element,
382  unsigned short & target,
383  const bool throwException = true) const;
384  int
385  GetElementUS(const unsigned short group,
386  const unsigned short element,
387  unsigned short *& target,
388  const bool throwException = true) const;
391  int
392  GetElementCS(const unsigned short group,
393  const unsigned short element,
394  std::string & target,
395  const bool throwException = true) const;
396 
399  int
400  GetElementPN(const unsigned short group,
401  const unsigned short element,
402  std::string & target,
403  const bool throwException = true) const;
404 
407  int
408  GetElementIS(const unsigned short group,
409  const unsigned short element,
410  itk::int32_t & target,
411  const bool throwException = true) const;
412 
413  int
414  GetElementSL(const unsigned short group,
415  const unsigned short element,
416  itk::int32_t & target,
417  const bool throwException = true) const;
418 
419  int
420  GetElementISorOB(const unsigned short group,
421  const unsigned short element,
422  itk::int32_t & target,
423  const bool throwException = true) const;
424 
425  int
426  GetElementCSorOB(const unsigned short group,
427  const unsigned short element,
428  std::string & target,
429  const bool throwException = true) const;
430 
433  int
434  GetElementOB(const unsigned short group,
435  const unsigned short element,
436  std::string & target,
437  const bool throwException = true) const;
438 
439  int
440  GetElementSQ(const unsigned short group,
441  unsigned short entry,
442  DCMTKSequence & sequence,
443  const bool throwException = true) const;
444 
445  int
446  GetElementUI(const unsigned short group,
447  unsigned short entry,
448  std::string & target,
449  const bool throwException = true) const;
450 
451  int
452  GetElementDA(const unsigned short group,
453  const unsigned short element,
454  std::string & target,
455  const bool throwException = true) const;
456 
457  int
458  GetElementTM(const unsigned short group,
459  const unsigned short element,
460  std::string & target,
461  const bool throwException = true) const;
462 
463  int
464  GetDirCosines(vnl_vector<double> & dir1, vnl_vector<double> & dir2, vnl_vector<double> & dir3) const;
465 
466  int
467  GetDirCosArray(double * const dircos) const;
468 
469  int
470  GetFrameCount() const;
471 
472  int
473  GetSlopeIntercept(double & slope, double & intercept) const;
474 
475  int
476  GetDimensions(unsigned short & rows, unsigned short & columns) const;
477 
479  GetImageDataType() const;
481  GetImagePixelType() const;
482 
483  int
484  GetSpacing(double * const spacing) const;
485  int
486  GetOrigin(double * const origin) const;
487 
488  bool
489  HasPixelData() const;
490 
491  E_TransferSyntax
492  GetTransferSyntax() const;
493 
494  long
495  GetFileNumber() const;
496  static void
497  AddDictEntry(DcmDictEntry * entry);
498 
499  static bool
500  CanReadFile(const std::string & filename);
501  static bool
502  IsImageFile(const std::string & filename);
503 
504 private:
505  std::string m_FileName;
506  DcmFileFormat * m_DFile{ nullptr };
507  DcmDataset * m_Dataset{ nullptr };
508  E_TransferSyntax m_Xfer{ EXS_Unknown };
509  Sint32 m_FrameCount{ 0 };
510  long m_FileNumber{ -1L };
511 };
512 
513 extern bool
514 CompareDCMTKFileReaders(DCMTKFileReader * a, DCMTKFileReader * b);
515 } // namespace itk
516 
517 #endif // itkDCMTKFileReader_h
itk::DCMTKSequence::GetElementDS
int GetElementDS(const unsigned short group, const unsigned short element, unsigned short count, TType *target, const bool throwException=true) const
Definition: itkDCMTKFileReader.h:190
itkByteSwapper.h
itk::DCMTKSequence::GetElementDSorOB
int GetElementDSorOB(const unsigned short group, const unsigned short element, TType &target, const bool throwException=true) const
Definition: itkDCMTKFileReader.h:115
itk::DCMTKItem
Definition: itkDCMTKFileReader.h:63
itk::DCMTKSequence
Definition: itkDCMTKFileReader.h:80
itk::DCMTKSequence::GetElementDSorOB
int GetElementDSorOB(const unsigned short group, const unsigned short element, int count, TType *target, const bool throwException=true) const
Definition: itkDCMTKFileReader.h:138
itk::DCMTKFileReader::GetElementDSorOB
int GetElementDSorOB(const unsigned short group, const unsigned short element, TType &target, const bool throwException=true) const
Definition: itkDCMTKFileReader.h:316
itk::CommonEnums::IOComponent
IOComponent
Definition: itkCommonEnums.h:76
itk::CommonEnums::IOPixel
IOPixel
Definition: itkCommonEnums.h:49
itk::DCMTKSequence::print
void print(std::ostream &out) const
Definition: itkDCMTKFileReader.h:235
itk::ByteSwapper::SwapFromSystemToBigEndian
static void SwapFromSystemToBigEndian(T *p)
itk::CompareDCMTKFileReaders
bool CompareDCMTKFileReaders(DCMTKFileReader *a, DCMTKFileReader *b)
itkMacro.h
itk::DCMTKFileReader::GetElementDS
int GetElementDS(const unsigned short group, const unsigned short element, unsigned short count, TType *target, const bool throwException=true) const
Definition: itkDCMTKFileReader.h:277
itk::DCMTKSequence
class ITK_FORWARD_EXPORT DCMTKSequence
Definition: itkDCMTKFileReader.h:61
itk::DCMTKFileReader
Definition: itkDCMTKFileReader.h:244
itk::DCMTKFileReader::m_FileName
std::string m_FileName
Definition: itkDCMTKFileReader.h:505
itkImageIOBase.h
itkIntTypes.h
DCMTKExceptionOrErrorReturn
#define DCMTKExceptionOrErrorReturn(body)
Definition: itkDCMTKFileReader.h:46
itk
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....
Definition: itkAnnulusOperator.h:24
itk::ByteSwapper::SwapFromSystemToLittleEndian
static void SwapFromSystemToLittleEndian(T *p)