Mercurial > hg > orthanc-wsi
changeset 345:e1d9a00d6f64
improved code reuse
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 10 Dec 2024 13:32:20 +0100 |
parents | 5050be0f646b |
children | e42d0e9c0c23 |
files | ViewerPlugin/Plugin.cpp |
diffstat | 1 files changed, 135 insertions(+), 193 deletions(-) [+] |
line wrap: on
line diff
--- a/ViewerPlugin/Plugin.cpp Tue Dec 10 13:11:58 2024 +0100 +++ b/ViewerPlugin/Plugin.cpp Tue Dec 10 13:32:20 2024 +0100 @@ -113,35 +113,25 @@ } -void ServePyramid(OrthancPluginRestOutput* output, - const char* url, - const OrthancPluginHttpRequest* request) +static void DescribePyramid(Json::Value& result, + const OrthancWSI::ITiledPyramid& pyramid) { - std::string seriesId(request->groups[0]); - - char tmp[1024]; - sprintf(tmp, "Accessing whole-slide pyramid of series %s", seriesId.c_str()); - OrthancPluginLogInfo(OrthancPlugins::GetGlobalContext(), tmp); - - - OrthancWSI::DicomPyramidCache::Locker locker(seriesId); - - unsigned int totalWidth = locker.GetPyramid().GetLevelWidth(0); - unsigned int totalHeight = locker.GetPyramid().GetLevelHeight(0); + unsigned int totalWidth = pyramid.GetLevelWidth(0); + unsigned int totalHeight = pyramid.GetLevelHeight(0); Json::Value sizes = Json::arrayValue; Json::Value resolutions = Json::arrayValue; Json::Value tilesCount = Json::arrayValue; Json::Value tilesSizes = Json::arrayValue; - for (unsigned int i = 0; i < locker.GetPyramid().GetLevelCount(); i++) + for (unsigned int i = 0; i < pyramid.GetLevelCount(); i++) { - const unsigned int levelWidth = locker.GetPyramid().GetLevelWidth(i); - const unsigned int levelHeight = locker.GetPyramid().GetLevelHeight(i); - const unsigned int tileWidth = locker.GetPyramid().GetTileWidth(i); - const unsigned int tileHeight = locker.GetPyramid().GetTileHeight(i); - + const unsigned int levelWidth = pyramid.GetLevelWidth(i); + const unsigned int levelHeight = pyramid.GetLevelHeight(i); + const unsigned int tileWidth = pyramid.GetTileWidth(i); + const unsigned int tileHeight = pyramid.GetTileHeight(i); + resolutions.append(static_cast<float>(totalWidth) / static_cast<float>(levelWidth)); - + Json::Value s = Json::arrayValue; s.append(levelWidth); s.append(levelHeight); @@ -158,28 +148,138 @@ tilesSizes.append(s); } - Json::Value result; - result["ID"] = seriesId; + result = Json::objectValue; result["Resolutions"] = resolutions; result["Sizes"] = sizes; result["TilesCount"] = tilesCount; result["TilesSizes"] = tilesSizes; result["TotalHeight"] = totalHeight; result["TotalWidth"] = totalWidth; +} + + +void ServePyramid(OrthancPluginRestOutput* output, + const char* url, + const OrthancPluginHttpRequest* request) +{ + std::string seriesId(request->groups[0]); + + char tmp[1024]; + sprintf(tmp, "Accessing whole-slide pyramid of series %s", seriesId.c_str()); + OrthancPluginLogInfo(OrthancPlugins::GetGlobalContext(), tmp); + + Json::Value answer; + answer["ID"] = seriesId; + + { + OrthancWSI::DicomPyramidCache::Locker locker(seriesId); + DescribePyramid(answer, locker.GetPyramid()); + + { + // New in WSI 2.1 + sprintf(tmp, "#%02x%02x%02x", locker.GetPyramid().GetBackgroundRed(), + locker.GetPyramid().GetBackgroundGreen(), + locker.GetPyramid().GetBackgroundBlue()); + answer["BackgroundColor"] = tmp; + } + } + + std::string s = answer.toStyledString(); + OrthancPluginAnswerBuffer(OrthancPlugins::GetGlobalContext(), output, s.c_str(), s.size(), "application/json"); +} + + +void ServeFramePyramid(OrthancPluginRestOutput* output, + const char* url, + const OrthancPluginHttpRequest* request) +{ + std::string instanceId(request->groups[0]); + int frameNumber = boost::lexical_cast<int>(request->groups[1]); + + LOG(INFO) << "Accessing pyramid of frame " << frameNumber << " in instance " << instanceId; + + if (frameNumber < 0) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + + Json::Value answer; + answer["ID"] = instanceId; + answer["FrameNumber"] = frameNumber; { - // New in WSI 2.1 - sprintf(tmp, "#%02x%02x%02x", locker.GetPyramid().GetBackgroundRed(), - locker.GetPyramid().GetBackgroundGreen(), - locker.GetPyramid().GetBackgroundBlue()); - result["BackgroundColor"] = tmp; + OrthancWSI::DecodedPyramidCache::Accessor accessor(OrthancWSI::DecodedPyramidCache::GetInstance(), instanceId, frameNumber); + DescribePyramid(answer, accessor.GetPyramid()); + + { + uint8_t red, green, blue; + accessor.GetPyramid().GetBackgroundColor(red, green, blue); // TODO + + char tmp[64]; + sprintf(tmp, "#%02x%02x%02x", red, green, blue); + answer["BackgroundColor"] = tmp; + } } - std::string s = result.toStyledString(); + std::string s = answer.toStyledString(); OrthancPluginAnswerBuffer(OrthancPlugins::GetGlobalContext(), output, s.c_str(), s.size(), "application/json"); } +static bool LookupAcceptHeader(Orthanc::MimeType& target, + const OrthancPluginHttpRequest* request) +{ + // 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<std::string> tokens; + Orthanc::Toolbox::TokenizeString(tokens, request->headersValues[i], ','); + + bool compatible = 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)) + { + target = Orthanc::MimeType_Png; + return true; + } + else if (s == Orthanc::EnumerationToString(Orthanc::MimeType_Jpeg)) + { + target = Orthanc::MimeType_Jpeg; + return true; + } + else if (s == Orthanc::EnumerationToString(Orthanc::MimeType_Jpeg2000)) + { + target = Orthanc::MimeType_Jpeg2000; + return true; + } + else if (s == "*/*" || + s == "image/*") + { + compatible = true; + } + } + + if (!compatible) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_NotAcceptable); + } + } + } + + return false; +} + + void ServeTile(OrthancPluginRestOutput* output, const char* url, const OrthancPluginHttpRequest* request) @@ -237,130 +337,16 @@ 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++) + Orthanc::MimeType accept; + if (LookupAcceptHeader(accept, request)) { - std::string key(request->headersKeys[i]); - Orthanc::Toolbox::ToLowerCase(key); - - if (key == "accept") - { - std::vector<std::string> 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; - } - } + mime = accept; } rawTile->Answer(output, mime); } -void ServeFramePyramid(OrthancPluginRestOutput* output, - const char* url, - const OrthancPluginHttpRequest* request) -{ - std::string instanceId(request->groups[0]); - int frameNumber = boost::lexical_cast<int>(request->groups[1]); - - LOG(INFO) << "Accessing pyramid of frame " << frameNumber << " in instance " << instanceId; - - if (frameNumber < 0) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); - } - - OrthancWSI::DecodedPyramidCache::Accessor accessor(OrthancWSI::DecodedPyramidCache::GetInstance(), instanceId, frameNumber); - - unsigned int totalWidth = accessor.GetPyramid().GetLevelWidth(0); - unsigned int totalHeight = accessor.GetPyramid().GetLevelHeight(0); - - Json::Value sizes = Json::arrayValue; - Json::Value resolutions = Json::arrayValue; - Json::Value tilesCount = Json::arrayValue; - Json::Value tilesSizes = Json::arrayValue; - for (unsigned int i = 0; i < accessor.GetPyramid().GetLevelCount(); i++) - { - const unsigned int levelWidth = accessor.GetPyramid().GetLevelWidth(i); - const unsigned int levelHeight = accessor.GetPyramid().GetLevelHeight(i); - const unsigned int tileWidth = accessor.GetPyramid().GetTileWidth(i); - const unsigned int tileHeight = accessor.GetPyramid().GetTileHeight(i); - - resolutions.append(static_cast<float>(totalWidth) / static_cast<float>(levelWidth)); - - Json::Value s = Json::arrayValue; - s.append(levelWidth); - s.append(levelHeight); - sizes.append(s); - - s = Json::arrayValue; - s.append(OrthancWSI::CeilingDivision(levelWidth, tileWidth)); - s.append(OrthancWSI::CeilingDivision(levelHeight, tileHeight)); - tilesCount.append(s); - - s = Json::arrayValue; - s.append(tileWidth); - s.append(tileHeight); - tilesSizes.append(s); - } - - Json::Value result; - result["ID"] = instanceId; - result["FrameNumber"] = frameNumber; - result["Resolutions"] = resolutions; - result["Sizes"] = sizes; - result["TilesCount"] = tilesCount; - result["TilesSizes"] = tilesSizes; - result["TotalHeight"] = totalHeight; - result["TotalWidth"] = totalWidth; - - { - uint8_t red, green, blue; - accessor.GetPyramid().GetBackgroundColor(red, green, blue); // TODO - - char tmp[64]; - sprintf(tmp, "#%02x%02x%02x", red, green, blue); - result["BackgroundColor"] = tmp; - } - - std::string s = result.toStyledString(); - OrthancPluginAnswerBuffer(OrthancPlugins::GetGlobalContext(), output, s.c_str(), s.size(), "application/json"); -} - - void ServeFrameTile(OrthancPluginRestOutput* output, const char* url, const OrthancPluginHttpRequest* request) @@ -396,54 +382,10 @@ tile.reset(accessor.GetPyramid().DecodeTile(isEmpty, level, tileX, tileY)); } - Orthanc::MimeType mime = Orthanc::MimeType_Png; // By default, use lossless compression - - // Lookup whether a "Accept" HTTP header is present, to overwrite - // the default MIME type - for (uint32_t i = 0; i < request->headersCount; i++) + Orthanc::MimeType mime; + if (!LookupAcceptHeader(mime, request)) { - std::string key(request->headersKeys[i]); - Orthanc::Toolbox::ToLowerCase(key); - - if (key == "accept") - { - std::vector<std::string> 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; - } - } + mime = Orthanc::MimeType_Png; // By default, use lossless compression } std::string encoded;