Mercurial > hg > orthanc-webviewer
annotate Plugin/ViewerToolbox.cpp @ 99:46ec13a1177c refactoring
use of ordered-slices
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 27 Nov 2015 21:39:41 +0100 |
parents | abdde1dfb3eb |
children | 3809121c3290 |
rev | line source |
---|---|
0 | 1 /** |
2 * Orthanc - A Lightweight, RESTful DICOM Store | |
3 * Copyright (C) 2012-2015 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
5 * | |
6 * This program is free software: you can redistribute it and/or | |
7 * modify it under the terms of the GNU Affero General Public License | |
8 * as published by the Free Software Foundation, either version 3 of | |
9 * the License, or (at your option) any later version. | |
10 * | |
11 * This program is distributed in the hope that it will be useful, but | |
12 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 * Affero General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU Affero General Public License | |
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
18 **/ | |
19 | |
20 | |
21 #include "ViewerToolbox.h" | |
22 | |
26 | 23 #include "../Orthanc/Core/OrthancException.h" |
24 #include "../Orthanc/Core/Toolbox.h" | |
0 | 25 |
26 #include <json/reader.h> | |
27 #include <stdexcept> | |
28 #include <boost/lexical_cast.hpp> | |
29 #include <sys/stat.h> | |
30 | |
31 namespace OrthancPlugins | |
32 { | |
33 bool GetStringFromOrthanc(std::string& content, | |
34 OrthancPluginContext* context, | |
35 const std::string& uri) | |
36 { | |
37 OrthancPluginMemoryBuffer answer; | |
38 | |
39 if (OrthancPluginRestApiGet(context, &answer, uri.c_str())) | |
40 { | |
41 return false; | |
42 } | |
43 | |
44 if (answer.size) | |
45 { | |
46 try | |
47 { | |
48 content.assign(reinterpret_cast<const char*>(answer.data), answer.size); | |
49 } | |
50 catch (std::bad_alloc&) | |
51 { | |
52 OrthancPluginFreeMemoryBuffer(context, &answer); | |
79 | 53 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotEnoughMemory); |
0 | 54 } |
55 } | |
56 | |
57 OrthancPluginFreeMemoryBuffer(context, &answer); | |
58 return true; | |
59 } | |
60 | |
61 | |
62 bool GetJsonFromOrthanc(Json::Value& json, | |
63 OrthancPluginContext* context, | |
64 const std::string& uri) | |
65 { | |
66 OrthancPluginMemoryBuffer answer; | |
67 | |
68 if (OrthancPluginRestApiGet(context, &answer, uri.c_str())) | |
69 { | |
70 return false; | |
71 } | |
72 | |
73 if (answer.size) | |
74 { | |
75 try | |
76 { | |
77 const char* data = reinterpret_cast<const char*>(answer.data); | |
78 Json::Reader reader; | |
79 if (!reader.parse(data, data + answer.size, json, | |
80 false /* don't collect comments */)) | |
81 { | |
82 return false; | |
83 } | |
84 } | |
85 catch (std::runtime_error&) | |
86 { | |
87 OrthancPluginFreeMemoryBuffer(context, &answer); | |
88 return false; | |
89 } | |
90 } | |
91 | |
92 OrthancPluginFreeMemoryBuffer(context, &answer); | |
93 return true; | |
94 } | |
95 | |
96 | |
97 | |
98 | |
99 bool TokenizeVector(std::vector<float>& result, | |
100 const std::string& value, | |
101 unsigned int expectedSize) | |
102 { | |
103 std::vector<std::string> tokens; | |
104 Orthanc::Toolbox::TokenizeString(tokens, value, '\\'); | |
105 | |
106 if (tokens.size() != expectedSize) | |
107 { | |
108 return false; | |
109 } | |
110 | |
111 result.resize(tokens.size()); | |
112 | |
113 for (size_t i = 0; i < tokens.size(); i++) | |
114 { | |
115 try | |
116 { | |
117 result[i] = boost::lexical_cast<float>(tokens[i]); | |
118 } | |
119 catch (boost::bad_lexical_cast&) | |
120 { | |
121 return false; | |
122 } | |
123 } | |
124 | |
125 return true; | |
126 } | |
127 | |
128 | |
79 | 129 void CompressUsingDeflate(std::string& compressed, |
130 OrthancPluginContext* context, | |
0 | 131 const void* uncompressed, |
79 | 132 size_t uncompressedSize) |
0 | 133 { |
79 | 134 OrthancPluginMemoryBuffer tmp; |
135 | |
136 OrthancPluginErrorCode code = OrthancPluginBufferCompression( | |
137 context, &tmp, uncompressed, uncompressedSize, | |
138 OrthancPluginCompressionType_Zlib, 0 /*compress*/); | |
139 | |
140 if (code != OrthancPluginErrorCode_Success) | |
0 | 141 { |
79 | 142 throw Orthanc::OrthancException(static_cast<Orthanc::ErrorCode>(code)); |
0 | 143 } |
144 | |
79 | 145 try |
146 { | |
147 compressed.assign(reinterpret_cast<const char*>(tmp.data), tmp.size); | |
148 } | |
149 catch (...) | |
150 { | |
151 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotEnoughMemory); | |
152 } | |
0 | 153 |
79 | 154 OrthancPluginFreeMemoryBuffer(context, &tmp); |
0 | 155 } |
156 | |
157 | |
158 const char* GetMimeType(const std::string& path) | |
159 { | |
160 size_t dot = path.find_last_of('.'); | |
161 | |
162 std::string extension = (dot == std::string::npos) ? "" : path.substr(dot); | |
163 std::transform(extension.begin(), extension.end(), extension.begin(), tolower); | |
164 | |
165 if (extension == ".html") | |
166 { | |
167 return "text/html"; | |
168 } | |
169 else if (extension == ".css") | |
170 { | |
171 return "text/css"; | |
172 } | |
173 else if (extension == ".js") | |
174 { | |
175 return "application/javascript"; | |
176 } | |
177 else if (extension == ".gif") | |
178 { | |
179 return "image/gif"; | |
180 } | |
181 else if (extension == ".svg") | |
182 { | |
183 return "image/svg+xml"; | |
184 } | |
185 else if (extension == ".json") | |
186 { | |
187 return "application/json"; | |
188 } | |
189 else if (extension == ".xml") | |
190 { | |
191 return "application/xml"; | |
192 } | |
193 else if (extension == ".png") | |
194 { | |
195 return "image/png"; | |
196 } | |
197 else if (extension == ".jpg" || extension == ".jpeg") | |
198 { | |
199 return "image/jpeg"; | |
200 } | |
201 else | |
202 { | |
203 return "application/octet-stream"; | |
204 } | |
205 } | |
206 | |
207 | |
208 bool ReadConfiguration(Json::Value& configuration, | |
209 OrthancPluginContext* context) | |
210 { | |
33
d7bd116777eb
Use of OrthancPluginGetConfiguration
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
26
diff
changeset
|
211 std::string s; |
0 | 212 |
213 { | |
33
d7bd116777eb
Use of OrthancPluginGetConfiguration
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
26
diff
changeset
|
214 char* tmp = OrthancPluginGetConfiguration(context); |
d7bd116777eb
Use of OrthancPluginGetConfiguration
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
26
diff
changeset
|
215 if (tmp == NULL) |
0 | 216 { |
33
d7bd116777eb
Use of OrthancPluginGetConfiguration
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
26
diff
changeset
|
217 OrthancPluginLogError(context, "Error while retrieving the configuration from Orthanc"); |
0 | 218 return false; |
219 } | |
220 | |
33
d7bd116777eb
Use of OrthancPluginGetConfiguration
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
26
diff
changeset
|
221 s.assign(tmp); |
d7bd116777eb
Use of OrthancPluginGetConfiguration
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
26
diff
changeset
|
222 OrthancPluginFreeString(context, tmp); |
0 | 223 } |
224 | |
225 Json::Reader reader; | |
33
d7bd116777eb
Use of OrthancPluginGetConfiguration
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
26
diff
changeset
|
226 if (reader.parse(s, configuration)) |
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 { |
d7bd116777eb
Use of OrthancPluginGetConfiguration
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
26
diff
changeset
|
232 OrthancPluginLogError(context, "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 | |
285 case Orthanc::PixelFormat_RGBA32: | |
286 return OrthancPluginPixelFormat_RGBA32; | |
287 | |
288 case Orthanc::PixelFormat_SignedGrayscale16: | |
289 return OrthancPluginPixelFormat_SignedGrayscale16; | |
290 | |
291 default: | |
292 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
293 } | |
294 } | |
295 | |
296 | |
297 Orthanc::PixelFormat Convert(OrthancPluginPixelFormat format) | |
298 { | |
299 switch (format) | |
0 | 300 { |
79 | 301 case OrthancPluginPixelFormat_Grayscale16: |
302 return Orthanc::PixelFormat_Grayscale16; | |
303 | |
304 case OrthancPluginPixelFormat_Grayscale8: | |
305 return Orthanc::PixelFormat_Grayscale8; | |
306 | |
307 case OrthancPluginPixelFormat_RGB24: | |
308 return Orthanc::PixelFormat_RGB24; | |
309 | |
310 case OrthancPluginPixelFormat_RGBA32: | |
311 return Orthanc::PixelFormat_RGBA32; | |
312 | |
313 case OrthancPluginPixelFormat_SignedGrayscale16: | |
314 return Orthanc::PixelFormat_SignedGrayscale16; | |
0 | 315 |
79 | 316 default: |
317 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
318 } | |
319 } | |
320 | |
321 | |
322 void WriteJpegToMemory(std::string& result, | |
323 OrthancPluginContext* context, | |
324 const Orthanc::ImageAccessor& accessor, | |
325 uint8_t quality) | |
326 { | |
327 OrthancPluginMemoryBuffer tmp; | |
328 | |
329 OrthancPluginErrorCode code = OrthancPluginCompressJpegImage | |
330 (context, &tmp, Convert(accessor.GetFormat()), | |
331 accessor.GetWidth(), accessor.GetHeight(), accessor.GetPitch(), | |
99
46ec13a1177c
use of ordered-slices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
79
diff
changeset
|
332 accessor.GetConstBuffer(), quality); |
79 | 333 |
334 if (code != OrthancPluginErrorCode_Success) | |
0 | 335 { |
79 | 336 throw Orthanc::OrthancException(static_cast<Orthanc::ErrorCode>(code)); |
0 | 337 } |
338 | |
79 | 339 try |
0 | 340 { |
79 | 341 result.assign(reinterpret_cast<const char*>(tmp.data), tmp.size); |
342 } | |
343 catch (...) | |
344 { | |
345 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotEnoughMemory); | |
0 | 346 } |
347 | |
79 | 348 OrthancPluginFreeMemoryBuffer(context, &tmp); |
349 } | |
350 | |
351 | |
352 | |
353 ImageReader::ImageReader(OrthancPluginContext* context, | |
354 const std::string& image, | |
355 OrthancPluginImageFormat format) : context_(context) | |
356 { | |
357 image_ = OrthancPluginUncompressImage(context_, image.c_str(), image.size(), format); | |
358 | |
359 if (image_ == NULL) | |
0 | 360 { |
79 | 361 throw Orthanc::OrthancException(Orthanc::ErrorCode_CorruptedFile); |
0 | 362 } |
79 | 363 } |
0 | 364 |
365 | |
79 | 366 ImageReader::~ImageReader() |
367 { | |
368 OrthancPluginFreeImage(context_, image_); | |
369 } | |
370 | |
0 | 371 |
79 | 372 Orthanc::ImageAccessor ImageReader::GetAccessor() const |
373 { | |
374 Orthanc::ImageAccessor accessor; | |
0 | 375 |
79 | 376 accessor.AssignReadOnly(Convert(OrthancPluginGetImagePixelFormat(context_, image_)), |
377 OrthancPluginGetImageWidth(context_, image_), | |
378 OrthancPluginGetImageHeight(context_, image_), | |
379 OrthancPluginGetImagePitch(context_, image_), | |
380 OrthancPluginGetImageBuffer(context_, image_)); | |
381 | |
382 return accessor; | |
0 | 383 } |
384 } |