Mercurial > hg > orthanc-dicomweb
changeset 90:cb86c0518d74
transcoding is working
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 09 Dec 2015 16:29:31 +0100 |
parents | 4667d4235791 |
children | 2bd3bf4d95bb |
files | Plugin/Dicom.cpp Plugin/Dicom.h Plugin/QidoRs.cpp Plugin/StowRs.cpp Plugin/WadoRs.cpp |
diffstat | 5 files changed, 393 insertions(+), 207 deletions(-) [+] |
line wrap: on
line diff
--- a/Plugin/Dicom.cpp Wed Dec 09 11:57:44 2015 +0100 +++ b/Plugin/Dicom.cpp Wed Dec 09 16:29:31 2015 +0100 @@ -57,120 +57,6 @@ - void ParsedDicomFile::Setup(const std::string& dicom) - { - // Prepare a memory stream over the DICOM instance - std::stringstream stream(dicom); - - // Parse the DICOM instance using GDCM - reader_.SetStream(stream); - if (!reader_.Read()) - { - /* "GDCM cannot read this DICOM instance of length " + - boost::lexical_cast<std::string>(dicom.size()) */ - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); - } - } - - - ParsedDicomFile::ParsedDicomFile(const OrthancPlugins::MultipartItem& item) - { - std::string dicom(item.data_, item.data_ + item.size_); - Setup(dicom); - } - - - static bool GetTag(std::string& result, - const gdcm::DataSet& dataset, - const gdcm::Tag& tag, - bool stripSpaces) - { - if (dataset.FindDataElement(tag)) - { - const gdcm::ByteValue* value = dataset.GetDataElement(tag).GetByteValue(); - if (value) - { - result = std::string(value->GetPointer(), value->GetLength()); - - if (stripSpaces) - { - result = Orthanc::Toolbox::StripSpaces(result); - } - - return true; - } - } - - return false; - } - - - static std::string GetTagWithDefault(const gdcm::DataSet& dataset, - const gdcm::Tag& tag, - const std::string& defaultValue, - bool stripSpaces) - { - std::string result; - if (!GetTag(result, dataset, tag, false)) - { - result = defaultValue; - } - - if (stripSpaces) - { - result = Orthanc::Toolbox::StripSpaces(result); - } - - return result; - } - - - bool ParsedDicomFile::GetTag(std::string& result, - const gdcm::Tag& tag, - bool stripSpaces) const - { - return OrthancPlugins::GetTag(result, GetDataSet(), tag, stripSpaces); - } - - - std::string ParsedDicomFile::GetTagWithDefault(const gdcm::Tag& tag, - const std::string& defaultValue, - bool stripSpaces) const - { - return OrthancPlugins::GetTagWithDefault(GetDataSet(), tag, defaultValue, stripSpaces); - } - - - static std::string FormatTag(const gdcm::Tag& tag) - { - char tmp[16]; - sprintf(tmp, "%04X%04X", tag.GetGroup(), tag.GetElement()); - return std::string(tmp); - } - - - static const char* GetKeyword(const gdcm::Dict& dictionary, - const gdcm::Tag& tag) - { - const gdcm::DictEntry &entry = dictionary.GetDictEntry(tag); - const char* keyword = entry.GetKeyword(); - - if (strlen(keyword) != 0) - { - return keyword; - } - - if (tag == DICOM_TAG_RETRIEVE_URL) - { - return "RetrieveURL"; - } - - //throw Orthanc::OrthancException("Unknown keyword for tag: " + FormatTag(tag)); - return NULL; - } - - - static const char* GetVRName(bool& isSequence, const gdcm::Dict& dictionary, const gdcm::DataElement& element) @@ -209,6 +95,206 @@ } + + static bool ConvertDicomStringToUtf8(std::string& result, + const gdcm::Dict& dictionary, + const gdcm::File* file, + const gdcm::DataElement& element, + const Orthanc::Encoding sourceEncoding) + { + const gdcm::ByteValue* data = element.GetByteValue(); + if (!data) + { + return false; + } + + if (file != NULL) + { + bool isSequence; + std::string vr = GetVRName(isSequence, dictionary, element); + if (!isSequence && ( + vr == "FL" || + vr == "FD" || + vr == "SL" || + vr == "SS" || + vr == "UL" || + vr == "US" + )) + { + gdcm::StringFilter f; + f.SetFile(*file); + result = f.ToString(element.GetTag()); + return true; + } + } + + if (sourceEncoding == Orthanc::Encoding_Utf8) + { + result.assign(data->GetPointer(), data->GetLength()); + } + else + { + std::string tmp(data->GetPointer(), data->GetLength()); + result = Orthanc::Toolbox::ConvertToUtf8(tmp, sourceEncoding); + } + + result = Orthanc::Toolbox::StripSpaces(result); + return true; + } + + + + void ParsedDicomFile::Setup(const std::string& dicom) + { + // Prepare a memory stream over the DICOM instance + std::stringstream stream(dicom); + + // Parse the DICOM instance using GDCM + reader_.SetStream(stream); + if (!reader_.Read()) + { + /* "GDCM cannot read this DICOM instance of length " + + boost::lexical_cast<std::string>(dicom.size()) */ + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); + } + } + + + ParsedDicomFile::ParsedDicomFile(const OrthancPlugins::MultipartItem& item) + { + std::string dicom(item.data_, item.data_ + item.size_); + Setup(dicom); + } + + + static bool GetRawTag(std::string& result, + const gdcm::DataSet& dataset, + const gdcm::Tag& tag, + bool stripSpaces) + { + if (dataset.FindDataElement(tag)) + { + const gdcm::ByteValue* value = dataset.GetDataElement(tag).GetByteValue(); + if (value) + { + result.assign(value->GetPointer(), value->GetLength()); + + if (stripSpaces) + { + result = Orthanc::Toolbox::StripSpaces(result); + } + + return true; + } + } + + return false; + } + + + bool ParsedDicomFile::GetRawTag(std::string& result, + const gdcm::Tag& tag, + bool stripSpaces) const + { + return OrthancPlugins::GetRawTag(result, GetDataSet(), tag, stripSpaces); + } + + + std::string ParsedDicomFile::GetRawTagWithDefault(const gdcm::Tag& tag, + const std::string& defaultValue, + bool stripSpaces) const + { + std::string result; + if (!GetRawTag(result, tag, stripSpaces)) + { + return defaultValue; + } + else + { + return result; + } + } + + + bool ParsedDicomFile::GetStringTag(std::string& result, + const gdcm::Dict& dictionary, + const gdcm::Tag& tag, + bool stripSpaces) const + { + if (!GetDataSet().FindDataElement(tag)) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_InexistentTag); + } + + const gdcm::DataElement& element = GetDataSet().GetDataElement(tag); + + if (!ConvertDicomStringToUtf8(result, dictionary, &GetFile(), element, GetEncoding())) + { + return false; + } + + if (stripSpaces) + { + result = Orthanc::Toolbox::StripSpaces(result); + } + + return true; + } + + + bool ParsedDicomFile::GetIntegerTag(int& result, + const gdcm::Dict& dictionary, + const gdcm::Tag& tag) const + { + std::string tmp; + if (!GetStringTag(tmp, dictionary, tag, true)) + { + return false; + } + + try + { + result = boost::lexical_cast<int>(tmp); + return true; + } + catch (boost::bad_lexical_cast&) + { + return false; + } + } + + + + static std::string FormatTag(const gdcm::Tag& tag) + { + char tmp[16]; + sprintf(tmp, "%04X%04X", tag.GetGroup(), tag.GetElement()); + return std::string(tmp); + } + + + static const char* GetKeyword(const gdcm::Dict& dictionary, + const gdcm::Tag& tag) + { + const gdcm::DictEntry &entry = dictionary.GetDictEntry(tag); + const char* keyword = entry.GetKeyword(); + + if (strlen(keyword) != 0) + { + return keyword; + } + + if (tag == DICOM_TAG_RETRIEVE_URL) + { + return "RetrieveURL"; + } + + //throw Orthanc::OrthancException("Unknown keyword for tag: " + FormatTag(tag)); + return NULL; + } + + + static bool IsBulkData(const std::string& vr) { /** @@ -239,9 +325,9 @@ { std::string study, series, instance; - if (!GetTag(study, dicom, DICOM_TAG_STUDY_INSTANCE_UID, true) || - !GetTag(series, dicom, DICOM_TAG_SERIES_INSTANCE_UID, true) || - !GetTag(instance, dicom, DICOM_TAG_SOP_INSTANCE_UID, true)) + if (!GetRawTag(study, dicom, DICOM_TAG_STUDY_INSTANCE_UID, true) || + !GetRawTag(series, dicom, DICOM_TAG_SERIES_INSTANCE_UID, true) || + !GetRawTag(instance, dicom, DICOM_TAG_SOP_INSTANCE_UID, true)) { return ""; } @@ -285,51 +371,11 @@ } - static bool ConvertDicomStringToUf8(std::string& result, - const gdcm::Dict& dictionary, - const gdcm::File* file, - const gdcm::DataElement& element, - const Orthanc::Encoding sourceEncoding) + Orthanc::Encoding ParsedDicomFile::GetEncoding() const { - const gdcm::ByteValue* data = element.GetByteValue(); - if (!data) - { - return false; - } - - if (file != NULL) - { - bool isSequence; - std::string vr = GetVRName(isSequence, dictionary, element); - if (!isSequence && ( - vr == "FL" || - vr == "FD" || - vr == "SL" || - vr == "SS" || - vr == "UL" || - vr == "US" - )) - { - gdcm::StringFilter f; - f.SetFile(*file); - result = f.ToString(element.GetTag()); - return true; - } - } - - if (sourceEncoding == Orthanc::Encoding_Utf8) - { - result.assign(data->GetPointer(), data->GetLength()); - } - else - { - std::string tmp(data->GetPointer(), data->GetLength()); - result = Orthanc::Toolbox::ConvertToUtf8(tmp, sourceEncoding); - } - - result = Orthanc::Toolbox::StripSpaces(result); - return true; + return DetectEncoding(GetDataSet()); } + static void DicomToXmlInternal(pugi::xml_node& target, @@ -406,7 +452,7 @@ value.append_attribute("number").set_value("1"); std::string tmp; - if (ConvertDicomStringToUf8(tmp, dictionary, file, *it, sourceEncoding)) + if (ConvertDicomStringToUtf8(tmp, dictionary, file, *it, sourceEncoding)) { value.append_child(pugi::node_pcdata).set_value(tmp.c_str()); } @@ -504,7 +550,7 @@ node["Value"] = Json::arrayValue; std::string value; - if (ConvertDicomStringToUf8(value, dictionary, file, *it, sourceEncoding)) + if (ConvertDicomStringToUtf8(value, dictionary, file, *it, sourceEncoding)) { node["Value"].append(value.c_str()); }
--- a/Plugin/Dicom.h Wed Dec 09 11:57:44 2015 +0100 +++ b/Plugin/Dicom.h Wed Dec 09 16:29:31 2015 +0100 @@ -22,6 +22,8 @@ #include "Configuration.h" +#include "../Orthanc/Core/Enumerations.h" + #include <gdcmReader.h> #include <gdcmDataSet.h> #include <pugixml.hpp> @@ -45,6 +47,9 @@ static const gdcm::Tag DICOM_TAG_ACCESSION_NUMBER(0x0008, 0x0050); 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_COLUMNS(0x0028, 0x0011); + static const gdcm::Tag DICOM_TAG_ROWS(0x0028, 0x0010); + static const gdcm::Tag DICOM_TAG_BITS_ALLOCATED(0x0028, 0x0100); class ParsedDicomFile { @@ -71,13 +76,24 @@ return reader_.GetFile().GetDataSet(); } - bool GetTag(std::string& result, - const gdcm::Tag& tag, - bool stripSpaces) const; + bool GetRawTag(std::string& result, + const gdcm::Tag& tag, + bool stripSpaces) const; + + std::string GetRawTagWithDefault(const gdcm::Tag& tag, + const std::string& defaultValue, + bool stripSpaces) const; - std::string GetTagWithDefault(const gdcm::Tag& tag, - const std::string& defaultValue, - bool stripSpaces) const; + bool GetStringTag(std::string& result, + const gdcm::Dict& dictionary, + const gdcm::Tag& tag, + bool stripSpaces) const; + + bool GetIntegerTag(int& result, + const gdcm::Dict& dictionary, + const gdcm::Tag& tag) const; + + Orthanc::Encoding GetEncoding() const; };
--- a/Plugin/QidoRs.cpp Wed Dec 09 11:57:44 2015 +0100 +++ b/Plugin/QidoRs.cpp Wed Dec 09 16:29:31 2015 +0100 @@ -376,16 +376,16 @@ // Set the retrieve URL for WADO-RS std::string url = (wadoBase + "studies/" + - dicom.GetTagWithDefault(OrthancPlugins::DICOM_TAG_STUDY_INSTANCE_UID, "", true)); + dicom.GetRawTagWithDefault(OrthancPlugins::DICOM_TAG_STUDY_INSTANCE_UID, "", true)); if (level == QueryLevel_Series || level == QueryLevel_Instance) { - url += "/series/" + dicom.GetTagWithDefault(OrthancPlugins::DICOM_TAG_SERIES_INSTANCE_UID, "", true); + url += "/series/" + dicom.GetRawTagWithDefault(OrthancPlugins::DICOM_TAG_SERIES_INSTANCE_UID, "", true); } if (level == QueryLevel_Instance) { - url += "/instances/" + dicom.GetTagWithDefault(OrthancPlugins::DICOM_TAG_SOP_INSTANCE_UID, "", true); + url += "/instances/" + dicom.GetRawTagWithDefault(OrthancPlugins::DICOM_TAG_SOP_INSTANCE_UID, "", true); } gdcm::DataElement element(OrthancPlugins::DICOM_TAG_RETRIEVE_URL);
--- a/Plugin/StowRs.cpp Wed Dec 09 11:57:44 2015 +0100 +++ b/Plugin/StowRs.cpp Wed Dec 09 16:29:31 2015 +0100 @@ -169,9 +169,9 @@ OrthancPlugins::ParsedDicomFile dicom(items[i]); - std::string studyInstanceUid = dicom.GetTagWithDefault(OrthancPlugins::DICOM_TAG_STUDY_INSTANCE_UID, "", true); - std::string sopClassUid = dicom.GetTagWithDefault(OrthancPlugins::DICOM_TAG_SOP_CLASS_UID, "", true); - std::string sopInstanceUid = dicom.GetTagWithDefault(OrthancPlugins::DICOM_TAG_SOP_INSTANCE_UID, "", true); + std::string studyInstanceUid = dicom.GetRawTagWithDefault(OrthancPlugins::DICOM_TAG_STUDY_INSTANCE_UID, "", true); + 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(); @@ -207,7 +207,7 @@ { std::string url = (wadoBase + "studies/" + studyInstanceUid + - "/series/" + dicom.GetTagWithDefault(OrthancPlugins::DICOM_TAG_SERIES_INSTANCE_UID, "", true) + + "/series/" + dicom.GetRawTagWithDefault(OrthancPlugins::DICOM_TAG_SERIES_INSTANCE_UID, "", true) + "/instances/" + sopInstanceUid); SetTag(status, OrthancPlugins::DICOM_TAG_RETRIEVE_URL, gdcm::VR::UT, url);
--- a/Plugin/WadoRs.cpp Wed Dec 09 11:57:44 2015 +0100 +++ b/Plugin/WadoRs.cpp Wed Dec 09 16:29:31 2015 +0100 @@ -797,36 +797,160 @@ for (size_t i = 0; i < tokens.size(); i++) { - frames.push_back(boost::lexical_cast<unsigned int>(tokens[i])); + int frame = boost::lexical_cast<int>(tokens[i]); + if (frame <= 0) + { + std::string s = "Invalid frame number (must be > 0): " + tokens[i]; + OrthancPluginLogError(context_, s.c_str()); + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + + frames.push_back(static_cast<unsigned int>(frame - 1)); } } +static const char* GetMimeType(const gdcm::TransferSyntax& syntax) +{ + switch (syntax) + { + case gdcm::TransferSyntax::ImplicitVRLittleEndian: + return "application/octet-stream"; + + case gdcm::TransferSyntax::JPEGBaselineProcess1: + return "image/dicom+jpeg; transfer-syntax=1.2.840.10008.1.2.4.50"; + + case gdcm::TransferSyntax::JPEGExtendedProcess2_4: + return "image/dicom+jpeg; transfer-syntax=1.2.840.10008.1.2.4.51"; + + case gdcm::TransferSyntax::JPEGLosslessProcess14: + return "image/dicom+jpeg; transfer-syntax=1.2.840.10008.1.2.4.57"; + + case gdcm::TransferSyntax::JPEGLosslessProcess14_1: + return "image/dicom+jpeg; transferSyntax=1.2.840.10008.1.2.4.70"; + + case gdcm::TransferSyntax::RLELossless: + return "image/dicom+rle; transferSyntax=1.2.840.10008.1.2.5"; + + case gdcm::TransferSyntax::JPEGLSLossless: + return "image/dicom+jpeg-ls; transferSyntax=1.2.840.10008.1.2.4.80"; + + case gdcm::TransferSyntax::JPEGLSNearLossless: + return "image/dicom+jpeg-ls; transfer-syntax=1.2.840.10008.1.2.4.81"; + + case gdcm::TransferSyntax::JPEG2000Lossless: + return "image/dicom+jp2; transferSyntax=1.2.840.10008.1.2.4.90"; + + case gdcm::TransferSyntax::JPEG2000: + return "image/dicom+jp2; transfer-syntax=1.2.840.10008.1.2.4.91"; + + case gdcm::TransferSyntax::JPEG2000Part2Lossless: + return "image/dicom+jpx; transferSyntax=1.2.840.10008.1.2.4.92"; + + case gdcm::TransferSyntax::JPEG2000Part2: + return "image/dicom+jpx; transfer-syntax=1.2.840.10008.1.2.4.93"; + + default: + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); + } +} + + static bool AnswerFrames(OrthancPluginRestOutput* output, - const gdcm::DataSet& dicom, + const OrthancPlugins::ParsedDicomFile& dicom, + const gdcm::TransferSyntax& syntax, const std::list<unsigned int>& frames) { - if (!dicom.FindDataElement(OrthancPlugins::DICOM_TAG_PIXEL_DATA)) + if (!dicom.GetDataSet().FindDataElement(OrthancPlugins::DICOM_TAG_PIXEL_DATA)) { return OrthancPluginErrorCode_IncompatibleImageFormat; } - const gdcm::DataElement& pixelData = dicom.GetDataElement(OrthancPlugins::DICOM_TAG_PIXEL_DATA); + const gdcm::DataElement& pixelData = dicom.GetDataSet().GetDataElement(OrthancPlugins::DICOM_TAG_PIXEL_DATA); const gdcm::SequenceOfFragments* fragments = pixelData.GetSequenceOfFragments(); + if (OrthancPluginStartMultipartAnswer(context_, output, "related", GetMimeType(syntax)) != OrthancPluginErrorCode_Success) + { + return false; + } + if (fragments == NULL) { - printf("Single-frame image\n"); - printf("%d\n", pixelData.GetByteValue()->GetLength()); + // Single-fragment image + + if (pixelData.GetByteValue() == NULL) + { + OrthancPluginLogError(context_, "Image was not properly decoded"); + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); + } + + int width, height, bits; + + if (!dicom.GetIntegerTag(height, *dictionary_, OrthancPlugins::DICOM_TAG_ROWS) || + !dicom.GetIntegerTag(width, *dictionary_, OrthancPlugins::DICOM_TAG_COLUMNS) || + !dicom.GetIntegerTag(bits, *dictionary_, OrthancPlugins::DICOM_TAG_BITS_ALLOCATED)) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); + } + + size_t frameSize = height * width * bits / 8; + + if (pixelData.GetByteValue()->GetLength() % frameSize != 0) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); + } + + size_t framesCount = pixelData.GetByteValue()->GetLength() / frameSize; + const char* buffer = pixelData.GetByteValue()->GetPointer(); + assert(sizeof(char) == 1); + + for (std::list<unsigned int>::const_iterator + frame = frames.begin(); frame != frames.end(); ++frame) + { + if (*frame >= framesCount) + { + std::string s = ("Trying to access frame number " + boost::lexical_cast<std::string>(*frame + 1) + + " of an image with " + boost::lexical_cast<std::string>(framesCount) + " frames"); + OrthancPluginLogError(context_, s.c_str()); + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + else + { + const char* p = buffer + (*frame) * frameSize; + + // TODO SET Content-Location + if (OrthancPluginSendMultipartItem(context_, output, p, frameSize) != OrthancPluginErrorCode_Success) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol); + } + } + } } else { - printf("Multi-frame image (%d fragments)\n", fragments->GetNumberOfFragments()); + // Multi-fragment image, we assume that each fragment corresponds to one frame - for (gdcm::SequenceOfFragments::SizeType i = 0; i < fragments->GetNumberOfFragments(); i++) + for (std::list<unsigned int>::const_iterator + frame = frames.begin(); frame != frames.end(); ++frame) { - printf("%d: %d\n", i, fragments->GetFragment(i).GetByteValue()->GetLength()); + if (*frame >= fragments->GetNumberOfFragments()) + { + std::string s = ("Trying to access frame number " + boost::lexical_cast<std::string>(*frame + 1) + + " of an image with " + boost::lexical_cast<std::string>(fragments->GetNumberOfFragments()) + " frames"); + OrthancPluginLogError(context_, s.c_str()); + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + else + { + // TODO SET Content-Location + if (OrthancPluginSendMultipartItem(context_, output, + fragments->GetFragment(*frame).GetByteValue()->GetPointer(), + fragments->GetFragment(*frame).GetByteValue()->GetLength()) != OrthancPluginErrorCode_Success) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol); + } + } } } @@ -840,8 +964,8 @@ { // storescu -xs localhost 4242 ~/Subversion/orthanc-tests/Database/Multiframe.dcm - // curl http://localhost:8042/dicom-web/studies/1.3.51.0.1.1.192.168.29.133.1681753.1681732/series/1.3.12.2.1107.5.2.33.37097.2012041612474981424569674.0.0.0/instances/1.3.12.2.1107.5.2.33.37097.2012041612485517294169680/frames/0 - // curl http://localhost:8042/dicom-web/studies/1.3.46.670589.7.5.8.80001255161.20000323.151537.1/series/1.3.46.670589.7.5.7.80001255161.20000323.151537.1/instances/1.3.46.670589.7.5.1.981501.20000323.16172540.1.1.13/frames/0 + // curl http://localhost:8042/dicom-web/studies/1.3.51.0.1.1.192.168.29.133.1681753.1681732/series/1.3.12.2.1107.5.2.33.37097.2012041612474981424569674.0.0.0/instances/1.3.12.2.1107.5.2.33.37097.2012041612485517294169680/frames/1 + // curl http://localhost:8042/dicom-web/studies/1.3.46.670589.7.5.8.80001255161.20000323.151537.1/series/1.3.46.670589.7.5.7.80001255161.20000323.151537.1/instances/1.3.46.670589.7.5.1.981501.20000323.16172540.1.1.13/frames/1 // http://gdcm.sourceforge.net/html/CompressLossyJPEG_8cs-example.html @@ -859,9 +983,10 @@ { { std::string s = "DICOMweb RetrieveFrames on " + uri + ", frames: "; - for (std::list<unsigned int>::const_iterator it = frames.begin(); it != frames.end(); ++it) + for (std::list<unsigned int>::const_iterator + frame = frames.begin(); frame != frames.end(); ++frame) { - s += boost::lexical_cast<std::string>(*it) + " "; + s += boost::lexical_cast<std::string>(*frame + 1) + " "; } OrthancPluginLogInfo(context_, s.c_str()); } @@ -892,7 +1017,7 @@ source.reset(new OrthancPlugins::ParsedDicomFile(content)); } - AnswerFrames(output, source->GetFile().GetDataSet(), frames); + AnswerFrames(output, *source, targetSyntax, frames); } else { @@ -905,25 +1030,24 @@ } gdcm::ImageChangeTransferSyntax change; - change.SetTransferSyntax(gdcm::TransferSyntax::JPEG2000Lossless); - - gdcm::JPEG2000Codec codec; - if (!codec.CanCode(change.GetTransferSyntax())) - { - return OrthancPluginErrorCode_Plugin; - } - - //codec.SetLossless(true); - change.SetUserCodec(&codec); + change.SetTransferSyntax(targetSyntax); std::stringstream stream(content); gdcm::ImageReader reader; reader.SetStream(stream); - printf("Read: %d\n", reader.Read()); + if (!reader.Read()) + { + OrthancPluginLogError(context_, "Cannot decode the image"); + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); + } change.SetInput(reader.GetImage()); - printf("Change: %d\n", change.Change()); + if (!change.Change()) + { + OrthancPluginLogError(context_, "Cannot change the transfer syntax of the image"); + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); + } gdcm::ImageWriter writer; writer.SetImage(change.GetOutput()); @@ -931,13 +1055,13 @@ std::stringstream ss; writer.SetStream(ss); - printf("Write: %d\n", writer.Write()); + if (!writer.Write()) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_NotEnoughMemory); + } - gdcm::Reader reader2; - reader2.SetStream(ss); - printf("Read: %d\n", reader2.Read()); - - AnswerFrames(output, reader2.GetFile().GetDataSet(), frames); + OrthancPlugins::ParsedDicomFile transcoded(ss.str()); + AnswerFrames(output, transcoded, targetSyntax, frames); } }