changeset 140:29f7e2571143 dev

RAII for plugin images
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 24 Jun 2016 21:59:32 +0200
parents a56a59896dcb
children 022cb1de0db0
files Orthanc/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp Orthanc/Plugins/Samples/Common/OrthancPluginCppWrapper.h Plugin/WadoUri.cpp
diffstat 3 files changed, 253 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/Orthanc/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp	Fri Jun 24 21:20:27 2016 +0200
+++ b/Orthanc/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp	Fri Jun 24 21:59:32 2016 +0200
@@ -70,6 +70,18 @@
   }
 
 
+  void MemoryBuffer::Assign(OrthancPluginMemoryBuffer& other)
+  {
+    Clear();
+
+    buffer_.data = other.data;
+    buffer_.size = other.size;
+
+    other.data = NULL;
+    other.size = 0;
+  }
+
+
   void MemoryBuffer::ToString(std::string& target) const
   {
     if (buffer_.size == 0)
@@ -549,6 +561,183 @@
   }
 
 
+  void Image::Clear()
+  {
+    if (image_ != NULL)
+    {
+      OrthancPluginFreeImage(context_, image_);
+      image_ = NULL;
+    }
+  }
+
+
+  void Image::CheckImageAvailable()
+  {
+    if (image_ == NULL)
+    {
+      OrthancPluginLogError(context_, "Trying to access a NULL image");
+      throw PluginException(OrthancPluginErrorCode_ParameterOutOfRange);
+    }
+  }
+
+
+  Image::Image(OrthancPluginContext*  context) :
+    context_(context),
+    image_(NULL)
+  {
+    if (context == NULL)
+    {
+      throw PluginException(OrthancPluginErrorCode_ParameterOutOfRange);
+    }
+  }
+
+
+  Image::Image(OrthancPluginContext*  context,
+               OrthancPluginImage*    image) :
+    context_(context),
+    image_(image)
+  {
+    if (context == NULL)
+    {
+      throw PluginException(OrthancPluginErrorCode_ParameterOutOfRange);
+    }
+  }
+  
+
+  Image::Image(OrthancPluginContext*     context,
+               OrthancPluginPixelFormat  format,
+               uint32_t                  width,
+               uint32_t                  height) :
+    context_(context)
+  {
+    if (context == NULL)
+    {
+      throw PluginException(OrthancPluginErrorCode_ParameterOutOfRange);
+    }
+    else
+    {
+      image_ = OrthancPluginCreateImage(context, format, width, height);
+    }
+  }
+
+
+  void Image::UncompressPngImage(const void* data,
+                                 size_t size)
+  {
+    Clear();
+    image_ = OrthancPluginUncompressImage(context_, data, size, OrthancPluginImageFormat_Png);
+    if (image_ == NULL)
+    {
+      OrthancPluginLogError(context_, "Cannot uncompress a PNG image");
+      throw PluginException(OrthancPluginErrorCode_ParameterOutOfRange);
+    }
+  }
+
+
+  void Image::UncompressJpegImage(const void* data,
+                                  size_t size)
+  {
+    Clear();
+    image_ = OrthancPluginUncompressImage(context_, data, size, OrthancPluginImageFormat_Jpeg);
+    if (image_ == NULL)
+    {
+      OrthancPluginLogError(context_, "Cannot uncompress a JPEG image");
+      throw PluginException(OrthancPluginErrorCode_ParameterOutOfRange);
+    }
+  }
+
+
+  void Image::DecodeDicomImage(const void* data,
+                               size_t size,
+                               unsigned int frame)
+  {
+    Clear();
+    image_ = OrthancPluginDecodeDicomImage(context_, data, size, frame);
+    if (image_ == NULL)
+    {
+      OrthancPluginLogError(context_, "Cannot uncompress a DICOM image");
+      throw PluginException(OrthancPluginErrorCode_ParameterOutOfRange);
+    }
+  }
+
+
+  OrthancPluginPixelFormat Image::GetPixelFormat()
+  {
+    CheckImageAvailable();
+    return OrthancPluginGetImagePixelFormat(context_, image_);
+  }
+
+
+  unsigned int Image::GetWidth()
+  {
+    CheckImageAvailable();
+    return OrthancPluginGetImageWidth(context_, image_);
+  }
+
+
+  unsigned int Image::GetHeight()
+  {
+    CheckImageAvailable();
+    return OrthancPluginGetImageHeight(context_, image_);
+  }
+
+
+  unsigned int Image::GetPitch()
+  {
+    CheckImageAvailable();
+    return OrthancPluginGetImagePitch(context_, image_);
+  }
+
+    
+  const void* Image::GetBuffer()
+  {
+    CheckImageAvailable();
+    return OrthancPluginGetImageBuffer(context_, image_);
+  }
+
+
+  void Image::CompressPngImage(MemoryBuffer& target)
+  {
+    CheckImageAvailable();
+    
+    OrthancPluginMemoryBuffer tmp;
+    OrthancPluginCompressPngImage(context_, &tmp, GetPixelFormat(), 
+                                  GetWidth(), GetHeight(), GetPitch(), GetBuffer());
+
+    target.Assign(tmp);
+  }
+
+
+  void Image::CompressJpegImage(MemoryBuffer& target,
+                                uint8_t quality)
+  {
+    CheckImageAvailable();
+    
+    OrthancPluginMemoryBuffer tmp;
+    OrthancPluginCompressJpegImage(context_, &tmp, GetPixelFormat(), 
+                                   GetWidth(), GetHeight(), GetPitch(), GetBuffer(), quality);
+    
+    target.Assign(tmp);
+  }
+
+
+  void Image::AnswerPngImage(OrthancPluginRestOutput* output)
+  {
+    CheckImageAvailable();
+    OrthancPluginCompressAndAnswerPngImage(context_, output, GetPixelFormat(),
+                                           GetWidth(), GetHeight(), GetPitch(), GetBuffer());
+  }
+
+
+  void Image::AnswerJpegImage(OrthancPluginRestOutput* output,
+                              uint8_t quality)
+  {
+    CheckImageAvailable();
+    OrthancPluginCompressAndAnswerJpegImage(context_, output, GetPixelFormat(),
+                                            GetWidth(), GetHeight(), GetPitch(), GetBuffer(), quality);
+  }
+
+
   bool RestApiGetJson(Json::Value& result,
                       OrthancPluginContext* context,
                       const std::string& uri,
--- a/Orthanc/Plugins/Samples/Common/OrthancPluginCppWrapper.h	Fri Jun 24 21:20:27 2016 +0200
+++ b/Orthanc/Plugins/Samples/Common/OrthancPluginCppWrapper.h	Fri Jun 24 21:59:32 2016 +0200
@@ -87,6 +87,9 @@
       return &buffer_;
     }
 
+    // This transfers ownership
+    void Assign(OrthancPluginMemoryBuffer& other);
+
     const char* GetData() const
     {
       if (buffer_.size > 0)
@@ -224,6 +227,63 @@
                         float defaultValue) const;
   };
 
+  class Image
+  {
+  private:
+    OrthancPluginContext*  context_;
+    OrthancPluginImage*    image_;
+
+    void Clear();
+
+    void CheckImageAvailable();
+
+  public:
+    Image(OrthancPluginContext*  context);
+
+    Image(OrthancPluginContext*  context,
+          OrthancPluginImage*    image);
+
+    Image(OrthancPluginContext*     context,
+          OrthancPluginPixelFormat  format,
+          uint32_t                  width,
+          uint32_t                  height);
+
+    ~Image()
+    {
+      Clear();
+    }
+
+    void UncompressPngImage(const void* data,
+                            size_t size);
+
+    void UncompressJpegImage(const void* data,
+                             size_t size);
+
+    void DecodeDicomImage(const void* data,
+                          size_t size,
+                          unsigned int frame);
+
+    OrthancPluginPixelFormat GetPixelFormat();
+
+    unsigned int GetWidth();
+
+    unsigned int GetHeight();
+
+    unsigned int GetPitch();
+    
+    const void* GetBuffer();
+
+    void CompressPngImage(MemoryBuffer& target);
+
+    void CompressJpegImage(MemoryBuffer& target,
+                           uint8_t quality);
+
+    void AnswerPngImage(OrthancPluginRestOutput* output);
+
+    void AnswerJpegImage(OrthancPluginRestOutput* output,
+                         uint8_t quality);
+  };
+
 
   bool RestApiGetJson(Json::Value& result,
                       OrthancPluginContext* context,
--- a/Plugin/WadoUri.cpp	Fri Jun 24 21:20:27 2016 +0200
+++ b/Plugin/WadoUri.cpp	Fri Jun 24 21:59:32 2016 +0200
@@ -209,28 +209,10 @@
   {
     throw OrthancPlugins::PluginException(OrthancPluginErrorCode_Plugin);
   }
-
-  // TODO RAII
-  // Decode the PNG file
-  OrthancPluginImage* image = OrthancPluginUncompressImage(
-    context, png.GetData(), png.GetSize(), OrthancPluginImageFormat_Png);
-  if (image == NULL)
-  {
-    OrthancPlugins::Configuration::LogError("Cannot decode this DICOM image");
-    throw OrthancPlugins::PluginException(OrthancPluginErrorCode_NotImplemented);
-  }
-
-  // Convert to JPEG
-  OrthancPluginCompressAndAnswerJpegImage(
-    context, output, 
-    OrthancPluginGetImagePixelFormat(context, image),
-    OrthancPluginGetImageWidth(context, image),
-    OrthancPluginGetImageHeight(context, image),
-    OrthancPluginGetImagePitch(context, image),
-    OrthancPluginGetImageBuffer(context, image), 
-    90 /*quality*/);
-
-  OrthancPluginFreeImage(context, image);
+  
+  OrthancPlugins::Image image(context);
+  image.UncompressPngImage(png.GetData(), png.GetSize());
+  image.AnswerJpegImage(output, 90 /* quality */);
 }