# HG changeset patch # User Sebastien Jodogne # Date 1689171259 -7200 # Node ID ac1508b438b1adb1746661589c72df40175ed165 # Parent ef8a673b5fb933af40851042a91a86e1ceb661bd support of "Accept" header in /wsi/tiles/{id}/{z}/{x}/{y} diff -r ef8a673b5fb9 -r ac1508b438b1 NEWS --- a/NEWS Wed Jul 12 14:51:46 2023 +0200 +++ b/NEWS Wed Jul 12 16:14:19 2023 +0200 @@ -2,6 +2,8 @@ =============================== * Support of IIIF +* URI "/wsi/tiles/{id}/{z}/{x}/{y}" supports the "Accept" HTTP header + to force JPEG, JPEG2k or PNG in the decoded tiles Version 1.1 (2021-12-11) diff -r ef8a673b5fb9 -r ac1508b438b1 ViewerPlugin/Plugin.cpp --- a/ViewerPlugin/Plugin.cpp Wed Jul 12 14:51:46 2023 +0200 +++ b/ViewerPlugin/Plugin.cpp Wed Jul 12 16:14:19 2023 +0200 @@ -27,9 +27,9 @@ #include "RawTile.h" #include // For std::unique_ptr -#include #include #include +#include #include #include @@ -161,20 +161,72 @@ static_cast(tileY))); } + Orthanc::MimeType mime; + if (rawTile->GetCompression() == OrthancWSI::ImageCompression_Jpeg) { // The tile is already a JPEG image. In such a case, we can // serve it as such, because any Web browser can handle JPEG. - rawTile->Answer(output, Orthanc::MimeType_Jpeg); + mime = Orthanc::MimeType_Jpeg; } else { - // This is a lossless frame (coming from a JPEG2000 or an - // uncompressed DICOM instance), which is not a DICOM-JPEG - // instance. We need to decompress the raw tile, then transcode it - // to the PNG/JPEG, depending on the "encoding". - rawTile->Answer(output, Orthanc::MimeType_Png); + // This is a lossless frame (coming from JPEG2000 or uncompressed + // DICOM instance), not a DICOM-JPEG instance. Decompress the raw + // tile, then transcode it to PNG to prevent lossy compression and + // to avoid JPEG2000 that is not supported by all the browsers. + mime = Orthanc::MimeType_Png; } + + // Lookup whether a "Accept" HTTP header is present, to overwrite + // the default MIME type + for (uint32_t i = 0; i < request->headersCount; i++) + { + std::string key(request->headersKeys[i]); + Orthanc::Toolbox::ToLowerCase(key); + + if (key == "accept") + { + std::vector tokens; + Orthanc::Toolbox::TokenizeString(tokens, request->headersValues[i], ','); + + bool found = false; + + for (size_t j = 0; j < tokens.size(); j++) + { + std::string s = Orthanc::Toolbox::StripSpaces(tokens[j]); + + if (s == Orthanc::EnumerationToString(Orthanc::MimeType_Png)) + { + mime = Orthanc::MimeType_Png; + found = true; + } + else if (s == Orthanc::EnumerationToString(Orthanc::MimeType_Jpeg)) + { + mime = Orthanc::MimeType_Jpeg; + found = true; + } + else if (s == Orthanc::EnumerationToString(Orthanc::MimeType_Jpeg2000)) + { + mime = Orthanc::MimeType_Jpeg2000; + found = true; + } + else if (s == "*/*" || + s == "image/*") + { + found = true; + } + } + + if (!found) + { + OrthancPluginSendHttpStatusCode(OrthancPlugins::GetGlobalContext(), output, 406 /* Not acceptable */); + return; + } + } + } + + rawTile->Answer(output, mime); } diff -r ef8a673b5fb9 -r ac1508b438b1 ViewerPlugin/RawTile.cpp --- a/ViewerPlugin/RawTile.cpp Wed Jul 12 14:51:46 2023 +0200 +++ b/ViewerPlugin/RawTile.cpp Wed Jul 12 16:14:19 2023 +0200 @@ -39,6 +39,25 @@ namespace OrthancWSI { + static ImageCompression Convert(Orthanc::MimeType type) + { + switch (type) + { + case Orthanc::MimeType_Png: + return ImageCompression_Png; + + case Orthanc::MimeType_Jpeg: + return ImageCompression_Jpeg; + + case Orthanc::MimeType_Jpeg2000: + return ImageCompression_Jpeg2000; + + default: + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + } + + Orthanc::ImageAccessor* RawTile::DecodeInternal() { switch (compression_) @@ -82,30 +101,11 @@ } } - void RawTile::EncodeInternal(std::string& encoded, const Orthanc::ImageAccessor& decoded, Orthanc::MimeType encoding) { - switch (encoding) - { - case Orthanc::MimeType_Png: - { - Orthanc::PngWriter writer; - Orthanc::IImageWriter::WriteToMemory(writer, encoded, decoded); - break; - } - - case Orthanc::MimeType_Jpeg: - { - Orthanc::JpegWriter writer; - Orthanc::IImageWriter::WriteToMemory(writer, encoded, decoded); - break; - } - - default: - throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); - } + ImageToolbox::EncodeTile(encoded, decoded, Convert(encoding), 90 /* only used for JPEG */); }