comparison Plugins/Samples/GdcmDecoder/Plugin.cpp @ 3933:f67b48833a4f transcoding

new option "Throttling" to the GDCM plugin
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 15 May 2020 12:25:36 +0200
parents b99acc213937
children
comparison
equal deleted inserted replaced
3932:bf46e10de8ae 3933:f67b48833a4f
19 **/ 19 **/
20 20
21 21
22 #include "../../../Core/Compatibility.h" 22 #include "../../../Core/Compatibility.h"
23 #include "../../../Core/DicomFormat/DicomMap.h" 23 #include "../../../Core/DicomFormat/DicomMap.h"
24 #include "../../../Core/MultiThreading/Semaphore.h"
24 #include "../../../Core/Toolbox.h" 25 #include "../../../Core/Toolbox.h"
25 #include "GdcmDecoderCache.h" 26 #include "GdcmDecoderCache.h"
26 27
27 #include <gdcmImageChangeTransferSyntax.h> 28 #include <gdcmImageChangeTransferSyntax.h>
28 #include <gdcmImageReader.h> 29 #include <gdcmImageReader.h>
32 33
33 34
34 static OrthancPlugins::GdcmDecoderCache cache_; 35 static OrthancPlugins::GdcmDecoderCache cache_;
35 static bool restrictTransferSyntaxes_ = false; 36 static bool restrictTransferSyntaxes_ = false;
36 static std::set<std::string> enabledTransferSyntaxes_; 37 static std::set<std::string> enabledTransferSyntaxes_;
37 38 static bool hasThrottling_ = false;
39 static std::unique_ptr<Orthanc::Semaphore> throttlingSemaphore_;
38 40
39 static bool ExtractTransferSyntax(std::string& transferSyntax, 41 static bool ExtractTransferSyntax(std::string& transferSyntax,
40 const void* dicom, 42 const void* dicom,
41 const uint32_t size) 43 const uint32_t size)
42 { 44 {
109 const uint32_t size, 111 const uint32_t size,
110 uint32_t frameIndex) 112 uint32_t frameIndex)
111 { 113 {
112 try 114 try
113 { 115 {
116 std::unique_ptr<Orthanc::Semaphore::Locker> locker;
117
118 if (hasThrottling_)
119 {
120 if (throttlingSemaphore_.get() == NULL)
121 {
122 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
123 }
124 else
125 {
126 locker.reset(new Orthanc::Semaphore::Locker(*throttlingSemaphore_));
127 }
128 }
129
114 if (!IsTransferSyntaxEnabled(dicom, size)) 130 if (!IsTransferSyntaxEnabled(dicom, size))
115 { 131 {
116 *target = NULL; 132 *target = NULL;
117 return OrthancPluginErrorCode_Success; 133 return OrthancPluginErrorCode_Success;
118 } 134 }
164 uint32_t countSyntaxes, 180 uint32_t countSyntaxes,
165 uint8_t allowNewSopInstanceUid) 181 uint8_t allowNewSopInstanceUid)
166 { 182 {
167 try 183 try
168 { 184 {
185 std::unique_ptr<Orthanc::Semaphore::Locker> locker;
186
187 if (hasThrottling_)
188 {
189 if (throttlingSemaphore_.get() == NULL)
190 {
191 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
192 }
193 else
194 {
195 locker.reset(new Orthanc::Semaphore::Locker(*throttlingSemaphore_));
196 }
197 }
198
169 std::string dicom(reinterpret_cast<const char*>(buffer), size); 199 std::string dicom(reinterpret_cast<const char*>(buffer), size);
170 std::stringstream stream(dicom); 200 std::stringstream stream(dicom);
171 201
172 gdcm::ImageReader reader; 202 gdcm::ImageReader reader;
173 reader.SetStream(stream); 203 reader.SetStream(stream);
295 extern "C" 325 extern "C"
296 { 326 {
297 ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* context) 327 ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* context)
298 { 328 {
299 static const char* const KEY_GDCM = "Gdcm"; 329 static const char* const KEY_GDCM = "Gdcm";
300 static const char* const KEY_ENABLE_GDCM = "EnableGdcm"; 330 static const char* const KEY_ENABLE_GDCM = "Enable";
331 static const char* const KEY_THROTTLING = "Throttling";
301 static const char* const KEY_RESTRICT_TRANSFER_SYNTAXES = "RestrictTransferSyntaxes"; 332 static const char* const KEY_RESTRICT_TRANSFER_SYNTAXES = "RestrictTransferSyntaxes";
302 333
303 OrthancPlugins::SetGlobalContext(context); 334 try
304 Orthanc::Logging::Initialize(context); 335 {
305 LOG(INFO) << "Initializing the decoder/transcoder of medical images using GDCM"; 336 OrthancPlugins::SetGlobalContext(context);
306 337 Orthanc::Logging::Initialize(context);
307 /* Check the version of the Orthanc core */ 338 LOG(INFO) << "Initializing the decoder/transcoder of medical images using GDCM";
308 if (!OrthancPlugins::CheckMinimalOrthancVersion(0, 9, 5)) 339
309 { 340 /* Check the version of the Orthanc core */
310 LOG(ERROR) << "Your version of Orthanc (" << std::string(context->orthancVersion) 341 if (!OrthancPlugins::CheckMinimalOrthancVersion(0, 9, 5))
311 << ") must be above 0.9.5 to run this plugin"; 342 {
343 LOG(ERROR) << "Your version of Orthanc (" << std::string(context->orthancVersion)
344 << ") must be above 0.9.5 to run this plugin";
345 return -1;
346 }
347
348 OrthancPluginSetDescription(context, "Decoder/transcoder of medical images using GDCM.");
349
350 OrthancPlugins::OrthancConfiguration global;
351
352 bool enabled = true;
353 hasThrottling_ = false;
354
355 if (global.IsSection(KEY_GDCM))
356 {
357 OrthancPlugins::OrthancConfiguration config;
358 global.GetSection(config, KEY_GDCM);
359
360 enabled = config.GetBooleanValue(KEY_ENABLE_GDCM, true);
361
362 if (enabled &&
363 config.LookupSetOfStrings(enabledTransferSyntaxes_, KEY_RESTRICT_TRANSFER_SYNTAXES, false))
364 {
365 restrictTransferSyntaxes_ = true;
366
367 for (std::set<std::string>::const_iterator it = enabledTransferSyntaxes_.begin();
368 it != enabledTransferSyntaxes_.end(); ++it)
369 {
370 LOG(WARNING) << "Orthanc will use GDCM to decode transfer syntax: " << *it;
371 }
372 }
373
374 unsigned int throttling;
375 if (enabled &&
376 config.LookupUnsignedIntegerValue(throttling, KEY_THROTTLING))
377 {
378 if (throttling == 0)
379 {
380 LOG(ERROR) << "Bad value for option \"" << KEY_THROTTLING
381 << "\": Must be a strictly positive integer";
382 return -1;
383 }
384 else
385 {
386 LOG(WARNING) << "Throttling GDCM to " << throttling << " concurrent thread(s)";
387 hasThrottling_ = true;
388 throttlingSemaphore_.reset(new Orthanc::Semaphore(throttling));
389 }
390 }
391 }
392
393 if (enabled)
394 {
395 if (!hasThrottling_)
396 {
397 LOG(WARNING) << "GDCM throttling is disabled";
398 }
399
400 OrthancPluginRegisterDecodeImageCallback(context, DecodeImageCallback);
401
402 if (OrthancPlugins::CheckMinimalOrthancVersion(1, 7, 0))
403 {
404 OrthancPluginRegisterTranscoderCallback(context, TranscoderCallback);
405 }
406 else
407 {
408 LOG(WARNING) << "Your version of Orthanc (" << std::string(context->orthancVersion)
409 << ") must be above 1.7.0 to benefit from transcoding";
410 }
411 }
412 else
413 {
414 LOG(WARNING) << "The decoder/transcoder of medical images using GDCM is disabled";
415 }
416
417 return 0;
418 }
419 catch (Orthanc::OrthancException& e)
420 {
421 LOG(ERROR) << "Exception while initializing the GDCM plugin: " << e.What();
312 return -1; 422 return -1;
313 } 423 }
314
315 OrthancPluginSetDescription(context, "Decoder/transcoder of medical images using GDCM.");
316
317 OrthancPlugins::OrthancConfiguration global;
318
319 bool enabled = true;
320
321 if (global.IsSection(KEY_GDCM))
322 {
323 OrthancPlugins::OrthancConfiguration config;
324 global.GetSection(config, KEY_GDCM);
325
326 enabled = config.GetBooleanValue(KEY_ENABLE_GDCM, true);
327
328 if (config.LookupSetOfStrings(enabledTransferSyntaxes_, KEY_RESTRICT_TRANSFER_SYNTAXES, false))
329 {
330 restrictTransferSyntaxes_ = true;
331
332 for (std::set<std::string>::const_iterator it = enabledTransferSyntaxes_.begin();
333 it != enabledTransferSyntaxes_.end(); ++it)
334 {
335 LOG(WARNING) << "Orthanc will use GDCM to decode transfer syntax: " << *it;
336 }
337 }
338 }
339
340 if (enabled)
341 {
342 OrthancPluginRegisterDecodeImageCallback(context, DecodeImageCallback);
343
344 if (OrthancPlugins::CheckMinimalOrthancVersion(1, 7, 0))
345 {
346 OrthancPluginRegisterTranscoderCallback(context, TranscoderCallback);
347 }
348 else
349 {
350 LOG(ERROR) << "Your version of Orthanc (" << std::string(context->orthancVersion)
351 << ") must be above 1.7.0 to benefit from transcoding";
352 }
353 }
354 else
355 {
356 LOG(WARNING) << "The decoder/transcoder of medical images using GDCM is disabled";
357 }
358
359 return 0;
360 } 424 }
361 425
362 426
363 ORTHANC_PLUGINS_API void OrthancPluginFinalize() 427 ORTHANC_PLUGINS_API void OrthancPluginFinalize()
364 { 428 {