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 }