# HG changeset patch # User Sebastien Jodogne # Date 1440170956 -7200 # Node ID 4b23310eb7e8ccbc59ff0d9a6bbf420910764446 # Parent 1b7def486e62a8a7c2946f85d156d5339ad374c6 add tags per instances in a series diff -r 1b7def486e62 -r 4b23310eb7e8 Core/Enumerations.cpp --- a/Core/Enumerations.cpp Fri Aug 21 15:01:21 2015 +0200 +++ b/Core/Enumerations.cpp Fri Aug 21 17:29:16 2015 +0200 @@ -748,4 +748,56 @@ throw OrthancException(ErrorCode_ParameterOutOfRange); } } + + + + const char* GetDicomSpecificCharacterSet(Encoding encoding) + { + // http://www.dabsoft.ch/dicom/3/C.12.1.1.2/ + switch (encoding) + { + case Encoding_Utf8: + case Encoding_Ascii: + return "ISO_IR 192"; + + case Encoding_Latin1: + return "ISO_IR 100"; + + case Encoding_Latin2: + return "ISO_IR 101"; + + case Encoding_Latin3: + return "ISO_IR 109"; + + case Encoding_Latin4: + return "ISO_IR 110"; + + case Encoding_Latin5: + return "ISO_IR 148"; + + case Encoding_Cyrillic: + return "ISO_IR 144"; + + case Encoding_Arabic: + return "ISO_IR 127"; + + case Encoding_Greek: + return "ISO_IR 126"; + + case Encoding_Hebrew: + return "ISO_IR 138"; + + case Encoding_Japanese: + return "ISO_IR 13"; + + case Encoding_Chinese: + return "GB18030"; + + case Encoding_Thai: + return "ISO_IR 166"; + + default: + throw OrthancException(ErrorCode_ParameterOutOfRange); + } + } } diff -r 1b7def486e62 -r 4b23310eb7e8 Core/Enumerations.h --- a/Core/Enumerations.h Fri Aug 21 15:01:21 2015 +0200 +++ b/Core/Enumerations.h Fri Aug 21 17:29:16 2015 +0200 @@ -386,4 +386,6 @@ ResourceType GetParentResourceType(ResourceType type); DicomModule GetModule(ResourceType type); + + const char* GetDicomSpecificCharacterSet(Encoding encoding); } diff -r 1b7def486e62 -r 4b23310eb7e8 Core/Toolbox.cpp --- a/Core/Toolbox.cpp Fri Aug 21 15:01:21 2015 +0200 +++ b/Core/Toolbox.cpp Fri Aug 21 17:29:16 2015 +0200 @@ -1335,56 +1335,5 @@ return static_cast(getpid()); #endif } - - - const char* Toolbox::GetDicomSpecificCharacterSet(Encoding encoding) - { - // http://www.dabsoft.ch/dicom/3/C.12.1.1.2/ - switch (encoding) - { - case Encoding_Utf8: - case Encoding_Ascii: - return "ISO_IR 192"; - - case Encoding_Latin1: - return "ISO_IR 100"; - - case Encoding_Latin2: - return "ISO_IR 101"; - - case Encoding_Latin3: - return "ISO_IR 109"; - - case Encoding_Latin4: - return "ISO_IR 110"; - - case Encoding_Latin5: - return "ISO_IR 148"; - - case Encoding_Cyrillic: - return "ISO_IR 144"; - - case Encoding_Arabic: - return "ISO_IR 127"; - - case Encoding_Greek: - return "ISO_IR 126"; - - case Encoding_Hebrew: - return "ISO_IR 138"; - - case Encoding_Japanese: - return "ISO_IR 13"; - - case Encoding_Chinese: - return "GB18030"; - - case Encoding_Thai: - return "ISO_IR 166"; - - default: - throw OrthancException(ErrorCode_ParameterOutOfRange); - } - } } diff -r 1b7def486e62 -r 4b23310eb7e8 Core/Toolbox.h --- a/Core/Toolbox.h Fri Aug 21 15:01:21 2015 +0200 +++ b/Core/Toolbox.h Fri Aug 21 17:29:16 2015 +0200 @@ -178,7 +178,5 @@ const std::string& prefix); int GetProcessId(); - - const char* GetDicomSpecificCharacterSet(Encoding encoding); } } diff -r 1b7def486e62 -r 4b23310eb7e8 OrthancServer/OrthancRestApi/OrthancRestAnonymizeModify.cpp --- a/OrthancServer/OrthancRestApi/OrthancRestAnonymizeModify.cpp Fri Aug 21 15:01:21 2015 +0200 +++ b/OrthancServer/OrthancRestApi/OrthancRestAnonymizeModify.cpp Fri Aug 21 17:29:16 2015 +0200 @@ -488,6 +488,54 @@ } + static bool InjectTags(ParsedDicomFile& dicom, + const Json::Value& tags) + { + if (tags.type() != Json::objectValue) + { + LOG(ERROR) << "Bad syntax to specify the tags"; + return false; + } + + // Inject the user-specified tags + Json::Value::Members members = tags.getMemberNames(); + for (size_t i = 0; i < members.size(); i++) + { + const std::string& name = members[i]; + if (tags[name].type() != Json::stringValue) + { + LOG(ERROR) << "Only string values are supported when creating DICOM instances"; + return false; + } + + std::string value = tags[name].asString(); + + DicomTag tag = FromDcmtkBridge::ParseTag(name); + if (tag != DICOM_TAG_SPECIFIC_CHARACTER_SET) + { + if (tag != DICOM_TAG_PATIENT_ID && + dicom.HasTag(tag)) + { + LOG(ERROR) << "Trying to override a value inherited from a parent module"; + return false; + } + + if (tag == DICOM_TAG_PIXEL_DATA) + { + LOG(ERROR) << "Use \"Content\" to inject an image into a new DICOM instance"; + return false; + } + else + { + dicom.Replace(tag, Toolbox::ConvertFromUtf8(value, dicom.GetEncoding())); + } + } + } + + return true; + } + + static void CreateSeries(RestApiPostCall& call, ParsedDicomFile& base /* in */, const Json::Value& content) @@ -503,14 +551,38 @@ for (Json::ArrayIndex i = 0; i < content.size(); i++) { - if (content[i].type() != Json::stringValue) + std::auto_ptr dicom(base.Clone()); + const Json::Value* payload = NULL; + + if (content[i].type() == Json::stringValue) + { + payload = &content[i]; + } + else if (content[i].type() == Json::objectValue) + { + if (!content[i].isMember("Content")) + { + LOG(ERROR) << "No payload is present for one instance in the series"; + return; + } + + payload = &content[i]["Content"]; + + if (content[i].isMember("Tags") && + !InjectTags(*dicom, content[i]["Tags"])) + { + return; + } + } + + if (payload == NULL || + payload->type() != Json::stringValue) { LOG(ERROR) << "The payload of the DICOM instance must be specified according to Data URI scheme"; return; } - std::auto_ptr dicom(base.Clone()); - dicom->EmbedContent(content[i].asString()); + dicom->EmbedContent(payload->asString()); dicom->Replace(DICOM_TAG_INSTANCE_NUMBER, boost::lexical_cast(i + 1)); dicom->Replace(DICOM_TAG_IMAGE_INDEX, boost::lexical_cast(i + 1)); @@ -541,25 +613,28 @@ return; } - Encoding encoding; + ParsedDicomFile dicom; - if (request["Tags"].isMember("SpecificCharacterSet")) { - const char* tmp = request["Tags"]["SpecificCharacterSet"].asCString(); - if (!GetDicomEncoding(encoding, tmp)) + Encoding encoding; + + if (request["Tags"].isMember("SpecificCharacterSet")) { - LOG(ERROR) << "Unknown specific character set: " << tmp; - return; + const char* tmp = request["Tags"]["SpecificCharacterSet"].asCString(); + if (!GetDicomEncoding(encoding, tmp)) + { + LOG(ERROR) << "Unknown specific character set: " << tmp; + return; + } } + else + { + std::string tmp = Configuration::GetGlobalStringParameter("DefaultEncoding", "Latin1"); + encoding = StringToEncoding(tmp.c_str()); + } + + dicom.SetEncoding(encoding); } - else - { - std::string tmp = Configuration::GetGlobalStringParameter("DefaultEncoding", "Latin1"); - encoding = StringToEncoding(tmp.c_str()); - } - - ParsedDicomFile dicom; - dicom.SetEncoding(encoding); ResourceType parentType = ResourceType_Instance; @@ -596,6 +671,27 @@ context.ReadJson(siblingTags, siblingInstances.front()); } + + // Choose the same encoding as the parent resource + { + static const char* SPECIFIC_CHARACTER_SET = "0008,0005"; + + if (siblingTags.isMember(SPECIFIC_CHARACTER_SET)) + { + Encoding encoding; + if (!siblingTags[SPECIFIC_CHARACTER_SET].isMember("Value") || + siblingTags[SPECIFIC_CHARACTER_SET]["Value"].type() != Json::stringValue || + !GetDicomEncoding(encoding, siblingTags[SPECIFIC_CHARACTER_SET]["Value"].asCString())) + { + LOG(ERROR) << "Unable to get the encoding of the parent resource"; + return; + } + + dicom.SetEncoding(encoding); + } + } + + // Retrieve the tags for all the parent modules typedef std::set ModuleTags; ModuleTags moduleTags; @@ -635,13 +731,13 @@ else if (tag["Type"] == "String") { std::string value = tag["Value"].asString(); - dicom.Replace(*it, Toolbox::ConvertFromUtf8(value, encoding)); + dicom.Replace(*it, Toolbox::ConvertFromUtf8(value, dicom.GetEncoding())); } } } } - + // Inject time-related information std::string date, time; Toolbox::GetNowDicom(date, time); @@ -668,39 +764,11 @@ } - // Inject the user-specified tags - Json::Value::Members members = request["Tags"].getMemberNames(); - for (size_t i = 0; i < members.size(); i++) + if (!InjectTags(dicom, request["Tags"])) { - const std::string& name = members[i]; - if (request["Tags"][name].type() != Json::stringValue) - { - LOG(ERROR) << "Only string values are supported when creating DICOM instances"; - return; - } - - std::string value = request["Tags"][name].asString(); + return; // Error + } - DicomTag tag = FromDcmtkBridge::ParseTag(name); - if (tag != DICOM_TAG_SPECIFIC_CHARACTER_SET) - { - if (dicom.HasTag(tag)) - { - LOG(ERROR) << "Trying to override a value inherited from a parent module"; - return; - } - - if (tag == DICOM_TAG_PIXEL_DATA) - { - LOG(ERROR) << "Use \"Content\" to inject an image into a new DICOM instance"; - return; - } - else - { - dicom.Replace(tag, Toolbox::ConvertFromUtf8(value, encoding)); - } - } - } // Inject the content (either an image, or a PDF file) if (request.isMember("Content")) @@ -716,7 +784,7 @@ { if (content.size() > 0) { - // Let's create a series + // Let's create a series instead of a single instance CreateSeries(call, dicom, content); return; } diff -r 1b7def486e62 -r 4b23310eb7e8 OrthancServer/ParsedDicomFile.cpp --- a/OrthancServer/ParsedDicomFile.cpp Fri Aug 21 15:01:21 2015 +0200 +++ b/OrthancServer/ParsedDicomFile.cpp Fri Aug 21 17:29:16 2015 +0200 @@ -1357,7 +1357,9 @@ return; } - std::string s = Toolbox::GetDicomSpecificCharacterSet(encoding); + pimpl_->encoding_ = encoding; + + std::string s = GetDicomSpecificCharacterSet(encoding); Replace(DICOM_TAG_SPECIFIC_CHARACTER_SET, s, DicomReplaceMode_InsertIfAbsent); }