Slicer  4.11
Slicer is a multi-platform, free and open source software package for visualization and medical image computing
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 // XXX # Workaround bug in packaging of DCMTK 3.6.0 on Debian.
22 // # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=637687
23 #ifndef HAVE_CONFIG_H
24 #define HAVE_CONFIG_H
25 #endif
26 
27 #include <stack>
28 #include <vector>
29 #include "itkByteSwapper.h"
30 #include "itkIntTypes.h"
31 #include "vnl/vnl_vector.h"
32 #include "dcmtk/dcmdata/dcxfer.h"
33 #include "dcmtk/dcmdata/dcvrds.h"
34 #include "dcmtk/dcmdata/dcstack.h"
35 #include "dcmtk/dcmdata/dcdatset.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 DCMTKException(body) \
47  { \
48  if(throwException) \
49  { \
50  itkGenericExceptionMacro(body); \
51  } \
52  else \
53  { \
54  return EXIT_FAILURE; \
55  } \
56  }
57 
58 namespace itk
59 {
61 {
62 public:
63  DCMTKSequence() = default;
64  void SetDcmSequenceOfItems(DcmSequenceOfItems *seq);
65  int card();
66  int GetSequence(unsigned long index,
67  DCMTKSequence &target,bool throwException = true);
68  int GetStack(unsigned short group,
69  unsigned short element,
70  DcmStack *resultStack, bool throwException = true);
71  int GetElementCS(unsigned short group,
72  unsigned short element,
73  std::string &target,
74  bool throwException = true);
75  int GetElementFD(unsigned short group,
76  unsigned short element,
77  double * &target,
78  bool throwException = true);
79  int GetElementFD(unsigned short group,
80  unsigned short element,
81  double &target,
82  bool throwException = true);
83  int GetElementDS(unsigned short group,
84  unsigned short element,
85  std::string &target,
86  bool throwException = true);
87  int GetElementTM(unsigned short group,
88  unsigned short element,
89  std::string &target,
90  bool throwException = true);
94  template <typename TType>
95  int GetElementDS(unsigned short group,
96  unsigned short element,
97  unsigned short count,
98  TType *target,
99  bool throwException)
100  {
101  DcmStack resultStack;
102  this->GetStack(group,element,&resultStack);
103  DcmDecimalString *dsItem =
104  dynamic_cast<DcmDecimalString *>(resultStack.top());
105  if(dsItem == nullptr)
106  {
107  DCMTKException(<< "Can't get DecimalString Element at tag "
108  << std::hex << group << " "
109  << element << std::dec);
110  }
111 
112  OFVector<Float64> doubleVals;
113  if(dsItem->getFloat64Vector(doubleVals) != EC_Normal)
114  {
115  DCMTKException(<< "Can't extract Array from DecimalString " << std::hex
116  << group << " " << std::hex
117  << element << std::dec);
118  }
119  if(doubleVals.size() != count)
120  {
121  DCMTKException(<< "DecimalString " << std::hex
122  << group << " " << std::hex
123  << element << " expected "
124  << count << "items, but found "
125  << doubleVals.size() << std::dec);
126 
127  }
128  for(unsigned i = 0; i < count; i++)
129  {
130  target[i] = static_cast<TType>(doubleVals[i]);
131  }
132  return EXIT_SUCCESS;
133  }
134  int GetElementSQ(unsigned short group,
135  unsigned short element,
136  DCMTKSequence &target,
137  bool throwException = true);
138 private:
139  DcmSequenceOfItems *m_DcmSequenceOfItems{nullptr};
140 };
141 
143 {
144 public:
146 
147  DCMTKFileReader() = default;
149 
150  void SetFileName(const std::string &fileName);
151 
152  const std::string &GetFileName() const;
153 
154  void LoadFile();
155 
156  int GetElementLO(unsigned short group,
157  unsigned short element,
158  std::string &target,
159  bool throwException = true);
160  int GetElementLO(unsigned short group,
161  unsigned short element,
162  std::vector<std::string> &target,
163  bool throwException = true);
164 
168  template <typename TType>
169  int GetElementDS(unsigned short group,
170  unsigned short element,
171  unsigned short count,
172  TType *target,
173  bool throwException = true)
174  {
175  DcmTagKey tagkey(group,element);
176  DcmElement *el;
177  if(this->m_Dataset->findAndGetElement(tagkey,el) != EC_Normal)
178  {
179  DCMTKException(<< "Can't find tag " << std::hex
180  << group << " " << std::hex
181  << element << std::dec);
182  }
183  DcmDecimalString *dsItem = dynamic_cast<DcmDecimalString *>(el);
184  if(dsItem == nullptr)
185  {
186  DCMTKException(<< "Can't find DecimalString element " << std::hex
187  << group << " " << std::hex
188  << element << std::dec);
189  }
190  OFVector<Float64> doubleVals;
191  if(dsItem->getFloat64Vector(doubleVals) != EC_Normal)
192  {
193  DCMTKException(<< "Can't extract Array from DecimalString " << std::hex
194  << group << " " << std::hex
195  << element << std::dec);
196  }
197  if(doubleVals.size() != count)
198  {
199  DCMTKException(<< "DecimalString " << std::hex
200  << group << " " << std::hex
201  << element << " expected "
202  << count << "items, but found "
203  << doubleVals.size() << std::dec);
204 
205  }
206  for(unsigned i = 0; i < count; i++)
207  {
208  target[i] = static_cast<TType>(doubleVals[i]);
209  }
210  return EXIT_SUCCESS;
211  }
212 
213  template <typename TType>
214  int GetElementDSorOB(unsigned short group,
215  unsigned short element,
216  TType &target,
217  bool throwException = true)
218  {
219  if(this->GetElementDS<TType>(group,element,1,&target,false) == EXIT_SUCCESS)
220  {
221  return EXIT_SUCCESS;
222  }
223  std::string val;
224  if(this->GetElementOB(group,element,val) != EXIT_SUCCESS)
225  {
226  DCMTKException(<< "Can't find DecimalString element " << std::hex
227  << group << " " << std::hex
228  << element << std::dec);
229  }
230  const char *data = val.c_str();
231  const TType *fptr = reinterpret_cast<const TType *>(data);
232  target = *fptr;
233  switch(this->GetTransferSyntax())
234  {
235  case EXS_LittleEndianImplicit:
236  case EXS_LittleEndianExplicit:
237  itk::ByteSwapper<TType>::SwapFromSystemToLittleEndian(&target);
238  break;
239  case EXS_BigEndianImplicit:
240  case EXS_BigEndianExplicit:
241  itk::ByteSwapper<TType>::SwapFromSystemToBigEndian(&target);
242  break;
243  default:
244  break;
245  }
246  return EXIT_SUCCESS;
247 
248  }
251  int GetElementDS(unsigned short group,
252  unsigned short element,
253  std::string &target,
254  bool throwException = true);
255  int GetElementFD(unsigned short group,
256  unsigned short element,
257  double &target,
258  bool throwException = true);
259  int GetElementFD(unsigned short group,
260  unsigned short element,
261  double * &target,
262  bool throwException = true);
263  int GetElementFL(unsigned short group,
264  unsigned short element,
265  float &target,
266  bool throwException = true);
267  int GetElementFLorOB(unsigned short group,
268  unsigned short element,
269  float &target,
270  bool throwException = true);
271 
272  int GetElementUS(unsigned short group,
273  unsigned short element,
274  unsigned short &target,
275  bool throwException = true);
276  int GetElementUS(unsigned short group,
277  unsigned short element,
278  unsigned short *&target,
279  bool throwException = true);
282  int GetElementCS(unsigned short group,
283  unsigned short element,
284  std::string &target,
285  bool throwException = true);
286 
289  int GetElementPN(unsigned short group,
290  unsigned short element,
291  std::string &target,
292  bool throwException = true);
293 
296  int GetElementIS(unsigned short group,
297  unsigned short element,
298  ::itk::int32_t &target,
299  bool throwException = true);
300 
301  int GetElementISorOB(unsigned short group,
302  unsigned short element,
303  ::itk::int32_t &target,
304  bool throwException = true);
307  int GetElementOB(unsigned short group,
308  unsigned short element,
309  std::string &target,
310  bool throwException = true);
311 
312  int GetElementSQ(unsigned short group,
313  unsigned short entry,
314  DCMTKSequence &sequence,
315  bool throwException = true);
316 
317  int GetElementUI(unsigned short group,
318  unsigned short entry,
319  std::string &target,
320  bool throwException = true);
321 
322  int GetElementDA(unsigned short group,
323  unsigned short element,
324  std::string &target,
325  bool throwException = true);
326 
327  int GetElementTM(unsigned short group,
328  unsigned short element,
329  std::string &target,
330  bool throwException = true);
331 
332  int GetDirCosines(vnl_vector<double> &dir1,
333  vnl_vector<double> &dir2,
334  vnl_vector<double> &dir3);
335 
336  int GetFrameCount() const;
337 
338  int GetSlopeIntercept(double &slope, double &intercept);
339 
340  int GetDimensions(unsigned short &rows, unsigned short &columns);
341 
342  ImageIOBase::IOComponentType GetImageDataType();
343  ImageIOBase::IOPixelType GetImagePixelType();
344 
345  int GetSpacing(double *spacing);
346  int GetOrigin(double *origin);
347 
348  E_TransferSyntax GetTransferSyntax() const;
349 
350  long GetFileNumber() const;
351 
352  static void
353  AddDictEntry(DcmDictEntry *entry);
354 
355 private:
356  static unsigned ascii2hex(char c);
357 
358  static std::string ConvertFromOB(OFString &toConvert);
359 
360  std::string m_FileName;
361  DcmFileFormat* m_DFile{nullptr};
362  DcmDataset * m_Dataset{nullptr};
363  E_TransferSyntax m_Xfer{EXS_Unknown};
364  Sint32 m_FrameCount{0};
365  long m_FileNumber{-1L};
366 };
367 
368 extern bool CompareDCMTKFileReaders(DCMTKFileReader *a, DCMTKFileReader *b);
369 }
370 
371 #endif // itkDCMTKFileReader_h
int GetDimensions(unsigned short &rows, unsigned short &columns)
int GetElementSQ(unsigned short group, unsigned short entry, DCMTKSequence &sequence, bool throwException=true)
int GetElementDSorOB(unsigned short group, unsigned short element, TType &target, bool throwException=true)
int GetSlopeIntercept(double &slope, double &intercept)
int GetElementOB(unsigned short group, unsigned short element, std::string &target, bool throwException=true)
int GetElementCS(unsigned short group, unsigned short element, std::string &target, bool throwException=true)
ImageIOBase::IOComponentType GetImageDataType()
int GetElementIS(unsigned short group, unsigned short element, ::itk::int32_t &target, bool throwException=true)
int GetElementDA(unsigned short group, unsigned short element, std::string &target, bool throwException=true)
Simplified inverse ITK transforms.
const std::string & GetFileName() const
long GetFileNumber() const
int GetElementDS(unsigned short group, unsigned short element, unsigned short count, TType *target, bool throwException)
static void AddDictEntry(DcmDictEntry *entry)
bool CompareDCMTKFileReaders(DCMTKFileReader *a, DCMTKFileReader *b)
#define DCMTKException(body)
int GetElementDS(unsigned short group, unsigned short element, unsigned short count, TType *target, bool throwException=true)
int GetElementFLorOB(unsigned short group, unsigned short element, float &target, bool throwException=true)
int GetSequence(unsigned long index, DCMTKSequence &target, bool throwException=true)
int GetElementFL(unsigned short group, unsigned short element, float &target, bool throwException=true)
int GetElementTM(unsigned short group, unsigned short element, std::string &target, bool throwException=true)
int GetElementUI(unsigned short group, unsigned short entry, std::string &target, bool throwException=true)
int GetElementSQ(unsigned short group, unsigned short element, DCMTKSequence &target, bool throwException=true)
void SetDcmSequenceOfItems(DcmSequenceOfItems *seq)
int GetElementTM(unsigned short group, unsigned short element, std::string &target, bool throwException=true)
int GetSpacing(double *spacing)
int GetDirCosines(vnl_vector< double > &dir1, vnl_vector< double > &dir2, vnl_vector< double > &dir3)
int GetFrameCount() const
int GetElementISorOB(unsigned short group, unsigned short element, ::itk::int32_t &target, bool throwException=true)
ImageIOBase::IOPixelType GetImagePixelType()
int GetElementPN(unsigned short group, unsigned short element, std::string &target, bool throwException=true)
int GetStack(unsigned short group, unsigned short element, DcmStack *resultStack, bool throwException=true)
int GetElementLO(unsigned short group, unsigned short element, std::string &target, bool throwException=true)
int GetElementFD(unsigned short group, unsigned short element, double &target, bool throwException=true)
int GetElementUS(unsigned short group, unsigned short element, unsigned short &target, bool throwException=true)
void SetFileName(const std::string &fileName)
DCMTKFileReader()=default
DCMTKSequence()=default
int GetElementDS(unsigned short group, unsigned short element, std::string &target, bool throwException=true)
E_TransferSyntax GetTransferSyntax() const
int GetOrigin(double *origin)
int GetElementCS(unsigned short group, unsigned short element, std::string &target, bool throwException=true)
int GetElementFD(unsigned short group, unsigned short element, double *&target, bool throwException=true)