Mercurial > hg > orthanc-webviewer
annotate Plugin/ViewerToolbox.cpp @ 287:ec1af1fdcaca
fix build
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 06 Nov 2020 17:33:32 +0100 |
parents | 3a9749b1dfce |
children | aadbffcee805 |
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 |
226
aee499712ac4
upgrade to year 2020
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
209
diff
changeset
|
5 * Copyright (C) 2017-2020 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 <json/reader.h> |
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 { | |
82 const char* data = reinterpret_cast<const char*>(answer.data); | |
83 Json::Reader reader; | |
84 if (!reader.parse(data, data + answer.size, json, | |
85 false /* don't collect comments */)) | |
86 { | |
87 return false; | |
88 } | |
89 } | |
90 catch (std::runtime_error&) | |
91 { | |
92 OrthancPluginFreeMemoryBuffer(context, &answer); | |
93 return false; | |
94 } | |
95 } | |
96 | |
97 OrthancPluginFreeMemoryBuffer(context, &answer); | |
98 return true; | |
99 } | |
100 | |
101 | |
102 | |
103 | |
104 bool TokenizeVector(std::vector<float>& result, | |
105 const std::string& value, | |
106 unsigned int expectedSize) | |
107 { | |
108 std::vector<std::string> tokens; | |
109 Orthanc::Toolbox::TokenizeString(tokens, value, '\\'); | |
110 | |
111 if (tokens.size() != expectedSize) | |
112 { | |
113 return false; | |
114 } | |
115 | |
116 result.resize(tokens.size()); | |
117 | |
118 for (size_t i = 0; i < tokens.size(); i++) | |
119 { | |
120 try | |
121 { | |
122 result[i] = boost::lexical_cast<float>(tokens[i]); | |
123 } | |
124 catch (boost::bad_lexical_cast&) | |
125 { | |
126 return false; | |
127 } | |
128 } | |
129 | |
130 return true; | |
131 } | |
132 | |
133 | |
79 | 134 void CompressUsingDeflate(std::string& compressed, |
135 OrthancPluginContext* context, | |
0 | 136 const void* uncompressed, |
79 | 137 size_t uncompressedSize) |
0 | 138 { |
79 | 139 OrthancPluginMemoryBuffer tmp; |
140 | |
141 OrthancPluginErrorCode code = OrthancPluginBufferCompression( | |
142 context, &tmp, uncompressed, uncompressedSize, | |
143 OrthancPluginCompressionType_Zlib, 0 /*compress*/); | |
144 | |
145 if (code != OrthancPluginErrorCode_Success) | |
0 | 146 { |
79 | 147 throw Orthanc::OrthancException(static_cast<Orthanc::ErrorCode>(code)); |
0 | 148 } |
149 | |
79 | 150 try |
151 { | |
152 compressed.assign(reinterpret_cast<const char*>(tmp.data), tmp.size); | |
153 } | |
154 catch (...) | |
155 { | |
156 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotEnoughMemory); | |
157 } | |
0 | 158 |
79 | 159 OrthancPluginFreeMemoryBuffer(context, &tmp); |
0 | 160 } |
161 | |
162 | |
163 const char* GetMimeType(const std::string& path) | |
164 { | |
165 size_t dot = path.find_last_of('.'); | |
166 | |
167 std::string extension = (dot == std::string::npos) ? "" : path.substr(dot); | |
168 std::transform(extension.begin(), extension.end(), extension.begin(), tolower); | |
169 | |
170 if (extension == ".html") | |
171 { | |
172 return "text/html"; | |
173 } | |
174 else if (extension == ".css") | |
175 { | |
176 return "text/css"; | |
177 } | |
178 else if (extension == ".js") | |
179 { | |
180 return "application/javascript"; | |
181 } | |
182 else if (extension == ".gif") | |
183 { | |
184 return "image/gif"; | |
185 } | |
186 else if (extension == ".svg") | |
187 { | |
188 return "image/svg+xml"; | |
189 } | |
190 else if (extension == ".json") | |
191 { | |
192 return "application/json"; | |
193 } | |
194 else if (extension == ".xml") | |
195 { | |
196 return "application/xml"; | |
197 } | |
198 else if (extension == ".png") | |
199 { | |
200 return "image/png"; | |
201 } | |
202 else if (extension == ".jpg" || extension == ".jpeg") | |
203 { | |
204 return "image/jpeg"; | |
205 } | |
206 else | |
207 { | |
208 return "application/octet-stream"; | |
209 } | |
210 } | |
211 | |
212 | |
213 bool ReadConfiguration(Json::Value& configuration, | |
214 OrthancPluginContext* context) | |
215 { | |
33
d7bd116777eb
Use of OrthancPluginGetConfiguration
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
26
diff
changeset
|
216 std::string s; |
0 | 217 |
218 { | |
33
d7bd116777eb
Use of OrthancPluginGetConfiguration
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
26
diff
changeset
|
219 char* tmp = OrthancPluginGetConfiguration(context); |
d7bd116777eb
Use of OrthancPluginGetConfiguration
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
26
diff
changeset
|
220 if (tmp == NULL) |
0 | 221 { |
260
620ed85fb514
replacing OrthancPluginLog...() by LOG(...)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
229
diff
changeset
|
222 LOG(ERROR) << "Error while retrieving the configuration from Orthanc"; |
0 | 223 return false; |
224 } | |
225 | |
33
d7bd116777eb
Use of OrthancPluginGetConfiguration
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
26
diff
changeset
|
226 s.assign(tmp); |
d7bd116777eb
Use of OrthancPluginGetConfiguration
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
26
diff
changeset
|
227 OrthancPluginFreeString(context, tmp); |
0 | 228 } |
229 | |
230 Json::Reader reader; | |
33
d7bd116777eb
Use of OrthancPluginGetConfiguration
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
26
diff
changeset
|
231 if (reader.parse(s, configuration)) |
0 | 232 { |
33
d7bd116777eb
Use of OrthancPluginGetConfiguration
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
26
diff
changeset
|
233 return true; |
d7bd116777eb
Use of OrthancPluginGetConfiguration
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
26
diff
changeset
|
234 } |
d7bd116777eb
Use of OrthancPluginGetConfiguration
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
26
diff
changeset
|
235 else |
d7bd116777eb
Use of OrthancPluginGetConfiguration
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
26
diff
changeset
|
236 { |
260
620ed85fb514
replacing OrthancPluginLog...() by LOG(...)
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
229
diff
changeset
|
237 LOG(ERROR) << "Unable to parse the configuration"; |
0 | 238 return false; |
239 } | |
240 } | |
241 | |
242 | |
243 std::string GetStringValue(const Json::Value& configuration, | |
244 const std::string& key, | |
245 const std::string& defaultValue) | |
246 { | |
247 if (configuration.type() != Json::objectValue || | |
248 !configuration.isMember(key) || | |
249 configuration[key].type() != Json::stringValue) | |
250 { | |
251 return defaultValue; | |
252 } | |
253 else | |
254 { | |
255 return configuration[key].asString(); | |
256 } | |
257 } | |
258 | |
259 | |
260 int GetIntegerValue(const Json::Value& configuration, | |
261 const std::string& key, | |
262 int defaultValue) | |
263 { | |
264 if (configuration.type() != Json::objectValue || | |
265 !configuration.isMember(key) || | |
266 configuration[key].type() != Json::intValue) | |
267 { | |
268 return defaultValue; | |
269 } | |
270 else | |
271 { | |
272 return configuration[key].asInt(); | |
273 } | |
274 } | |
275 | |
276 | |
79 | 277 OrthancPluginPixelFormat Convert(Orthanc::PixelFormat format) |
0 | 278 { |
79 | 279 switch (format) |
280 { | |
281 case Orthanc::PixelFormat_Grayscale16: | |
282 return OrthancPluginPixelFormat_Grayscale16; | |
283 | |
284 case Orthanc::PixelFormat_Grayscale8: | |
285 return OrthancPluginPixelFormat_Grayscale8; | |
286 | |
287 case Orthanc::PixelFormat_RGB24: | |
288 return OrthancPluginPixelFormat_RGB24; | |
289 | |
172 | 290 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 3, 1) |
291 case Orthanc::PixelFormat_RGB48: | |
292 return OrthancPluginPixelFormat_RGB48; | |
293 #endif | |
294 | |
79 | 295 case Orthanc::PixelFormat_RGBA32: |
296 return OrthancPluginPixelFormat_RGBA32; | |
297 | |
298 case Orthanc::PixelFormat_SignedGrayscale16: | |
299 return OrthancPluginPixelFormat_SignedGrayscale16; | |
300 | |
301 default: | |
302 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
303 } | |
304 } | |
305 | |
306 | |
307 Orthanc::PixelFormat Convert(OrthancPluginPixelFormat format) | |
308 { | |
309 switch (format) | |
0 | 310 { |
79 | 311 case OrthancPluginPixelFormat_Grayscale16: |
312 return Orthanc::PixelFormat_Grayscale16; | |
313 | |
314 case OrthancPluginPixelFormat_Grayscale8: | |
315 return Orthanc::PixelFormat_Grayscale8; | |
316 | |
317 case OrthancPluginPixelFormat_RGB24: | |
318 return Orthanc::PixelFormat_RGB24; | |
319 | |
172 | 320 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 3, 1) |
321 case OrthancPluginPixelFormat_RGB48: | |
322 return Orthanc::PixelFormat_RGB48; | |
323 #endif | |
324 | |
79 | 325 case OrthancPluginPixelFormat_RGBA32: |
326 return Orthanc::PixelFormat_RGBA32; | |
327 | |
328 case OrthancPluginPixelFormat_SignedGrayscale16: | |
329 return Orthanc::PixelFormat_SignedGrayscale16; | |
0 | 330 |
79 | 331 default: |
332 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
333 } | |
334 } | |
335 | |
336 | |
337 void WriteJpegToMemory(std::string& result, | |
338 OrthancPluginContext* context, | |
339 const Orthanc::ImageAccessor& accessor, | |
340 uint8_t quality) | |
341 { | |
342 OrthancPluginMemoryBuffer tmp; | |
343 | |
344 OrthancPluginErrorCode code = OrthancPluginCompressJpegImage | |
345 (context, &tmp, Convert(accessor.GetFormat()), | |
346 accessor.GetWidth(), accessor.GetHeight(), accessor.GetPitch(), | |
99
46ec13a1177c
use of ordered-slices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
79
diff
changeset
|
347 accessor.GetConstBuffer(), quality); |
79 | 348 |
349 if (code != OrthancPluginErrorCode_Success) | |
0 | 350 { |
79 | 351 throw Orthanc::OrthancException(static_cast<Orthanc::ErrorCode>(code)); |
0 | 352 } |
353 | |
79 | 354 try |
0 | 355 { |
79 | 356 result.assign(reinterpret_cast<const char*>(tmp.data), tmp.size); |
357 } | |
358 catch (...) | |
359 { | |
360 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotEnoughMemory); | |
0 | 361 } |
362 | |
79 | 363 OrthancPluginFreeMemoryBuffer(context, &tmp); |
364 } | |
365 | |
366 | |
367 | |
368 ImageReader::ImageReader(OrthancPluginContext* context, | |
369 const std::string& image, | |
370 OrthancPluginImageFormat format) : context_(context) | |
371 { | |
372 image_ = OrthancPluginUncompressImage(context_, image.c_str(), image.size(), format); | |
373 | |
374 if (image_ == NULL) | |
0 | 375 { |
79 | 376 throw Orthanc::OrthancException(Orthanc::ErrorCode_CorruptedFile); |
0 | 377 } |
79 | 378 } |
0 | 379 |
380 | |
79 | 381 ImageReader::~ImageReader() |
382 { | |
383 OrthancPluginFreeImage(context_, image_); | |
384 } | |
385 | |
0 | 386 |
207
3d3d00e3e715
fix for new ImageAccessor API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
191
diff
changeset
|
387 void ImageReader::GetAccessor(Orthanc::ImageAccessor& target) const |
79 | 388 { |
207
3d3d00e3e715
fix for new ImageAccessor API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
191
diff
changeset
|
389 target.AssignReadOnly(Convert(OrthancPluginGetImagePixelFormat(context_, image_)), |
3d3d00e3e715
fix for new ImageAccessor API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
191
diff
changeset
|
390 OrthancPluginGetImageWidth(context_, image_), |
3d3d00e3e715
fix for new ImageAccessor API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
191
diff
changeset
|
391 OrthancPluginGetImageHeight(context_, image_), |
3d3d00e3e715
fix for new ImageAccessor API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
191
diff
changeset
|
392 OrthancPluginGetImagePitch(context_, image_), |
3d3d00e3e715
fix for new ImageAccessor API
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
191
diff
changeset
|
393 OrthancPluginGetImageBuffer(context_, image_)); |
0 | 394 } |
395 } |