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