Mercurial > hg > orthanc
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. |