Mercurial > hg > orthanc-wsi
annotate ViewerPlugin/Plugin.cpp @ 259:3e511f10896c iiif
avoid non-integer scale factors in IIIF
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 10 Jul 2023 08:06:10 +0200 |
parents | 07be799fa383 |
children | 35c241231af2 |
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 |
217
20bc074ec19a
Viewer can display DICOM pyramids whose tile sizes vary across levels
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
25 #include "../Framework/ImageToolbox.h" |
196
b0bd22077cd8
sharing code with orthanc-stone
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
194
diff
changeset
|
26 #include "../Framework/Jpeg2000Reader.h" |
73
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
27 #include "DicomPyramidCache.h" |
196
b0bd22077cd8
sharing code with orthanc-stone
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
194
diff
changeset
|
28 #include "OrthancPluginConnection.h" |
59
7a3853d51c45
Move "Framework/Orthanc/" as "Resources/Orthanc/"
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
57
diff
changeset
|
29 |
199
a1c265cb2174
replacing deprecated std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
196
diff
changeset
|
30 #include <Compatibility.h> // For std::unique_ptr |
192 | 31 #include <Logging.h> |
32 #include <Images/ImageProcessing.h> | |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
33 #include <Images/JpegReader.h> |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
34 #include <Images/JpegWriter.h> |
192 | 35 #include <Images/PngWriter.h> |
36 #include <MultiThreading/Semaphore.h> | |
37 #include <OrthancException.h> | |
38 #include <SystemToolbox.h> | |
39 | |
194 | 40 #include "../Resources/Orthanc/Plugins/OrthancPluginCppWrapper.h" |
0 | 41 |
42 #include <EmbeddedResources.h> | |
43 | |
44 #include <cassert> | |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
45 #include <boost/regex.hpp> |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
46 #include <boost/math/special_functions/round.hpp> |
0 | 47 |
199
a1c265cb2174
replacing deprecated std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
196
diff
changeset
|
48 std::unique_ptr<OrthancWSI::OrthancPluginConnection> orthanc_; |
a1c265cb2174
replacing deprecated std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
196
diff
changeset
|
49 std::unique_ptr<OrthancWSI::DicomPyramidCache> cache_; |
a1c265cb2174
replacing deprecated std::auto_ptr by std::unique_ptr
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
196
diff
changeset
|
50 std::unique_ptr<Orthanc::Semaphore> transcoderSemaphore_; |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
51 static std::string publicIIIFUrl_; |
57
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
16
diff
changeset
|
52 |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
16
diff
changeset
|
53 static void AnswerSparseTile(OrthancPluginRestOutput* output, |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
16
diff
changeset
|
54 unsigned int tileWidth, |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
16
diff
changeset
|
55 unsigned int tileHeight) |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
16
diff
changeset
|
56 { |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
16
diff
changeset
|
57 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
|
58 |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
16
diff
changeset
|
59 // Black (TODO parameter) |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
16
diff
changeset
|
60 uint8_t red = 0; |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
16
diff
changeset
|
61 uint8_t green = 0; |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
16
diff
changeset
|
62 uint8_t blue = 0; |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
16
diff
changeset
|
63 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
|
64 |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
16
diff
changeset
|
65 // TODO Cache the tile |
156
dafbb7ebc00f
fix for compatibility with simplified OrthancPluginCppWrapper
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
66 OrthancPluginCompressAndAnswerPngImage(OrthancPlugins::GetGlobalContext(), |
dafbb7ebc00f
fix for compatibility with simplified OrthancPluginCppWrapper
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
67 output, OrthancPluginPixelFormat_RGB24, |
57
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
16
diff
changeset
|
68 tile.GetWidth(), tile.GetHeight(), |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
16
diff
changeset
|
69 tile.GetPitch(), tile.GetBuffer()); |
91fc9583b2de
big refactoring to support sparse tiling
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
16
diff
changeset
|
70 } |
0 | 71 |
72 | |
73 static bool DisplayPerformanceWarning() | |
74 { | |
75 (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
|
76 OrthancPluginLogWarning(OrthancPlugins::GetGlobalContext(), "Performance warning in whole-slide imaging: " |
0 | 77 "Non-release build, runtime debug assertions are turned on"); |
78 return true; | |
79 } | |
80 | |
81 | |
82 void ServePyramid(OrthancPluginRestOutput* output, | |
83 const char* url, | |
84 const OrthancPluginHttpRequest* request) | |
85 { | |
86 std::string seriesId(request->groups[0]); | |
87 | |
88 char tmp[1024]; | |
89 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
|
90 OrthancPluginLogInfo(OrthancPlugins::GetGlobalContext(), tmp); |
0 | 91 |
92 | |
93 OrthancWSI::DicomPyramidCache::Locker locker(*cache_, seriesId); | |
94 | |
95 unsigned int totalWidth = locker.GetPyramid().GetLevelWidth(0); | |
96 unsigned int totalHeight = locker.GetPyramid().GetLevelHeight(0); | |
97 | |
73
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
98 Json::Value sizes = Json::arrayValue; |
0 | 99 Json::Value resolutions = Json::arrayValue; |
73
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
100 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
|
101 Json::Value tilesSizes = Json::arrayValue; |
0 | 102 for (unsigned int i = 0; i < locker.GetPyramid().GetLevelCount(); i++) |
103 { | |
217
20bc074ec19a
Viewer can display DICOM pyramids whose tile sizes vary across levels
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
104 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
|
105 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
|
106 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
|
107 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
|
108 |
73
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
109 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
|
110 |
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
111 Json::Value s = Json::arrayValue; |
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
112 s.append(levelWidth); |
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
113 s.append(levelHeight); |
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
114 sizes.append(s); |
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
115 |
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
116 s = Json::arrayValue; |
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
117 s.append(OrthancWSI::CeilingDivision(levelWidth, tileWidth)); |
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
118 s.append(OrthancWSI::CeilingDivision(levelHeight, tileHeight)); |
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
119 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
|
120 |
20bc074ec19a
Viewer can display DICOM pyramids whose tile sizes vary across levels
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
214
diff
changeset
|
121 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
|
122 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
|
123 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
|
124 tilesSizes.append(s); |
0 | 125 } |
126 | |
127 Json::Value result; | |
128 result["ID"] = seriesId; | |
73
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
129 result["Resolutions"] = resolutions; |
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
130 result["Sizes"] = sizes; |
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
131 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
|
132 result["TilesSizes"] = tilesSizes; |
0 | 133 result["TotalHeight"] = totalHeight; |
73
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
134 result["TotalWidth"] = totalWidth; |
0 | 135 |
136 std::string s = result.toStyledString(); | |
156
dafbb7ebc00f
fix for compatibility with simplified OrthancPluginCppWrapper
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
137 OrthancPluginAnswerBuffer(OrthancPlugins::GetGlobalContext(), output, s.c_str(), s.size(), "application/json"); |
0 | 138 } |
139 | |
140 | |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
141 class RawTile : public boost::noncopyable |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
142 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
143 private: |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
144 Orthanc::PixelFormat format_; |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
145 unsigned int tileWidth_; |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
146 unsigned int tileHeight_; |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
147 Orthanc::PhotometricInterpretation photometric_; |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
148 std::string tile_; |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
149 OrthancWSI::ImageCompression compression_; |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
150 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
151 Orthanc::ImageAccessor* DecodeInternal() |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
152 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
153 switch (compression_) |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
154 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
155 case OrthancWSI::ImageCompression_Jpeg: |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
156 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
157 std::unique_ptr<Orthanc::JpegReader> decoded(new Orthanc::JpegReader); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
158 decoded->ReadFromMemory(tile_); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
159 return decoded.release(); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
160 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
161 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
162 case OrthancWSI::ImageCompression_Jpeg2000: |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
163 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
164 std::unique_ptr<OrthancWSI::Jpeg2000Reader> decoded(new OrthancWSI::Jpeg2000Reader); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
165 decoded->ReadFromMemory(tile_); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
166 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
167 if (photometric_ == Orthanc::PhotometricInterpretation_YBR_ICT) |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
168 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
169 OrthancWSI::ImageToolbox::ConvertJpegYCbCrToRgb(*decoded); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
170 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
171 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
172 return decoded.release(); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
173 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
174 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
175 case OrthancWSI::ImageCompression_None: |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
176 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
177 unsigned int bpp = Orthanc::GetBytesPerPixel(format_); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
178 if (bpp * tileWidth_ * tileHeight_ != tile_.size()) |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
179 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
180 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
181 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
182 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
183 std::unique_ptr<Orthanc::ImageAccessor> decoded(new Orthanc::ImageAccessor); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
184 decoded->AssignReadOnly(format_, tileWidth_, tileHeight_, bpp * tileWidth_, tile_.c_str()); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
185 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
186 return decoded.release(); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
187 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
188 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
189 default: |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
190 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
191 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
192 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
193 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
194 static void EncodeInternal(std::string& encoded, |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
195 const Orthanc::ImageAccessor& decoded, |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
196 Orthanc::MimeType transcodingType) |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
197 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
198 switch (transcodingType) |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
199 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
200 case Orthanc::MimeType_Png: |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
201 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
202 Orthanc::PngWriter writer; |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
203 Orthanc::IImageWriter::WriteToMemory(writer, encoded, decoded); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
204 break; |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
205 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
206 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
207 case Orthanc::MimeType_Jpeg: |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
208 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
209 Orthanc::JpegWriter writer; |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
210 Orthanc::IImageWriter::WriteToMemory(writer, encoded, decoded); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
211 break; |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
212 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
213 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
214 default: |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
215 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
216 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
217 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
218 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
219 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
220 public: |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
221 RawTile(OrthancWSI::ITiledPyramid& pyramid, |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
222 unsigned int level, |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
223 unsigned int tileX, |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
224 unsigned int tileY) : |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
225 format_(pyramid.GetPixelFormat()), |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
226 tileWidth_(pyramid.GetTileWidth(level)), |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
227 tileHeight_(pyramid.GetTileHeight(level)), |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
228 photometric_(pyramid.GetPhotometricInterpretation()) |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
229 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
230 if (!pyramid.ReadRawTile(tile_, compression_, level, tileX, tileY)) |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
231 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
232 // Handling of missing tile (for sparse tiling): TODO parameter? |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
233 // AnswerSparseTile(output, tileWidth, tileHeight); return; |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
234 throw Orthanc::OrthancException(Orthanc::ErrorCode_UnknownResource); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
235 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
236 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
237 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
238 void Answer(OrthancPluginRestOutput* output, |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
239 Orthanc::MimeType transcodingType) |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
240 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
241 if (compression_ == OrthancWSI::ImageCompression_Jpeg) |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
242 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
243 // The tile is already a JPEG image. In such a case, we can |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
244 // serve it as such, because any Web browser can handle JPEG. |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
245 OrthancPluginAnswerBuffer(OrthancPlugins::GetGlobalContext(), output, tile_.c_str(), |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
246 tile_.size(), Orthanc::EnumerationToString(Orthanc::MimeType_Jpeg)); |
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 else |
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 // This is a lossless frame (coming from a JPEG2000 or an |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
251 // uncompressed DICOM instance), which is not a DICOM-JPEG |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
252 // instance. We need to decompress the raw tile, then transcode |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
253 // it to the PNG/JPEG, depending on the "transcodingType". |
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 std::string transcoded; |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
256 |
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 // The semaphore is used to throttle the number of simultaneous computations |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
259 Orthanc::Semaphore::Locker locker(*transcoderSemaphore_); |
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 std::unique_ptr<Orthanc::ImageAccessor> decoded(DecodeInternal()); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
262 EncodeInternal(transcoded, *decoded, transcodingType); |
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 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
265 OrthancPluginAnswerBuffer(OrthancPlugins::GetGlobalContext(), output, transcoded.c_str(), |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
266 transcoded.size(), Orthanc::EnumerationToString(transcodingType)); |
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 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
270 Orthanc::ImageAccessor* Decode() |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
271 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
272 Orthanc::Semaphore::Locker locker(*transcoderSemaphore_); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
273 return DecodeInternal(); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
274 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
275 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
276 static void Encode(std::string& encoded, |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
277 const Orthanc::ImageAccessor& decoded, |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
278 Orthanc::MimeType transcodingType) |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
279 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
280 Orthanc::Semaphore::Locker locker(*transcoderSemaphore_); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
281 EncodeInternal(encoded, decoded, transcodingType); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
282 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
283 }; |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
284 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
285 |
0 | 286 void ServeTile(OrthancPluginRestOutput* output, |
287 const char* url, | |
288 const OrthancPluginHttpRequest* request) | |
289 { | |
290 std::string seriesId(request->groups[0]); | |
291 int level = boost::lexical_cast<int>(request->groups[1]); | |
292 int tileY = boost::lexical_cast<int>(request->groups[3]); | |
293 int tileX = boost::lexical_cast<int>(request->groups[2]); | |
294 | |
295 char tmp[1024]; | |
296 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
|
297 OrthancPluginLogInfo(OrthancPlugins::GetGlobalContext(), tmp); |
0 | 298 |
299 if (level < 0 || | |
300 tileX < 0 || | |
301 tileY < 0) | |
302 { | |
303 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
304 } | |
305 | |
306 // 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
|
307 std::unique_ptr<RawTile> rawTile; |
0 | 308 |
309 { | |
310 OrthancWSI::DicomPyramidCache::Locker locker(*cache_, seriesId); | |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
311 rawTile.reset(new RawTile(locker.GetPyramid(), |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
312 static_cast<unsigned int>(level), |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
313 static_cast<unsigned int>(tileX), |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
314 static_cast<unsigned int>(tileY))); |
0 | 315 } |
316 | |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
317 /** |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
318 * 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
|
319 * 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
|
320 * 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
|
321 * 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
|
322 **/ |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
323 rawTile->Answer(output, Orthanc::MimeType_Png); |
0 | 324 } |
325 | |
326 | |
327 OrthancPluginErrorCode OnChangeCallback(OrthancPluginChangeType changeType, | |
328 OrthancPluginResourceType resourceType, | |
329 const char *resourceId) | |
330 { | |
331 if (resourceType == OrthancPluginResourceType_Series && | |
332 changeType == OrthancPluginChangeType_NewChildInstance) | |
333 { | |
334 char tmp[1024]; | |
335 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
|
336 OrthancPluginLogInfo(OrthancPlugins::GetGlobalContext(), tmp); |
0 | 337 |
338 cache_->Invalidate(resourceId); | |
339 } | |
340 | |
341 return OrthancPluginErrorCode_Success; | |
342 } | |
343 | |
344 | |
345 | |
346 void ServeFile(OrthancPluginRestOutput* output, | |
347 const char* url, | |
348 const OrthancPluginHttpRequest* request) | |
349 { | |
350 Orthanc::EmbeddedResources::FileResourceId resource; | |
351 | |
352 std::string f(request->groups[0]); | |
353 std::string mime; | |
354 | |
355 if (f == "viewer.html") | |
356 { | |
357 resource = Orthanc::EmbeddedResources::VIEWER_HTML; | |
358 mime = "text/html"; | |
359 } | |
360 else if (f == "viewer.js") | |
361 { | |
362 resource = Orthanc::EmbeddedResources::VIEWER_JS; | |
363 mime = "application/javascript"; | |
364 } | |
365 else if (f == "ol.js") | |
366 { | |
367 resource = Orthanc::EmbeddedResources::OPENLAYERS_JS; | |
368 mime = "application/javascript"; | |
369 } | |
370 else if (f == "ol.css") | |
371 { | |
372 resource = Orthanc::EmbeddedResources::OPENLAYERS_CSS; | |
373 mime = "text/css"; | |
374 } | |
375 else | |
376 { | |
377 throw Orthanc::OrthancException(Orthanc::ErrorCode_UnknownResource); | |
378 } | |
379 | |
380 std::string content; | |
381 Orthanc::EmbeddedResources::GetFileResource(content, resource); | |
382 | |
156
dafbb7ebc00f
fix for compatibility with simplified OrthancPluginCppWrapper
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
383 OrthancPluginAnswerBuffer(OrthancPlugins::GetGlobalContext(), output, content.c_str(), content.size(), mime.c_str()); |
0 | 384 } |
385 | |
386 | |
387 | |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
388 void ServeIIIFImageInfo(OrthancPluginRestOutput* output, |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
389 const char* url, |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
390 const OrthancPluginHttpRequest* request) |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
391 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
392 std::string seriesId(request->groups[0]); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
393 |
258
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
394 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
|
395 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
396 OrthancWSI::DicomPyramidCache::Locker locker(*cache_, seriesId); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
397 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
398 if (locker.GetPyramid().GetLevelCount() == 0) |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
399 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
400 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
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 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
403 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
|
404 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
405 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat, |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
406 "IIIF doesn't support non-isotropic tile sizes"); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
407 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
408 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
409 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
|
410 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
411 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
|
412 locker.GetPyramid().GetTileHeight(i) != locker.GetPyramid().GetTileHeight(0)) |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
413 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
414 throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat, |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
415 "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
|
416 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
417 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
418 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
419 Json::Value sizes = Json::arrayValue; |
259
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
420 Json::Value scaleFactors = Json::arrayValue; |
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
421 |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
422 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
|
423 { |
259
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
424 /** |
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
425 * 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
|
426 * 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
|
427 * levels with an integer scale factor. |
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
428 **/ |
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
429 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
|
430 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
|
431 { |
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
432 Json::Value level; |
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
433 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
|
434 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
|
435 sizes.append(level); |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
436 |
259
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
437 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
|
438 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
|
439 } |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
440 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
441 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
442 Json::Value tiles; |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
443 tiles["width"] = locker.GetPyramid().GetTileWidth(0); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
444 tiles["height"] = locker.GetPyramid().GetTileHeight(0); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
445 tiles["scaleFactors"] = scaleFactors; |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
446 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
447 Json::Value result; |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
448 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
|
449 result["@id"] = publicIIIFUrl_ + seriesId; |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
450 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
|
451 result["protocol"] = "http://iiif.io/api/image"; |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
452 result["width"] = locker.GetPyramid().GetLevelWidth(0); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
453 result["height"] = locker.GetPyramid().GetLevelHeight(0); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
454 result["sizes"] = sizes; |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
455 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
456 result["tiles"] = Json::arrayValue; |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
457 result["tiles"].append(tiles); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
458 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
459 std::string s = result.toStyledString(); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
460 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
|
461 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
462 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
463 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
464 static unsigned int GetPhysicalTileWidth(const OrthancWSI::ITiledPyramid& pyramid, |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
465 unsigned int level) |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
466 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
467 return static_cast<unsigned int>(boost::math::iround( |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
468 static_cast<float>(pyramid.GetTileWidth(level)) * |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
469 static_cast<float>(pyramid.GetLevelWidth(0)) / |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
470 static_cast<float>(pyramid.GetLevelWidth(level)))); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
471 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
472 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
473 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
474 static unsigned int GetPhysicalTileHeight(const OrthancWSI::ITiledPyramid& pyramid, |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
475 unsigned int level) |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
476 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
477 return static_cast<unsigned int>(boost::math::iround( |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
478 static_cast<float>(pyramid.GetTileHeight(level)) * |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
479 static_cast<float>(pyramid.GetLevelHeight(0)) / |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
480 static_cast<float>(pyramid.GetLevelHeight(level)))); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
481 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
482 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
483 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
484 void ServeIIIFImageTile(OrthancPluginRestOutput* output, |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
485 const char* url, |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
486 const OrthancPluginHttpRequest* request) |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
487 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
488 std::string seriesId(request->groups[0]); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
489 std::string region(request->groups[1]); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
490 std::string size(request->groups[2]); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
491 std::string rotation(request->groups[3]); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
492 std::string quality(request->groups[4]); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
493 std::string format(request->groups[5]); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
494 |
258
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
495 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
|
496 << "region=" << region << "; size=" << size << "; rotation=" |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
497 << rotation << "; quality=" << quality << "; format=" << format; |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
498 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
499 if (rotation != "0") |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
500 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
501 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
|
502 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
503 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
504 if (quality != "default") |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
505 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
506 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
|
507 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
508 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
509 if (format != "jpg") |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
510 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
511 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
|
512 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
513 |
257
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
514 if (region == "full") |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
515 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
516 OrthancWSI::DicomPyramidCache::Locker locker(*cache_, seriesId); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
517 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
518 OrthancWSI::ITiledPyramid& pyramid = locker.GetPyramid(); |
257
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
519 const unsigned int level = pyramid.GetLevelCount() - 1; |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
520 |
257
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
521 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
|
522 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
|
523 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
524 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
|
525 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
|
526 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
|
527 { |
257
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
528 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
|
529 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
|
530 |
257
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
531 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
|
532 { |
257
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
533 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
|
534 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
|
535 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
536 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
|
537 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
538 Orthanc::ImageAccessor source, target; |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
539 tile->GetRegion(source, 0, 0, width, height); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
540 full.GetRegion(target, x, y, width, height); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
541 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
542 Orthanc::ImageProcessing::Copy(target, source); |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
543 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
544 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
545 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
546 std::string encoded; |
257
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
547 RawTile::Encode(encoded, full, Orthanc::MimeType_Jpeg); |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
548 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
549 OrthancPluginAnswerBuffer(OrthancPlugins::GetGlobalContext(), output, encoded.c_str(), |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
550 encoded.size(), Orthanc::EnumerationToString(Orthanc::MimeType_Jpeg)); |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
551 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
552 else |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
553 { |
257
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
554 int regionX, regionY, regionWidth, regionHeight; |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
555 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
556 bool ok = false; |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
557 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
|
558 boost::cmatch regionWhat; |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
559 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
|
560 { |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
561 try |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
562 { |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
563 regionX = boost::lexical_cast<int>(regionWhat[1]); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
564 regionY = boost::lexical_cast<int>(regionWhat[2]); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
565 regionWidth = boost::lexical_cast<int>(regionWhat[3]); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
566 regionHeight = boost::lexical_cast<int>(regionWhat[4]); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
567 ok = (regionX >= 0 && |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
568 regionY >= 0 && |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
569 regionWidth > 0 && |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
570 regionHeight > 0); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
571 } |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
572 catch (boost::bad_lexical_cast&) |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
573 { |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
574 } |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
575 } |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
576 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
577 if (!ok) |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
578 { |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
579 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
|
580 } |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
581 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
582 int cropWidth; |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
583 boost::regex sizePattern("([0-9]+),"); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
584 boost::cmatch sizeWhat; |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
585 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
|
586 { |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
587 try |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
588 { |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
589 cropWidth = boost::lexical_cast<int>(sizeWhat[1]); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
590 ok = (cropWidth > 0); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
591 } |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
592 catch (boost::bad_lexical_cast&) |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
593 { |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
594 } |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
595 } |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
596 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
597 if (!ok) |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
598 { |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
599 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
|
600 } |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
601 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
602 std::unique_ptr<RawTile> rawTile; |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
603 std::unique_ptr<Orthanc::ImageAccessor> toCrop; |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
604 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
605 { |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
606 OrthancWSI::DicomPyramidCache::Locker locker(*cache_, seriesId); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
607 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
608 OrthancWSI::ITiledPyramid& pyramid = locker.GetPyramid(); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
609 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
610 unsigned int level; |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
611 for (level = 0; level < pyramid.GetLevelCount(); level++) |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
612 { |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
613 const unsigned int physicalTileWidth = GetPhysicalTileWidth(pyramid, level); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
614 const unsigned int physicalTileHeight = GetPhysicalTileHeight(pyramid, level); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
615 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
616 if (regionX % physicalTileWidth == 0 && |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
617 regionY % physicalTileHeight == 0 && |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
618 regionWidth <= physicalTileWidth && |
259
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
619 regionHeight <= physicalTileHeight && |
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
620 regionX + regionWidth <= pyramid.GetLevelWidth(0) && |
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
621 regionY + regionHeight <= pyramid.GetLevelHeight(0)) |
257
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
622 { |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
623 break; |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
624 } |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
625 } |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
626 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
627 if (level == pyramid.GetLevelCount()) |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
628 { |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
629 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
|
630 } |
259
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
631 else if (cropWidth > pyramid.GetTileWidth(level)) |
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
632 { |
3e511f10896c
avoid non-integer scale factors in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
258
diff
changeset
|
633 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
|
634 } |
257
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
635 else |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
636 { |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
637 rawTile.reset(new RawTile(locker.GetPyramid(), level, |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
638 regionX / GetPhysicalTileWidth(pyramid, level), |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
639 regionY / GetPhysicalTileHeight(pyramid, level))); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
640 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
641 if (cropWidth < pyramid.GetTileWidth(level)) |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
642 { |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
643 toCrop.reset(rawTile->Decode()); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
644 rawTile.reset(NULL); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
645 } |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
646 } |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
647 } |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
648 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
649 if (rawTile.get() != NULL) |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
650 { |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
651 assert(toCrop.get() == NULL); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
652 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
653 // 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
|
654 rawTile->Answer(output, Orthanc::MimeType_Jpeg); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
655 } |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
656 else if (toCrop.get() != NULL) |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
657 { |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
658 assert(rawTile.get() == NULL); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
659 assert(cropWidth < toCrop->GetWidth()); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
660 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
661 Orthanc::ImageAccessor cropped; |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
662 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
|
663 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
664 std::string encoded; |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
665 RawTile::Encode(encoded, cropped, Orthanc::MimeType_Jpeg); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
666 |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
667 OrthancPluginAnswerBuffer(OrthancPlugins::GetGlobalContext(), output, encoded.c_str(), |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
668 encoded.size(), Orthanc::EnumerationToString(Orthanc::MimeType_Jpeg)); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
669 } |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
670 else |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
671 { |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
672 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
9af4ba0d92fe
support of full rendering in IIIF
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
256
diff
changeset
|
673 } |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
674 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
675 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
676 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
677 |
258
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
678 void ServeIIIFManifest(OrthancPluginRestOutput* output, |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
679 const char* url, |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
680 const OrthancPluginHttpRequest* request) |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
681 { |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
682 /** |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
683 * 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
|
684 * Use of a IIIF Image Service." |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
685 * 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
|
686 **/ |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
687 |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
688 std::string seriesId(request->groups[0]); |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
689 |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
690 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
|
691 |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
692 Json::Value study, series; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
693 if (!OrthancPlugins::RestApiGet(series, "/series/" + seriesId, false) || |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
694 !OrthancPlugins::RestApiGet(study, "/series/" + seriesId + "/study", false)) |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
695 { |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
696 throw Orthanc::OrthancException(Orthanc::ErrorCode_UnknownResource); |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
697 } |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
698 |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
699 unsigned int width, height; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
700 |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
701 { |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
702 OrthancWSI::DicomPyramidCache::Locker locker(*cache_, seriesId); |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
703 width = locker.GetPyramid().GetLevelWidth(0); |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
704 height = locker.GetPyramid().GetLevelHeight(0); |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
705 } |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
706 |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
707 const std::string base = publicIIIFUrl_ + seriesId; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
708 |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
709 Json::Value service; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
710 service["id"] = base; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
711 service["profile"] = "level0"; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
712 service["type"] = "ImageService3"; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
713 |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
714 Json::Value body; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
715 body["id"] = base + "/full/max/0/default.jpg"; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
716 body["type"] = "Image"; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
717 body["format"] = Orthanc::EnumerationToString(Orthanc::MimeType_Jpeg); |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
718 body["height"] = height; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
719 body["width"] = width; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
720 body["service"].append(service); |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
721 |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
722 Json::Value annotation; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
723 annotation["id"] = base + "/annotation/p0001-image"; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
724 annotation["type"] = "Annotation"; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
725 annotation["motivation"] = "painting"; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
726 annotation["body"] = body; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
727 annotation["target"] = base + "/canvas/p1"; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
728 |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
729 Json::Value annotationPage; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
730 annotationPage["id"] = base + "/page/p1/1"; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
731 annotationPage["type"] = "AnnotationPage"; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
732 annotationPage["items"].append(annotation); |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
733 |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
734 Json::Value canvas; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
735 canvas["id"] = annotation["target"]; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
736 canvas["type"] = "Canvas"; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
737 canvas["width"] = width; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
738 canvas["height"] = height; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
739 |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
740 Json::Value labels = Json::arrayValue; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
741 labels.append(series["MainDicomTags"]["SeriesDate"].asString() + " - " + |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
742 series["MainDicomTags"]["SeriesDescription"].asString()); |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
743 canvas["label"]["en"] = labels; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
744 |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
745 canvas["items"].append(annotationPage); |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
746 |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
747 Json::Value manifest; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
748 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
|
749 manifest["id"] = base + "/manifest.json"; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
750 manifest["type"] = "Manifest"; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
751 |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
752 labels = Json::arrayValue; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
753 labels.append(study["MainDicomTags"]["StudyDate"].asString() + " - " + |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
754 study["MainDicomTags"]["StudyDescription"].asString()); |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
755 manifest["label"]["en"] = labels; |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
756 |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
757 manifest["items"].append(canvas); |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
758 |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
759 std::string s = manifest.toStyledString(); |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
760 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
|
761 } |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
762 |
07be799fa383
generation of IIIF manifest.json
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
257
diff
changeset
|
763 |
0 | 764 extern "C" |
765 { | |
766 ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* context) | |
767 { | |
156
dafbb7ebc00f
fix for compatibility with simplified OrthancPluginCppWrapper
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
768 OrthancPlugins::SetGlobalContext(context); |
0 | 769 assert(DisplayPerformanceWarning()); |
770 | |
771 /* 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
|
772 if (OrthancPluginCheckVersion(OrthancPlugins::GetGlobalContext()) == 0) |
0 | 773 { |
774 char info[1024]; | |
775 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
|
776 OrthancPlugins::GetGlobalContext()->orthancVersion, |
0 | 777 ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER, |
778 ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER, | |
779 ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER); | |
156
dafbb7ebc00f
fix for compatibility with simplified OrthancPluginCppWrapper
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
780 OrthancPluginLogError(OrthancPlugins::GetGlobalContext(), info); |
0 | 781 return -1; |
782 } | |
783 | |
156
dafbb7ebc00f
fix for compatibility with simplified OrthancPluginCppWrapper
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
784 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
|
785 { |
77b76c1a213f
check the version of the Orthanc core
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
786 // 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
|
787 return -1; |
77b76c1a213f
check the version of the Orthanc core
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
788 } |
77b76c1a213f
check the version of the Orthanc core
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
789 |
206 | 790 #if ORTHANC_FRAMEWORK_VERSION_IS_ABOVE(1, 7, 2) |
191 | 791 Orthanc::Logging::InitializePluginContext(context); |
193 | 792 #else |
793 Orthanc::Logging::Initialize(context); | |
794 #endif | |
151 | 795 |
0 | 796 // Limit the number of PNG transcoders to the number of available |
797 // hardware threads (e.g. number of CPUs or cores or | |
798 // hyperthreading units) | |
153
b798d200ac90
using Semaphore from Orthanc framework
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
150
diff
changeset
|
799 unsigned int threads = Orthanc::SystemToolbox::GetHardwareConcurrency(); |
b798d200ac90
using Semaphore from Orthanc framework
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
150
diff
changeset
|
800 transcoderSemaphore_.reset(new Orthanc::Semaphore(threads)); |
0 | 801 |
802 char info[1024]; | |
145 | 803 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
|
804 OrthancPluginLogWarning(OrthancPlugins::GetGlobalContext(), info); |
0 | 805 |
8
62adabb8c122
Provide "--version" in command-line tools
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
5
diff
changeset
|
806 OrthancPluginSetDescription(context, "Provides a Web viewer of whole-slide microscopic images within Orthanc."); |
0 | 807 |
196
b0bd22077cd8
sharing code with orthanc-stone
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
194
diff
changeset
|
808 orthanc_.reset(new OrthancWSI::OrthancPluginConnection); |
73
a8c90aa32ca6
LRU caching of pyramids, OrthancWSIClearCache script
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
69
diff
changeset
|
809 cache_.reset(new OrthancWSI::DicomPyramidCache(*orthanc_, 10 /* Number of pyramids to be cached - TODO parameter */)); |
0 | 810 |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
811 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
812 // TODO => CONFIG |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
813 publicIIIFUrl_ = "http://localhost:8042/wsi/iiif"; |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
814 |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
815 if (publicIIIFUrl_.empty() || |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
816 publicIIIFUrl_[publicIIIFUrl_.size() - 1] != '/') |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
817 { |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
818 publicIIIFUrl_ += "/"; |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
819 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
820 } |
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
821 |
156
dafbb7ebc00f
fix for compatibility with simplified OrthancPluginCppWrapper
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
822 OrthancPluginRegisterOnChangeCallback(OrthancPlugins::GetGlobalContext(), OnChangeCallback); |
0 | 823 |
156
dafbb7ebc00f
fix for compatibility with simplified OrthancPluginCppWrapper
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
155
diff
changeset
|
824 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
|
825 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
|
826 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
|
827 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
|
828 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
|
829 OrthancPlugins::RegisterRestCallback<ServeTile>("/wsi/tiles/([0-9a-f-]+)/([0-9-]+)/([0-9-]+)/([0-9-]+)", true); |
0 | 830 |
256
7deea131c3c0
implementation of IIIF Image API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
254
diff
changeset
|
831 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
|
832 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
|
833 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
|
834 |
0 | 835 // Extend the default Orthanc Explorer with custom JavaScript for WSI |
836 std::string explorer; | |
837 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
|
838 OrthancPluginExtendOrthancExplorer(OrthancPlugins::GetGlobalContext(), explorer.c_str()); |
0 | 839 |
840 return 0; | |
841 } | |
842 | |
843 | |
844 ORTHANC_PLUGINS_API void OrthancPluginFinalize() | |
845 { | |
846 cache_.reset(NULL); | |
847 orthanc_.reset(NULL); | |
848 transcoderSemaphore_.reset(NULL); | |
849 } | |
850 | |
851 | |
852 ORTHANC_PLUGINS_API const char* OrthancPluginGetName() | |
853 { | |
854 return "wsi"; | |
855 } | |
856 | |
857 | |
858 ORTHANC_PLUGINS_API const char* OrthancPluginGetVersion() | |
859 { | |
860 return ORTHANC_WSI_VERSION; | |
861 } | |
862 } |