Mercurial > hg > orthanc-wsi
annotate ViewerPlugin/Plugin.cpp @ 260:35c241231af2 iiif
reorganization
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 10 Jul 2023 08:31:50 +0200 |
parents | 3e511f10896c |
children | c72fbdecdc38 |
rev | line source |
---|---|
0 | 1 /** |
2 * Orthanc - A Lightweight, RESTful DICOM Store | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
254 | 5 * Copyright (C) 2017-2023 Osimis S.A., Belgium |
6 * Copyright (C) 2021-2023 Sebastien Jodogne, ICTEAM UCLouvain, Belgium | |
0 | 7 * |
8 * This program is free software: you can redistribute it and/or | |
9 * modify it under the terms of the GNU Affero General Public License | |
10 * as published by the Free Software Foundation, either version 3 of | |
11 * the License, or (at your option) any later version. | |
12 * | |
13 * This program is distributed in the hope that it will be useful, but | |
14 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 * Affero General Public License for more details. | |
17 * | |
18 * You should have received a copy of the GNU Affero General Public License | |
19 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
20 **/ | |
21 | |
22 | |
16
7a88c614be04
preparing for precompiled headers
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
8
diff
changeset
|
23 #include "../Framework/PrecompiledHeadersWSI.h" |
73
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
24 |
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
25 #include "DicomPyramidCache.h" |
196
b0bd22077cd8
sharing code with orthanc-stone
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
194
diff
changeset
|
26 #include "OrthancPluginConnection.h" |
260 | 27 #include "RawTile.h" |
59
7a3853d51c45
Move "Framework/Orthanc/" as "Resources/Orthanc/"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
57
diff
changeset
|
28 |
199
a1c265cb2174
replacing deprecated std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
196
diff
changeset
|
29 #include <Compatibility.h> // For std::unique_ptr |
192 | 30 #include <Logging.h> |
260 | 31 #include <Images/Image.h> |
192 | 32 #include <Images/ImageProcessing.h> |
33 #include <OrthancException.h> | |
34 #include <SystemToolbox.h> | |
35 | |
194 | 36 #include "../Resources/Orthanc/Plugins/OrthancPluginCppWrapper.h" |
0 | 37 |
38 #include <EmbeddedResources.h> | |
39 | |
40 #include <cassert> | |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
41 #include <boost/regex.hpp> |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
42 #include <boost/math/special_functions/round.hpp> |
0 | 43 |
260 | 44 static std::unique_ptr<OrthancWSI::OrthancPluginConnection> orthanc_; |
45 static std::unique_ptr<OrthancWSI::DicomPyramidCache> cache_; | |
46 static std::string publicIIIFUrl_; | |
57
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
16
diff
changeset
|
47 |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
16
diff
changeset
|
48 static void AnswerSparseTile(OrthancPluginRestOutput* output, |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
16
diff
changeset
|
49 unsigned int tileWidth, |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
16
diff
changeset
|
50 unsigned int tileHeight) |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
16
diff
changeset
|
51 { |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
16
diff
changeset
|
52 Orthanc::Image tile(Orthanc::PixelFormat_RGB24, tileWidth, tileHeight, false); |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
16
diff
changeset
|
53 |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
16
diff
changeset
|
54 // Black (TODO parameter) |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
16
diff
changeset
|
55 uint8_t red = 0; |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
16
diff
changeset
|
56 uint8_t green = 0; |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
16
diff
changeset
|
57 uint8_t blue = 0; |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
16
diff
changeset
|
58 Orthanc::ImageProcessing::Set(tile, red, green, blue, 255); |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
16
diff
changeset
|
59 |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
16
diff
changeset
|
60 // TODO Cache the tile |
156
dafbb7ebc00f
fix for compatibility with simplified OrthancPluginCppWrapper
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
61 OrthancPluginCompressAndAnswerPngImage(OrthancPlugins::GetGlobalContext(), |
dafbb7ebc00f
fix for compatibility with simplified OrthancPluginCppWrapper
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
62 output, OrthancPluginPixelFormat_RGB24, |
57
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
16
diff
changeset
|
63 tile.GetWidth(), tile.GetHeight(), |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
16
diff
changeset
|
64 tile.GetPitch(), tile.GetBuffer()); |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
16
diff
changeset
|
65 } |
0 | 66 |
67 | |
68 static bool DisplayPerformanceWarning() | |
69 { | |
70 (void) DisplayPerformanceWarning; // Disable warning about unused function | |
156
dafbb7ebc00f
fix for compatibility with simplified OrthancPluginCppWrapper
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
71 OrthancPluginLogWarning(OrthancPlugins::GetGlobalContext(), "Performance warning in whole-slide imaging: " |
0 | 72 "Non-release build, runtime debug assertions are turned on"); |
73 return true; | |
74 } | |
75 | |
76 | |
77 void ServePyramid(OrthancPluginRestOutput* output, | |
78 const char* url, | |
79 const OrthancPluginHttpRequest* request) | |
80 { | |
81 std::string seriesId(request->groups[0]); | |
82 | |
83 char tmp[1024]; | |
84 sprintf(tmp, "Accessing whole-slide pyramid of series %s", seriesId.c_str()); | |
156
dafbb7ebc00f
fix for compatibility with simplified OrthancPluginCppWrapper
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
85 OrthancPluginLogInfo(OrthancPlugins::GetGlobalContext(), tmp); |
0 | 86 |
87 | |
88 OrthancWSI::DicomPyramidCache::Locker locker(*cache_, seriesId); | |
89 | |
90 unsigned int totalWidth = locker.GetPyramid().GetLevelWidth(0); | |
91 unsigned int totalHeight = locker.GetPyramid().GetLevelHeight(0); | |
92 | |
73
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
93 Json::Value sizes = Json::arrayValue; |
0 | 94 Json::Value resolutions = Json::arrayValue; |
73
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
95 Json::Value tilesCount = Json::arrayValue; |
217
20bc074ec19a
Viewer can display DICOM pyramids whose tile sizes vary across levels
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
96 Json::Value tilesSizes = Json::arrayValue; |
0 | 97 for (unsigned int i = 0; i < locker.GetPyramid().GetLevelCount(); i++) |
98 { | |
217
20bc074ec19a
Viewer can display DICOM pyramids whose tile sizes vary across levels
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
99 const unsigned int levelWidth = locker.GetPyramid().GetLevelWidth(i); |
20bc074ec19a
Viewer can display DICOM pyramids whose tile sizes vary across levels
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
100 const unsigned int levelHeight = locker.GetPyramid().GetLevelHeight(i); |
20bc074ec19a
Viewer can display DICOM pyramids whose tile sizes vary across levels
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
101 const unsigned int tileWidth = locker.GetPyramid().GetTileWidth(i); |
20bc074ec19a
Viewer can display DICOM pyramids whose tile sizes vary across levels
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
102 const unsigned int tileHeight = locker.GetPyramid().GetTileHeight(i); |
20bc074ec19a
Viewer can display DICOM pyramids whose tile sizes vary across levels
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
103 |
73
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
104 resolutions.append(static_cast<float>(totalWidth) / static_cast<float>(levelWidth)); |
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
105 |
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
106 Json::Value s = Json::arrayValue; |
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
107 s.append(levelWidth); |
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
108 s.append(levelHeight); |
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
109 sizes.append(s); |
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
110 |
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
111 s = Json::arrayValue; |
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
112 s.append(OrthancWSI::CeilingDivision(levelWidth, tileWidth)); |
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
113 s.append(OrthancWSI::CeilingDivision(levelHeight, tileHeight)); |
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
114 tilesCount.append(s); |
217
20bc074ec19a
Viewer can display DICOM pyramids whose tile sizes vary across levels
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
115 |
20bc074ec19a
Viewer can display DICOM pyramids whose tile sizes vary across levels
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
116 s = Json::arrayValue; |
20bc074ec19a
Viewer can display DICOM pyramids whose tile sizes vary across levels
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
117 s.append(tileWidth); |
20bc074ec19a
Viewer can display DICOM pyramids whose tile sizes vary across levels
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
118 s.append(tileHeight); |
20bc074ec19a
Viewer can display DICOM pyramids whose tile sizes vary across levels
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
119 tilesSizes.append(s); |
0 | 120 } |
121 | |
122 Json::Value result; | |
123 result["ID"] = seriesId; | |
73
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
124 result["Resolutions"] = resolutions; |
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
125 result["Sizes"] = sizes; |
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
126 result["TilesCount"] = tilesCount; |
217
20bc074ec19a
Viewer can display DICOM pyramids whose tile sizes vary across levels
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
127 result["TilesSizes"] = tilesSizes; |
0 | 128 result["TotalHeight"] = totalHeight; |
73
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
129 result["TotalWidth"] = totalWidth; |
0 | 130 |
131 std::string s = result.toStyledString(); | |
156
dafbb7ebc00f
fix for compatibility with simplified OrthancPluginCppWrapper
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
132 OrthancPluginAnswerBuffer(OrthancPlugins::GetGlobalContext(), output, s.c_str(), s.size(), "application/json"); |
0 | 133 } |
134 | |
135 | |
136 void ServeTile(OrthancPluginRestOutput* output, | |
137 const char* url, | |
138 const OrthancPluginHttpRequest* request) | |
139 { | |
140 std::string seriesId(request->groups[0]); | |
141 int level = boost::lexical_cast<int>(request->groups[1]); | |
142 int tileY = boost::lexical_cast<int>(request->groups[3]); | |
143 int tileX = boost::lexical_cast<int>(request->groups[2]); | |
144 | |
145 char tmp[1024]; | |
146 sprintf(tmp, "Accessing tile in series %s: (%d,%d) at level %d", seriesId.c_str(), tileX, tileY, level); | |
156
dafbb7ebc00f
fix for compatibility with simplified OrthancPluginCppWrapper
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
147 OrthancPluginLogInfo(OrthancPlugins::GetGlobalContext(), tmp); |
0 | 148 |
149 if (level < 0 || | |
150 tileX < 0 || | |
151 tileY < 0) | |
152 { | |
153 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
154 } | |
155 | |
156 // Retrieve the raw tile from the WSI pyramid | |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
157 std::unique_ptr<RawTile> rawTile; |
0 | 158 |
159 { | |
160 OrthancWSI::DicomPyramidCache::Locker locker(*cache_, seriesId); | |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
161 rawTile.reset(new RawTile(locker.GetPyramid(), |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
162 static_cast<unsigned int>(level), |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
163 static_cast<unsigned int>(tileX), |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
164 static_cast<unsigned int>(tileY))); |
0 | 165 } |
166 | |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
167 /** |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
168 * In the case the DICOM file doesn't use the JPEG transfer syntax, |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
169 * transfer the tile (which is presumably lossless) as a PNG image |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
170 * so as to prevent lossy compression. Don't call "rawTile" while |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
171 * the Locker is around, as "Answer()" can be a costly operation. |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
172 **/ |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
173 rawTile->Answer(output, Orthanc::MimeType_Png); |
0 | 174 } |
175 | |
176 | |
177 OrthancPluginErrorCode OnChangeCallback(OrthancPluginChangeType changeType, | |
178 OrthancPluginResourceType resourceType, | |
179 const char *resourceId) | |
180 { | |
181 if (resourceType == OrthancPluginResourceType_Series && | |
182 changeType == OrthancPluginChangeType_NewChildInstance) | |
183 { | |
184 char tmp[1024]; | |
185 sprintf(tmp, "New instance has been added to series %s, invalidating it", resourceId); | |
156
dafbb7ebc00f
fix for compatibility with simplified OrthancPluginCppWrapper
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
186 OrthancPluginLogInfo(OrthancPlugins::GetGlobalContext(), tmp); |
0 | 187 |
188 cache_->Invalidate(resourceId); | |
189 } | |
190 | |
191 return OrthancPluginErrorCode_Success; | |
192 } | |
193 | |
194 | |
195 | |
196 void ServeFile(OrthancPluginRestOutput* output, | |
197 const char* url, | |
198 const OrthancPluginHttpRequest* request) | |
199 { | |
200 Orthanc::EmbeddedResources::FileResourceId resource; | |
201 | |
202 std::string f(request->groups[0]); | |
203 std::string mime; | |
204 | |
205 if (f == "viewer.html") | |
206 { | |
207 resource = Orthanc::EmbeddedResources::VIEWER_HTML; | |
208 mime = "text/html"; | |
209 } | |
210 else if (f == "viewer.js") | |
211 { | |
212 resource = Orthanc::EmbeddedResources::VIEWER_JS; | |
213 mime = "application/javascript"; | |
214 } | |
215 else if (f == "ol.js") | |
216 { | |
217 resource = Orthanc::EmbeddedResources::OPENLAYERS_JS; | |
218 mime = "application/javascript"; | |
219 } | |
220 else if (f == "ol.css") | |
221 { | |
222 resource = Orthanc::EmbeddedResources::OPENLAYERS_CSS; | |
223 mime = "text/css"; | |
224 } | |
225 else | |
226 { | |
227 throw Orthanc::OrthancException(Orthanc::ErrorCode_UnknownResource); | |
228 } | |
229 | |
230 std::string content; | |
231 Orthanc::EmbeddedResources::GetFileResource(content, resource); | |
232 | |
156
dafbb7ebc00f
fix for compatibility with simplified OrthancPluginCppWrapper
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
233 OrthancPluginAnswerBuffer(OrthancPlugins::GetGlobalContext(), output, content.c_str(), content.size(), mime.c_str()); |
0 | 234 } |
235 | |
236 | |
237 | |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
238 void ServeIIIFImageInfo(OrthancPluginRestOutput* output, |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
239 const char* url, |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
240 const OrthancPluginHttpRequest* request) |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
241 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
242 std::string seriesId(request->groups[0]); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
243 |
258
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
244 LOG(INFO) << "IIIF: Image API call to whole-slide pyramid of series " << seriesId; |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
245 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
246 OrthancWSI::DicomPyramidCache::Locker locker(*cache_, seriesId); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
247 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
248 if (locker.GetPyramid().GetLevelCount() == 0) |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
249 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
250 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
251 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
252 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
253 if (locker.GetPyramid().GetTileWidth(0) != locker.GetPyramid().GetTileHeight(0)) |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
254 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
255 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat, |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
256 "IIIF doesn't support non-isotropic tile sizes"); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
257 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
258 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
259 for (unsigned int i = 1; i < locker.GetPyramid().GetLevelCount(); i++) |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
260 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
261 if (locker.GetPyramid().GetTileWidth(i) != locker.GetPyramid().GetTileWidth(0) || |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
262 locker.GetPyramid().GetTileHeight(i) != locker.GetPyramid().GetTileHeight(0)) |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
263 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
264 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat, |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
265 "IIIF doesn't support levels with varying tile sizes"); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
266 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
267 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
268 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
269 Json::Value sizes = Json::arrayValue; |
259
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
270 Json::Value scaleFactors = Json::arrayValue; |
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
271 |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
272 for (unsigned int i = locker.GetPyramid().GetLevelCount(); i > 0; i--) |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
273 { |
259
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
274 /** |
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
275 * Openseadragon seems to have difficulties in rendering |
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
276 * non-integer scale factors. Consequently, we only keep the |
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
277 * levels with an integer scale factor. |
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
278 **/ |
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
279 if (locker.GetPyramid().GetLevelWidth(0) % locker.GetPyramid().GetLevelWidth(i - 1) == 0 && |
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
280 locker.GetPyramid().GetLevelHeight(0) % locker.GetPyramid().GetLevelHeight(i - 1) == 0) |
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
281 { |
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
282 Json::Value level; |
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
283 level["width"] = locker.GetPyramid().GetLevelWidth(i - 1); |
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
284 level["height"] = locker.GetPyramid().GetLevelHeight(i - 1); |
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
285 sizes.append(level); |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
286 |
259
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
287 scaleFactors.append(static_cast<float>(locker.GetPyramid().GetLevelWidth(0)) / |
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
288 static_cast<float>(locker.GetPyramid().GetLevelWidth(i - 1))); |
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
289 } |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
290 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
291 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
292 Json::Value tiles; |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
293 tiles["width"] = locker.GetPyramid().GetTileWidth(0); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
294 tiles["height"] = locker.GetPyramid().GetTileHeight(0); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
295 tiles["scaleFactors"] = scaleFactors; |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
296 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
297 Json::Value result; |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
298 result["@context"] = "http://iiif.io/api/image/2/context.json"; |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
299 result["@id"] = publicIIIFUrl_ + seriesId; |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
300 result["profile"] = "http://iiif.io/api/image/2/level0.json"; |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
301 result["protocol"] = "http://iiif.io/api/image"; |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
302 result["width"] = locker.GetPyramid().GetLevelWidth(0); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
303 result["height"] = locker.GetPyramid().GetLevelHeight(0); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
304 result["sizes"] = sizes; |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
305 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
306 result["tiles"] = Json::arrayValue; |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
307 result["tiles"].append(tiles); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
308 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
309 std::string s = result.toStyledString(); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
310 OrthancPluginAnswerBuffer(OrthancPlugins::GetGlobalContext(), output, s.c_str(), s.size(), "application/json"); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
311 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
312 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
313 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
314 static unsigned int GetPhysicalTileWidth(const OrthancWSI::ITiledPyramid& pyramid, |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
315 unsigned int level) |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
316 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
317 return static_cast<unsigned int>(boost::math::iround( |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
318 static_cast<float>(pyramid.GetTileWidth(level)) * |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
319 static_cast<float>(pyramid.GetLevelWidth(0)) / |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
320 static_cast<float>(pyramid.GetLevelWidth(level)))); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
321 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
322 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
323 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
324 static unsigned int GetPhysicalTileHeight(const OrthancWSI::ITiledPyramid& pyramid, |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
325 unsigned int level) |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
326 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
327 return static_cast<unsigned int>(boost::math::iround( |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
328 static_cast<float>(pyramid.GetTileHeight(level)) * |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
329 static_cast<float>(pyramid.GetLevelHeight(0)) / |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
330 static_cast<float>(pyramid.GetLevelHeight(level)))); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
331 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
332 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
333 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
334 void ServeIIIFImageTile(OrthancPluginRestOutput* output, |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
335 const char* url, |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
336 const OrthancPluginHttpRequest* request) |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
337 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
338 std::string seriesId(request->groups[0]); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
339 std::string region(request->groups[1]); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
340 std::string size(request->groups[2]); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
341 std::string rotation(request->groups[3]); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
342 std::string quality(request->groups[4]); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
343 std::string format(request->groups[5]); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
344 |
258
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
345 LOG(INFO) << "IIIF: Image API call to tile of series " << seriesId << ": " |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
346 << "region=" << region << "; size=" << size << "; rotation=" |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
347 << rotation << "; quality=" << quality << "; format=" << format; |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
348 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
349 if (rotation != "0") |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
350 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
351 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented, "IIIF - Unsupported rotation: " + rotation); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
352 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
353 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
354 if (quality != "default") |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
355 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
356 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented, "IIIF - Unsupported quality: " + quality); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
357 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
358 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
359 if (format != "jpg") |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
360 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
361 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented, "IIIF - Unsupported format: " + format); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
362 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
363 |
257
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
364 if (region == "full") |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
365 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
366 OrthancWSI::DicomPyramidCache::Locker locker(*cache_, seriesId); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
367 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
368 OrthancWSI::ITiledPyramid& pyramid = locker.GetPyramid(); |
257
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
369 const unsigned int level = pyramid.GetLevelCount() - 1; |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
370 |
257
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
371 Orthanc::Image full(Orthanc::PixelFormat_RGB24, pyramid.GetLevelWidth(level), pyramid.GetLevelHeight(level), false); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
372 Orthanc::ImageProcessing::Set(full, 255, 255, 255, 0); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
373 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
374 const unsigned int nx = OrthancWSI::CeilingDivision(pyramid.GetLevelWidth(level), pyramid.GetTileWidth(level)); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
375 const unsigned int ny = OrthancWSI::CeilingDivision(pyramid.GetLevelHeight(level), pyramid.GetTileHeight(level)); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
376 for (unsigned int ty = 0; ty < ny; ty++) |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
377 { |
257
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
378 const unsigned int y = ty * pyramid.GetTileHeight(level); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
379 const unsigned int height = std::min(pyramid.GetTileHeight(level), full.GetHeight() - y); |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
380 |
257
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
381 for (unsigned int tx = 0; tx < nx; tx++) |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
382 { |
257
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
383 const unsigned int x = tx * pyramid.GetTileWidth(level); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
384 std::unique_ptr<Orthanc::ImageAccessor> tile(pyramid.DecodeTile(level, tx, ty)); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
385 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
386 const unsigned int width = std::min(pyramid.GetTileWidth(level), full.GetWidth() - x); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
387 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
388 Orthanc::ImageAccessor source, target; |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
389 tile->GetRegion(source, 0, 0, width, height); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
390 full.GetRegion(target, x, y, width, height); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
391 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
392 Orthanc::ImageProcessing::Copy(target, source); |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
393 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
394 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
395 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
396 std::string encoded; |
257
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
397 RawTile::Encode(encoded, full, Orthanc::MimeType_Jpeg); |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
398 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
399 OrthancPluginAnswerBuffer(OrthancPlugins::GetGlobalContext(), output, encoded.c_str(), |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
400 encoded.size(), Orthanc::EnumerationToString(Orthanc::MimeType_Jpeg)); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
401 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
402 else |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
403 { |
257
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
404 int regionX, regionY, regionWidth, regionHeight; |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
405 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
406 bool ok = false; |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
407 boost::regex regionPattern("([0-9]+),([0-9]+),([0-9]+),([0-9]+)"); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
408 boost::cmatch regionWhat; |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
409 if (regex_match(region.c_str(), regionWhat, regionPattern)) |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
410 { |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
411 try |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
412 { |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
413 regionX = boost::lexical_cast<int>(regionWhat[1]); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
414 regionY = boost::lexical_cast<int>(regionWhat[2]); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
415 regionWidth = boost::lexical_cast<int>(regionWhat[3]); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
416 regionHeight = boost::lexical_cast<int>(regionWhat[4]); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
417 ok = (regionX >= 0 && |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
418 regionY >= 0 && |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
419 regionWidth > 0 && |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
420 regionHeight > 0); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
421 } |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
422 catch (boost::bad_lexical_cast&) |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
423 { |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
424 } |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
425 } |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
426 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
427 if (!ok) |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
428 { |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
429 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented, "IIIF - Not a (x,y,width,height) region: " + region); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
430 } |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
431 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
432 int cropWidth; |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
433 boost::regex sizePattern("([0-9]+),"); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
434 boost::cmatch sizeWhat; |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
435 if (regex_match(size.c_str(), sizeWhat, sizePattern)) |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
436 { |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
437 try |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
438 { |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
439 cropWidth = boost::lexical_cast<int>(sizeWhat[1]); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
440 ok = (cropWidth > 0); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
441 } |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
442 catch (boost::bad_lexical_cast&) |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
443 { |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
444 } |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
445 } |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
446 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
447 if (!ok) |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
448 { |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
449 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented, "IIIF - Not a (width,) size: " + size); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
450 } |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
451 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
452 std::unique_ptr<RawTile> rawTile; |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
453 std::unique_ptr<Orthanc::ImageAccessor> toCrop; |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
454 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
455 { |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
456 OrthancWSI::DicomPyramidCache::Locker locker(*cache_, seriesId); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
457 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
458 OrthancWSI::ITiledPyramid& pyramid = locker.GetPyramid(); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
459 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
460 unsigned int level; |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
461 for (level = 0; level < pyramid.GetLevelCount(); level++) |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
462 { |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
463 const unsigned int physicalTileWidth = GetPhysicalTileWidth(pyramid, level); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
464 const unsigned int physicalTileHeight = GetPhysicalTileHeight(pyramid, level); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
465 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
466 if (regionX % physicalTileWidth == 0 && |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
467 regionY % physicalTileHeight == 0 && |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
468 regionWidth <= physicalTileWidth && |
259
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
469 regionHeight <= physicalTileHeight && |
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
470 regionX + regionWidth <= pyramid.GetLevelWidth(0) && |
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
471 regionY + regionHeight <= pyramid.GetLevelHeight(0)) |
257
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
472 { |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
473 break; |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
474 } |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
475 } |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
476 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
477 if (level == pyramid.GetLevelCount()) |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
478 { |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
479 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadRequest, "IIIF - Cannot locate the level of interest"); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
480 } |
259
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
481 else if (cropWidth > pyramid.GetTileWidth(level)) |
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
482 { |
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
483 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadRequest, "IIIF - Request for a cropping that is too large for the tile size"); |
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
484 } |
257
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
485 else |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
486 { |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
487 rawTile.reset(new RawTile(locker.GetPyramid(), level, |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
488 regionX / GetPhysicalTileWidth(pyramid, level), |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
489 regionY / GetPhysicalTileHeight(pyramid, level))); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
490 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
491 if (cropWidth < pyramid.GetTileWidth(level)) |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
492 { |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
493 toCrop.reset(rawTile->Decode()); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
494 rawTile.reset(NULL); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
495 } |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
496 } |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
497 } |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
498 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
499 if (rawTile.get() != NULL) |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
500 { |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
501 assert(toCrop.get() == NULL); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
502 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
503 // Level 0 Compliance of IIIF expects JPEG files |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
504 rawTile->Answer(output, Orthanc::MimeType_Jpeg); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
505 } |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
506 else if (toCrop.get() != NULL) |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
507 { |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
508 assert(rawTile.get() == NULL); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
509 assert(cropWidth < toCrop->GetWidth()); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
510 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
511 Orthanc::ImageAccessor cropped; |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
512 toCrop->GetRegion(cropped, 0, 0, cropWidth, toCrop->GetHeight()); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
513 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
514 std::string encoded; |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
515 RawTile::Encode(encoded, cropped, Orthanc::MimeType_Jpeg); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
516 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
517 OrthancPluginAnswerBuffer(OrthancPlugins::GetGlobalContext(), output, encoded.c_str(), |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
518 encoded.size(), Orthanc::EnumerationToString(Orthanc::MimeType_Jpeg)); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
519 } |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
520 else |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
521 { |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
522 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
523 } |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
524 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
525 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
526 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
527 |
258
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
528 void ServeIIIFManifest(OrthancPluginRestOutput* output, |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
529 const char* url, |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
530 const OrthancPluginHttpRequest* request) |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
531 { |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
532 /** |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
533 * This is based on IIIF cookbook: "Support Deep Viewing with Basic |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
534 * Use of a IIIF Image Service." |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
535 * https://iiif.io/api/cookbook/recipe/0005-image-service/ |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
536 **/ |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
537 |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
538 std::string seriesId(request->groups[0]); |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
539 |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
540 LOG(INFO) << "IIIF: Presentation API call to whole-slide pyramid of series " << seriesId; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
541 |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
542 Json::Value study, series; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
543 if (!OrthancPlugins::RestApiGet(series, "/series/" + seriesId, false) || |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
544 !OrthancPlugins::RestApiGet(study, "/series/" + seriesId + "/study", false)) |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
545 { |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
546 throw Orthanc::OrthancException(Orthanc::ErrorCode_UnknownResource); |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
547 } |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
548 |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
549 unsigned int width, height; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
550 |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
551 { |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
552 OrthancWSI::DicomPyramidCache::Locker locker(*cache_, seriesId); |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
553 width = locker.GetPyramid().GetLevelWidth(0); |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
554 height = locker.GetPyramid().GetLevelHeight(0); |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
555 } |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
556 |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
557 const std::string base = publicIIIFUrl_ + seriesId; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
558 |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
559 Json::Value service; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
560 service["id"] = base; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
561 service["profile"] = "level0"; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
562 service["type"] = "ImageService3"; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
563 |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
564 Json::Value body; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
565 body["id"] = base + "/full/max/0/default.jpg"; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
566 body["type"] = "Image"; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
567 body["format"] = Orthanc::EnumerationToString(Orthanc::MimeType_Jpeg); |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
568 body["height"] = height; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
569 body["width"] = width; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
570 body["service"].append(service); |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
571 |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
572 Json::Value annotation; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
573 annotation["id"] = base + "/annotation/p0001-image"; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
574 annotation["type"] = "Annotation"; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
575 annotation["motivation"] = "painting"; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
576 annotation["body"] = body; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
577 annotation["target"] = base + "/canvas/p1"; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
578 |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
579 Json::Value annotationPage; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
580 annotationPage["id"] = base + "/page/p1/1"; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
581 annotationPage["type"] = "AnnotationPage"; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
582 annotationPage["items"].append(annotation); |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
583 |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
584 Json::Value canvas; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
585 canvas["id"] = annotation["target"]; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
586 canvas["type"] = "Canvas"; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
587 canvas["width"] = width; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
588 canvas["height"] = height; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
589 |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
590 Json::Value labels = Json::arrayValue; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
591 labels.append(series["MainDicomTags"]["SeriesDate"].asString() + " - " + |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
592 series["MainDicomTags"]["SeriesDescription"].asString()); |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
593 canvas["label"]["en"] = labels; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
594 |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
595 canvas["items"].append(annotationPage); |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
596 |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
597 Json::Value manifest; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
598 manifest["@context"] = "http://iiif.io/api/presentation/3/context.json"; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
599 manifest["id"] = base + "/manifest.json"; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
600 manifest["type"] = "Manifest"; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
601 |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
602 labels = Json::arrayValue; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
603 labels.append(study["MainDicomTags"]["StudyDate"].asString() + " - " + |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
604 study["MainDicomTags"]["StudyDescription"].asString()); |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
605 manifest["label"]["en"] = labels; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
606 |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
607 manifest["items"].append(canvas); |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
608 |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
609 std::string s = manifest.toStyledString(); |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
610 OrthancPluginAnswerBuffer(OrthancPlugins::GetGlobalContext(), output, s.c_str(), s.size(), "application/json"); |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
611 } |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
612 |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
613 |
0 | 614 extern "C" |
615 { | |
616 ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* context) | |
617 { | |
156
dafbb7ebc00f
fix for compatibility with simplified OrthancPluginCppWrapper
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
618 OrthancPlugins::SetGlobalContext(context); |
0 | 619 assert(DisplayPerformanceWarning()); |
620 | |
621 /* Check the version of the Orthanc core */ | |
156
dafbb7ebc00f
fix for compatibility with simplified OrthancPluginCppWrapper
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
622 if (OrthancPluginCheckVersion(OrthancPlugins::GetGlobalContext()) == 0) |
0 | 623 { |
624 char info[1024]; | |
625 sprintf(info, "Your version of Orthanc (%s) must be above %d.%d.%d to run this plugin", | |
156
dafbb7ebc00f
fix for compatibility with simplified OrthancPluginCppWrapper
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
626 OrthancPlugins::GetGlobalContext()->orthancVersion, |
0 | 627 ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER, |
628 ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER, | |
629 ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER); | |
156
dafbb7ebc00f
fix for compatibility with simplified OrthancPluginCppWrapper
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
630 OrthancPluginLogError(OrthancPlugins::GetGlobalContext(), info); |
0 | 631 return -1; |
632 } | |
633 | |
156
dafbb7ebc00f
fix for compatibility with simplified OrthancPluginCppWrapper
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
634 if (!OrthancPlugins::CheckMinimalOrthancVersion(1, 1, 0)) |
5
77b76c1a213f
check the version of the Orthanc core
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
635 { |
77b76c1a213f
check the version of the Orthanc core
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
636 // We need the "/instances/.../frames/.../raw" URI that was introduced in Orthanc 1.1.0 |
77b76c1a213f
check the version of the Orthanc core
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
637 return -1; |
77b76c1a213f
check the version of the Orthanc core
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
638 } |
77b76c1a213f
check the version of the Orthanc core
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
639 |
206 | 640 #if ORTHANC_FRAMEWORK_VERSION_IS_ABOVE(1, 7, 2) |
191 | 641 Orthanc::Logging::InitializePluginContext(context); |
193 | 642 #else |
643 Orthanc::Logging::Initialize(context); | |
644 #endif | |
151 | 645 |
0 | 646 // Limit the number of PNG transcoders to the number of available |
647 // hardware threads (e.g. number of CPUs or cores or | |
648 // hyperthreading units) | |
153
b798d200ac90
using Semaphore from Orthanc framework
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
150
diff
changeset
|
649 unsigned int threads = Orthanc::SystemToolbox::GetHardwareConcurrency(); |
260 | 650 RawTile::InitializeTranscoderSemaphore(threads); |
0 | 651 |
652 char info[1024]; | |
145 | 653 sprintf(info, "The whole-slide imaging plugin will use at most %u threads to transcode the tiles", threads); |
156
dafbb7ebc00f
fix for compatibility with simplified OrthancPluginCppWrapper
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
654 OrthancPluginLogWarning(OrthancPlugins::GetGlobalContext(), info); |
0 | 655 |
8
62adabb8c122
Provide "--version" in command-line tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5
diff
changeset
|
656 OrthancPluginSetDescription(context, "Provides a Web viewer of whole-slide microscopic images within Orthanc."); |
0 | 657 |
196
b0bd22077cd8
sharing code with orthanc-stone
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
194
diff
changeset
|
658 orthanc_.reset(new OrthancWSI::OrthancPluginConnection); |
73
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
659 cache_.reset(new OrthancWSI::DicomPyramidCache(*orthanc_, 10 /* Number of pyramids to be cached - TODO parameter */)); |
0 | 660 |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
661 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
662 // TODO => CONFIG |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
663 publicIIIFUrl_ = "http://localhost:8042/wsi/iiif"; |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
664 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
665 if (publicIIIFUrl_.empty() || |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
666 publicIIIFUrl_[publicIIIFUrl_.size() - 1] != '/') |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
667 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
668 publicIIIFUrl_ += "/"; |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
669 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
670 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
671 |
156
dafbb7ebc00f
fix for compatibility with simplified OrthancPluginCppWrapper
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
672 OrthancPluginRegisterOnChangeCallback(OrthancPlugins::GetGlobalContext(), OnChangeCallback); |
0 | 673 |
156
dafbb7ebc00f
fix for compatibility with simplified OrthancPluginCppWrapper
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
674 OrthancPlugins::RegisterRestCallback<ServeFile>("/wsi/app/(ol.css)", true); |
dafbb7ebc00f
fix for compatibility with simplified OrthancPluginCppWrapper
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
675 OrthancPlugins::RegisterRestCallback<ServeFile>("/wsi/app/(ol.js)", true); |
dafbb7ebc00f
fix for compatibility with simplified OrthancPluginCppWrapper
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
676 OrthancPlugins::RegisterRestCallback<ServeFile>("/wsi/app/(viewer.html)", true); |
dafbb7ebc00f
fix for compatibility with simplified OrthancPluginCppWrapper
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
677 OrthancPlugins::RegisterRestCallback<ServeFile>("/wsi/app/(viewer.js)", true); |
dafbb7ebc00f
fix for compatibility with simplified OrthancPluginCppWrapper
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
678 OrthancPlugins::RegisterRestCallback<ServePyramid>("/wsi/pyramids/([0-9a-f-]+)", true); |
dafbb7ebc00f
fix for compatibility with simplified OrthancPluginCppWrapper
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
679 OrthancPlugins::RegisterRestCallback<ServeTile>("/wsi/tiles/([0-9a-f-]+)/([0-9-]+)/([0-9-]+)/([0-9-]+)", true); |
0 | 680 |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
681 OrthancPlugins::RegisterRestCallback<ServeIIIFImageInfo>("/wsi/iiif/([0-9a-f-]+)/info.json", true); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
682 OrthancPlugins::RegisterRestCallback<ServeIIIFImageTile>("/wsi/iiif/([0-9a-f-]+)/([0-9a-z,:]+)/([0-9a-z,!:]+)/([0-9,!]+)/([a-z]+)\\.([a-z]+)", true); |
258
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
683 OrthancPlugins::RegisterRestCallback<ServeIIIFManifest>("/wsi/iiif/([0-9a-f-]+)/manifest.json", true); |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
684 |
0 | 685 // Extend the default Orthanc Explorer with custom JavaScript for WSI |
686 std::string explorer; | |
687 Orthanc::EmbeddedResources::GetFileResource(explorer, Orthanc::EmbeddedResources::ORTHANC_EXPLORER); | |
156
dafbb7ebc00f
fix for compatibility with simplified OrthancPluginCppWrapper
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
688 OrthancPluginExtendOrthancExplorer(OrthancPlugins::GetGlobalContext(), explorer.c_str()); |
0 | 689 |
690 return 0; | |
691 } | |
692 | |
693 | |
694 ORTHANC_PLUGINS_API void OrthancPluginFinalize() | |
695 { | |
696 cache_.reset(NULL); | |
697 orthanc_.reset(NULL); | |
260 | 698 RawTile::FinalizeTranscoderSemaphore(); |
0 | 699 } |
700 | |
701 | |
702 ORTHANC_PLUGINS_API const char* OrthancPluginGetName() | |
703 { | |
704 return "wsi"; | |
705 } | |
706 | |
707 | |
708 ORTHANC_PLUGINS_API const char* OrthancPluginGetVersion() | |
709 { | |
710 return ORTHANC_WSI_VERSION; | |
711 } | |
712 } |