Mercurial > hg > orthanc
diff Plugins/Engine/OrthancPlugins.cpp @ 3916:0e3849268a55 transcoding
new plugin SDK primitives related to OrthancPluginDicomInstance
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 11 May 2020 21:07:36 +0200 |
parents | f0dd5ded8927 |
children | 6f11b3233a06 |
line wrap: on
line diff
--- a/Plugins/Engine/OrthancPlugins.cpp Mon May 11 15:13:16 2020 +0200 +++ b/Plugins/Engine/OrthancPlugins.cpp Mon May 11 21:07:36 2020 +0200 @@ -1761,19 +1761,84 @@ } + class OrthancPlugins::IDicomInstance : public boost::noncopyable + { + public: + virtual ~IDicomInstance() + { + } + + virtual bool CanBeFreed() const = 0; + + virtual const DicomInstanceToStore& GetInstance() const = 0; + }; + + + class OrthancPlugins::DicomInstanceFromCallback : public IDicomInstance + { + private: + const DicomInstanceToStore& instance_; + + public: + DicomInstanceFromCallback(const DicomInstanceToStore& instance) : + instance_(instance) + { + } + + virtual bool CanBeFreed() const ORTHANC_OVERRIDE + { + return false; + } + + virtual const DicomInstanceToStore& GetInstance() const ORTHANC_OVERRIDE + { + return instance_; + }; + }; + + + class OrthancPlugins::DicomInstanceFromBuffer : public IDicomInstance + { + private: + std::string buffer_; + DicomInstanceToStore instance_; + + public: + DicomInstanceFromBuffer(const void* buffer, + size_t size) + { + buffer_.assign(reinterpret_cast<const char*>(buffer), size); + instance_.SetBuffer(buffer_.empty() ? NULL : buffer_.c_str(), buffer_.size()); + instance_.SetOrigin(DicomInstanceOrigin::FromPlugins()); + } + + virtual bool CanBeFreed() const ORTHANC_OVERRIDE + { + return true; + } + + virtual const DicomInstanceToStore& GetInstance() const ORTHANC_OVERRIDE + { + return instance_; + }; + }; + + void OrthancPlugins::SignalStoredInstance(const std::string& instanceId, - DicomInstanceToStore& instance, + const DicomInstanceToStore& instance, const Json::Value& simplifiedTags) { + DicomInstanceFromCallback wrapped(instance); + boost::recursive_mutex::scoped_lock lock(pimpl_->storedCallbackMutex_); for (PImpl::OnStoredCallbacks::const_iterator callback = pimpl_->onStoredCallbacks_.begin(); callback != pimpl_->onStoredCallbacks_.end(); ++callback) { - OrthancPluginErrorCode error = (*callback) - (reinterpret_cast<OrthancPluginDicomInstance*>(&instance), - instanceId.c_str()); + OrthancPluginErrorCode error = (*callback) ( + reinterpret_cast<OrthancPluginDicomInstance*>(&wrapped), + instanceId.c_str()); if (error != OrthancPluginErrorCode_Success) { @@ -1787,14 +1852,15 @@ bool OrthancPlugins::FilterIncomingInstance(const DicomInstanceToStore& instance, const Json::Value& simplified) { + DicomInstanceFromCallback wrapped(instance); + boost::recursive_mutex::scoped_lock lock(pimpl_->invokeServiceMutex_); for (PImpl::IncomingDicomInstanceFilters::const_iterator filter = pimpl_->incomingDicomInstanceFilters_.begin(); filter != pimpl_->incomingDicomInstanceFilters_.end(); ++filter) { - int32_t allowed = (*filter) ( - reinterpret_cast<const OrthancPluginDicomInstance*>(&instance)); + int32_t allowed = (*filter) (reinterpret_cast<const OrthancPluginDicomInstance*>(&wrapped)); if (allowed == 0) { @@ -2451,14 +2517,19 @@ } - static void AccessDicomInstance(_OrthancPluginService service, - const void* parameters) + void OrthancPlugins::AccessDicomInstance(_OrthancPluginService service, + const void* parameters) { const _OrthancPluginAccessDicomInstance& p = *reinterpret_cast<const _OrthancPluginAccessDicomInstance*>(parameters); + if (p.instance == NULL) + { + throw OrthancException(ErrorCode_NullPointer); + } + const DicomInstanceToStore& instance = - *reinterpret_cast<const DicomInstanceToStore*>(p.instance); + reinterpret_cast<const IDicomInstance*>(p.instance)->GetInstance(); switch (service) { @@ -2523,6 +2594,10 @@ *p.resultInt64 = instance.HasPixelData(); return; + case _OrthancPluginService_GetInstanceFramesCount: // New in Orthanc 1.7.0 + *p.resultInt64 = instance.GetParsedDicomFile().GetFramesCount(); + return; + default: throw OrthancException(ErrorCode_InternalError); } @@ -2606,6 +2681,79 @@ } + void OrthancPlugins::AccessDicomInstance2(_OrthancPluginService service, + const void* parameters) + { + const _OrthancPluginAccessDicomInstance2& p = + *reinterpret_cast<const _OrthancPluginAccessDicomInstance2*>(parameters); + + if (p.instance == NULL) + { + throw OrthancException(ErrorCode_NullPointer); + } + + const DicomInstanceToStore& instance = + reinterpret_cast<const IDicomInstance*>(p.instance)->GetInstance(); + + switch (service) + { + case _OrthancPluginService_GetInstanceFramesCount: + *p.targetUint32 = instance.GetParsedDicomFile().GetFramesCount(); + return; + + case _OrthancPluginService_GetInstanceRawFrame: + { + if (p.targetBuffer == NULL) + { + throw OrthancException(ErrorCode_NullPointer); + } + + p.targetBuffer->data = NULL; + p.targetBuffer->size = 0; + + MimeType mime; + std::string frame; + instance.GetParsedDicomFile().GetRawFrame(frame, mime, p.frameIndex); + CopyToMemoryBuffer(*p.targetBuffer, frame); + return; + } + + case _OrthancPluginService_GetInstanceDecodedFrame: + { + bool hasDecoderPlugin; + + { + boost::mutex::scoped_lock lock(pimpl_->decodeImageCallbackMutex_); + hasDecoderPlugin = !pimpl_->decodeImageCallbacks_.empty(); + } + + std::unique_ptr<ImageAccessor> decoded; + if (p.targetImage == NULL) + { + throw OrthancException(ErrorCode_NullPointer); + } + else if (hasDecoderPlugin) + { + // TODO - This call could be speeded up the future, if a + // "decoding context" gets introduced in the decoder plugins + + decoded.reset(Decode(instance.GetBufferData(), instance.GetBufferSize(), p.frameIndex)); + } + else + { + decoded.reset(DicomImageDecoder::Decode(instance.GetParsedDicomFile(), p.frameIndex)); + } + + *(p.targetImage) = ReturnImage(decoded); + return; + } + + default: + throw OrthancException(ErrorCode_InternalError); + } + } + + void OrthancPlugins::UncompressImage(const void* parameters) { const _OrthancPluginUncompressImage& p = *reinterpret_cast<const _OrthancPluginUncompressImage*>(parameters); @@ -3481,6 +3629,12 @@ AccessDicomInstance(service, parameters); return true; + case _OrthancPluginService_GetInstanceFramesCount: + case _OrthancPluginService_GetInstanceRawFrame: + case _OrthancPluginService_GetInstanceDecodedFrame: + AccessDicomInstance2(service, parameters); + return true; + case _OrthancPluginService_SetGlobalProperty: { const _OrthancPluginGlobalProperty& p = @@ -4027,6 +4181,37 @@ GetTagName(parameters); return true; + case _OrthancPluginService_CreateDicomInstance: + { + const _OrthancPluginCreateDicomInstance& p = + *reinterpret_cast<const _OrthancPluginCreateDicomInstance*>(parameters); + *(p.target) = reinterpret_cast<OrthancPluginDicomInstance*>( + new DicomInstanceFromBuffer(p.buffer, p.size)); + return true; + } + + case _OrthancPluginService_FreeDicomInstance: + { + const _OrthancPluginFreeDicomInstance& p = + *reinterpret_cast<const _OrthancPluginFreeDicomInstance*>(parameters); + + if (p.dicom != NULL) + { + IDicomInstance* obj = reinterpret_cast<IDicomInstance*>(p.dicom); + + if (obj->CanBeFreed()) + { + delete obj; + } + else + { + throw OrthancException(ErrorCode_Plugin, "Cannot free a DICOM instance provided to a callback"); + } + } + + return true; + } + default: return false; }