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