Mercurial > hg > orthanc
changeset 2012:50b9bc19dc62
More than one custom image decoder can be installed (e.g. to handle different transfer syntaxes)
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 10 Jun 2016 17:54:26 +0200 |
parents | 5b3b2de4e018 |
children | f6e68c0c2737 |
files | NEWS OrthancServer/OrthancRestApi/OrthancRestResources.cpp Plugins/Engine/OrthancPlugins.cpp Plugins/Engine/OrthancPlugins.h |
diffstat | 4 files changed, 54 insertions(+), 29 deletions(-) [+] |
line wrap: on
line diff
--- a/NEWS Fri Jun 10 09:26:26 2016 +0200 +++ b/NEWS Fri Jun 10 17:54:26 2016 +0200 @@ -25,6 +25,7 @@ * New callback to handle C-Move requests: OrthancPluginRegisterMoveCallback() * New function: "OrthancPluginHttpClient()" to do HTTP requests with full control * New function: "OrthancPluginGenerateUuid()" to generate a UUID +* More than one custom image decoder can be installed (e.g. to handle different transfer syntaxes) Lua ---
--- a/OrthancServer/OrthancRestApi/OrthancRestResources.cpp Fri Jun 10 09:26:26 2016 +0200 +++ b/OrthancServer/OrthancRestApi/OrthancRestResources.cpp Fri Jun 10 17:54:26 2016 +0200 @@ -380,7 +380,14 @@ // TODO create a cache of file std::string dicomContent; context.ReadFile(dicomContent, publicId, FileContentType_Dicom); - decoded.reset(context.GetPlugins().Decode(dicomContent.c_str(), dicomContent.size(), frame)); + decoded.reset(context.GetPlugins().DecodeUnsafe(dicomContent.c_str(), dicomContent.size(), frame)); + + /** + * Note that we call "DecodeUnsafe()": We do not fallback to + * the builtin decoder if no installed decoder plugin is able + * to decode the image. This allows us to take advantage of + * the cache below. + **/ } #endif
--- a/Plugins/Engine/OrthancPlugins.cpp Fri Jun 10 09:26:26 2016 +0200 +++ b/Plugins/Engine/OrthancPlugins.cpp Fri Jun 10 17:54:26 2016 +0200 @@ -344,6 +344,7 @@ typedef std::list<OrthancPluginOnStoredInstanceCallback> OnStoredCallbacks; typedef std::list<OrthancPluginOnChangeCallback> OnChangeCallbacks; typedef std::list<OrthancPluginIncomingHttpRequestFilter> IncomingHttpRequestFilters; + typedef std::list<OrthancPluginDecodeImageCallback> DecodeImageCallbacks; typedef std::map<Property, std::string> Properties; PluginsManager manager_; @@ -353,7 +354,7 @@ OnChangeCallbacks onChangeCallbacks_; OrthancPluginFindCallback findCallback_; OrthancPluginWorklistCallback worklistCallback_; - OrthancPluginDecodeImageCallback decodeImageCallback_; + DecodeImageCallbacks decodeImageCallbacks_; _OrthancPluginMoveCallback moveCallbacks_; IncomingHttpRequestFilters incomingHttpRequestFilters_; std::auto_ptr<StorageAreaFactory> storageArea_; @@ -376,7 +377,6 @@ context_(NULL), findCallback_(NULL), worklistCallback_(NULL), - decodeImageCallback_(NULL), argc_(1), argv_(NULL) { @@ -1104,16 +1104,9 @@ boost::mutex::scoped_lock lock(pimpl_->decodeImageCallbackMutex_); - if (pimpl_->decodeImageCallback_ != NULL) - { - LOG(ERROR) << "Can only register one plugin to handle the decompression of DICOM images"; - throw OrthancException(ErrorCode_Plugin); - } - else - { - LOG(INFO) << "Plugin has registered a callback to decode DICOM images"; - pimpl_->decodeImageCallback_ = p.callback; - } + pimpl_->decodeImageCallbacks_.push_back(p.callback); + LOG(INFO) << "Plugin has registered a callback to decode DICOM images (" + << pimpl_->decodeImageCallbacks_.size() << " decoder(s) now active)"; } @@ -2968,31 +2961,48 @@ bool OrthancPlugins::HasCustomImageDecoder() { boost::mutex::scoped_lock lock(pimpl_->decodeImageCallbackMutex_); - return (pimpl_->decodeImageCallback_ != NULL); + return !pimpl_->decodeImageCallbacks_.empty(); } - ImageAccessor* OrthancPlugins::Decode(const void* dicom, - size_t size, - unsigned int frame) + ImageAccessor* OrthancPlugins::DecodeUnsafe(const void* dicom, + size_t size, + unsigned int frame) { + boost::mutex::scoped_lock lock(pimpl_->decodeImageCallbackMutex_); + + for (PImpl::DecodeImageCallbacks::const_iterator + decoder = pimpl_->decodeImageCallbacks_.begin(); + decoder != pimpl_->decodeImageCallbacks_.end(); ++decoder) { - boost::mutex::scoped_lock lock(pimpl_->decodeImageCallbackMutex_); - if (pimpl_->decodeImageCallback_ != NULL) + OrthancPluginImage* pluginImage = NULL; + if ((*decoder) (&pluginImage, dicom, size, frame) == OrthancPluginErrorCode_Success && + pluginImage != NULL) { - OrthancPluginImage* pluginImage = NULL; - if (pimpl_->decodeImageCallback_(&pluginImage, dicom, size, frame) == OrthancPluginErrorCode_Success && - pluginImage != NULL) - { - return reinterpret_cast<ImageAccessor*>(pluginImage); - } - - LOG(INFO) << "The installed image decoding plugins cannot handle an image, fallback to the built-in decoder"; + return reinterpret_cast<ImageAccessor*>(pluginImage); } } - DefaultDicomImageDecoder defaultDecoder; - return defaultDecoder.Decode(dicom, size, frame); // TODO RETURN NULL ??? + return NULL; + } + + + ImageAccessor* OrthancPlugins::Decode(const void* dicom, + size_t size, + unsigned int frame) + { + ImageAccessor* result = DecodeUnsafe(dicom, size, frame); + + if (result != NULL) + { + return result; + } + else + { + LOG(INFO) << "The installed image decoding plugins cannot handle an image, fallback to the built-in decoder"; + DefaultDicomImageDecoder defaultDecoder; + return defaultDecoder.Decode(dicom, size, frame); + } }
--- a/Plugins/Engine/OrthancPlugins.h Fri Jun 10 09:26:26 2016 +0200 +++ b/Plugins/Engine/OrthancPlugins.h Fri Jun 10 17:54:26 2016 +0200 @@ -260,6 +260,13 @@ bool HasCustomImageDecoder(); + // Contrarily to "Decode()", this method does not fallback to the + // builtin image decoder, if no installed custom decoder can + // handle the image (it returns NULL in this case). + ImageAccessor* DecodeUnsafe(const void* dicom, + size_t size, + unsigned int frame); + virtual ImageAccessor* Decode(const void* dicom, size_t size, unsigned int frame);