Mercurial > hg > orthanc-webviewer
annotate Plugin/ViewerToolbox.cpp @ 316:591ca447ebf8
Upgrade to Orthanc framework 1.12.3
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 26 Mar 2024 11:15:27 +0100 |
parents | 0a1ad7492050 |
children | 553fa466835a |
rev | line source |
---|---|
0 | 1 /** |
2 * Orthanc - A Lightweight, RESTful DICOM Store | |
122 | 3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics |
0 | 4 * Department, University Hospital of Liege, Belgium |
316
591ca447ebf8
Upgrade to Orthanc framework 1.12.3
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
314
diff
changeset
|
5 * Copyright (C) 2017-2024 Osimis S.A., Belgium |
314
0a1ad7492050
update year to 2024
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
303
diff
changeset
|
6 * Copyright (C) 2021-2024 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 | |
23 #include "ViewerToolbox.h" | |
24 | |
287 | 25 #include <Logging.h> |
266
4e9d30c19b4b
linking against orthanc framework library
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
260
diff
changeset
|
26 #include <OrthancException.h> |
4e9d30c19b4b
linking against orthanc framework library
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
260
diff
changeset
|
27 #include <Toolbox.h> |
0 | 28 |
275
3a9749b1dfce
link against system-wide Orthanc Framework
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
266
diff
changeset
|
29 // To gain access to ORTHANC_PLUGINS_VERSION_IS_ABOVE if Orthanc SDK <= 1.3.0 |
3a9749b1dfce
link against system-wide Orthanc Framework
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
266
diff
changeset
|
30 #include "../Resources/Orthanc/Plugins/OrthancPluginCppWrapper.h" |
172 | 31 |
0 | 32 #include <stdexcept> |
33 #include <boost/lexical_cast.hpp> | |
34 #include <sys/stat.h> | |
35 | |
36 namespace OrthancPlugins | |
37 { | |
38 bool GetStringFromOrthanc(std::string& content, | |
39 OrthancPluginContext* context, | |
40 const std::string& uri) | |
41 { | |
42 OrthancPluginMemoryBuffer answer; | |
43 | |
44 if (OrthancPluginRestApiGet(context, &answer, uri.c_str())) | |
45 { | |
46 return false; | |
47 } | |
48 | |
49 if (answer.size) | |
50 { | |
51 try | |
52 { | |
53 content.assign(reinterpret_cast<const char*>(answer.data), answer.size); | |
54 } | |
55 catch (std::bad_alloc&) | |
56 { | |
57 OrthancPluginFreeMemoryBuffer(context, &answer); | |
79 | 58 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotEnoughMemory); |
0 | 59 } |
60 } | |
61 | |
62 OrthancPluginFreeMemoryBuffer(context, &answer); | |
63 return true; | |
64 } | |
65 | |
66 | |
67 bool GetJsonFromOrthanc(Json::Value& json, | |
68 OrthancPluginContext* context, | |
69 const std::string& uri) | |
70 { | |
71 OrthancPluginMemoryBuffer answer; | |
72 | |
73 if (OrthancPluginRestApiGet(context, &answer, uri.c_str())) | |
74 { | |
75 return false; | |
76 } | |
77 | |
78 if (answer.size) | |
79 { | |
80 try | |
81 { | |
292
aadbffcee805
remove calls to deprecated classes of JsonCpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
287
diff
changeset
|
82 if (!Orthanc::Toolbox::ReadJsonWithoutComments(json, answer.data, answer.size)) |
0 | 83 { |
84 return false; | |
85 } | |
86 } | |
87 catch (std::runtime_error&) | |
88 { | |
89 OrthancPluginFreeMemoryBuffer(context, &answer); | |
90 return false; | |
91 } | |
92 } | |
93 | |
94 OrthancPluginFreeMemoryBuffer(context, &answer); | |
95 return true; | |
96 } | |
97 | |
98 | |
99 | |
100 | |
101 bool TokenizeVector(std::vector<float>& result, | |
102 const std::string& value, | |
103 unsigned int expectedSize) | |
104 { | |
105 std::vector<std::string> tokens; | |
106 Orthanc::Toolbox::TokenizeString(tokens, value, '\\'); | |
107 | |
108 if (tokens.size() != expectedSize) | |
109 { | |
110 return false; | |
111 } | |
112 | |
113 result.resize(tokens.size()); | |
114 | |
115 for (size_t i = 0; i < tokens.size(); i++) | |
116 { | |
117 try | |
118 { | |
119 result[i] = boost::lexical_cast<float>(tokens[i]); | |
120 } | |
121 catch (boost::bad_lexical_cast&) | |
122 { | |
123 return false; | |
124 } | |
125 } | |
126 | |
127 return true; | |
128 } | |
129 | |
130 | |
79 | 131 void CompressUsingDeflate(std::string& compressed, |
132 OrthancPluginContext* context, | |
0 | 133 const void* uncompressed, |
79 | 134 size_t uncompressedSize) |
0 | 135 { |
79 | 136 OrthancPluginMemoryBuffer tmp; |
137 | |
138 OrthancPluginErrorCode code = OrthancPluginBufferCompression( | |
139 context, &tmp, uncompressed, uncompressedSize, | |
140 OrthancPluginCompressionType_Zlib, 0 /*compress*/); | |
141 | |
142 if (code != OrthancPluginErrorCode_Success) | |
0 | 143 { |
79 | 144 throw Orthanc::OrthancException(static_cast<Orthanc::ErrorCode>(code)); |
0 | 145 } |
146 | |
79 | 147 try |
148 { | |
149 compressed.assign(reinterpret_cast<const char*>(tmp.data), tmp.size); | |
150 } | |
151 catch (...) | |
152 { | |
153 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotEnoughMemory); | |
154 } | |
0 | 155 |
79 | 156 OrthancPluginFreeMemoryBuffer(context, &tmp); |
0 | 157 } |
158 | |
159 | |
160 const char* GetMimeType(const std::string& path) | |
161 { | |
162 size_t dot = path.find_last_of('.'); | |
163 | |
164 std::string extension = (dot == std::string::npos) ? "" : path.substr(dot); | |
165 std::transform(extension.begin(), extension.end(), extension.begin(), tolower); | |
166 | |
167 if (extension == ".html") | |
168 { | |
169 return "text/html"; | |
170 } | |
171 else if (extension == ".css") | |
172 { | |
173 return "text/css"; | |
174 } | |
175 else if (extension == ".js") | |
176 { | |
177 return "application/javascript"; | |
178 } | |
179 else if (extension == ".gif") | |
180 { | |
181 return "image/gif"; | |
182 } | |
183 else if (extension == ".svg") | |
184 { | |
185 return "image/svg+xml"; | |
186 } | |
187 else if (extension == ".json") | |
188 { | |
189 return "application/json"; | |
190 } | |
191 else if (extension == ".xml") | |
192 { | |
193 return "application/xml"; | |
194 } | |
195 else if (extension == ".png") | |
196 { | |
197 return "image/png"; | |
198 } | |
199 else if (extension == ".jpg" || extension == ".jpeg") | |
200 { | |
201 return "image/jpeg"; | |
202 } | |
203 else | |
204 { | |
205 return "application/octet-stream"; | |
206 } | |
207 } | |
208 | |
209 | |
210 bool ReadConfiguration(Json::Value& configuration, | |
211 OrthancPluginContext* context) | |
212 { | |
33
d7bd116777eb
Use of OrthancPluginGetConfiguration
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
26
diff
changeset
|
213 std::string s; |
0 | 214 |
215 { | |
33
d7bd116777eb
Use of OrthancPluginGetConfiguration
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
26
diff
changeset
|
216 char* tmp = OrthancPluginGetConfiguration(context); |
d7bd116777eb
Use of OrthancPluginGetConfiguration
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
26
diff
changeset
|
217 if (tmp == NULL) |
0 | 218 { |
260
620ed85fb514
replacing OrthancPluginLog...() by LOG(...)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
229
diff
changeset
|
219 LOG(ERROR) << "Error while retrieving the configuration from Orthanc"; |
0 | 220 return false; |
221 } | |
222 | |
33
d7bd116777eb
Use of OrthancPluginGetConfiguration
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
26
diff
changeset
|
223 s.assign(tmp); |
d7bd116777eb
Use of OrthancPluginGetConfiguration
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
26
diff
changeset
|
224 OrthancPluginFreeString(context, tmp); |
0 | 225 } |
226 | |
292
aadbffcee805
remove calls to deprecated classes of JsonCpp
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
287
diff
changeset
|
227 if (Orthanc::Toolbox::ReadJson(configuration, s)) |
0 | 228 { |
33
d7bd116777eb
Use of OrthancPluginGetConfiguration
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
26
diff
changeset
|
229 return true; |
d7bd116777eb
Use of OrthancPluginGetConfiguration
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
26
diff
changeset
|
230 } |
d7bd116777eb
Use of OrthancPluginGetConfiguration
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
26
diff
changeset
|
231 else |
d7bd116777eb
Use of OrthancPluginGetConfiguration
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
26
diff
changeset
|
232 { |
260
620ed85fb514
replacing OrthancPluginLog...() by LOG(...)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
229
diff
changeset
|
233 LOG(ERROR) << "Unable to parse the configuration"; |
0 | 234 return false; |
235 } | |
236 } | |
237 | |
238 | |
239 std::string GetStringValue(const Json::Value& configuration, | |
240 const std::string& key, | |
241 const std::string& defaultValue) | |
242 { | |
243 if (configuration.type() != Json::objectValue || | |
244 !configuration.isMember(key) || | |
245 configuration[key].type() != Json::stringValue) | |
246 { | |
247 return defaultValue; | |
248 } | |
249 else | |
250 { | |
251 return configuration[key].asString(); | |
252 } | |
253 } | |
254 | |
255 | |
256 int GetIntegerValue(const Json::Value& configuration, | |
257 const std::string& key, | |
258 int defaultValue) | |
259 { | |
260 if (configuration.type() != Json::objectValue || | |
261 !configuration.isMember(key) || | |
262 configuration[key].type() != Json::intValue) | |
263 { | |
264 return defaultValue; | |
265 } | |
266 else | |
267 { | |
268 return configuration[key].asInt(); | |
269 } | |
270 } | |
271 | |
272 | |
79 | 273 OrthancPluginPixelFormat Convert(Orthanc::PixelFormat format) |
0 | 274 { |
79 | 275 switch (format) |
276 { | |
277 case Orthanc::PixelFormat_Grayscale16: | |
278 return OrthancPluginPixelFormat_Grayscale16; | |
279 | |
280 case Orthanc::PixelFormat_Grayscale8: | |
281 return OrthancPluginPixelFormat_Grayscale8; | |
282 | |
283 case Orthanc::PixelFormat_RGB24: | |
284 return OrthancPluginPixelFormat_RGB24; | |
285 | |
172 | 286 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 3, 1) |
287 case Orthanc::PixelFormat_RGB48: | |
288 return OrthancPluginPixelFormat_RGB48; | |
289 #endif | |
290 | |
79 | 291 case Orthanc::PixelFormat_RGBA32: |
292 return OrthancPluginPixelFormat_RGBA32; | |
293 | |
294 case Orthanc::PixelFormat_SignedGrayscale16: | |
295 return OrthancPluginPixelFormat_SignedGrayscale16; | |
296 | |
297 default: | |
298 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
299 } | |
300 } | |
301 | |
302 | |
303 Orthanc::PixelFormat Convert(OrthancPluginPixelFormat format) | |
304 { | |
305 switch (format) | |
0 | 306 { |
79 | 307 case OrthancPluginPixelFormat_Grayscale16: |
308 return Orthanc::PixelFormat_Grayscale16; | |
309 | |
310 case OrthancPluginPixelFormat_Grayscale8: | |
311 return Orthanc::PixelFormat_Grayscale8; | |
312 | |
313 case OrthancPluginPixelFormat_RGB24: | |
314 return Orthanc::PixelFormat_RGB24; | |
315 | |
172 | 316 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 3, 1) |
317 case OrthancPluginPixelFormat_RGB48: | |
318 return Orthanc::PixelFormat_RGB48; | |
319 #endif | |
320 | |
79 | 321 case OrthancPluginPixelFormat_RGBA32: |
322 return Orthanc::PixelFormat_RGBA32; | |
323 | |
324 case OrthancPluginPixelFormat_SignedGrayscale16: | |
325 return Orthanc::PixelFormat_SignedGrayscale16; | |
0 | 326 |
79 | 327 default: |
328 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
329 } | |
330 } | |
331 | |
332 | |
333 void WriteJpegToMemory(std::string& result, | |
334 OrthancPluginContext* context, | |
335 const Orthanc::ImageAccessor& accessor, | |
336 uint8_t quality) | |
337 { | |
338 OrthancPluginMemoryBuffer tmp; | |
339 | |
340 OrthancPluginErrorCode code = OrthancPluginCompressJpegImage | |
341 (context, &tmp, Convert(accessor.GetFormat()), | |
342 accessor.GetWidth(), accessor.GetHeight(), accessor.GetPitch(), | |
99
46ec13a1177c
use of ordered-slices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
79
diff
changeset
|
343 accessor.GetConstBuffer(), quality); |
79 | 344 |
345 if (code != OrthancPluginErrorCode_Success) | |
0 | 346 { |
79 | 347 throw Orthanc::OrthancException(static_cast<Orthanc::ErrorCode>(code)); |
0 | 348 } |
349 | |
79 | 350 try |
0 | 351 { |
79 | 352 result.assign(reinterpret_cast<const char*>(tmp.data), tmp.size); |
353 } | |
354 catch (...) | |
355 { | |
356 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotEnoughMemory); | |
0 | 357 } |
358 | |
79 | 359 OrthancPluginFreeMemoryBuffer(context, &tmp); |
360 } | |
361 | |
362 | |
363 | |
364 ImageReader::ImageReader(OrthancPluginContext* context, | |
365 const std::string& image, | |
366 OrthancPluginImageFormat format) : context_(context) | |
367 { | |
368 image_ = OrthancPluginUncompressImage(context_, image.c_str(), image.size(), format); | |
369 | |
370 if (image_ == NULL) | |
0 | 371 { |
79 | 372 throw Orthanc::OrthancException(Orthanc::ErrorCode_CorruptedFile); |
0 | 373 } |
79 | 374 } |
0 | 375 |
376 | |
79 | 377 ImageReader::~ImageReader() |
378 { | |
379 OrthancPluginFreeImage(context_, image_); | |
380 } | |
381 | |
0 | 382 |
207
3d3d00e3e715
fix for new ImageAccessor API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
191
diff
changeset
|
383 void ImageReader::GetAccessor(Orthanc::ImageAccessor& target) const |
79 | 384 { |
207
3d3d00e3e715
fix for new ImageAccessor API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
191
diff
changeset
|
385 target.AssignReadOnly(Convert(OrthancPluginGetImagePixelFormat(context_, image_)), |
3d3d00e3e715
fix for new ImageAccessor API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
191
diff
changeset
|
386 OrthancPluginGetImageWidth(context_, image_), |
3d3d00e3e715
fix for new ImageAccessor API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
191
diff
changeset
|
387 OrthancPluginGetImageHeight(context_, image_), |
3d3d00e3e715
fix for new ImageAccessor API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
191
diff
changeset
|
388 OrthancPluginGetImagePitch(context_, image_), |
3d3d00e3e715
fix for new ImageAccessor API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
191
diff
changeset
|
389 OrthancPluginGetImageBuffer(context_, image_)); |
0 | 390 } |
391 } |