# HG changeset patch # User Sebastien Jodogne # Date 1465476520 -7200 # Node ID 6301bbcbcaed931d9e305004e8b4ac58ffeb929a # Parent 9e021b2b348b6585bdbc2d8128844587152ba70e more generic support of value representations diff -r 9e021b2b348b -r 6301bbcbcaed Core/Enumerations.cpp --- a/Core/Enumerations.cpp Wed Jun 08 12:36:21 2016 +0200 +++ b/Core/Enumerations.cpp Thu Jun 09 14:48:40 2016 +0200 @@ -35,6 +35,7 @@ #include "OrthancException.h" #include "Toolbox.h" +#include "Logging.h" #include #include @@ -900,6 +901,151 @@ } + ValueRepresentation StringToValueRepresentation(const std::string& vr, + bool throwIfUnsupported) + { + if (vr == "AE") + { + return ValueRepresentation_ApplicationEntity; + } + else if (vr == "AS") + { + return ValueRepresentation_AgeString; + } + else if (vr == "AT") + { + return ValueRepresentation_AttributeTag; + } + else if (vr == "CS") + { + return ValueRepresentation_CodeString; + } + else if (vr == "DA") + { + return ValueRepresentation_Date; + } + else if (vr == "DS") + { + return ValueRepresentation_DecimalString; + } + else if (vr == "DT") + { + return ValueRepresentation_DateTime; + } + else if (vr == "FL") + { + return ValueRepresentation_FloatingPointSingle; + } + else if (vr == "FD") + { + return ValueRepresentation_FloatingPointDouble; + } + else if (vr == "IS") + { + return ValueRepresentation_IntegerString; + } + else if (vr == "LO") + { + return ValueRepresentation_LongString; + } + else if (vr == "LT") + { + return ValueRepresentation_LongText; + } + else if (vr == "OB") + { + return ValueRepresentation_OtherByte; + } + else if (vr == "OD") + { + return ValueRepresentation_OtherDouble; + } + else if (vr == "OF") + { + return ValueRepresentation_OtherFloat; + } + else if (vr == "OL") + { + return ValueRepresentation_OtherLong; + } + else if (vr == "OW") + { + return ValueRepresentation_OtherWord; + } + else if (vr == "PN") + { + return ValueRepresentation_PatientName; + } + else if (vr == "SH") + { + return ValueRepresentation_ShortString; + } + else if (vr == "SL") + { + return ValueRepresentation_SignedLong; + } + else if (vr == "SQ") + { + return ValueRepresentation_Sequence; + } + else if (vr == "SS") + { + return ValueRepresentation_SignedShort; + } + else if (vr == "ST") + { + return ValueRepresentation_ShortText; + } + else if (vr == "TM") + { + return ValueRepresentation_Time; + } + else if (vr == "UC") + { + return ValueRepresentation_UnlimitedCharacters; + } + else if (vr == "UI") + { + return ValueRepresentation_UniqueIdentifier; + } + else if (vr == "UL") + { + return ValueRepresentation_UnsignedLong; + } + else if (vr == "UN") + { + return ValueRepresentation_Unknown; + } + else if (vr == "UR") + { + return ValueRepresentation_UniversalResource; + } + else if (vr == "US") + { + return ValueRepresentation_UnsignedShort; + } + else if (vr == "UT") + { + return ValueRepresentation_UnlimitedText; + } + else + { + std::string s = "Unsupported value representation encountered: " + vr; + + if (throwIfUnsupported) + { + LOG(ERROR) << s; + throw OrthancException(ErrorCode_ParameterOutOfRange); + } + else + { + LOG(INFO) << s; + return ValueRepresentation_NotSupported; + } + } + } + + unsigned int GetBytesPerPixel(PixelFormat format) { switch (format) diff -r 9e021b2b348b -r 6301bbcbcaed Core/Enumerations.h --- a/Core/Enumerations.h Wed Jun 08 12:36:21 2016 +0200 +++ b/Core/Enumerations.h Thu Jun 09 14:48:40 2016 +0200 @@ -32,6 +32,8 @@ #pragma once +#include + namespace Orthanc { enum Endianness @@ -385,6 +387,48 @@ /** + * The value representations Orthanc knows about. They correspond to + * the DICOM 2016b version of the standard. + * http://dicom.nema.org/medical/dicom/current/output/chtml/part05/sect_6.2.html + **/ + enum ValueRepresentation + { + ValueRepresentation_ApplicationEntity = 1, // AE + ValueRepresentation_AgeString = 2, // AS + ValueRepresentation_AttributeTag = 3, // AT (2 x uint16_t) + ValueRepresentation_CodeString = 4, // CS + ValueRepresentation_Date = 5, // DA + ValueRepresentation_DecimalString = 6, // DS + ValueRepresentation_DateTime = 7, // DT + ValueRepresentation_FloatingPointSingle = 8, // FL (float) + ValueRepresentation_FloatingPointDouble = 9, // FD (double) + ValueRepresentation_IntegerString = 10, // IS + ValueRepresentation_LongString = 11, // LO + ValueRepresentation_LongText = 12, // LT + ValueRepresentation_OtherByte = 13, // OB + ValueRepresentation_OtherDouble = 14, // OD + ValueRepresentation_OtherFloat = 15, // OF + ValueRepresentation_OtherLong = 16, // OL + ValueRepresentation_OtherWord = 17, // OW + ValueRepresentation_PatientName = 18, // PN + ValueRepresentation_ShortString = 19, // SH + ValueRepresentation_SignedLong = 20, // SL (int32_t) + ValueRepresentation_Sequence = 21, // SQ + ValueRepresentation_SignedShort = 22, // SS (int16_t) + ValueRepresentation_ShortText = 23, // ST + ValueRepresentation_Time = 24, // TM + ValueRepresentation_UnlimitedCharacters = 25, // UC + ValueRepresentation_UniqueIdentifier = 26, // UI (UID) + ValueRepresentation_UnsignedLong = 27, // UL (uint32_t) + ValueRepresentation_Unknown = 28, // UN + ValueRepresentation_UniversalResource = 29, // UR (URI or URL) + ValueRepresentation_UnsignedShort = 30, // US (uint16_t) + ValueRepresentation_UnlimitedText = 31, // UT + ValueRepresentation_NotSupported // Not supported by Orthanc, or tag not in dictionary + }; + + + /** * WARNING: Do not change the explicit values in the enumerations * below this point. This would result in incompatible databases * between versions of Orthanc! @@ -459,7 +503,10 @@ ImageFormat StringToImageFormat(const char* format); - LogLevel StringToLogLevel(const char* format); + LogLevel StringToLogLevel(const char* level); + + ValueRepresentation StringToValueRepresentation(const std::string& vr, + bool throwIfUnsupported); unsigned int GetBytesPerPixel(PixelFormat format); diff -r 9e021b2b348b -r 6301bbcbcaed OrthancServer/DicomProtocol/DicomUserConnection.cpp --- a/OrthancServer/DicomProtocol/DicomUserConnection.cpp Wed Jun 08 12:36:21 2016 +0200 +++ b/OrthancServer/DicomProtocol/DicomUserConnection.cpp Thu Jun 09 14:48:40 2016 +0200 @@ -496,7 +496,7 @@ for (std::set::const_iterator it = tags.begin(); it != tags.end(); ++it) { - if (FromDcmtkBridge::GetValueRepresentation(*it) == ValueRepresentation_Date) + if (FromDcmtkBridge::LookupValueRepresentation(*it) == ValueRepresentation_Date) { // Replace a "*" query by an empty query ("") for "date" // value representations. Necessary to search over dates diff -r 9e021b2b348b -r 6301bbcbcaed OrthancServer/FromDcmtkBridge.cpp --- a/OrthancServer/FromDcmtkBridge.cpp Wed Jun 08 12:36:21 2016 +0200 +++ b/OrthancServer/FromDcmtkBridge.cpp Thu Jun 09 14:48:40 2016 +0200 @@ -37,6 +37,7 @@ #endif #include "FromDcmtkBridge.h" +#include "ToDcmtkBridge.h" #include "../Core/Logging.h" #include "../Core/Toolbox.h" #include "../Core/Uuid.h" @@ -232,7 +233,7 @@ void FromDcmtkBridge::RegisterDictionaryTag(const DicomTag& tag, - const DcmEVR& vr, + ValueRepresentation vr, const std::string& name, unsigned int minMultiplicity, unsigned int maxMultiplicity) @@ -253,13 +254,15 @@ throw OrthancException(ErrorCode_ParameterOutOfRange); } - LOG(INFO) << "Registering tag in dictionary: " << tag << " " << (DcmVR(vr).getValidVRName()) << " " + DcmEVR evr = ToDcmtkBridge::Convert(vr); + + LOG(INFO) << "Registering tag in dictionary: " << tag << " " << (DcmVR(evr).getValidVRName()) << " " << name << " (multiplicity: " << minMultiplicity << "-" << (arbitrary ? "n" : boost::lexical_cast(maxMultiplicity)) << ")"; std::auto_ptr entry(new DcmDictEntry(tag.GetGroup(), tag.GetElement(), - vr, name.c_str(), + evr, name.c_str(), static_cast(minMultiplicity), static_cast(maxMultiplicity), NULL /* version */, @@ -1069,28 +1072,115 @@ } - ValueRepresentation FromDcmtkBridge::GetValueRepresentation(const DicomTag& tag) + ValueRepresentation FromDcmtkBridge::LookupValueRepresentation(const DicomTag& tag) { DcmTag t(tag.GetGroup(), tag.GetElement()); - switch (t.getEVR()) + return Convert(t.getEVR()); + } + + ValueRepresentation FromDcmtkBridge::Convert(const DcmEVR vr) + { + switch (vr) { - case EVR_PN: - return ValueRepresentation_PatientName; + case EVR_AE: + return ValueRepresentation_ApplicationEntity; + + case EVR_AS: + return ValueRepresentation_AgeString; + + case EVR_AT: + return ValueRepresentation_AttributeTag; + + case EVR_CS: + return ValueRepresentation_CodeString; case EVR_DA: return ValueRepresentation_Date; + case EVR_DS: + return ValueRepresentation_DecimalString; + case EVR_DT: return ValueRepresentation_DateTime; + case EVR_FL: + return ValueRepresentation_FloatingPointSingle; + + case EVR_FD: + return ValueRepresentation_FloatingPointDouble; + + case EVR_IS: + return ValueRepresentation_IntegerString; + + case EVR_LO: + return ValueRepresentation_LongString; + + case EVR_LT: + return ValueRepresentation_LongText; + + case EVR_OB: + return ValueRepresentation_OtherByte; + + // Not supported as of DCMTK 3.6.0 + /*case EVR_OD: + return ValueRepresentation_OtherDouble;*/ + + case EVR_OF: + return ValueRepresentation_OtherFloat; + + // Not supported as of DCMTK 3.6.0 + /*case EVR_OL: + return ValueRepresentation_OtherLong;*/ + + case EVR_OW: + return ValueRepresentation_OtherWord; + + case EVR_PN: + return ValueRepresentation_PatientName; + + case EVR_SH: + return ValueRepresentation_ShortString; + + case EVR_SL: + return ValueRepresentation_SignedLong; + + case EVR_SQ: + return ValueRepresentation_Sequence; + + case EVR_SS: + return ValueRepresentation_SignedShort; + + case EVR_ST: + return ValueRepresentation_ShortText; + case EVR_TM: return ValueRepresentation_Time; - case EVR_SQ: - return ValueRepresentation_Sequence; + // Not supported as of DCMTK 3.6.0 + /*case EVR_UC: + return ValueRepresentation_UnlimitedCharacters;*/ + + case EVR_UI: + return ValueRepresentation_UniqueIdentifier; + + case EVR_UL: + return ValueRepresentation_UnsignedLong; + + case EVR_UN: + return ValueRepresentation_Unknown; + + // Not supported as of DCMTK 3.6.0 + /*case EVR_UR: + return ValueRepresentation_UniversalResource;*/ + + case EVR_US: + return ValueRepresentation_UnsignedShort; + + case EVR_UT: + return ValueRepresentation_UnlimitedText; default: - return ValueRepresentation_Other; + return ValueRepresentation_NotSupported; } } @@ -1477,93 +1567,6 @@ } - DcmEVR FromDcmtkBridge::ParseValueRepresentation(const std::string& s) - { - if (s == "AE") - return EVR_AE; - - if (s == "AS") - return EVR_AS; - - if (s == "AT") - return EVR_AT; - - if (s == "CS") - return EVR_CS; - - if (s == "DA") - return EVR_DA; - - if (s == "DS") - return EVR_DS; - - if (s == "DT") - return EVR_DT; - - if (s == "FD") - return EVR_FD; - - if (s == "FL") - return EVR_FL; - - if (s == "IS") - return EVR_IS; - - if (s == "LO") - return EVR_LO; - - if (s == "LT") - return EVR_LT; - - if (s == "OB") - return EVR_OB; - - if (s == "OF") - return EVR_OF; - - if (s == "OW") - return EVR_OW; - - if (s == "PN") - return EVR_PN; - - if (s == "SH") - return EVR_SH; - - if (s == "SL") - return EVR_SL; - - if (s == "SQ") - return EVR_SQ; - - if (s == "SS") - return EVR_SS; - - if (s == "ST") - return EVR_ST; - - if (s == "TM") - return EVR_TM; - - if (s == "UI") - return EVR_UI; - - if (s == "UL") - return EVR_UL; - - if (s == "UN") - return EVR_UN; - - if (s == "US") - return EVR_US; - - if (s == "UT") - return EVR_UT; - - throw OrthancException(ErrorCode_ParameterOutOfRange); - } - - DcmPixelSequence* FromDcmtkBridge::GetPixelSequence(DcmDataset& dataset) { DcmElement *element = NULL; diff -r 9e021b2b348b -r 6301bbcbcaed OrthancServer/FromDcmtkBridge.h --- a/OrthancServer/FromDcmtkBridge.h Wed Jun 08 12:36:21 2016 +0200 +++ b/OrthancServer/FromDcmtkBridge.h Thu Jun 09 14:48:40 2016 +0200 @@ -50,7 +50,7 @@ static void InitializeDictionary(); static void RegisterDictionaryTag(const DicomTag& tag, - const DcmEVR& vr, + ValueRepresentation vr, const std::string& name, unsigned int minMultiplicity, unsigned int maxMultiplicity); @@ -131,7 +131,9 @@ static bool SaveToMemoryBuffer(std::string& buffer, DcmDataset& dataSet); - static ValueRepresentation GetValueRepresentation(const DicomTag& tag); + static ValueRepresentation Convert(DcmEVR vr); + + static ValueRepresentation LookupValueRepresentation(const DicomTag& tag); static DcmElement* CreateElementForTag(const DicomTag& tag); @@ -146,8 +148,6 @@ bool decodeDataUriScheme, Encoding dicomEncoding); - static DcmEVR ParseValueRepresentation(const std::string& s); - static DcmPixelSequence* GetPixelSequence(DcmDataset& dataset); static Encoding ExtractEncoding(const Json::Value& json, diff -r 9e021b2b348b -r 6301bbcbcaed OrthancServer/OrthancFindRequestHandler.cpp --- a/OrthancServer/OrthancFindRequestHandler.cpp Wed Jun 08 12:36:21 2016 +0200 +++ b/OrthancServer/OrthancFindRequestHandler.cpp Thu Jun 09 14:48:40 2016 +0200 @@ -610,7 +610,7 @@ if (FilterQueryTag(value, level, tag, modality.GetManufacturer())) { - ValueRepresentation vr = FromDcmtkBridge::GetValueRepresentation(tag); + ValueRepresentation vr = FromDcmtkBridge::LookupValueRepresentation(tag); // DICOM specifies that searches must be case sensitive, except // for tags with a PN value representation diff -r 9e021b2b348b -r 6301bbcbcaed OrthancServer/OrthancInitialization.cpp --- a/OrthancServer/OrthancInitialization.cpp Wed Jun 08 12:36:21 2016 +0200 +++ b/OrthancServer/OrthancInitialization.cpp Thu Jun 09 14:48:40 2016 +0200 @@ -42,6 +42,7 @@ #include "ServerEnumerations.h" #include "DatabaseWrapper.h" #include "FromDcmtkBridge.h" +#include "ToDcmtkBridge.h" #include #include @@ -378,7 +379,7 @@ } DicomTag tag(FromDcmtkBridge::ParseTag(tags[i])); - DcmEVR vr = FromDcmtkBridge::ParseValueRepresentation(content[0].asString()); + ValueRepresentation vr = StringToValueRepresentation(content[0].asString(), true); std::string name = content[1].asString(); unsigned int minMultiplicity = (content.size() >= 2) ? content[2].asUInt() : 1; unsigned int maxMultiplicity = (content.size() >= 3) ? content[3].asUInt() : 1; diff -r 9e021b2b348b -r 6301bbcbcaed OrthancServer/Search/HierarchicalMatcher.cpp --- a/OrthancServer/Search/HierarchicalMatcher.cpp Wed Jun 08 12:36:21 2016 +0200 +++ b/OrthancServer/Search/HierarchicalMatcher.cpp Thu Jun 09 14:48:40 2016 +0200 @@ -92,7 +92,7 @@ continue; } - ValueRepresentation vr = FromDcmtkBridge::GetValueRepresentation(tag); + ValueRepresentation vr = FromDcmtkBridge::LookupValueRepresentation(tag); if (constraints_.find(tag) != constraints_.end() || sequences_.find(tag) != sequences_.end()) diff -r 9e021b2b348b -r 6301bbcbcaed OrthancServer/Search/IFindConstraint.cpp --- a/OrthancServer/Search/IFindConstraint.cpp Wed Jun 08 12:36:21 2016 +0200 +++ b/OrthancServer/Search/IFindConstraint.cpp Thu Jun 09 14:48:40 2016 +0200 @@ -47,7 +47,7 @@ const std::string& dicomQuery, bool caseSensitive) { - ValueRepresentation vr = FromDcmtkBridge::GetValueRepresentation(tag); + ValueRepresentation vr = FromDcmtkBridge::LookupValueRepresentation(tag); if (vr == ValueRepresentation_Sequence) { diff -r 9e021b2b348b -r 6301bbcbcaed OrthancServer/ServerEnumerations.h --- a/OrthancServer/ServerEnumerations.h Wed Jun 08 12:36:21 2016 +0200 +++ b/OrthancServer/ServerEnumerations.h Thu Jun 09 14:48:40 2016 +0200 @@ -95,16 +95,6 @@ TransferSyntax_Rle }; - enum ValueRepresentation - { - ValueRepresentation_Other, - ValueRepresentation_PatientName, - ValueRepresentation_Date, - ValueRepresentation_DateTime, - ValueRepresentation_Time, - ValueRepresentation_Sequence - }; - enum DicomToJsonFormat { DicomToJsonFormat_Full, diff -r 9e021b2b348b -r 6301bbcbcaed OrthancServer/ToDcmtkBridge.cpp --- a/OrthancServer/ToDcmtkBridge.cpp Wed Jun 08 12:36:21 2016 +0200 +++ b/OrthancServer/ToDcmtkBridge.cpp Thu Jun 09 14:48:40 2016 +0200 @@ -36,6 +36,8 @@ #include #include +#include "../Core/OrthancException.h" + namespace Orthanc { @@ -55,4 +57,111 @@ return result.release(); } + + + DcmEVR ToDcmtkBridge::Convert(ValueRepresentation vr) + { + switch (vr) + { + case ValueRepresentation_ApplicationEntity: + return EVR_AE; + + case ValueRepresentation_AgeString: + return EVR_AS; + + case ValueRepresentation_AttributeTag: + return EVR_AT; + + case ValueRepresentation_CodeString: + return EVR_CS; + + case ValueRepresentation_Date: + return EVR_DA; + + case ValueRepresentation_DecimalString: + return EVR_DS; + + case ValueRepresentation_DateTime: + return EVR_DT; + + case ValueRepresentation_FloatingPointSingle: + return EVR_FL; + + case ValueRepresentation_FloatingPointDouble: + return EVR_FD; + + case ValueRepresentation_IntegerString: + return EVR_IS; + + case ValueRepresentation_LongString: + return EVR_LO; + + case ValueRepresentation_LongText: + return EVR_LT; + + case ValueRepresentation_OtherByte: + return EVR_OB; + + // Not supported as of DCMTK 3.6.0 + /*case ValueRepresentation_OtherDouble: + return EVR_OD;*/ + + case ValueRepresentation_OtherFloat: + return EVR_OF; + + // Not supported as of DCMTK 3.6.0 + /*case ValueRepresentation_OtherLong: + return EVR_OL;*/ + + case ValueRepresentation_OtherWord: + return EVR_OW; + + case ValueRepresentation_PatientName: + return EVR_PN; + + case ValueRepresentation_ShortString: + return EVR_SH; + + case ValueRepresentation_SignedLong: + return EVR_SL; + + case ValueRepresentation_Sequence: + return EVR_SQ; + + case ValueRepresentation_SignedShort: + return EVR_SS; + + case ValueRepresentation_ShortText: + return EVR_ST; + + case ValueRepresentation_Time: + return EVR_TM; + + // Not supported as of DCMTK 3.6.0 + /*case ValueRepresentation_UnlimitedCharacters: + return EVR_UC;*/ + + case ValueRepresentation_UniqueIdentifier: + return EVR_UI; + + case ValueRepresentation_UnsignedLong: + return EVR_UL; + + case ValueRepresentation_Unknown: + return EVR_UN; + + // Not supported as of DCMTK 3.6.0 + /*case ValueRepresentation_UniversalResource: + return EVR_UR;*/ + + case ValueRepresentation_UnsignedShort: + return EVR_US; + + case ValueRepresentation_UnlimitedText: + return EVR_UT; + + default: + throw OrthancException(ErrorCode_ParameterOutOfRange); + } + } } diff -r 9e021b2b348b -r 6301bbcbcaed OrthancServer/ToDcmtkBridge.h --- a/OrthancServer/ToDcmtkBridge.h Wed Jun 08 12:36:21 2016 +0200 +++ b/OrthancServer/ToDcmtkBridge.h Thu Jun 09 14:48:40 2016 +0200 @@ -46,5 +46,7 @@ } static DcmDataset* Convert(const DicomMap& map); + + static DcmEVR Convert(ValueRepresentation vr); }; } diff -r 9e021b2b348b -r 6301bbcbcaed Plugins/Engine/OrthancPlugins.cpp --- a/Plugins/Engine/OrthancPlugins.cpp Wed Jun 08 12:36:21 2016 +0200 +++ b/Plugins/Engine/OrthancPlugins.cpp Thu Jun 09 14:48:40 2016 +0200 @@ -2126,7 +2126,7 @@ { p.target->group = entry->getKey().getGroup(); p.target->element = entry->getKey().getElement(); - p.target->vr = Plugins::Convert(entry->getEVR()); + p.target->vr = Plugins::Convert(FromDcmtkBridge::Convert(entry->getEVR())); p.target->minMultiplicity = static_cast(entry->getVMMin()); p.target->maxMultiplicity = (entry->getVMMax() == DcmVariableVM ? 0 : static_cast(entry->getVMMax())); } diff -r 9e021b2b348b -r 6301bbcbcaed Plugins/Engine/PluginsEnumerations.cpp --- a/Plugins/Engine/PluginsEnumerations.cpp Wed Jun 08 12:36:21 2016 +0200 +++ b/Plugins/Engine/PluginsEnumerations.cpp Thu Jun 09 14:48:40 2016 +0200 @@ -326,185 +326,201 @@ } -#if !defined(ORTHANC_ENABLE_DCMTK) || ORTHANC_ENABLE_DCMTK != 0 - DcmEVR Convert(OrthancPluginValueRepresentation vr) + ValueRepresentation Convert(OrthancPluginValueRepresentation vr) { switch (vr) { case OrthancPluginValueRepresentation_AE: - return EVR_AE; + return ValueRepresentation_ApplicationEntity; case OrthancPluginValueRepresentation_AS: - return EVR_AS; + return ValueRepresentation_AgeString; case OrthancPluginValueRepresentation_AT: - return EVR_AT; + return ValueRepresentation_AttributeTag; case OrthancPluginValueRepresentation_CS: - return EVR_CS; + return ValueRepresentation_CodeString; case OrthancPluginValueRepresentation_DA: - return EVR_DA; + return ValueRepresentation_Date; case OrthancPluginValueRepresentation_DS: - return EVR_DS; + return ValueRepresentation_DecimalString; case OrthancPluginValueRepresentation_DT: - return EVR_DT; + return ValueRepresentation_DateTime; case OrthancPluginValueRepresentation_FD: - return EVR_FD; + return ValueRepresentation_FloatingPointDouble; case OrthancPluginValueRepresentation_FL: - return EVR_FL; + return ValueRepresentation_FloatingPointSingle; case OrthancPluginValueRepresentation_IS: - return EVR_IS; + return ValueRepresentation_IntegerString; case OrthancPluginValueRepresentation_LO: - return EVR_LO; + return ValueRepresentation_LongString; case OrthancPluginValueRepresentation_LT: - return EVR_LT; + return ValueRepresentation_LongText; case OrthancPluginValueRepresentation_OB: - return EVR_OB; + return ValueRepresentation_OtherByte; case OrthancPluginValueRepresentation_OF: - return EVR_OF; + return ValueRepresentation_OtherFloat; case OrthancPluginValueRepresentation_OW: - return EVR_OW; + return ValueRepresentation_OtherWord; case OrthancPluginValueRepresentation_PN: - return EVR_PN; + return ValueRepresentation_PatientName; case OrthancPluginValueRepresentation_SH: - return EVR_SH; + return ValueRepresentation_ShortString; case OrthancPluginValueRepresentation_SL: - return EVR_SL; + return ValueRepresentation_SignedLong; case OrthancPluginValueRepresentation_SQ: - return EVR_SQ; + return ValueRepresentation_Sequence; case OrthancPluginValueRepresentation_SS: - return EVR_SS; + return ValueRepresentation_SignedShort; case OrthancPluginValueRepresentation_ST: - return EVR_ST; + return ValueRepresentation_ShortText; case OrthancPluginValueRepresentation_TM: - return EVR_TM; + return ValueRepresentation_Time; case OrthancPluginValueRepresentation_UI: - return EVR_UI; + return ValueRepresentation_UniqueIdentifier; case OrthancPluginValueRepresentation_UL: - return EVR_UL; + return ValueRepresentation_UnsignedLong; case OrthancPluginValueRepresentation_UN: - return EVR_UN; + return ValueRepresentation_Unknown; case OrthancPluginValueRepresentation_US: - return EVR_US; + return ValueRepresentation_UnsignedShort; case OrthancPluginValueRepresentation_UT: - return EVR_UT; + return ValueRepresentation_UnlimitedText; + + default: + throw OrthancException(ErrorCode_ParameterOutOfRange); + + /* + Not supported as of DCMTK 3.6.0: + return ValueRepresentation_OtherDouble + return ValueRepresentation_OtherLong + return ValueRepresentation_UniversalResource + return ValueRepresentation_UnlimitedCharacters + */ + } + } + + + OrthancPluginValueRepresentation Convert(ValueRepresentation vr) + { + switch (vr) + { + case ValueRepresentation_ApplicationEntity: + return OrthancPluginValueRepresentation_AE; + + case ValueRepresentation_AgeString: + return OrthancPluginValueRepresentation_AS; + + case ValueRepresentation_AttributeTag: + return OrthancPluginValueRepresentation_AT; + + case ValueRepresentation_CodeString: + return OrthancPluginValueRepresentation_CS; + + case ValueRepresentation_Date: + return OrthancPluginValueRepresentation_DA; + + case ValueRepresentation_DecimalString: + return OrthancPluginValueRepresentation_DS; + + case ValueRepresentation_DateTime: + return OrthancPluginValueRepresentation_DT; + + case ValueRepresentation_FloatingPointDouble: + return OrthancPluginValueRepresentation_FD; + + case ValueRepresentation_FloatingPointSingle: + return OrthancPluginValueRepresentation_FL; + + case ValueRepresentation_IntegerString: + return OrthancPluginValueRepresentation_IS; + + case ValueRepresentation_LongString: + return OrthancPluginValueRepresentation_LO; + + case ValueRepresentation_LongText: + return OrthancPluginValueRepresentation_LT; + + case ValueRepresentation_OtherByte: + return OrthancPluginValueRepresentation_OB; + + case ValueRepresentation_OtherFloat: + return OrthancPluginValueRepresentation_OF; + + case ValueRepresentation_OtherWord: + return OrthancPluginValueRepresentation_OW; + + case ValueRepresentation_PatientName: + return OrthancPluginValueRepresentation_PN; + + case ValueRepresentation_ShortString: + return OrthancPluginValueRepresentation_SH; + + case ValueRepresentation_SignedLong: + return OrthancPluginValueRepresentation_SL; + + case ValueRepresentation_Sequence: + return OrthancPluginValueRepresentation_SQ; + + case ValueRepresentation_SignedShort: + return OrthancPluginValueRepresentation_SS; + + case ValueRepresentation_ShortText: + return OrthancPluginValueRepresentation_ST; + + case ValueRepresentation_Time: + return OrthancPluginValueRepresentation_TM; + + case ValueRepresentation_UniqueIdentifier: + return OrthancPluginValueRepresentation_UI; + + case ValueRepresentation_UnsignedLong: + return OrthancPluginValueRepresentation_UL; + + case ValueRepresentation_UnsignedShort: + return OrthancPluginValueRepresentation_US; + + case ValueRepresentation_UnlimitedText: + return OrthancPluginValueRepresentation_UT; + + case ValueRepresentation_Unknown: + return OrthancPluginValueRepresentation_UN; // Unknown + + // These VR are not supported as of DCMTK 3.6.0, so they are + // mapped to "UN" (unknown) VR in the plugins + case ValueRepresentation_OtherDouble: + case ValueRepresentation_OtherLong: + case ValueRepresentation_UniversalResource: + case ValueRepresentation_UnlimitedCharacters: + return OrthancPluginValueRepresentation_UN; default: throw OrthancException(ErrorCode_ParameterOutOfRange); } } - - - OrthancPluginValueRepresentation Convert(DcmEVR vr) - { - switch (vr) - { - case EVR_AE: - return OrthancPluginValueRepresentation_AE; - - case EVR_AS: - return OrthancPluginValueRepresentation_AS; - - case EVR_AT: - return OrthancPluginValueRepresentation_AT; - - case EVR_CS: - return OrthancPluginValueRepresentation_CS; - - case EVR_DA: - return OrthancPluginValueRepresentation_DA; - - case EVR_DS: - return OrthancPluginValueRepresentation_DS; - - case EVR_DT: - return OrthancPluginValueRepresentation_DT; - - case EVR_FD: - return OrthancPluginValueRepresentation_FD; - - case EVR_FL: - return OrthancPluginValueRepresentation_FL; - - case EVR_IS: - return OrthancPluginValueRepresentation_IS; - - case EVR_LO: - return OrthancPluginValueRepresentation_LO; - - case EVR_LT: - return OrthancPluginValueRepresentation_LT; - - case EVR_OB: - return OrthancPluginValueRepresentation_OB; - - case EVR_OF: - return OrthancPluginValueRepresentation_OF; - - case EVR_OW: - return OrthancPluginValueRepresentation_OW; - - case EVR_PN: - return OrthancPluginValueRepresentation_PN; - - case EVR_SH: - return OrthancPluginValueRepresentation_SH; - - case EVR_SL: - return OrthancPluginValueRepresentation_SL; - - case EVR_SQ: - return OrthancPluginValueRepresentation_SQ; - - case EVR_SS: - return OrthancPluginValueRepresentation_SS; - - case EVR_ST: - return OrthancPluginValueRepresentation_ST; - - case EVR_TM: - return OrthancPluginValueRepresentation_TM; - - case EVR_UI: - return OrthancPluginValueRepresentation_UI; - - case EVR_UL: - return OrthancPluginValueRepresentation_UL; - - case EVR_US: - return OrthancPluginValueRepresentation_US; - - case EVR_UT: - return OrthancPluginValueRepresentation_UT; - - case EVR_UN: - default: - return OrthancPluginValueRepresentation_UN; // Unknown - } - } -#endif } } diff -r 9e021b2b348b -r 6301bbcbcaed Plugins/Engine/PluginsEnumerations.h --- a/Plugins/Engine/PluginsEnumerations.h Wed Jun 08 12:36:21 2016 +0200 +++ b/Plugins/Engine/PluginsEnumerations.h Thu Jun 09 14:48:40 2016 +0200 @@ -37,10 +37,6 @@ #include "../Include/orthanc/OrthancCPlugin.h" #include "../../OrthancServer/ServerEnumerations.h" -#if !defined(ORTHANC_ENABLE_DCMTK) || ORTHANC_ENABLE_DCMTK != 0 -#include -#endif - namespace Orthanc { namespace Plugins @@ -69,11 +65,9 @@ OrthancPluginHttpMethod Convert(HttpMethod method); -#if !defined(ORTHANC_ENABLE_DCMTK) || ORTHANC_ENABLE_DCMTK != 0 - DcmEVR Convert(OrthancPluginValueRepresentation vr); + ValueRepresentation Convert(OrthancPluginValueRepresentation vr); - OrthancPluginValueRepresentation Convert(DcmEVR vr); -#endif + OrthancPluginValueRepresentation Convert(ValueRepresentation vr); } } diff -r 9e021b2b348b -r 6301bbcbcaed UnitTestsSources/FromDcmtkTests.cpp --- a/UnitTestsSources/FromDcmtkTests.cpp Wed Jun 08 12:36:21 2016 +0200 +++ b/UnitTestsSources/FromDcmtkTests.cpp Thu Jun 09 14:48:40 2016 +0200 @@ -34,6 +34,7 @@ #include "gtest/gtest.h" #include "../OrthancServer/FromDcmtkBridge.h" +#include "../OrthancServer/ToDcmtkBridge.h" #include "../OrthancServer/OrthancInitialization.h" #include "../OrthancServer/DicomModification.h" #include "../OrthancServer/ServerToolbox.h" @@ -48,6 +49,7 @@ #include "../Resources/EncodingTests.h" #include "../OrthancServer/DicomProtocol/DicomFindAnswers.h" #include "../OrthancServer/Internals/DicomImageDecoder.h" +#include "../Plugins/Engine/PluginsEnumerations.h" #include @@ -300,15 +302,58 @@ TEST(FromDcmtkBridge, ValueRepresentation) { ASSERT_EQ(ValueRepresentation_PatientName, - FromDcmtkBridge::GetValueRepresentation(DICOM_TAG_PATIENT_NAME)); + FromDcmtkBridge::LookupValueRepresentation(DICOM_TAG_PATIENT_NAME)); ASSERT_EQ(ValueRepresentation_Date, - FromDcmtkBridge::GetValueRepresentation(DicomTag(0x0008, 0x0020) /* StudyDate */)); + FromDcmtkBridge::LookupValueRepresentation(DicomTag(0x0008, 0x0020) /* StudyDate */)); ASSERT_EQ(ValueRepresentation_Time, - FromDcmtkBridge::GetValueRepresentation(DicomTag(0x0008, 0x0030) /* StudyTime */)); + FromDcmtkBridge::LookupValueRepresentation(DicomTag(0x0008, 0x0030) /* StudyTime */)); ASSERT_EQ(ValueRepresentation_DateTime, - FromDcmtkBridge::GetValueRepresentation(DicomTag(0x0008, 0x002a) /* AcquisitionDateTime */)); - ASSERT_EQ(ValueRepresentation_Other, - FromDcmtkBridge::GetValueRepresentation(DICOM_TAG_PATIENT_ID)); + FromDcmtkBridge::LookupValueRepresentation(DicomTag(0x0008, 0x002a) /* AcquisitionDateTime */)); + ASSERT_EQ(ValueRepresentation_NotSupported, + FromDcmtkBridge::LookupValueRepresentation(DicomTag(0x0001, 0x0001) /* some private tag */)); +} + + +TEST(FromDcmtkBridge, ValueRepresentationConversions) +{ + ASSERT_EQ(1, ValueRepresentation_ApplicationEntity); + ASSERT_EQ(1, OrthancPluginValueRepresentation_AE); + + for (int i = ValueRepresentation_ApplicationEntity; + i <= ValueRepresentation_NotSupported; i++) + { + ValueRepresentation vr = static_cast(i); + + if (vr == ValueRepresentation_NotSupported) + { + ASSERT_THROW(ToDcmtkBridge::Convert(vr), OrthancException); + ASSERT_THROW(Plugins::Convert(vr), OrthancException); + } + else if (vr == ValueRepresentation_OtherDouble || + vr == ValueRepresentation_OtherLong || + vr == ValueRepresentation_UniversalResource || + vr == ValueRepresentation_UnlimitedCharacters) + { + // These VR are not supported as of DCMTK 3.6.0 + ASSERT_THROW(ToDcmtkBridge::Convert(vr), OrthancException); + ASSERT_EQ(OrthancPluginValueRepresentation_UN, Plugins::Convert(vr)); + } + else + { + ASSERT_EQ(vr, FromDcmtkBridge::Convert(ToDcmtkBridge::Convert(vr))); + + OrthancPluginValueRepresentation plugins = Plugins::Convert(vr); + ASSERT_EQ(vr, Plugins::Convert(plugins)); + } + } + + for (int i = OrthancPluginValueRepresentation_AE; + i <= OrthancPluginValueRepresentation_UT; i++) + { + OrthancPluginValueRepresentation plugins = static_cast(i); + ValueRepresentation orthanc = Plugins::Convert(plugins); + ASSERT_EQ(plugins, Plugins::Convert(orthanc)); + } } @@ -531,8 +576,8 @@ TEST(ParsedDicomFile, ToJsonFlags1) { - FromDcmtkBridge::RegisterDictionaryTag(DicomTag(0x7053, 0x1000), EVR_PN, "MyPrivateTag", 1, 1); - FromDcmtkBridge::RegisterDictionaryTag(DicomTag(0x7050, 0x1000), EVR_PN, "Declared public tag", 1, 1); + FromDcmtkBridge::RegisterDictionaryTag(DicomTag(0x7053, 0x1000), ValueRepresentation_PatientName, "MyPrivateTag", 1, 1); + FromDcmtkBridge::RegisterDictionaryTag(DicomTag(0x7050, 0x1000), ValueRepresentation_PatientName, "Declared public tag", 1, 1); ParsedDicomFile f(true); f.Insert(DicomTag(0x7050, 0x1000), "Some public tag", false); // Even group => public tag @@ -672,9 +717,9 @@ TEST(ParsedDicomFile, FromJson) { - FromDcmtkBridge::RegisterDictionaryTag(DicomTag(0x7057, 0x1000), EVR_OB, "MyPrivateTag", 1, 1); - FromDcmtkBridge::RegisterDictionaryTag(DicomTag(0x7059, 0x1000), EVR_OB, "MyPrivateTag", 1, 1); - FromDcmtkBridge::RegisterDictionaryTag(DicomTag(0x7050, 0x1000), EVR_PN, "Declared public tag", 1, 1); + FromDcmtkBridge::RegisterDictionaryTag(DicomTag(0x7057, 0x1000), ValueRepresentation_OtherByte, "MyPrivateTag", 1, 1); + FromDcmtkBridge::RegisterDictionaryTag(DicomTag(0x7059, 0x1000), ValueRepresentation_OtherByte, "MyPrivateTag", 1, 1); + FromDcmtkBridge::RegisterDictionaryTag(DicomTag(0x7050, 0x1000), ValueRepresentation_PatientName, "Declared public tag", 1, 1); Json::Value v; const std::string sopClassUid = "1.2.840.10008.5.1.4.1.1.1"; // CR Image Storage: