Mercurial > hg > orthanc-wsi
comparison ViewerPlugin/IIIF.cpp @ 274:2805246064aa iiif
added SetIIIFForcePowersOfTwoScaleFactors()
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 12 Jul 2023 11:24:56 +0200 |
parents | 1c95010d9d2e |
children | 801790c81f20 |
comparison
equal
deleted
inserted
replaced
273:1c95010d9d2e | 274:2805246064aa |
---|---|
38 static const char* const ROWS = "0028,0010"; | 38 static const char* const ROWS = "0028,0010"; |
39 static const char* const COLUMNS = "0028,0011"; | 39 static const char* const COLUMNS = "0028,0011"; |
40 | 40 |
41 | 41 |
42 static std::string iiifPublicUrl_; | 42 static std::string iiifPublicUrl_; |
43 static bool iiifForcePowersOfTwoScaleFactors_ = false; | |
43 | 44 |
44 | 45 |
45 static void ServeIIIFTiledImageInfo(OrthancPluginRestOutput* output, | 46 static void ServeIIIFTiledImageInfo(OrthancPluginRestOutput* output, |
46 const char* url, | 47 const char* url, |
47 const OrthancPluginHttpRequest* request) | 48 const OrthancPluginHttpRequest* request) |
75 } | 76 } |
76 | 77 |
77 Json::Value sizes = Json::arrayValue; | 78 Json::Value sizes = Json::arrayValue; |
78 Json::Value scaleFactors = Json::arrayValue; | 79 Json::Value scaleFactors = Json::arrayValue; |
79 | 80 |
80 for (unsigned int i = pyramid.GetLevelCount(); i > 0; i--) | 81 unsigned int power = 1; |
82 | |
83 for (unsigned int i = 0; i < pyramid.GetLevelCount(); i++) | |
81 { | 84 { |
82 /** | 85 /** |
83 * According to the IIIF Image API 3.0 specification, | 86 * According to the IIIF Image API 3.0 specification, |
84 * "scaleFactors" is: "The set of resolution scaling factors for | 87 * "scaleFactors" is: "The set of resolution scaling factors for |
85 * the image's predefined tiles, expressed as POSITIVE INTEGERS by | 88 * the image's predefined tiles, expressed as POSITIVE INTEGERS by |
88 * deliver images at 1/4 or 25% of the height and width of the | 91 * deliver images at 1/4 or 25% of the height and width of the |
89 * full image." => We can only serve the levels for which the full | 92 * full image." => We can only serve the levels for which the full |
90 * width/height of the image is divisible by the width/height of | 93 * width/height of the image is divisible by the width/height of |
91 * the level. | 94 * the level. |
92 **/ | 95 **/ |
93 if (pyramid.GetLevelWidth(0) % pyramid.GetLevelWidth(i - 1) == 0 && | 96 if (pyramid.GetLevelWidth(0) % pyramid.GetLevelWidth(i) == 0 && |
94 pyramid.GetLevelHeight(0) % pyramid.GetLevelHeight(i - 1) == 0) | 97 pyramid.GetLevelHeight(0) % pyramid.GetLevelHeight(i) == 0) |
95 { | 98 { |
96 Json::Value level; | 99 unsigned int scaleFactor = pyramid.GetLevelWidth(0) / pyramid.GetLevelWidth(i); |
97 level["width"] = pyramid.GetLevelWidth(i - 1); | 100 |
98 level["height"] = pyramid.GetLevelHeight(i - 1); | 101 if (!iiifForcePowersOfTwoScaleFactors_ || |
99 sizes.append(level); | 102 scaleFactor == power) |
100 | 103 { |
101 scaleFactors.append(pyramid.GetLevelWidth(0) / | 104 Json::Value level; |
102 pyramid.GetLevelWidth(i - 1)); | 105 level["width"] = pyramid.GetLevelWidth(i); |
106 level["height"] = pyramid.GetLevelHeight(i); | |
107 sizes.append(level); | |
108 | |
109 scaleFactors.append(scaleFactor); | |
110 | |
111 power *= 2; | |
112 } | |
113 else | |
114 { | |
115 LOG(WARNING) << "IIIF - Dropping level " << i << " of series " << seriesId | |
116 << ", as it doesn't follow the powers-of-two pattern"; | |
117 } | |
103 } | 118 } |
104 else | 119 else |
105 { | 120 { |
106 LOG(WARNING) << "IIIF - Dropping level " << i << " of series " << seriesId | 121 LOG(WARNING) << "IIIF - Dropping level " << i << " of series " << seriesId |
107 << ", as the full width/height (" | 122 << ", as the full width/height (" |
108 << pyramid.GetLevelWidth(0) << "x" << pyramid.GetLevelHeight(0) | 123 << pyramid.GetLevelWidth(0) << "x" << pyramid.GetLevelHeight(0) |
109 << ") of the image is not an integer multiple of the level width/height (" | 124 << ") of the image is not an integer multiple of the level width/height (" |
110 << pyramid.GetLevelWidth(i - 1) << "x" << pyramid.GetLevelHeight(i - 1) << ")"; | 125 << pyramid.GetLevelWidth(i) << "x" << pyramid.GetLevelHeight(i) << ")"; |
111 } | 126 } |
112 } | 127 } |
113 | 128 |
114 Json::Value tiles; | 129 Json::Value tiles; |
115 tiles["width"] = pyramid.GetTileWidth(0); | 130 tiles["width"] = pyramid.GetTileWidth(0); |
232 !Orthanc::SerializationToolbox::ParseUnsignedInteger32(regionX, tokens[0]) || | 247 !Orthanc::SerializationToolbox::ParseUnsignedInteger32(regionX, tokens[0]) || |
233 !Orthanc::SerializationToolbox::ParseUnsignedInteger32(regionY, tokens[1]) || | 248 !Orthanc::SerializationToolbox::ParseUnsignedInteger32(regionY, tokens[1]) || |
234 !Orthanc::SerializationToolbox::ParseUnsignedInteger32(regionWidth, tokens[2]) || | 249 !Orthanc::SerializationToolbox::ParseUnsignedInteger32(regionWidth, tokens[2]) || |
235 !Orthanc::SerializationToolbox::ParseUnsignedInteger32(regionHeight, tokens[3])) | 250 !Orthanc::SerializationToolbox::ParseUnsignedInteger32(regionHeight, tokens[3])) |
236 { | 251 { |
237 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented, "IIIF - Not a (x,y,width,height) region, found: " + region); | 252 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented, "IIIF - Invalid (x,y,width,height) region, found: " + region); |
238 } | 253 } |
239 | 254 |
240 uint32_t cropWidth, cropHeight; | 255 uint32_t cropWidth, cropHeight; |
241 | 256 |
242 Orthanc::Toolbox::TokenizeString(tokens, size, ','); | 257 Orthanc::Toolbox::TokenizeString(tokens, size, ','); |
256 } | 271 } |
257 } | 272 } |
258 | 273 |
259 if (!ok) | 274 if (!ok) |
260 { | 275 { |
261 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented, "IIIF - Not a (width,height) crop, found: " + size); | 276 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented, "IIIF - Invalid (width,height) crop, found: " + size); |
262 } | 277 } |
263 | 278 |
264 std::unique_ptr<OrthancWSI::RawTile> rawTile; | 279 std::unique_ptr<OrthancWSI::RawTile> rawTile; |
265 std::unique_ptr<Orthanc::ImageAccessor> toCrop; | 280 std::unique_ptr<Orthanc::ImageAccessor> toCrop; |
266 | 281 |
600 OrthancPlugins::RegisterRestCallback<ServeIIIFTiledImageTile>("/wsi/iiif/tiles/([0-9a-f-]+)/([0-9a-z,:]+)/([0-9a-z,!:]+)/([0-9,!]+)/([a-z]+)\\.([a-z]+)", true); | 615 OrthancPlugins::RegisterRestCallback<ServeIIIFTiledImageTile>("/wsi/iiif/tiles/([0-9a-f-]+)/([0-9a-z,:]+)/([0-9a-z,!:]+)/([0-9,!]+)/([a-z]+)\\.([a-z]+)", true); |
601 OrthancPlugins::RegisterRestCallback<ServeIIIFManifest>("/wsi/iiif/([0-9a-f-]+)/manifest.json", true); | 616 OrthancPlugins::RegisterRestCallback<ServeIIIFManifest>("/wsi/iiif/([0-9a-f-]+)/manifest.json", true); |
602 OrthancPlugins::RegisterRestCallback<ServeIIIFFrameInfo>("/wsi/iiif/frames/([0-9a-f-]+)/([0-9]+)/info.json", true); | 617 OrthancPlugins::RegisterRestCallback<ServeIIIFFrameInfo>("/wsi/iiif/frames/([0-9a-f-]+)/([0-9]+)/info.json", true); |
603 OrthancPlugins::RegisterRestCallback<ServeIIIFFrameImage>("/wsi/iiif/frames/([0-9a-f-]+)/([0-9]+)/full/max/0/default.jpg", true); | 618 OrthancPlugins::RegisterRestCallback<ServeIIIFFrameImage>("/wsi/iiif/frames/([0-9a-f-]+)/([0-9]+)/full/max/0/default.jpg", true); |
604 } | 619 } |
620 | |
621 void SetIIIFForcePowersOfTwoScaleFactors(bool force) | |
622 { | |
623 iiifForcePowersOfTwoScaleFactors_ = force; | |
624 } |