changeset 3919:6f11b3233a06 transcoding

OrthancPluginTranscodeDicomInstance() and OrthancPluginSerializeDicomInstance()
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 12 May 2020 12:38:27 +0200
parents 04fb907dfc85
children 82e88ff003d7 f6ccff28fbed
files NEWS Plugins/Engine/OrthancPlugins.cpp Plugins/Engine/OrthancPlugins.h Plugins/Include/orthanc/OrthancCPlugin.h Plugins/Samples/Common/OrthancPluginCppWrapper.cpp Plugins/Samples/Common/OrthancPluginCppWrapper.h
diffstat 6 files changed, 185 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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<ParsedDicomFile>  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<const _OrthancPluginCreateDicomInstance*>(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<DicomTransferSyntax> syntaxes;
+          syntaxes.insert(transferSyntax);
+          
+          std::unique_ptr<IDicomTranscoder::TranscodedDicom> 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<OrthancPluginDicomInstance*>(
+              new DicomInstanceFromTranscoded(*transcoded));
+            return true;
+          }
+        }
+      }
+        
       default:
         return false;
     }
--- 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);
--- 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 = &target;
+    params.buffer = buffer;
+    params.size = size;
+    params.transferSyntax = transferSyntax;
+
+    if (context->InvokeService(context, _OrthancPluginService_TranscodeDicomInstance, &params) != OrthancPluginErrorCode_Success)
+    {
+      /* Error */
+      return NULL;
+    }
+    else
+    {
+      return target;
+    }
+  }
+
+  ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginSerializeDicomInstance(
+    OrthancPluginContext*             context,
+    OrthancPluginMemoryBuffer*        target,
+    const OrthancPluginDicomInstance* instance)
+  {
+    _OrthancPluginAccessDicomInstance2 params;
+    memset(&params, 0, sizeof(params));
+    params.targetBuffer = target;
+    params.instance = instance;
+
+    return context->InvokeService(context, _OrthancPluginService_SerializeDicomInstance, &params);
+  }
+
 #ifdef  __cplusplus
 }
 #endif
--- 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
 }
--- 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
   };
 }