Mercurial > hg > orthanc-wsi
comparison ViewerPlugin/IIIF.cpp @ 271:45e3b5adf4ae iiif
opened issue #2379 in OpenSeadragon
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 12 Jul 2023 07:38:59 +0200 |
parents | ca605878dc73 |
children | c766c25fe492 |
comparison
equal
deleted
inserted
replaced
270:0040ce361d4c | 271:45e3b5adf4ae |
---|---|
50 const std::string seriesId(request->groups[0]); | 50 const std::string seriesId(request->groups[0]); |
51 | 51 |
52 LOG(INFO) << "IIIF: Image API call to whole-slide pyramid of series " << seriesId; | 52 LOG(INFO) << "IIIF: Image API call to whole-slide pyramid of series " << seriesId; |
53 | 53 |
54 OrthancWSI::DicomPyramidCache::Locker locker(seriesId); | 54 OrthancWSI::DicomPyramidCache::Locker locker(seriesId); |
55 | 55 const OrthancWSI::ITiledPyramid& pyramid = locker.GetPyramid(); |
56 if (locker.GetPyramid().GetLevelCount() == 0) | 56 |
57 if (pyramid.GetLevelCount() == 0) | |
57 { | 58 { |
58 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | 59 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
59 } | 60 } |
60 | 61 |
61 if (locker.GetPyramid().GetTileWidth(0) != locker.GetPyramid().GetTileHeight(0)) | 62 if (pyramid.GetTileWidth(0) != pyramid.GetTileHeight(0)) |
62 { | 63 { |
63 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat, | 64 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat, |
64 "IIIF doesn't support non-isotropic tile sizes"); | 65 "IIIF doesn't support non-isotropic tile sizes"); |
65 } | 66 } |
66 | 67 |
67 for (unsigned int i = 1; i < locker.GetPyramid().GetLevelCount(); i++) | 68 for (unsigned int i = 1; i < pyramid.GetLevelCount(); i++) |
68 { | 69 { |
69 if (locker.GetPyramid().GetTileWidth(i) != locker.GetPyramid().GetTileWidth(0) || | 70 if (pyramid.GetTileWidth(i) != pyramid.GetTileWidth(0) || |
70 locker.GetPyramid().GetTileHeight(i) != locker.GetPyramid().GetTileHeight(0)) | 71 pyramid.GetTileHeight(i) != pyramid.GetTileHeight(0)) |
71 { | 72 { |
72 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat, | 73 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat, |
73 "IIIF doesn't support levels with varying tile sizes"); | 74 "IIIF doesn't support levels with varying tile sizes"); |
74 } | 75 } |
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 = locker.GetPyramid().GetLevelCount(); i > 0; i--) | 81 for (unsigned int i = pyramid.GetLevelCount(); i > 0; i--) |
81 { | 82 { |
82 /** | 83 /** |
83 * Openseadragon seems to have difficulties in rendering | 84 * According to the IIIF Image API 3.0 specification, |
84 * non-integer scale factors. Consequently, we only keep the | 85 * "scaleFactors" is: "The set of resolution scaling factors for |
85 * levels with an integer scale factor. | 86 * the image's predefined tiles, expressed as POSITIVE INTEGERS by |
87 * which to divide the full size of the image. For example, a | |
88 * scale factor of 4 indicates that the service can efficiently | |
89 * deliver images at 1/4 or 25% of the height and width of the | |
90 * full image." => We can only serve the levels for which the full | |
91 * width/height of the image is divisible by the width/height of | |
92 * the level. | |
86 **/ | 93 **/ |
87 if (locker.GetPyramid().GetLevelWidth(0) % locker.GetPyramid().GetLevelWidth(i - 1) == 0 && | 94 if (pyramid.GetLevelWidth(0) % pyramid.GetLevelWidth(i - 1) == 0 && |
88 locker.GetPyramid().GetLevelHeight(0) % locker.GetPyramid().GetLevelHeight(i - 1) == 0) | 95 pyramid.GetLevelHeight(0) % pyramid.GetLevelHeight(i - 1) == 0) |
89 { | 96 { |
90 Json::Value level; | 97 Json::Value level; |
91 level["width"] = locker.GetPyramid().GetLevelWidth(i - 1); | 98 level["width"] = pyramid.GetLevelWidth(i - 1); |
92 level["height"] = locker.GetPyramid().GetLevelHeight(i - 1); | 99 level["height"] = pyramid.GetLevelHeight(i - 1); |
93 sizes.append(level); | 100 sizes.append(level); |
94 | 101 |
95 scaleFactors.append(static_cast<float>(locker.GetPyramid().GetLevelWidth(0)) / | 102 scaleFactors.append(pyramid.GetLevelWidth(0) / |
96 static_cast<float>(locker.GetPyramid().GetLevelWidth(i - 1))); | 103 pyramid.GetLevelWidth(i - 1)); |
104 } | |
105 else | |
106 { | |
107 LOG(WARNING) << "IIIF - Dropping level " << i << " of series " << seriesId | |
108 << ", as the full width/height (" | |
109 << pyramid.GetLevelWidth(0) << "x" << pyramid.GetLevelHeight(0) | |
110 << ") of the image is not an integer multiple of the level width/height (" | |
111 << pyramid.GetLevelWidth(i - 1) << "x" << pyramid.GetLevelHeight(i - 1) << ")"; | |
97 } | 112 } |
98 } | 113 } |
99 | 114 |
100 Json::Value tiles; | 115 Json::Value tiles; |
101 tiles["width"] = locker.GetPyramid().GetTileWidth(0); | 116 tiles["width"] = pyramid.GetTileWidth(0); |
102 tiles["height"] = locker.GetPyramid().GetTileHeight(0); | 117 tiles["height"] = pyramid.GetTileHeight(0); |
103 tiles["scaleFactors"] = scaleFactors; | 118 tiles["scaleFactors"] = scaleFactors; |
104 | 119 |
105 Json::Value result; | 120 Json::Value result; |
106 result["@context"] = "http://iiif.io/api/image/2/context.json"; | 121 result["@context"] = "http://iiif.io/api/image/2/context.json"; |
107 result["@id"] = iiifPublicUrl_ + "tiles/" + seriesId; | 122 result["@id"] = iiifPublicUrl_ + "tiles/" + seriesId; |
108 result["profile"] = "http://iiif.io/api/image/2/level0.json"; | 123 result["profile"] = "http://iiif.io/api/image/2/level0.json"; |
109 result["protocol"] = "http://iiif.io/api/image"; | 124 result["protocol"] = "http://iiif.io/api/image"; |
110 result["width"] = locker.GetPyramid().GetLevelWidth(0); | 125 result["width"] = pyramid.GetLevelWidth(0); |
111 result["height"] = locker.GetPyramid().GetLevelHeight(0); | 126 result["height"] = pyramid.GetLevelHeight(0); |
112 result["sizes"] = sizes; | 127 result["sizes"] = sizes; |
113 | 128 |
114 result["tiles"] = Json::arrayValue; | 129 result["tiles"] = Json::arrayValue; |
115 result["tiles"].append(tiles); | 130 result["tiles"].append(tiles); |
116 | 131 |