Mercurial > hg > orthanc-dicomweb
changeset 88:e009c43f4dbb
switch between the media types
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 09 Dec 2015 11:30:05 +0100 |
parents | 8effbfc4cf28 |
children | 4667d4235791 |
files | Plugin/Dicom.h Plugin/WadoRs.cpp |
diffstat | 2 files changed, 185 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/Plugin/Dicom.h Wed Dec 09 10:13:39 2015 +0100 +++ b/Plugin/Dicom.h Wed Dec 09 11:30:05 2015 +0100 @@ -44,6 +44,7 @@ static const gdcm::Tag DICOM_TAG_REFERENCED_SOP_SEQUENCE(0x0008, 0x1199); 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); class ParsedDicomFile {
--- a/Plugin/WadoRs.cpp Wed Dec 09 10:13:39 2015 +0100 +++ b/Plugin/WadoRs.cpp Wed Dec 09 11:30:05 2015 +0100 @@ -635,19 +635,200 @@ +static bool Test(const gdcm::DataSet& dicom) +{ + if (!dicom.FindDataElement(OrthancPlugins::DICOM_TAG_PIXEL_DATA)) + { + return OrthancPluginErrorCode_IncompatibleImageFormat; + } + + const gdcm::DataElement& pixelData = dicom.GetDataElement(OrthancPlugins::DICOM_TAG_PIXEL_DATA); + const gdcm::SequenceOfFragments* fragments = pixelData.GetSequenceOfFragments(); + + if (fragments == NULL) + { + printf("Single-frame image\n"); + printf("%d\n", pixelData.GetByteValue()->GetLength()); + } + else + { + printf("Multi-frame image (%d fragments)\n", fragments->GetNumberOfFragments()); + + for (gdcm::SequenceOfFragments::SizeType i = 0; i < fragments->GetNumberOfFragments(); i++) + { + printf("%d: %d\n", i, fragments->GetFragment(i).GetByteValue()->GetLength()); + } + } + + return true; +} + + +static void TokenizeAndNormalize(std::vector<std::string>& tokens, + const std::string& source, + char separator) +{ + Orthanc::Toolbox::TokenizeString(tokens, source, separator); + + for (size_t i = 0; i < tokens.size(); i++) + { + tokens[i] = Orthanc::Toolbox::StripSpaces(tokens[i]); + Orthanc::Toolbox::ToLowerCase(tokens[i]); + } +} + + + +static gdcm::TransferSyntax GetTransferSyntax(const OrthancPluginHttpRequest* request) +{ + for (uint32_t i = 0; i < request->headersCount; i++) + { + std::string key(request->headersKeys[i]); + Orthanc::Toolbox::ToLowerCase(key); + + if (key == "accept") + { + std::vector<std::string> tokens; + TokenizeAndNormalize(tokens, request->headersValues[i], ';'); + + if (tokens.size() < 0 || + tokens[0] != "multipart/related") + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + + std::string type("application/octet-stream"); + std::string transferSyntax; + + for (size_t j = 1; j < tokens.size(); j++) + { + std::vector<std::string> parsed; + TokenizeAndNormalize(parsed, tokens[j], '='); + + if (parsed.size() != 2) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadRequest); + } + + if (parsed[0] == "type") + { + type = parsed[1]; + } + + if (parsed[0] == "transfer-syntax") + { + transferSyntax = parsed[1]; + } + } + + if (type == "application/octet-stream") + { + if (transferSyntax.empty()) + { + return gdcm::TransferSyntax(gdcm::TransferSyntax::ImplicitVRLittleEndian); + } + else + { + std::string s = ("DICOMweb RetrieveFrames: Cannot specify a transfer syntax (" + + transferSyntax + ") for default Little Endian uncompressed pixel data"); + OrthancPluginLogError(context_, s.c_str()); + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadRequest); + } + } + else + { + // http://dicom.nema.org/medical/dicom/current/output/html/part18.html#table_6.5-1 + if (type == "image/dicom+jpeg" && transferSyntax == "1.2.840.10008.1.2.4.50") + { + return gdcm::TransferSyntax::JPEGBaselineProcess1; + } + else if (type == "image/dicom+jpeg" && transferSyntax == "1.2.840.10008.1.2.4.51") + { + return gdcm::TransferSyntax::JPEGExtendedProcess2_4; + } + else if (type == "image/dicom+jpeg" && transferSyntax == "1.2.840.10008.1.2.4.57") + { + return gdcm::TransferSyntax::JPEGLosslessProcess14; + } + else if (type == "image/dicom+jpeg" && (transferSyntax.empty() || + transferSyntax == "1.2.840.10008.1.2.4.70")) + { + return gdcm::TransferSyntax::JPEGLosslessProcess14_1; + } + else if (type == "image/dicom+rle" && (transferSyntax.empty() || + transferSyntax == "1.2.840.10008.1.2.5")) + { + return gdcm::TransferSyntax::RLELossless; + } + else if (type == "image/dicom+jpeg-ls" && (transferSyntax.empty() || + transferSyntax == "1.2.840.10008.1.2.4.80")) + { + return gdcm::TransferSyntax::JPEGLSLossless; + } + else if (type == "image/dicom+jpeg-ls" && transferSyntax == "1.2.840.10008.1.2.4.81") + { + return gdcm::TransferSyntax::JPEGLSNearLossless; + } + else if (type == "image/dicom+jp2" && (transferSyntax.empty() || + transferSyntax == "1.2.840.10008.1.2.4.90")) + { + return gdcm::TransferSyntax::JPEG2000Lossless; + } + else if (type == "image/dicom+jp2" && transferSyntax == "1.2.840.10008.1.2.4.91") + { + return gdcm::TransferSyntax::JPEG2000; + } + else if (type == "image/dicom+jpx" && (transferSyntax.empty() || + transferSyntax == "1.2.840.10008.1.2.4.92")) + { + return gdcm::TransferSyntax::JPEG2000Part2Lossless; + } + else if (type == "image/dicom+jpx" && transferSyntax == "1.2.840.10008.1.2.4.93") + { + return gdcm::TransferSyntax::JPEG2000Part2; + } + else + { + std::string s = ("DICOMweb RetrieveFrames: Transfer syntax \"" + + transferSyntax + "\" is incompatible with media type \"" + type + "\""); + OrthancPluginLogError(context_, s.c_str()); + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadRequest); + } + } + } + } + + // By default, DICOMweb expectes Little Endian uncompressed pixel data + return gdcm::TransferSyntax::ImplicitVRLittleEndian; +} + OrthancPluginErrorCode RetrieveFrames(OrthancPluginRestOutput* output, const char* url, const OrthancPluginHttpRequest* request) { + // 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 + // http://gdcm.sourceforge.net/html/CompressLossyJPEG_8cs-example.html + printf("T: %s\n", GetTransferSyntax(request).GetString()); + + std::string uri, content; if (LocateInstance(output, uri, request) && OrthancPlugins::RestApiGetString(content, context_, uri + "/file")) { + { + OrthancPlugins::ParsedDicomFile dicom(content); + Test(dicom.GetDataSet()); + //return OrthancPluginErrorCode_Success; + } + + printf("RetrieveFrames: [%s] [%s]\n", uri.c_str(), request->groups[3]); gdcm::ImageChangeTransferSyntax change; @@ -679,9 +860,11 @@ writer.SetStream(ss); printf("Write: %d\n", writer.Write()); - gdcm::ImageReader reader2; + gdcm::Reader reader2; reader2.SetStream(ss); printf("Read: %d\n", reader2.Read()); + + Test(reader2.GetFile().GetDataSet()); } return OrthancPluginErrorCode_Success;