changeset 904:2732b5f57d9c plugins

sample to forward dicom data
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 18 Jun 2014 16:07:47 +0200
parents 06b9a30f1e6d
children 89e3cc078df0
files OrthancServer/main.cpp Plugins/Engine/PluginsHttpHandler.cpp Plugins/Engine/PluginsHttpHandler.h Plugins/Engine/PluginsManager.cpp Plugins/OrthancCPlugin/OrthancCPlugin.h Plugins/Samples/Basic/Plugin.c
diffstat 6 files changed, 153 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancServer/main.cpp	Wed Jun 18 15:26:35 2014 +0200
+++ b/OrthancServer/main.cpp	Wed Jun 18 16:07:47 2014 +0200
@@ -374,7 +374,7 @@
 
     LoadLuaScripts(context);
 
-    PluginsHttpHandler httpPlugins;
+    PluginsHttpHandler httpPlugins(context);
 
     PluginsManager pluginsManager;
     pluginsManager.RegisterServiceProvider(httpPlugins);
--- a/Plugins/Engine/PluginsHttpHandler.cpp	Wed Jun 18 15:26:35 2014 +0200
+++ b/Plugins/Engine/PluginsHttpHandler.cpp	Wed Jun 18 16:07:47 2014 +0200
@@ -47,13 +47,18 @@
     typedef std::pair<boost::regex*, OrthancPluginRestCallback> Callback;
     typedef std::list<Callback>  Callbacks;
 
+    ServerContext& context_;
     Callbacks callbacks_;
+
+    PImpl(ServerContext& context) : context_(context)
+    {
+    }
   };
 
 
-  PluginsHttpHandler::PluginsHttpHandler()
+  PluginsHttpHandler::PluginsHttpHandler(ServerContext& context)
   {
-    pimpl_.reset(new PImpl);
+    pimpl_.reset(new PImpl(context));
   }
 
   
@@ -151,8 +156,8 @@
     }
 
 
-    request.groupValues = (cgroups.size() ? &cgroups[0] : NULL);
-    request.groupCount = cgroups.size();
+    request.groups = (cgroups.size() ? &cgroups[0] : NULL);
+    request.groupsCount = cgroups.size();
     request.getCount = getArguments.size();
     request.body = (postData.size() ? &postData[0] : NULL);
     request.bodySize = postData.size();
@@ -192,8 +197,8 @@
     {
       case OrthancPluginService_RegisterRestCallback:
       {
-        const _OrthancPluginRestCallbackParams& p = 
-          *reinterpret_cast<const _OrthancPluginRestCallbackParams*>(parameters);
+        const _OrthancPluginRestCallback& p = 
+          *reinterpret_cast<const _OrthancPluginRestCallback*>(parameters);
 
         LOG(INFO) << "Plugin has registered a REST callback on: " << p.pathRegularExpression;
         pimpl_->callbacks_.push_back(std::make_pair(new boost::regex(p.pathRegularExpression), p.callback));
@@ -203,8 +208,8 @@
 
       case OrthancPluginService_AnswerBuffer:
       {
-        const _OrthancPluginAnswerBufferParams& p = 
-          *reinterpret_cast<const _OrthancPluginAnswerBufferParams*>(parameters);
+        const _OrthancPluginAnswerBuffer& p = 
+          *reinterpret_cast<const _OrthancPluginAnswerBuffer*>(parameters);
 
         HttpOutput* translatedOutput = reinterpret_cast<HttpOutput*>(p.output);
         translatedOutput->AnswerBufferWithContentType(p.answer, p.answerSize, p.mimeType);
@@ -214,8 +219,8 @@
 
       case OrthancPluginService_CompressAndAnswerPngImage:
       {
-        const _OrthancPluginCompressAndAnswerPngImageParams& p = 
-          *reinterpret_cast<const _OrthancPluginCompressAndAnswerPngImageParams*>(parameters);
+        const _OrthancPluginCompressAndAnswerPngImage& p = 
+          *reinterpret_cast<const _OrthancPluginCompressAndAnswerPngImage*>(parameters);
 
         HttpOutput* translatedOutput = reinterpret_cast<HttpOutput*>(p.output);
 
@@ -258,6 +263,36 @@
         return true;
       }
 
+      case OrthancPluginService_GetDicomForInstance:
+      {
+        const _OrthancPluginGetDicomForInstance& p = 
+          *reinterpret_cast<const _OrthancPluginGetDicomForInstance*>(parameters);
+
+        std::string dicom;
+        pimpl_->context_.ReadFile(dicom, p.instanceId, FileContentType_Dicom);
+
+        p.target->size = dicom.size();
+
+        if (dicom.size() == 0)
+        {
+          p.target->data = NULL;
+        }
+        else
+        {
+          p.target->data = malloc(dicom.size());
+          if (p.target->data != NULL)
+          {
+            memcpy(p.target->data, &dicom[0], dicom.size());
+          }
+          else
+          {
+            return false;
+          }
+        }
+
+        return true;
+      }
+
       default:
         return false;
     }
--- a/Plugins/Engine/PluginsHttpHandler.h	Wed Jun 18 15:26:35 2014 +0200
+++ b/Plugins/Engine/PluginsHttpHandler.h	Wed Jun 18 16:07:47 2014 +0200
@@ -34,6 +34,7 @@
 
 #include "PluginsManager.h"
 #include "../../Core/HttpServer/HttpHandler.h"
+#include "../../OrthancServer/ServerContext.h"
 
 #include <list>
 #include <boost/shared_ptr.hpp>
@@ -48,7 +49,7 @@
     boost::shared_ptr<PImpl> pimpl_;
 
   public:
-    PluginsHttpHandler();
+    PluginsHttpHandler(ServerContext& context);
 
     virtual ~PluginsHttpHandler();
 
--- a/Plugins/Engine/PluginsManager.cpp	Wed Jun 18 15:26:35 2014 +0200
+++ b/Plugins/Engine/PluginsManager.cpp	Wed Jun 18 16:07:47 2014 +0200
@@ -193,7 +193,7 @@
     memset(&context_, 0, sizeof(context_));
     context_.pluginsManager = this;
     context_.orthancVersion = ORTHANC_VERSION;
-    context_.FreeBuffer = ::free;
+    context_.Free = ::free;
     context_.InvokeService = InvokeService;
   }
 
--- a/Plugins/OrthancCPlugin/OrthancCPlugin.h	Wed Jun 18 15:26:35 2014 +0200
+++ b/Plugins/OrthancCPlugin/OrthancCPlugin.h	Wed Jun 18 16:07:47 2014 +0200
@@ -124,8 +124,8 @@
     OrthancPluginHttpMethod method;
 
     /* Groups of the regular expression */
-    const char* const*      groupValues;
-    uint32_t                groupCount;
+    const char* const*      groups;
+    uint32_t                groupsCount;
 
     /* For GET requests */
     const char* const*      getKeys;
@@ -149,7 +149,10 @@
 
     /* Sending answers to REST calls */
     OrthancPluginService_AnswerBuffer = 2000,
-    OrthancPluginService_CompressAndAnswerPngImage = 2001
+    OrthancPluginService_CompressAndAnswerPngImage = 2001,
+
+    /* Access to the Orthanc database */
+    OrthancPluginService_GetDicomForInstance = 3000
   } OrthancPluginService;
 
 
@@ -201,6 +204,15 @@
   } OrthancPluginPixelFormat;
 
 
+  typedef struct
+  {
+    void*      data;
+    uint32_t   size;
+  } OrthancPluginMemoryBuffer;
+
+
+
+
   typedef struct _OrthancPluginRestOutput_t OrthancPluginRestOutput;
 
   typedef int32_t (*OrthancPluginRestCallback) (
@@ -212,13 +224,29 @@
   {
     void*        pluginsManager;
     const char*  orthancVersion;
-    void       (*FreeBuffer) (void* buffer);
+    void       (*Free) (void* buffer);
     int32_t    (*InvokeService) (struct _OrthancPluginContext_t* context,
                                  OrthancPluginService service,
                                  const void* params);
   } OrthancPluginContext;
 
 
+  ORTHANC_PLUGIN_INLINE void  OrthancPluginFreeString(
+    OrthancPluginContext* context, 
+    char* str)
+  {
+    context->Free(str);
+  }
+
+
+  ORTHANC_PLUGIN_INLINE void  OrthancPluginFreeMemoryBuffer(
+    OrthancPluginContext* context, 
+    OrthancPluginMemoryBuffer* buffer)
+  {
+    context->Free(buffer->data);
+  }
+
+
   ORTHANC_PLUGIN_INLINE void OrthancPluginLogError(
     OrthancPluginContext* context,
     const char* str)
@@ -247,7 +275,7 @@
   {
     const char* pathRegularExpression;
     OrthancPluginRestCallback callback;
-  } _OrthancPluginRestCallbackParams;
+  } _OrthancPluginRestCallback;
 
 
   ORTHANC_PLUGIN_INLINE void OrthancPluginRegisterRestCallback(
@@ -255,7 +283,7 @@
     const char*               pathRegularExpression,
     OrthancPluginRestCallback callback)
   {
-    _OrthancPluginRestCallbackParams params;
+    _OrthancPluginRestCallback params;
     params.pathRegularExpression = pathRegularExpression;
     params.callback = callback;
     context->InvokeService(context, OrthancPluginService_RegisterRestCallback, &params);
@@ -268,7 +296,7 @@
     const char*              answer;
     uint32_t                 answerSize;
     const char*              mimeType;
-  } _OrthancPluginAnswerBufferParams;
+  } _OrthancPluginAnswerBuffer;
 
   ORTHANC_PLUGIN_INLINE void OrthancPluginAnswerBuffer(
     OrthancPluginContext*    context,
@@ -277,7 +305,7 @@
     uint32_t                 answerSize,
     const char*              mimeType)
   {
-    _OrthancPluginAnswerBufferParams params;
+    _OrthancPluginAnswerBuffer params;
     params.output = output;
     params.answer = answer;
     params.answerSize = answerSize;
@@ -294,7 +322,7 @@
     uint32_t                  height;
     uint32_t                  pitch;
     const void*               buffer;
-  } _OrthancPluginCompressAndAnswerPngImageParams;
+  } _OrthancPluginCompressAndAnswerPngImage;
 
   ORTHANC_PLUGIN_INLINE void OrthancPluginCompressAndAnswerPngImage(
     OrthancPluginContext*     context,
@@ -305,7 +333,7 @@
     uint32_t                  pitch,
     const void*               buffer)
   {
-    _OrthancPluginCompressAndAnswerPngImageParams params;
+    _OrthancPluginCompressAndAnswerPngImage params;
     params.output = output;
     params.format = format;
     params.width = width;
@@ -316,6 +344,23 @@
   }
 
 
+  typedef struct
+  {
+    OrthancPluginMemoryBuffer*  target;
+    const char*                 instanceId;
+  } _OrthancPluginGetDicomForInstance;
+
+  ORTHANC_PLUGIN_INLINE int  OrthancPluginGetDicomForInstance(
+    OrthancPluginContext*       context,
+    OrthancPluginMemoryBuffer*  target,
+    const char*                 instanceId)
+  {
+    _OrthancPluginGetDicomForInstance params;
+    params.target = target;
+    params.instanceId = instanceId;
+    return context->InvokeService(context, OrthancPluginService_GetDicomForInstance, &params);
+  }
+
 
   /**
      Each plugin must define 4 functions, whose signature are:
--- a/Plugins/Samples/Basic/Plugin.c	Wed Jun 18 15:26:35 2014 +0200
+++ b/Plugins/Samples/Basic/Plugin.c	Wed Jun 18 16:07:47 2014 +0200
@@ -51,10 +51,10 @@
     OrthancPluginLogInfo(context, buffer);    
   }
 
-  printf("** %d\n", request->groupCount);
-  for (i = 0; i < request->groupCount; i++)
+  printf("** %d\n", request->groupsCount);
+  for (i = 0; i < request->groupsCount; i++)
   {
-    printf("** [%s]\n",  request->groupValues[i]);
+    printf("** [%s]\n",  request->groups[i]);
   }
 
   return 1;
@@ -65,9 +65,7 @@
                                       const char* url,
                                       const OrthancPluginHttpRequest* request)
 {
-  /**
-   * Answer with a sample 16bpp image.
-   **/
+  /* Answer with a sample 16bpp image. */
 
   uint16_t buffer[256 * 256];
   uint32_t x, y, value;
@@ -87,6 +85,48 @@
 }
 
 
+ORTHANC_PLUGINS_API int32_t Callback3(OrthancPluginRestOutput* output,
+                                      const char* url,
+                                      const OrthancPluginHttpRequest* request)
+{
+  OrthancPluginMemoryBuffer dicom;
+  if (!OrthancPluginGetDicomForInstance(context, &dicom, request->groups[0]))
+  {
+    /* No error, forward the DICOM file */
+    OrthancPluginAnswerBuffer(context, output, dicom.data, dicom.size, "application/dicom");
+
+    /* Free memory */
+    OrthancPluginFreeMemoryBuffer(context, &dicom);
+  }
+
+  return 0;
+}
+
+
+ORTHANC_PLUGINS_API int32_t Callback4(OrthancPluginRestOutput* output,
+                                      const char* url,
+                                      const OrthancPluginHttpRequest* request)
+{
+  /* Answer with a sample 8bpp image. */
+
+  uint8_t  buffer[256 * 256];
+  uint32_t x, y, value;
+
+  value = 0;
+  for (y = 0; y < 256; y++)
+  {
+    for (x = 0; x < 256; x++, value++)
+    {
+      buffer[value] = x;
+    }
+  }
+
+  OrthancPluginCompressAndAnswerPngImage(context, output, OrthancPluginPixelFormat_Grayscale8,
+                                         256, 256, 256, buffer);
+  return 0;
+}
+
+
 ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* c)
 {
   char info[1024];
@@ -99,6 +139,9 @@
 
   OrthancPluginRegisterRestCallback(context, "/(plu.*)/hello", Callback1);
   OrthancPluginRegisterRestCallback(context, "/plu.*/image", Callback2);
+  OrthancPluginRegisterRestCallback(context, "/plugin/instances/([^/]+)/info", Callback3);
+
+  OrthancPluginRegisterRestCallback(context, "/instances/([^/]+)/preview", Callback4);
 
   return 0;
 }