comparison Core/DicomParsing/FromDcmtkBridge.cpp @ 2554:ea63d9f90377

/tags now returns multiple numerical values in a \ separated string
author am@osimis.io
date Wed, 02 May 2018 11:50:47 +0200
parents 832217e4e872
children 47d812308d63
comparison
equal deleted inserted replaced
2553:7853c9a67605 2554:ea63d9f90377
55 #include <limits> 55 #include <limits>
56 56
57 #include <boost/lexical_cast.hpp> 57 #include <boost/lexical_cast.hpp>
58 #include <boost/filesystem.hpp> 58 #include <boost/filesystem.hpp>
59 #include <boost/algorithm/string/predicate.hpp> 59 #include <boost/algorithm/string/predicate.hpp>
60 #include <boost/algorithm/string/join.hpp>
60 61
61 #include <dcmtk/dcmdata/dcdeftag.h> 62 #include <dcmtk/dcmdata/dcdeftag.h>
62 #include <dcmtk/dcmdata/dcdicent.h> 63 #include <dcmtk/dcmdata/dcdicent.h>
63 #include <dcmtk/dcmdata/dcdict.h> 64 #include <dcmtk/dcmdata/dcdict.h>
64 #include <dcmtk/dcmdata/dcfilefo.h> 65 #include <dcmtk/dcmdata/dcfilefo.h>
196 DcmDataDictionary* operator->() 197 DcmDataDictionary* operator->()
197 { 198 {
198 return &dictionary_; 199 return &dictionary_;
199 } 200 }
200 }; 201 };
202
203
204 #define DCMTK_TO_CTYPE_CONVERTER(converter, cType, dcmtkType, getter) \
205 \
206 struct converter \
207 { \
208 typedef cType CType; \
209 \
210 static bool Apply(CType& result, \
211 DcmElement& element, \
212 size_t i) \
213 { \
214 return dynamic_cast<dcmtkType&>(element).getter(result, i).good(); \
215 } \
216 };
217
218 DCMTK_TO_CTYPE_CONVERTER(DcmtkToSint32Converter, Sint32, DcmSignedLong, getSint32)
219 DCMTK_TO_CTYPE_CONVERTER(DcmtkToSint16Converter, Sint16, DcmSignedShort, getSint16)
220 DCMTK_TO_CTYPE_CONVERTER(DcmtkToUint32Converter, Uint32, DcmUnsignedLong, getUint32)
221 DCMTK_TO_CTYPE_CONVERTER(DcmtkToUint16Converter, Uint16, DcmUnsignedShort, getUint16)
222 DCMTK_TO_CTYPE_CONVERTER(DcmtkToFloat32Converter, Float32, DcmFloatingPointSingle, getFloat32)
223 DCMTK_TO_CTYPE_CONVERTER(DcmtkToFloat64Converter, Float64, DcmFloatingPointDouble, getFloat64)
224
225
226 template <typename F>
227 static DicomValue* ApplyDcmtkToCTypeConverter(DcmElement& element)
228 {
229 F f;
230 typename F::CType value;
231
232 if (element.getLength() > sizeof(typename F::CType)
233 && (element.getLength() % sizeof(typename F::CType)) == 0)
234 {
235 size_t count = element.getLength() / sizeof(typename F::CType);
236 std::vector<std::string> strings;
237 for (size_t i = 0; i < count; i++) {
238 if (f.Apply(value, element, i)) {
239 strings.push_back(boost::lexical_cast<std::string>(value));
240 }
241 }
242 return new DicomValue(boost::algorithm::join(strings, "\\"), false);
243 }
244 else if (f.Apply(value, element, 0)) {
245 return new DicomValue(boost::lexical_cast<std::string>(value), false);
246 }
247 else {
248 return new DicomValue;
249 }
250 }
251
201 } 252 }
202 253
203 254
204 void FromDcmtkBridge::InitializeDictionary(bool loadPrivateDictionary) 255 void FromDcmtkBridge::InitializeDictionary(bool loadPrivateDictionary)
205 { 256 {
570 * Numeric types 621 * Numeric types
571 **/ 622 **/
572 623
573 case EVR_SL: // signed long 624 case EVR_SL: // signed long
574 { 625 {
575 Sint32 f; 626 return ApplyDcmtkToCTypeConverter<DcmtkToSint32Converter>(element);
576 if (dynamic_cast<DcmSignedLong&>(element).getSint32(f).good())
577 return new DicomValue(boost::lexical_cast<std::string>(f), false);
578 else
579 return new DicomValue;
580 } 627 }
581 628
582 case EVR_SS: // signed short 629 case EVR_SS: // signed short
583 { 630 {
584 Sint16 f; 631 return ApplyDcmtkToCTypeConverter<DcmtkToSint16Converter>(element);
585 if (dynamic_cast<DcmSignedShort&>(element).getSint16(f).good())
586 return new DicomValue(boost::lexical_cast<std::string>(f), false);
587 else
588 return new DicomValue;
589 } 632 }
590 633
591 case EVR_UL: // unsigned long 634 case EVR_UL: // unsigned long
592 { 635 {
593 Uint32 f; 636 return ApplyDcmtkToCTypeConverter<DcmtkToUint32Converter>(element);
594 if (dynamic_cast<DcmUnsignedLong&>(element).getUint32(f).good())
595 return new DicomValue(boost::lexical_cast<std::string>(f), false);
596 else
597 return new DicomValue;
598 } 637 }
599 638
600 case EVR_US: // unsigned short 639 case EVR_US: // unsigned short
601 { 640 {
602 Uint16 f; 641 return ApplyDcmtkToCTypeConverter<DcmtkToUint16Converter>(element);
603 if (dynamic_cast<DcmUnsignedShort&>(element).getUint16(f).good())
604 return new DicomValue(boost::lexical_cast<std::string>(f), false);
605 else
606 return new DicomValue;
607 } 642 }
608 643
609 case EVR_FL: // float single-precision 644 case EVR_FL: // float single-precision
610 { 645 {
611 Float32 f; 646 return ApplyDcmtkToCTypeConverter<DcmtkToFloat32Converter>(element);
612 if (dynamic_cast<DcmFloatingPointSingle&>(element).getFloat32(f).good())
613 return new DicomValue(boost::lexical_cast<std::string>(f), false);
614 else
615 return new DicomValue;
616 } 647 }
617 648
618 case EVR_FD: // float double-precision 649 case EVR_FD: // float double-precision
619 { 650 {
620 Float64 f; 651 return ApplyDcmtkToCTypeConverter<DcmtkToFloat64Converter>(element);
621 if (dynamic_cast<DcmFloatingPointDouble&>(element).getFloat64(f).good())
622 return new DicomValue(boost::lexical_cast<std::string>(f), false);
623 else
624 return new DicomValue;
625 } 652 }
626 653
627 654
628 /** 655 /**
629 * Attribute tag. 656 * Attribute tag.