# HG changeset patch # User Sebastien Jodogne # Date 1589279907 -7200 # Node ID 6f11b3233a066d4057f8dc7c95587463b4ba1d91 # Parent 04fb907dfc8568401befbf576643e05905210bc5 OrthancPluginTranscodeDicomInstance() and OrthancPluginSerializeDicomInstance() diff -r 04fb907dfc85 -r 6f11b3233a06 NEWS --- a/NEWS Mon May 11 21:12:40 2020 +0200 +++ b/NEWS Tue May 12 12:38:27 2020 +0200 @@ -26,6 +26,8 @@ - OrthancPluginGetInstanceFramesCount() - OrthancPluginGetInstanceRawFrame() - OrthancPluginGetInstanceDecodedFrame() + - OrthancPluginTranscodeDicomInstance() + - OrthancPluginSerializeDicomInstance() * "OrthancPluginDicomInstance" structure wrapped in "OrthancPluginCppWrapper.h" Maintenance diff -r 04fb907dfc85 -r 6f11b3233a06 Plugins/Engine/OrthancPlugins.cpp --- a/Plugins/Engine/OrthancPlugins.cpp Mon May 11 21:12:40 2020 +0200 +++ b/Plugins/Engine/OrthancPlugins.cpp Tue May 12 12:38:27 2020 +0200 @@ -1824,6 +1824,32 @@ }; + class OrthancPlugins::DicomInstanceFromTranscoded : public IDicomInstance + { + private: + std::unique_ptr parsed_; + DicomInstanceToStore instance_; + + public: + DicomInstanceFromTranscoded(IDicomTranscoder::TranscodedDicom& transcoded) : + parsed_(ParsedDicomFile::AcquireDcmtkObject(transcoded.ReleaseDicom())) + { + instance_.SetParsedDicomFile(*parsed_); + 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, const DicomInstanceToStore& instance, const Json::Value& simplifiedTags) @@ -2748,6 +2774,22 @@ return; } + case _OrthancPluginService_SerializeDicomInstance: + { + if (p.targetBuffer == NULL) + { + throw OrthancException(ErrorCode_NullPointer); + } + + p.targetBuffer->data = NULL; + p.targetBuffer->size = 0; + + std::string serialized; + instance.GetParsedDicomFile().SaveToMemoryBuffer(serialized); + CopyToMemoryBuffer(*p.targetBuffer, serialized); + return; + } + default: throw OrthancException(ErrorCode_InternalError); } @@ -3632,6 +3674,7 @@ case _OrthancPluginService_GetInstanceFramesCount: case _OrthancPluginService_GetInstanceRawFrame: case _OrthancPluginService_GetInstanceDecodedFrame: + case _OrthancPluginService_SerializeDicomInstance: AccessDicomInstance2(service, parameters); return true; @@ -4212,6 +4255,47 @@ return true; } + case _OrthancPluginService_TranscodeDicomInstance: + { + const _OrthancPluginCreateDicomInstance& p = + *reinterpret_cast(parameters); + + DicomTransferSyntax transferSyntax; + if (p.transferSyntax == NULL || + !LookupTransferSyntax(transferSyntax, p.transferSyntax)) + { + throw OrthancException(ErrorCode_ParameterOutOfRange, "Unsupported transfer syntax: " + + std::string(p.transferSyntax == NULL ? "(null)" : p.transferSyntax)); + } + else + { + ParsedDicomFile dicom(p.buffer, p.size); + + std::set syntaxes; + syntaxes.insert(transferSyntax); + + std::unique_ptr transcoded; + + { + PImpl::ServerContextLock lock(*pimpl_); + transcoded.reset(lock.GetContext().GetTranscoder().TranscodeToParsed( + dicom.GetDcmtkObject(), p.buffer, p.size, + syntaxes, true /* allow new sop */)); + } + + if (transcoded.get() == NULL) + { + throw OrthancException(ErrorCode_NotImplemented, "Cannot transcode image"); + } + else + { + *(p.target) = reinterpret_cast( + new DicomInstanceFromTranscoded(*transcoded)); + return true; + } + } + } + default: return false; } diff -r 04fb907dfc85 -r 6f11b3233a06 Plugins/Engine/OrthancPlugins.h --- a/Plugins/Engine/OrthancPlugins.h Mon May 11 21:12:40 2020 +0200 +++ b/Plugins/Engine/OrthancPlugins.h Tue May 12 12:38:27 2020 +0200 @@ -99,6 +99,7 @@ class IDicomInstance; class DicomInstanceFromCallback; class DicomInstanceFromBuffer; + class DicomInstanceFromTranscoded; void RegisterRestCallback(const void* parameters, bool lock); diff -r 04fb907dfc85 -r 6f11b3233a06 Plugins/Include/orthanc/OrthancCPlugin.h --- a/Plugins/Include/orthanc/OrthancCPlugin.h Mon May 11 21:12:40 2020 +0200 +++ b/Plugins/Include/orthanc/OrthancCPlugin.h Tue May 12 12:38:27 2020 +0200 @@ -507,6 +507,8 @@ _OrthancPluginService_GetInstanceFramesCount = 4012, /* New in Orthanc 1.7.0 */ _OrthancPluginService_GetInstanceRawFrame = 4013, /* New in Orthanc 1.7.0 */ _OrthancPluginService_GetInstanceDecodedFrame = 4014, /* New in Orthanc 1.7.0 */ + _OrthancPluginService_TranscodeDicomInstance = 4015, /* New in Orthanc 1.7.0 */ + _OrthancPluginService_SerializeDicomInstance = 4016, /* New in Orthanc 1.7.0 */ /* Services for plugins implementing a database back-end */ _OrthancPluginService_RegisterDatabaseBackend = 5000, @@ -7552,6 +7554,7 @@ OrthancPluginDicomInstance** target; const void* buffer; uint32_t size; + const char* transferSyntax; } _OrthancPluginCreateDicomInstance; ORTHANC_PLUGIN_INLINE OrthancPluginDicomInstance* OrthancPluginCreateDicomInstance( @@ -7662,6 +7665,44 @@ } } + ORTHANC_PLUGIN_INLINE OrthancPluginDicomInstance* OrthancPluginTranscodeDicomInstance( + OrthancPluginContext* context, + const void* buffer, + uint32_t size, + const char* transferSyntax) + { + OrthancPluginDicomInstance* target = NULL; + + _OrthancPluginCreateDicomInstance params; + params.target = ⌖ + params.buffer = buffer; + params.size = size; + params.transferSyntax = transferSyntax; + + if (context->InvokeService(context, _OrthancPluginService_TranscodeDicomInstance, ¶ms) != OrthancPluginErrorCode_Success) + { + /* Error */ + return NULL; + } + else + { + return target; + } + } + + ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginSerializeDicomInstance( + OrthancPluginContext* context, + OrthancPluginMemoryBuffer* target, + const OrthancPluginDicomInstance* instance) + { + _OrthancPluginAccessDicomInstance2 params; + memset(¶ms, 0, sizeof(params)); + params.targetBuffer = target; + params.instance = instance; + + return context->InvokeService(context, _OrthancPluginService_SerializeDicomInstance, ¶ms); + } + #ifdef __cplusplus } #endif diff -r 04fb907dfc85 -r 6f11b3233a06 Plugins/Samples/Common/OrthancPluginCppWrapper.cpp --- a/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp Mon May 11 21:12:40 2020 +0200 +++ b/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp Tue May 12 12:38:27 2020 +0200 @@ -3297,11 +3297,15 @@ void DicomInstance::GetRawFrame(std::string& target, unsigned int frameIndex) const { - OrthancPluginMemoryBuffer buffer; + MemoryBuffer buffer; OrthancPluginErrorCode code = OrthancPluginGetInstanceRawFrame( - GetGlobalContext(), &buffer, instance_, frameIndex); - - if (code != OrthancPluginErrorCode_Success) + GetGlobalContext(), *buffer, instance_, frameIndex); + + if (code == OrthancPluginErrorCode_Success) + { + buffer.ToString(target); + } + else { ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(code); } @@ -3309,7 +3313,6 @@ #endif - #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 7, 0) OrthancImage* DicomInstance::GetDecodedFrame(unsigned int frameIndex) const { @@ -3326,4 +3329,43 @@ } } #endif + + +#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 7, 0) + void DicomInstance::Serialize(std::string& target) const + { + MemoryBuffer buffer; + OrthancPluginErrorCode code = OrthancPluginSerializeDicomInstance( + GetGlobalContext(), *buffer, instance_); + + if (code == OrthancPluginErrorCode_Success) + { + buffer.ToString(target); + } + else + { + ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(code); + } + } +#endif + + +#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 7, 0) + DicomInstance* DicomInstance::Transcode(const void* buffer, + size_t size, + const std::string& transferSyntax) + { + OrthancPluginDicomInstance* instance = OrthancPluginTranscodeDicomInstance( + GetGlobalContext(), buffer, size, transferSyntax.c_str()); + + if (instance == NULL) + { + ORTHANC_PLUGINS_THROW_EXCEPTION(Plugin); + } + else + { + return new DicomInstance(instance); + } + } +#endif } diff -r 04fb907dfc85 -r 6f11b3233a06 Plugins/Samples/Common/OrthancPluginCppWrapper.h --- a/Plugins/Samples/Common/OrthancPluginCppWrapper.h Mon May 11 21:12:40 2020 +0200 +++ b/Plugins/Samples/Common/OrthancPluginCppWrapper.h Tue May 12 12:38:27 2020 +0200 @@ -1209,5 +1209,15 @@ #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 7, 0) OrthancImage* GetDecodedFrame(unsigned int frameIndex) const; #endif + +#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 7, 0) + void Serialize(std::string& target) const; +#endif + +#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 7, 0) + static DicomInstance* Transcode(const void* buffer, + size_t size, + const std::string& transferSyntax); +#endif }; }