Mercurial > hg > orthanc-dicomweb
changeset 259:c6881fa1935c
cont
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 27 Feb 2019 11:33:10 +0100 |
parents | 4e6093d65671 |
children | 2c71a99e533f |
files | Plugin/Configuration.h Plugin/Dicom.cpp Plugin/Dicom.h Plugin/DicomWebClient.cpp Plugin/DicomWebFormatter.cpp Plugin/DicomWebFormatter.h Plugin/StowRs.cpp |
diffstat | 7 files changed, 76 insertions(+), 67 deletions(-) [+] |
line wrap: on
line diff
--- a/Plugin/Configuration.h Wed Feb 27 10:08:53 2019 +0100 +++ b/Plugin/Configuration.h Wed Feb 27 11:33:10 2019 +0100 @@ -37,6 +37,14 @@ namespace OrthancPlugins { + static const Orthanc::DicomTag DICOM_TAG_RETRIEVE_URL(0x0008, 0x1190); + static const Orthanc::DicomTag DICOM_TAG_FAILURE_REASON(0x0008, 0x1197); + static const Orthanc::DicomTag DICOM_TAG_WARNING_REASON(0x0008, 0x1196); + static const Orthanc::DicomTag DICOM_TAG_FAILED_SOP_SEQUENCE(0x0008, 0x1198); + static const Orthanc::DicomTag DICOM_TAG_REFERENCED_SOP_SEQUENCE(0x0008, 0x1199); + static const Orthanc::DicomTag DICOM_TAG_REFERENCED_SOP_CLASS_UID(0x0008, 0x1150); + static const Orthanc::DicomTag DICOM_TAG_REFERENCED_SOP_INSTANCE_UID(0x0008, 0x1155); + struct MultipartItem { const char* data_;
--- a/Plugin/Dicom.cpp Wed Feb 27 10:08:53 2019 +0100 +++ b/Plugin/Dicom.cpp Wed Feb 27 11:33:10 2019 +0100 @@ -31,8 +31,12 @@ #include <boost/lexical_cast.hpp> #include <json/writer.h> + namespace OrthancPlugins { + static const gdcm::Tag GDCM_TAG_RETRIEVE_URL(0x0008, 0x1190); + + static std::string MyStripSpaces(const std::string& source) { size_t first = 0; @@ -367,7 +371,7 @@ return keyword; } - if (tag == DICOM_TAG_RETRIEVE_URL) + if (tag == GDCM_TAG_RETRIEVE_URL) { return "RetrieveURL"; } @@ -475,7 +479,7 @@ bool isSequence = false; std::string vr; - if (it->GetTag() == DICOM_TAG_RETRIEVE_URL) + if (it->GetTag() == GDCM_TAG_RETRIEVE_URL) { // The VR of this attribute has changed from UT to UR. vr = "UR"; @@ -581,7 +585,7 @@ bool isSequence = false; std::string vr; - if (it->GetTag() == DICOM_TAG_RETRIEVE_URL) + if (it->GetTag() == GDCM_TAG_RETRIEVE_URL) { // The VR of this attribute has changed from UT to UR. vr = "UR";
--- a/Plugin/Dicom.h Wed Feb 27 10:08:53 2019 +0100 +++ b/Plugin/Dicom.h Wed Feb 27 11:33:10 2019 +0100 @@ -37,23 +37,16 @@ namespace OrthancPlugins { + static const gdcm::Tag DICOM_TAG_BITS_ALLOCATED(0x0028, 0x0100); + static const gdcm::Tag DICOM_TAG_COLUMNS(0x0028, 0x0011); + static const gdcm::Tag DICOM_TAG_PIXEL_DATA(0x7fe0, 0x0010); + static const gdcm::Tag DICOM_TAG_ROWS(0x0028, 0x0010); + static const gdcm::Tag DICOM_TAG_SAMPLES_PER_PIXEL(0x0028, 0x0002); + static const gdcm::Tag DICOM_TAG_SERIES_INSTANCE_UID(0x0020, 0x000e); static const gdcm::Tag DICOM_TAG_SOP_CLASS_UID(0x0008, 0x0016); static const gdcm::Tag DICOM_TAG_SOP_INSTANCE_UID(0x0008, 0x0018); + static const gdcm::Tag DICOM_TAG_SPECIFIC_CHARACTER_SET(0x0008, 0x0005); static const gdcm::Tag DICOM_TAG_STUDY_INSTANCE_UID(0x0020, 0x000d); - static const gdcm::Tag DICOM_TAG_SERIES_INSTANCE_UID(0x0020, 0x000e); - static const gdcm::Tag DICOM_TAG_REFERENCED_SOP_CLASS_UID(0x0008, 0x1150); - static const gdcm::Tag DICOM_TAG_REFERENCED_SOP_INSTANCE_UID(0x0008, 0x1155); - static const gdcm::Tag DICOM_TAG_RETRIEVE_URL(0x0008, 0x1190); - static const gdcm::Tag DICOM_TAG_FAILED_SOP_SEQUENCE(0x0008, 0x1198); - static const gdcm::Tag DICOM_TAG_FAILURE_REASON(0x0008, 0x1197); - static const gdcm::Tag DICOM_TAG_WARNING_REASON(0x0008, 0x1196); - static const gdcm::Tag DICOM_TAG_REFERENCED_SOP_SEQUENCE(0x0008, 0x1199); - static const gdcm::Tag DICOM_TAG_SPECIFIC_CHARACTER_SET(0x0008, 0x0005); - static const gdcm::Tag DICOM_TAG_PIXEL_DATA(0x7fe0, 0x0010); - static const gdcm::Tag DICOM_TAG_SAMPLES_PER_PIXEL(0x0028, 0x0002); - static const gdcm::Tag DICOM_TAG_COLUMNS(0x0028, 0x0011); - static const gdcm::Tag DICOM_TAG_ROWS(0x0028, 0x0010); - static const gdcm::Tag DICOM_TAG_BITS_ALLOCATED(0x0028, 0x0100); class ParsedDicomFile {
--- a/Plugin/DicomWebClient.cpp Wed Feb 27 10:08:53 2019 +0100 +++ b/Plugin/DicomWebClient.cpp Wed Feb 27 11:33:10 2019 +0100 @@ -82,15 +82,23 @@ } if (value->type() != Json::objectValue || - !value->isMember("Value") || - (*value) ["Value"].type() != Json::arrayValue) + (value->isMember("Value") && + (*value) ["Value"].type() != Json::arrayValue)) { throw Orthanc::OrthancException( Orthanc::ErrorCode_NetworkProtocol, "Unable to parse STOW-RS JSON response from DICOMweb server " + server); } - result = (*value) ["Value"].size(); + if (value->isMember("Value")) + { + result = (*value) ["Value"].size(); + } + else + { + result = 0; + } + return true; }
--- a/Plugin/DicomWebFormatter.cpp Wed Feb 27 10:08:53 2019 +0100 +++ b/Plugin/DicomWebFormatter.cpp Wed Feb 27 11:33:10 2019 +0100 @@ -104,6 +104,17 @@ } + void DicomWebFormatter::Locker::Apply(std::string& target, + OrthancPluginContext* context, + const Json::Value& value, + bool xml) + { + MemoryBuffer dicom; + dicom.CreateDicom(value, OrthancPluginCreateDicomFlags_None); + Apply(target, context, dicom.GetData(), dicom.GetSize(), xml); + } + + DicomWebFormatter::HttpWriter::HttpWriter(OrthancPluginRestOutput* output, bool isXml) : context_(OrthancPlugins::GetGlobalContext()),
--- a/Plugin/DicomWebFormatter.h Wed Feb 27 10:08:53 2019 +0100 +++ b/Plugin/DicomWebFormatter.h Wed Feb 27 11:33:10 2019 +0100 @@ -72,6 +72,11 @@ const void* data, size_t size, bool xml); + + void Apply(std::string& target, + OrthancPluginContext* context, + const Json::Value& value, + bool xml); }; class HttpWriter : public boost::noncopyable
--- a/Plugin/StowRs.cpp Wed Feb 27 10:08:53 2019 +0100 +++ b/Plugin/StowRs.cpp Wed Feb 27 11:33:10 2019 +0100 @@ -24,38 +24,13 @@ #include "Configuration.h" #include "Dicom.h" +#include "DicomWebFormatter.h" #include <Core/Toolbox.h> #include <stdexcept> -static void SetTag(gdcm::DataSet& dataset, - const gdcm::Tag& tag, - const gdcm::VR& vr, - const std::string& value) -{ - gdcm::DataElement element(tag); - element.SetVR(vr); - element.SetByteValue(value.c_str(), value.size()); - dataset.Insert(element); -} - - -static void SetSequenceTag(gdcm::DataSet& dataset, - const gdcm::Tag& tag, - gdcm::SmartPointer<gdcm::SequenceOfItems>& sequence) -{ - gdcm::DataElement element; - element.SetTag(tag); - element.SetVR(gdcm::VR::SQ); - element.SetValue(*sequence); - element.SetVLToUndefined(); - dataset.Insert(element); -} - - - bool IsXmlExpected(const OrthancPluginHttpRequest* request) { std::string accept; @@ -117,8 +92,6 @@ OrthancPlugins::LogInfo("STOW-RS request restricted to study UID " + expectedStudy); } - bool isXml = IsXmlExpected(request); - std::string header; if (!OrthancPlugins::LookupHttpHeader(header, request, "content-type")) { @@ -152,9 +125,10 @@ bool isFirst = true; - gdcm::DataSet result; - gdcm::SmartPointer<gdcm::SequenceOfItems> success = new gdcm::SequenceOfItems(); - gdcm::SmartPointer<gdcm::SequenceOfItems> failed = new gdcm::SequenceOfItems(); + + Json::Value result = Json::objectValue; + Json::Value success = Json::arrayValue; + Json::Value failed = Json::arrayValue; std::vector<OrthancPlugins::MultipartItem> items; OrthancPlugins::ParseMultipartBody(items, request->body, request->bodySize, boundary); @@ -183,12 +157,9 @@ std::string sopClassUid = dicom.GetRawTagWithDefault(OrthancPlugins::DICOM_TAG_SOP_CLASS_UID, "", true); std::string sopInstanceUid = dicom.GetRawTagWithDefault(OrthancPlugins::DICOM_TAG_SOP_INSTANCE_UID, "", true); - gdcm::Item item; - item.SetVLToUndefined(); - gdcm::DataSet &status = item.GetNestedDataSet(); - - SetTag(status, OrthancPlugins::DICOM_TAG_REFERENCED_SOP_CLASS_UID, gdcm::VR::UI, sopClassUid); - SetTag(status, OrthancPlugins::DICOM_TAG_REFERENCED_SOP_INSTANCE_UID, gdcm::VR::UI, sopInstanceUid); + Json::Value item = Json::objectValue; + item[OrthancPlugins::DICOM_TAG_REFERENCED_SOP_CLASS_UID.Format()] = sopClassUid; + item[OrthancPlugins::DICOM_TAG_REFERENCED_SOP_INSTANCE_UID.Format()] = sopInstanceUid; if (!expectedStudy.empty() && studyInstanceUid != expectedStudy) @@ -196,15 +167,15 @@ OrthancPlugins::LogInfo("STOW-RS request restricted to study [" + expectedStudy + "]: Ignoring instance from study [" + studyInstanceUid + "]"); - SetTag(status, OrthancPlugins::DICOM_TAG_WARNING_REASON, gdcm::VR::US, "B006"); // Elements discarded - success->AddItem(item); + item[OrthancPlugins::DICOM_TAG_WARNING_REASON.Format()] = "B006"; // Elements discarded + success.append(item); } else { if (isFirst) { std::string url = wadoBase + "studies/" + studyInstanceUid; - SetTag(result, OrthancPlugins::DICOM_TAG_RETRIEVE_URL, gdcm::VR::UT, url); + result[OrthancPlugins::DICOM_TAG_RETRIEVE_URL.Format()] = url; isFirst = false; } @@ -219,20 +190,29 @@ "/series/" + dicom.GetRawTagWithDefault(OrthancPlugins::DICOM_TAG_SERIES_INSTANCE_UID, "", true) + "/instances/" + sopInstanceUid); - SetTag(status, OrthancPlugins::DICOM_TAG_RETRIEVE_URL, gdcm::VR::UT, url); - success->AddItem(item); + item[OrthancPlugins::DICOM_TAG_RETRIEVE_URL.Format()] = url; + success.append(item); } else { OrthancPlugins::LogError("Orthanc was unable to store instance through STOW-RS request"); - SetTag(status, OrthancPlugins::DICOM_TAG_FAILURE_REASON, gdcm::VR::US, "0110"); // Processing failure - failed->AddItem(item); + item[OrthancPlugins::DICOM_TAG_FAILURE_REASON.Format()] = "0110"; // Processing failure + failed.append(item); } } } - SetSequenceTag(result, OrthancPlugins::DICOM_TAG_FAILED_SOP_SEQUENCE, failed); - SetSequenceTag(result, OrthancPlugins::DICOM_TAG_REFERENCED_SOP_SEQUENCE, success); + result[OrthancPlugins::DICOM_TAG_FAILED_SOP_SEQUENCE.Format()] = failed; + result[OrthancPlugins::DICOM_TAG_REFERENCED_SOP_SEQUENCE.Format()] = success; - OrthancPlugins::AnswerDicom(output, wadoBase, *dictionary_, result, isXml, false); + const bool isXml = IsXmlExpected(request); + std::string answer; + + { + OrthancPlugins::DicomWebFormatter::Locker locker(OrthancPluginDicomWebBinaryMode_Ignore, ""); + locker.Apply(answer, context, result, isXml); + } + + OrthancPluginAnswerBuffer(context, output, answer.c_str(), answer.size(), + isXml ? "application/dicom+xml" : "application/dicom+json"); }