# HG changeset patch # User Sebastien Jodogne # Date 1481731294 -3600 # Node ID 5b127ab0080b279c9f5876ae8584931921483495 # Parent d101055fc20bffcb8e414f98f67205c3cf90978e sync diff -r d101055fc20b -r 5b127ab0080b Applications/CMakeLists.txt --- a/Applications/CMakeLists.txt Tue Nov 29 13:31:23 2016 +0100 +++ b/Applications/CMakeLists.txt Wed Dec 14 17:01:34 2016 +0100 @@ -78,14 +78,16 @@ include(${ORTHANC_WSI_DIR}/Resources/CMake/LibTiffConfiguration.cmake) add_definitions( + -DORTHANC_BUILD_UNIT_TESTS=0 # For FromDcmtkBridge -DORTHANC_ENABLE_BASE64=1 -DORTHANC_ENABLE_CURL=1 -DORTHANC_ENABLE_DCMTK=1 + -DORTHANC_ENABLE_JPEG=0 # Disable DCMTK's support for JPEG -DORTHANC_ENABLE_LOGGING=1 + -DORTHANC_ENABLE_LUA=0 # For FromDcmtkBridge -DORTHANC_ENABLE_MD5=0 - -DORTHANC_ENABLE_JPEG=0 # Disable DCMTK's support for JPEG -DORTHANC_ENABLE_PKCS11=0 - -DORTHANC_ENABLE_PLUGINS=1 # To enable class Orthanc::SharedLibrary + -DORTHANC_ENABLE_PLUGINS=1 # To enable class Orthanc::SharedLibrary -DORTHANC_ENABLE_PUGIXML=0 -DORTHANC_SANDBOXED=0 -DHAS_ORTHANC_EXCEPTION=1 diff -r d101055fc20b -r 5b127ab0080b Resources/Orthanc/Core/DicomFormat/DicomArray.h --- a/Resources/Orthanc/Core/DicomFormat/DicomArray.h Tue Nov 29 13:31:23 2016 +0100 +++ b/Resources/Orthanc/Core/DicomFormat/DicomArray.h Wed Dec 14 17:01:34 2016 +0100 @@ -47,7 +47,7 @@ Elements elements_; public: - DicomArray(const DicomMap& map); + explicit DicomArray(const DicomMap& map); ~DicomArray(); diff -r d101055fc20b -r 5b127ab0080b Resources/Orthanc/Core/DicomFormat/DicomMap.h --- a/Resources/Orthanc/Core/DicomFormat/DicomMap.h Tue Nov 29 13:31:23 2016 +0100 +++ b/Resources/Orthanc/Core/DicomFormat/DicomMap.h Wed Dec 14 17:01:34 2016 +0100 @@ -47,7 +47,7 @@ private: friend class DicomArray; friend class FromDcmtkBridge; - friend class ToDcmtkBridge; + friend class ParsedDicomFile; typedef std::map Map; diff -r d101055fc20b -r 5b127ab0080b Resources/Orthanc/Core/DicomFormat/DicomTag.h --- a/Resources/Orthanc/Core/DicomFormat/DicomTag.h Tue Nov 29 13:31:23 2016 +0100 +++ b/Resources/Orthanc/Core/DicomFormat/DicomTag.h Wed Dec 14 17:01:34 2016 +0100 @@ -100,6 +100,7 @@ static const DicomTag DICOM_TAG_SERIES_INSTANCE_UID(0x0020, 0x000e); static const DicomTag DICOM_TAG_STUDY_INSTANCE_UID(0x0020, 0x000d); static const DicomTag DICOM_TAG_PIXEL_DATA(0x7fe0, 0x0010); + static const DicomTag DICOM_TAG_TRANSFER_SYNTAX_UID(0x0002, 0x0010); static const DicomTag DICOM_TAG_IMAGE_INDEX(0x0054, 0x1330); static const DicomTag DICOM_TAG_INSTANCE_NUMBER(0x0020, 0x0013); @@ -127,6 +128,7 @@ static const DicomTag DICOM_TAG_TEMPORAL_POSITION_IDENTIFIER(0x0020, 0x0100); // Tags for C-FIND and C-MOVE + static const DicomTag DICOM_TAG_MESSAGE_ID(0x0000, 0x0110); static const DicomTag DICOM_TAG_SPECIFIC_CHARACTER_SET(0x0008, 0x0005); static const DicomTag DICOM_TAG_QUERY_RETRIEVE_LEVEL(0x0008, 0x0052); static const DicomTag DICOM_TAG_MODALITIES_IN_STUDY(0x0008, 0x0061); diff -r d101055fc20b -r 5b127ab0080b Resources/Orthanc/Core/Enumerations.cpp --- a/Resources/Orthanc/Core/Enumerations.cpp Tue Nov 29 13:31:23 2016 +0100 +++ b/Resources/Orthanc/Core/Enumerations.cpp Wed Dec 14 17:01:34 2016 +0100 @@ -1083,15 +1083,18 @@ bool GetDicomEncoding(Encoding& encoding, const char* specificCharacterSet) { - std::string s = specificCharacterSet; + std::string s = Toolbox::StripSpaces(specificCharacterSet); Toolbox::ToUpperCase(s); // http://dicom.nema.org/medical/dicom/current/output/html/part03.html#sect_C.12.1.1.2 // https://github.com/dcm4che/dcm4che/blob/master/dcm4che-core/src/main/java/org/dcm4che3/data/SpecificCharacterSet.java if (s == "ISO_IR 6" || - s == "ISO_IR 192" || s == "ISO 2022 IR 6") { + encoding = Encoding_Ascii; + } + else if (s == "ISO_IR 192") + { encoding = Encoding_Utf8; } else if (s == "ISO_IR 100" || @@ -1238,8 +1241,10 @@ // http://dicom.nema.org/medical/dicom/current/output/html/part03.html#sect_C.12.1.1.2 switch (encoding) { + case Encoding_Ascii: + return "ISO_IR 6"; + case Encoding_Utf8: - case Encoding_Ascii: return "ISO_IR 192"; case Encoding_Latin1: diff -r d101055fc20b -r 5b127ab0080b Resources/Orthanc/Core/HttpClient.cpp --- a/Resources/Orthanc/Core/HttpClient.cpp Tue Nov 29 13:31:23 2016 +0100 +++ b/Resources/Orthanc/Core/HttpClient.cpp Wed Dec 14 17:01:34 2016 +0100 @@ -318,10 +318,10 @@ url_ = ""; method_ = HttpMethod_Get; lastStatus_ = HttpStatus_200_Ok; - isVerbose_ = false; + SetVerbose(false); timeout_ = GlobalParameters::GetInstance().GetDefaultTimeout(); GlobalParameters::GetInstance().GetDefaultProxy(proxy_); - GlobalParameters::GetInstance().GetSslConfiguration(verifyPeers_, caCertificates_); + GlobalParameters::GetInstance().GetSslConfiguration(verifyPeers_, caCertificates_); } diff -r d101055fc20b -r 5b127ab0080b Resources/Orthanc/Core/Images/JpegWriter.cpp --- a/Resources/Orthanc/Core/Images/JpegWriter.cpp Tue Nov 29 13:31:23 2016 +0100 +++ b/Resources/Orthanc/Core/Images/JpegWriter.cpp Wed Dec 14 17:01:34 2016 +0100 @@ -105,7 +105,7 @@ void JpegWriter::SetQuality(uint8_t quality) { - if (quality <= 0 || quality > 100) + if (quality == 0 || quality > 100) { throw OrthancException(ErrorCode_ParameterOutOfRange); } diff -r d101055fc20b -r 5b127ab0080b Resources/Orthanc/Core/MultiThreading/BagOfTasksProcessor.h --- a/Resources/Orthanc/Core/MultiThreading/BagOfTasksProcessor.h Tue Nov 29 13:31:23 2016 +0100 +++ b/Resources/Orthanc/Core/MultiThreading/BagOfTasksProcessor.h Wed Dec 14 17:01:34 2016 +0100 @@ -64,10 +64,10 @@ { } - Bag(size_t size) : - size_(size), - done_(0), - status_(BagStatus_Running) + explicit Bag(size_t size) : + size_(size), + done_(0), + status_(BagStatus_Running) { } }; @@ -140,7 +140,7 @@ }; - BagOfTasksProcessor(size_t countThreads); + explicit BagOfTasksProcessor(size_t countThreads); ~BagOfTasksProcessor(); diff -r d101055fc20b -r 5b127ab0080b Resources/Orthanc/Core/MultiThreading/Semaphore.h --- a/Resources/Orthanc/Core/MultiThreading/Semaphore.h Tue Nov 29 13:31:23 2016 +0100 +++ b/Resources/Orthanc/Core/MultiThreading/Semaphore.h Wed Dec 14 17:01:34 2016 +0100 @@ -57,7 +57,7 @@ Semaphore& that_; public: - Locker(Semaphore& that) : + explicit Locker(Semaphore& that) : that_(that) { that_.Acquire(); diff -r d101055fc20b -r 5b127ab0080b Resources/Orthanc/Core/OrthancException.h --- a/Resources/Orthanc/Core/OrthancException.h Tue Nov 29 13:31:23 2016 +0100 +++ b/Resources/Orthanc/Core/OrthancException.h Wed Dec 14 17:01:34 2016 +0100 @@ -45,7 +45,7 @@ HttpStatus httpStatus_; public: - OrthancException(ErrorCode errorCode) : + explicit OrthancException(ErrorCode errorCode) : errorCode_(errorCode), httpStatus_(ConvertErrorCodeToHttpStatus(errorCode)) { diff -r d101055fc20b -r 5b127ab0080b Resources/Orthanc/OrthancServer/FromDcmtkBridge.cpp --- a/Resources/Orthanc/OrthancServer/FromDcmtkBridge.cpp Tue Nov 29 13:31:23 2016 +0100 +++ b/Resources/Orthanc/OrthancServer/FromDcmtkBridge.cpp Wed Dec 14 17:01:34 2016 +0100 @@ -1646,7 +1646,9 @@ if (!ok) { - throw OrthancException(ErrorCode_InternalError); + LOG(ERROR) << "While creating a DICOM instance, tag (" << tag.Format() + << ") has out-of-range value: \"" << *decoded << "\""; + throw OrthancException(ErrorCode_BadFileFormat); } } @@ -1665,6 +1667,11 @@ FillElementWithString(*element, tag, value.asString(), decodeDataUriScheme, dicomEncoding); break; + case Json::nullValue: + element.reset(CreateElementForTag(tag)); + FillElementWithString(*element, tag, "", decodeDataUriScheme, dicomEncoding); + break; + case Json::arrayValue: { DcmTag key(tag.GetGroup(), tag.GetElement()); @@ -1742,11 +1749,17 @@ { const Json::Value& value = json[tags[i]]; if (value.type() != Json::stringValue || - !GetDicomEncoding(encoding, value.asCString())) + (value.asString().length() != 0 && + !GetDicomEncoding(encoding, value.asCString()))) { LOG(ERROR) << "Unknown encoding while creating DICOM from JSON: " << value; throw OrthancException(ErrorCode_BadRequest); } + + if (value.asString().length() == 0) + { + return defaultEncoding; + } } } @@ -1897,4 +1910,108 @@ target.SetValue(ParseTag(members[i]), value.asString(), false); } } + + + void FromDcmtkBridge::ChangeStringEncoding(DcmItem& dataset, + Encoding source, + Encoding target) + { + // Recursive exploration of a dataset to change the encoding of + // each string-like element + + if (source == target) + { + return; + } + + for (unsigned long i = 0; i < dataset.card(); i++) + { + DcmElement* element = dataset.getElement(i); + if (element) + { + if (element->isLeaf()) + { + char *c = NULL; + if (element->isaString() && + element->getString(c).good() && + c != NULL) + { + std::string a = Toolbox::ConvertToUtf8(c, source); + std::string b = Toolbox::ConvertFromUtf8(a, target); + element->putString(b.c_str()); + } + } + else + { + // "All subclasses of DcmElement except for DcmSequenceOfItems + // are leaf nodes, while DcmSequenceOfItems, DcmItem, DcmDataset + // etc. are not." The following dynamic_cast is thus OK. + DcmSequenceOfItems& sequence = dynamic_cast(*element); + + for (unsigned long j = 0; j < sequence.card(); j++) + { + ChangeStringEncoding(*sequence.getItem(j), source, target); + } + } + } + } + } + + + bool FromDcmtkBridge::LookupTransferSyntax(std::string& result, + DcmFileFormat& dicom) + { + const char* value = NULL; + + if (dicom.getMetaInfo() != NULL && + dicom.getMetaInfo()->findAndGetString(DCM_TransferSyntaxUID, value).good() && + value != NULL) + { + result.assign(value); + return true; + } + else + { + return false; + } + } + + +#if ORTHANC_ENABLE_LUA == 1 + void FromDcmtkBridge::ExecuteToDicom(DicomMap& target, + LuaFunctionCall& call) + { + Json::Value output; + call.ExecuteToJson(output, true /* keep strings */); + + target.Clear(); + + if (output.type() == Json::arrayValue && + output.size() == 0) + { + // This case happens for empty tables + return; + } + + if (output.type() != Json::objectValue) + { + LOG(ERROR) << "Lua: IncomingFindRequestFilter must return a table"; + throw OrthancException(ErrorCode_LuaBadOutput); + } + + Json::Value::Members members = output.getMemberNames(); + + for (size_t i = 0; i < members.size(); i++) + { + if (output[members[i]].type() != Json::stringValue) + { + LOG(ERROR) << "Lua: IncomingFindRequestFilter must return a table mapping names of DICOM tags to strings"; + throw OrthancException(ErrorCode_LuaBadOutput); + } + + DicomTag tag(ParseTag(members[i])); + target.SetValue(tag, output[members[i]].asString(), false); + } + } +#endif } diff -r d101055fc20b -r 5b127ab0080b Resources/Orthanc/OrthancServer/FromDcmtkBridge.h --- a/Resources/Orthanc/OrthancServer/FromDcmtkBridge.h Tue Nov 29 13:31:23 2016 +0100 +++ b/Resources/Orthanc/OrthancServer/FromDcmtkBridge.h Wed Dec 14 17:01:34 2016 +0100 @@ -43,10 +43,22 @@ #include #include +#if !defined(ORTHANC_BUILD_UNIT_TESTS) +# error The macro ORTHANC_BUILD_UNIT_TESTS must be defined +#endif + +#if !defined(ORTHANC_ENABLE_LUA) +# error The macro ORTHANC_ENABLE_LUA must be defined +#endif + #if ORTHANC_BUILD_UNIT_TESTS == 1 # include #endif +#if ORTHANC_ENABLE_LUA == 1 +# include "../Core/Lua/LuaFunctionCall.h" +#endif + namespace Orthanc { @@ -88,6 +100,10 @@ unsigned int maxStringLength, Encoding defaultEncoding); + static void ChangeStringEncoding(DcmItem& dataset, + Encoding source, + Encoding target); + public: static void InitializeDictionary(bool loadPrivateDictionary); @@ -195,5 +211,13 @@ static void FromJson(DicomMap& values, const Json::Value& result); + + static bool LookupTransferSyntax(std::string& result, + DcmFileFormat& dicom); + +#if ORTHANC_ENABLE_LUA == 1 + static void ExecuteToDicom(DicomMap& target, + LuaFunctionCall& call); +#endif }; } diff -r d101055fc20b -r 5b127ab0080b Resources/Orthanc/OrthancServer/ServerEnumerations.cpp --- a/Resources/Orthanc/OrthancServer/ServerEnumerations.cpp Tue Nov 29 13:31:23 2016 +0100 +++ b/Resources/Orthanc/OrthancServer/ServerEnumerations.cpp Wed Dec 14 17:01:34 2016 +0100 @@ -64,6 +64,8 @@ dictMetadataType_.Add(MetadataType_AnonymizedFrom, "AnonymizedFrom"); dictMetadataType_.Add(MetadataType_LastUpdate, "LastUpdate"); dictMetadataType_.Add(MetadataType_Instance_Origin, "Origin"); + dictMetadataType_.Add(MetadataType_Instance_TransferSyntax, "TransferSyntax"); + dictMetadataType_.Add(MetadataType_Instance_SopClassUid, "SopClassUid"); dictContentType_.Add(FileContentType_Dicom, "dicom"); dictContentType_.Add(FileContentType_DicomAsJson, "dicom-as-json"); diff -r d101055fc20b -r 5b127ab0080b Resources/Orthanc/OrthancServer/ServerEnumerations.h --- a/Resources/Orthanc/OrthancServer/ServerEnumerations.h Tue Nov 29 13:31:23 2016 +0100 +++ b/Resources/Orthanc/OrthancServer/ServerEnumerations.h Wed Dec 14 17:01:34 2016 +0100 @@ -157,7 +157,9 @@ MetadataType_ModifiedFrom = 5, MetadataType_AnonymizedFrom = 6, MetadataType_LastUpdate = 7, - MetadataType_Instance_Origin = 8, // New in Orthanc 0.9.5 + MetadataType_Instance_Origin = 8, // New in Orthanc 0.9.5 + MetadataType_Instance_TransferSyntax = 9, // New in Orthanc 1.2.0 + MetadataType_Instance_SopClassUid = 10, // New in Orthanc 1.2.0 // Make sure that the value "65535" can be stored into this enumeration MetadataType_StartUser = 1024, diff -r d101055fc20b -r 5b127ab0080b Resources/Orthanc/OrthancServer/ToDcmtkBridge.cpp --- a/Resources/Orthanc/OrthancServer/ToDcmtkBridge.cpp Tue Nov 29 13:31:23 2016 +0100 +++ b/Resources/Orthanc/OrthancServer/ToDcmtkBridge.cpp Wed Dec 14 17:01:34 2016 +0100 @@ -41,24 +41,6 @@ namespace Orthanc { - DcmDataset* ToDcmtkBridge::Convert(const DicomMap& map) - { - std::auto_ptr result(new DcmDataset); - - for (DicomMap::Map::const_iterator - it = map.map_.begin(); it != map.map_.end(); ++it) - { - if (!it->second->IsNull()) - { - std::string s = it->second->GetContent(); - DU_putStringDOElement(result.get(), Convert(it->first), s.c_str()); - } - } - - return result.release(); - } - - DcmEVR ToDcmtkBridge::Convert(ValueRepresentation vr) { switch (vr) diff -r d101055fc20b -r 5b127ab0080b Resources/Orthanc/OrthancServer/ToDcmtkBridge.h --- a/Resources/Orthanc/OrthancServer/ToDcmtkBridge.h Tue Nov 29 13:31:23 2016 +0100 +++ b/Resources/Orthanc/OrthancServer/ToDcmtkBridge.h Wed Dec 14 17:01:34 2016 +0100 @@ -45,8 +45,6 @@ return DcmTagKey(tag.GetGroup(), tag.GetElement()); } - static DcmDataset* Convert(const DicomMap& map); - static DcmEVR Convert(ValueRepresentation vr); }; } diff -r d101055fc20b -r 5b127ab0080b Resources/Orthanc/Plugins/Engine/SharedLibrary.h --- a/Resources/Orthanc/Plugins/Engine/SharedLibrary.h Tue Nov 29 13:31:23 2016 +0100 +++ b/Resources/Orthanc/Plugins/Engine/SharedLibrary.h Wed Dec 14 17:01:34 2016 +0100 @@ -60,7 +60,7 @@ FunctionPointer GetFunctionInternal(const std::string& name); public: - SharedLibrary(const std::string& path); + explicit SharedLibrary(const std::string& path); ~SharedLibrary(); diff -r d101055fc20b -r 5b127ab0080b Resources/Orthanc/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp --- a/Resources/Orthanc/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp Tue Nov 29 13:31:23 2016 +0100 +++ b/Resources/Orthanc/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp Wed Dec 14 17:01:34 2016 +0100 @@ -276,11 +276,24 @@ } - OrthancString::OrthancString(OrthancPluginContext* context, - char* str) : - context_(context), - str_(str) + void MemoryBuffer::GetDicomQuery(const OrthancPluginWorklistQuery* query) + { + Clear(); + Check(OrthancPluginWorklistGetDicomQuery(context_, &buffer_, query)); + } + + + void OrthancString::Assign(char* str) { + if (str == NULL) + { + ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_InternalError); + } + else + { + Clear(); + str_ = str; + } } @@ -322,12 +335,25 @@ ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat); } } + + + void MemoryBuffer::DicomToJson(Json::Value& target, + OrthancPluginDicomToJsonFormat format, + OrthancPluginDicomToJsonFlags flags, + uint32_t maxStringLength) + { + OrthancString str(context_); + str.Assign(OrthancPluginDicomBufferToJson(context_, GetData(), GetSize(), format, flags, maxStringLength)); + str.ToJson(target); + } + OrthancConfiguration::OrthancConfiguration(OrthancPluginContext* context) : context_(context) { - OrthancString str(context, OrthancPluginGetConfiguration(context)); + OrthancString str(context); + str.Assign(OrthancPluginGetConfiguration(context)); if (str.GetContent() == NULL) { @@ -809,6 +835,83 @@ } + +#if HAS_ORTHANC_PLUGIN_FIND_MATCHER == 1 + FindMatcher::FindMatcher(OrthancPluginContext* context, + const OrthancPluginWorklistQuery* worklist) : + context_(context), + matcher_(NULL), + worklist_(worklist) + { + if (worklist_ == NULL) + { + ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_ParameterOutOfRange); + } + } + + + void FindMatcher::SetupDicom(OrthancPluginContext* context, + const void* query, + uint32_t size) + { + context_ = context; + worklist_ = NULL; + + matcher_ = OrthancPluginCreateFindMatcher(context_, query, size); + if (matcher_ == NULL) + { + ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_InternalError); + } + } + + + FindMatcher::~FindMatcher() + { + // The "worklist_" field + + if (matcher_ != NULL) + { + OrthancPluginFreeFindMatcher(context_, matcher_); + } + } + + + + bool FindMatcher::IsMatch(const void* dicom, + uint32_t size) const + { + int32_t result; + + if (matcher_ != NULL) + { + result = OrthancPluginFindMatcherIsMatch(context_, matcher_, dicom, size); + } + else if (worklist_ != NULL) + { + result = OrthancPluginWorklistIsMatch(context_, worklist_, dicom, size); + } + else + { + ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_InternalError); + } + + if (result == 0) + { + return false; + } + else if (result == 1) + { + return true; + } + else + { + ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_InternalError); + } + } + +#endif /* HAS_ORTHANC_PLUGIN_FIND_MATCHER == 1 */ + + bool RestApiGet(Json::Value& result, OrthancPluginContext* context, const std::string& uri, diff -r d101055fc20b -r 5b127ab0080b Resources/Orthanc/Plugins/Samples/Common/OrthancPluginCppWrapper.h --- a/Resources/Orthanc/Plugins/Samples/Common/OrthancPluginCppWrapper.h Tue Nov 29 13:31:23 2016 +0100 +++ b/Resources/Orthanc/Plugins/Samples/Common/OrthancPluginCppWrapper.h Wed Dec 14 17:01:34 2016 +0100 @@ -50,6 +50,17 @@ #endif +#if (ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER >= 2 || \ + (ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER == 1 && \ + ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER >= 2)) +// The "OrthancPluginFindMatcher()" primitive was introduced in Orthanc 1.2.0 +# define HAS_ORTHANC_PLUGIN_FIND_MATCHER 1 +#else +# define HAS_ORTHANC_PLUGIN_FIND_MATCHER 0 +#endif + + + namespace OrthancPlugins { @@ -172,6 +183,13 @@ OrthancPluginCreateDicomFlags flags); void ReadFile(const std::string& path); + + void GetDicomQuery(const OrthancPluginWorklistQuery* query); + + void DicomToJson(Json::Value& target, + OrthancPluginDicomToJsonFormat format, + OrthancPluginDicomToJsonFlags flags, + uint32_t maxStringLength); }; @@ -181,16 +199,23 @@ OrthancPluginContext* context_; char* str_; + void Clear(); + public: - OrthancString(OrthancPluginContext* context, - char* str); + OrthancString(OrthancPluginContext* context) : + context_(context), + str_(NULL) + { + } ~OrthancString() { Clear(); } - void Clear(); + // This transfers ownership, warning: The string must have been + // allocated by the Orthanc core + void Assign(char* str); const char* GetContent() const { @@ -262,7 +287,7 @@ float defaultValue) const; }; - class OrthancImage + class OrthancImage : public boost::noncopyable { private: OrthancPluginContext* context_; @@ -320,6 +345,48 @@ }; +#if HAS_ORTHANC_PLUGIN_FIND_MATCHER == 1 + class FindMatcher : public boost::noncopyable + { + private: + OrthancPluginContext* context_; + OrthancPluginFindMatcher* matcher_; + const OrthancPluginWorklistQuery* worklist_; + + void SetupDicom(OrthancPluginContext* context, + const void* query, + uint32_t size); + + public: + FindMatcher(OrthancPluginContext* context, + const OrthancPluginWorklistQuery* worklist); + + FindMatcher(OrthancPluginContext* context, + const void* query, + uint32_t size) + { + SetupDicom(context, query, size); + } + + FindMatcher(OrthancPluginContext* context, + const MemoryBuffer& dicom) + { + SetupDicom(context, dicom.GetData(), dicom.GetSize()); + } + + ~FindMatcher(); + + bool IsMatch(const void* dicom, + uint32_t size) const; + + bool IsMatch(const MemoryBuffer& dicom) const + { + return IsMatch(dicom.GetData(), dicom.GetSize()); + } + }; +#endif + + bool RestApiGet(Json::Value& result, OrthancPluginContext* context, const std::string& uri, diff -r d101055fc20b -r 5b127ab0080b Resources/Orthanc/Resources/CMake/DcmtkConfiguration.cmake --- a/Resources/Orthanc/Resources/CMake/DcmtkConfiguration.cmake Tue Nov 29 13:31:23 2016 +0100 +++ b/Resources/Orthanc/Resources/CMake/DcmtkConfiguration.cmake Wed Dec 14 17:01:34 2016 +0100 @@ -50,6 +50,17 @@ else() message("Using the dictionary of private tags from DCMTK 3.6.0") endif() + + # Patches specific to DCMTK 3.6.0 + execute_process( + COMMAND ${PATCH_EXECUTABLE} -p0 -N -i ${ORTHANC_ROOT}/Resources/Patches/dcmtk-3.6.0-dulparse-vulnerability.patch + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + RESULT_VARIABLE Failure + ) + + if (Failure) + message(FATAL_ERROR "Error while patching a file") + endif() endif()