changeset 1827:4b6673e828f4

"OrthancPluginCreateImage()" and "OrthancPluginCreateImageAccessor()" to create images
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 25 Nov 2015 16:39:03 +0100
parents ac5b0b4e2434
children a71d74987090
files NEWS OrthancServer/IDicomImageDecoder.h OrthancServer/ParsedDicomFile.cpp Plugins/Engine/OrthancPlugins.cpp Plugins/Engine/OrthancPlugins.h Plugins/Include/orthanc/OrthancCPlugin.h
diffstat 6 files changed, 177 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Wed Nov 25 16:00:57 2015 +0100
+++ b/NEWS	Wed Nov 25 16:39:03 2015 +0100
@@ -44,6 +44,7 @@
   - "OrthancPluginRegisterDictionaryTag()" to declare custom DICOM tags
   - "OrthancPluginRestApiGet2()" to provide HTTP headers when calling Orthanc API
   - "OrthancPluginGetInstanceOrigin()" to know through which mechanism an instance was received
+  - "OrthancPluginCreateImage()" and "OrthancPluginCreateImageAccessor()" to create images
 * New events in change callbacks:
   - "OrthancStarted"
   - "OrthancStopped"
--- a/OrthancServer/IDicomImageDecoder.h	Wed Nov 25 16:00:57 2015 +0100
+++ b/OrthancServer/IDicomImageDecoder.h	Wed Nov 25 16:39:03 2015 +0100
@@ -32,7 +32,7 @@
 
 #pragma once
 
-#include "../Core/Images/ImageBuffer.h"
+#include "../Core/Images/ImageAccessor.h"
 
 #include <boost/noncopyable.hpp>
 
--- a/OrthancServer/ParsedDicomFile.cpp	Wed Nov 25 16:00:57 2015 +0100
+++ b/OrthancServer/ParsedDicomFile.cpp	Wed Nov 25 16:39:03 2015 +0100
@@ -86,7 +86,6 @@
 #include "ToDcmtkBridge.h"
 #include "Internals/DicomImageDecoder.h"
 #include "../Core/DicomFormat/DicomIntegerPixelAccessor.h"
-#include "../Core/Images/ImageBuffer.h"
 #include "../Core/Images/JpegWriter.h"
 #include "../Core/Images/JpegReader.h"
 #include "../Core/Images/PngReader.h"
--- a/Plugins/Engine/OrthancPlugins.cpp	Wed Nov 25 16:00:57 2015 +0100
+++ b/Plugins/Engine/OrthancPlugins.cpp	Wed Nov 25 16:39:03 2015 +0100
@@ -430,7 +430,7 @@
         sizeof(int32_t) != sizeof(OrthancPluginValueRepresentation) ||
         sizeof(int32_t) != sizeof(OrthancPluginDicomToJsonFlags) ||
         sizeof(int32_t) != sizeof(OrthancPluginDicomToJsonFormat) ||
-        sizeof(int32_t) != sizeof(OrthancPluginDicomFromJsonFlags) ||
+        sizeof(int32_t) != sizeof(OrthancPluginCreateDicomFlags) ||
         sizeof(int32_t) != sizeof(_OrthancPluginDatabaseAnswerType) ||
         sizeof(int32_t) != sizeof(OrthancPluginIdentifierConstraint) ||
         sizeof(int32_t) != sizeof(OrthancPluginInstanceOrigin) ||
@@ -440,8 +440,8 @@
         static_cast<int>(OrthancPluginDicomToJsonFlags_IncludePixelData) != static_cast<int>(DicomToJsonFlags_IncludePixelData) ||
         static_cast<int>(OrthancPluginDicomToJsonFlags_ConvertBinaryToNull) != static_cast<int>(DicomToJsonFlags_ConvertBinaryToNull) ||
         static_cast<int>(OrthancPluginDicomToJsonFlags_ConvertBinaryToAscii) != static_cast<int>(DicomToJsonFlags_ConvertBinaryToAscii) ||
-        static_cast<int>(OrthancPluginDicomFromJsonFlags_DecodeDataUriScheme) != static_cast<int>(DicomFromJsonFlags_DecodeDataUriScheme) ||
-        static_cast<int>(OrthancPluginDicomFromJsonFlags_GenerateIdentifiers) != static_cast<int>(DicomFromJsonFlags_GenerateIdentifiers))
+        static_cast<int>(OrthancPluginCreateDicomFlags_DecodeDataUriScheme) != static_cast<int>(DicomFromJsonFlags_DecodeDataUriScheme) ||
+        static_cast<int>(OrthancPluginCreateDicomFlags_GenerateIdentifiers) != static_cast<int>(DicomFromJsonFlags_GenerateIdentifiers))
 
     {
       throw OrthancException(ErrorCode_Plugin);
@@ -1449,11 +1449,11 @@
   }
         
 
-  void OrthancPlugins::ApplyDicomFromJson(_OrthancPluginService service,
-                                          const void* parameters)
+  void OrthancPlugins::ApplyCreateDicom(_OrthancPluginService service,
+                                        const void* parameters)
   {
-    const _OrthancPluginDicomFromJson& p =
-      *reinterpret_cast<const _OrthancPluginDicomFromJson*>(parameters);
+    const _OrthancPluginCreateDicom& p =
+      *reinterpret_cast<const _OrthancPluginCreateDicom*>(parameters);
 
     Json::Value json;
     Json::Reader reader;
@@ -1467,11 +1467,39 @@
     {
       std::auto_ptr<ParsedDicomFile> file
         (ParsedDicomFile::CreateFromJson(json, static_cast<DicomFromJsonFlags>(p.flags)));
+
+      if (p.pixelData)
+      {
+        file->EmbedImage(*reinterpret_cast<const ImageAccessor*>(p.pixelData));
+      }
+
       file->SaveToMemoryBuffer(dicom);
     }
 
     CopyToMemoryBuffer(*p.target, dicom);
   }
+
+
+  void OrthancPlugins::ApplyCreateImage(_OrthancPluginService service,
+                                        const void* parameters)
+  {
+    const _OrthancPluginCreateImage& p =
+      *reinterpret_cast<const _OrthancPluginCreateImage*>(parameters);
+
+    std::auto_ptr<ImageAccessor> result;
+
+    if (service == _OrthancPluginService_CreateImage)
+    {
+      result.reset(new Image(Plugins::Convert(p.format), p.width, p.height));
+    }
+    else
+    {
+      result.reset(new ImageAccessor);
+      result->AssignWritable(Plugins::Convert(p.format), p.width, p.height, p.pitch, p.buffer);
+    }
+
+    *(p.target) = reinterpret_cast<OrthancPluginImage*>(result.release());
+  }
         
 
   void OrthancPlugins::DatabaseAnswer(const void* parameters)
@@ -2003,8 +2031,8 @@
         ApplyDicomToJson(service, parameters);
         return true;
 
-      case _OrthancPluginService_DicomFromJson:
-        ApplyDicomFromJson(service, parameters);
+      case _OrthancPluginService_CreateDicom:
+        ApplyCreateDicom(service, parameters);
         return true;
 
       case _OrthancPluginService_WorklistAddAnswer:
@@ -2039,6 +2067,11 @@
         return true;
       }
 
+      case _OrthancPluginService_CreateImage:
+      case _OrthancPluginService_CreateImageAccessor:
+        ApplyCreateImage(service, parameters);
+        return true;
+
       default:
       {
         // This service is unknown to the Orthanc plugin engine
--- a/Plugins/Engine/OrthancPlugins.h	Wed Nov 25 16:00:57 2015 +0100
+++ b/Plugins/Engine/OrthancPlugins.h	Wed Nov 25 16:39:03 2015 +0100
@@ -144,8 +144,11 @@
     void ApplyDicomToJson(_OrthancPluginService service,
                           const void* parameters);
 
-    void ApplyDicomFromJson(_OrthancPluginService service,
-                            const void* parameters);
+    void ApplyCreateDicom(_OrthancPluginService service,
+                          const void* parameters);
+
+    void ApplyCreateImage(_OrthancPluginService service,
+                          const void* parameters);
 
     void SignalChangeInternal(OrthancPluginChangeType changeType,
                               OrthancPluginResourceType resourceType,
--- a/Plugins/Include/orthanc/OrthancCPlugin.h	Wed Nov 25 16:00:57 2015 +0100
+++ b/Plugins/Include/orthanc/OrthancCPlugin.h	Wed Nov 25 16:39:03 2015 +0100
@@ -397,7 +397,7 @@
     _OrthancPluginService_RegisterDictionaryTag = 20,
     _OrthancPluginService_DicomBufferToJson = 21,
     _OrthancPluginService_DicomInstanceToJson = 22,
-    _OrthancPluginService_DicomFromJson = 23,
+    _OrthancPluginService_CreateDicom = 23,
 
     /* Registration of callbacks */
     _OrthancPluginService_RegisterRestCallback = 1000,
@@ -471,6 +471,8 @@
     _OrthancPluginService_GetFontsCount = 6009,
     _OrthancPluginService_GetFontInfo = 6010,
     _OrthancPluginService_DrawText = 6011,
+    _OrthancPluginService_CreateImage = 6012,
+    _OrthancPluginService_CreateImageAccessor = 6013,
 
     /* Primitives for handling worklists */
     _OrthancPluginService_WorklistAddAnswer = 7000,
@@ -670,6 +672,7 @@
   /**
    * The possible output formats for a DICOM-to-JSON conversion.
    * @ingroup Toolbox
+   * @see OrthancPluginDicomToJson()
    **/
   typedef enum
   {
@@ -700,16 +703,17 @@
 
 
   /**
-   * Flags to customize a JSON-to-DICOM conversion.
+   * Flags to the creation of a DICOM file.
    * @ingroup Toolbox
+   * @see OrthancPluginCreateDicom()
    **/
   typedef enum
   {
-    OrthancPluginDicomFromJsonFlags_DecodeDataUriScheme   = (1 << 0),  /*!< Decode fields encoded using data URI scheme */
-    OrthancPluginDicomFromJsonFlags_GenerateIdentifiers   = (1 << 1),  /*!< Automatically generate DICOM identifiers */
-
-    _OrthancPluginDicomFromJsonFlags_INTERNAL = 0x7fffffff
-  } OrthancPluginDicomFromJsonFlags;
+    OrthancPluginCreateDicomFlags_DecodeDataUriScheme   = (1 << 0),  /*!< Decode fields encoded using data URI scheme */
+    OrthancPluginCreateDicomFlags_GenerateIdentifiers   = (1 << 1),  /*!< Automatically generate DICOM identifiers */
+
+    _OrthancPluginCreateDicomFlags_INTERNAL = 0x7fffffff
+  } OrthancPluginCreateDicomFlags;
 
 
   /**
@@ -1005,7 +1009,7 @@
         sizeof(int32_t) != sizeof(OrthancPluginValueRepresentation) ||
         sizeof(int32_t) != sizeof(OrthancPluginDicomToJsonFormat) ||
         sizeof(int32_t) != sizeof(OrthancPluginDicomToJsonFlags) ||
-        sizeof(int32_t) != sizeof(OrthancPluginDicomFromJsonFlags) ||
+        sizeof(int32_t) != sizeof(OrthancPluginCreateDicomFlags) ||
         sizeof(int32_t) != sizeof(OrthancPluginIdentifierConstraint) ||
         sizeof(int32_t) != sizeof(OrthancPluginInstanceOrigin))
     {
@@ -4330,39 +4334,44 @@
 
   typedef struct
   {
-    OrthancPluginMemoryBuffer*       target;
-    const char*                      json;
-    OrthancPluginDicomFromJsonFlags  flags;
-  } _OrthancPluginDicomFromJson;
+    OrthancPluginMemoryBuffer*     target;
+    const char*                    json;
+    const OrthancPluginImage*      pixelData;
+    OrthancPluginCreateDicomFlags  flags;
+  } _OrthancPluginCreateDicom;
 
   /**
-   * @brief Create a DICOM instance from JSON.
+   * @brief Create a DICOM instance from a JSON string and an image.
    *
    * This function takes as input a string containing a JSON file
    * describing the content of a DICOM instance. As an output, it
    * writes the corresponding DICOM instance to a newly allocated
-   * memory buffer.
+   * memory buffer. Additionally, an image to be encoded within the
+   * DICOM instance can also be provided.
    *
    * @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
    * @param target The target memory buffer. It must be freed with OrthancPluginFreeMemoryBuffer().
    * @param json The input JSON file.
+   * @param pixelData The image. Can be NULL, if the pixel data is encoded inside the JSON with the data URI scheme.
    * @param flags Flags governing the output.
    * @return 0 if success, other value if error.
    * @ingroup Toolbox
    * @see OrthancPluginDicomBufferToJson
    **/
-  ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginDicomFromJson(
-    OrthancPluginContext*            context,
-    OrthancPluginMemoryBuffer*       target,
-    const char*                      json,
-    OrthancPluginDicomFromJsonFlags  flags)
+  ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginCreateDicom(
+    OrthancPluginContext*          context,
+    OrthancPluginMemoryBuffer*     target,
+    const char*                    json,
+    const OrthancPluginImage*      pixelData,
+    OrthancPluginCreateDicomFlags  flags)
   {
-    _OrthancPluginDicomFromJson params;
+    _OrthancPluginCreateDicom params;
     params.target = target;
     params.json = json;
+    params.pixelData = pixelData;
     params.flags = flags;
 
-    return context->InvokeService(context, _OrthancPluginService_DicomFromJson, &params);
+    return context->InvokeService(context, _OrthancPluginService_CreateDicom, &params);
   }
 
 
@@ -4391,6 +4400,104 @@
     context->InvokeService(context, _OrthancPluginService_RegisterDecodeImageCallback, &params);
   }
   
+
+
+  typedef struct
+  {
+    OrthancPluginImage**       target;
+    OrthancPluginPixelFormat   format;
+    uint32_t                   width;
+    uint32_t                   height;
+    uint32_t                   pitch;
+    void*                      buffer;
+  } _OrthancPluginCreateImage;
+
+
+  /**
+   * @brief Create an image.
+   *
+   * This function creates an image of given size and format.
+   *
+   * @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
+   * @param format The format of the pixels.
+   * @param width The width of the image.
+   * @param height The height of the image.
+   * @return The newly allocated image. It must be freed with OrthancPluginFreeImage().
+   * @ingroup Images
+   **/
+  ORTHANC_PLUGIN_INLINE OrthancPluginImage* OrthancPluginCreateImage(
+    OrthancPluginContext*     context,
+    OrthancPluginPixelFormat  format,
+    uint32_t                  width,
+    uint32_t                  height)
+  {
+    OrthancPluginImage* target = NULL;
+
+    _OrthancPluginCreateImage params;
+    memset(&params, 0, sizeof(params));
+    params.target = &target;
+    params.format = format;
+    params.width = width;
+    params.height = height;
+
+    if (context->InvokeService(context, _OrthancPluginService_CreateImage, &params) != OrthancPluginErrorCode_Success)
+    {
+      return NULL;
+    }
+    else
+    {
+      return target;
+    }
+  }
+
+
+  /**
+   * @brief Create an image pointing to a memory buffer.
+   *
+   * This function creates an image whose content points to a memory
+   * buffer managed by the plugin. Note that the buffer is directly
+   * accessed, no memory is allocated and no data is copied.
+   *
+   * @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
+   * @param format The format of the pixels.
+   * @param width The width of the image.
+   * @param height The height of the image.
+   * @param pitch The pitch of the image (i.e. the number of bytes
+   * between 2 successive lines of the image in the memory buffer).
+   * @param buffer The memory buffer.
+   * @return The newly allocated image. It must be freed with OrthancPluginFreeImage().
+   * @ingroup Images
+   **/
+  ORTHANC_PLUGIN_INLINE OrthancPluginImage* OrthancPluginCreateImageAccessor(
+    OrthancPluginContext*     context,
+    OrthancPluginPixelFormat  format,
+    uint32_t                  width,
+    uint32_t                  height,
+    uint32_t                  pitch,
+    void*                     buffer)
+  {
+    OrthancPluginImage* target = NULL;
+
+    _OrthancPluginCreateImage params;
+    memset(&params, 0, sizeof(params));
+    params.target = &target;
+    params.format = format;
+    params.width = width;
+    params.height = height;
+    params.pitch = pitch;
+    params.buffer = buffer;
+
+    if (context->InvokeService(context, _OrthancPluginService_CreateImageAccessor, &params) != OrthancPluginErrorCode_Success)
+    {
+      return NULL;
+    }
+    else
+    {
+      return target;
+    }
+  }
+
+
 #ifdef  __cplusplus
 }
 #endif