changeset 1843:d10a8164da5f

ensure images returned to plugins are writable
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 30 Nov 2015 13:50:21 +0100
parents 697ae8d0e287
children 1ba224001fd0
files Plugins/Engine/OrthancPlugins.cpp
diffstat 1 files changed, 24 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/Plugins/Engine/OrthancPlugins.cpp	Mon Nov 30 13:16:52 2015 +0100
+++ b/Plugins/Engine/OrthancPlugins.cpp	Mon Nov 30 13:50:21 2015 +0100
@@ -1263,6 +1263,25 @@
   }
 
 
+  static OrthancPluginImage* ReturnImage(std::auto_ptr<ImageAccessor>& image)
+  {
+    // Images returned to plugins are assumed to be writeable. If the
+    // input image is read-only, we return a copy so that it can be modified.
+
+    if (image->IsReadOnly())
+    {
+      std::auto_ptr<Image> copy(new Image(image->GetFormat(), image->GetWidth(), image->GetHeight()));
+      ImageProcessing::Copy(*copy, *image);
+      image.reset(NULL);
+      return reinterpret_cast<OrthancPluginImage*>(copy.release());
+    }
+    else
+    {
+      return reinterpret_cast<OrthancPluginImage*>(image.release());
+    }
+  }
+
+
   void OrthancPlugins::UncompressImage(const void* parameters)
   {
     const _OrthancPluginUncompressImage& p = *reinterpret_cast<const _OrthancPluginUncompressImage*>(parameters);
@@ -1296,7 +1315,7 @@
         throw OrthancException(ErrorCode_ParameterOutOfRange);
     }
 
-    *(p.target) = reinterpret_cast<OrthancPluginImage*>(image.release());
+    *(p.target) = ReturnImage(image);
   }
 
 
@@ -1386,7 +1405,7 @@
     std::auto_ptr<ImageAccessor> target(new Image(Plugins::Convert(p.targetFormat), source.GetWidth(), source.GetHeight()));
     ImageProcessing::Convert(*target, source);
 
-    *(p.target) = reinterpret_cast<OrthancPluginImage*>(target.release());
+    *(p.target) = ReturnImage(target);
   }
 
 
@@ -1550,7 +1569,7 @@
         throw OrthancException(ErrorCode_InternalError);
     }
 
-    *(p.target) = reinterpret_cast<OrthancPluginImage*>(result.release());
+    *(p.target) = ReturnImage(result);
   }
         
 
@@ -1964,14 +1983,7 @@
       case _OrthancPluginService_GetImageBuffer:
       {
         const _OrthancPluginGetImageInfo& p = *reinterpret_cast<const _OrthancPluginGetImageInfo*>(parameters);
-        const ImageAccessor& image = reinterpret_cast<const ImageAccessor&>(p.image);
-
-        if (image.IsReadOnly())
-        {
-          throw OrthancException(ErrorCode_ReadOnly);
-        }
-
-        *(p.resultBuffer) = image.GetBuffer();
+        *(p.resultBuffer) = reinterpret_cast<const ImageAccessor*>(p.image)->GetBuffer();
         return true;
       }
 
@@ -2293,7 +2305,7 @@
           return reinterpret_cast<ImageAccessor*>(pluginImage);
         }
 
-        LOG(WARNING) << "The custom image decoder cannot handle an image, trying with the built-in decoder";
+        LOG(WARNING) << "The custom image decoder cannot handle an image, fallback to the built-in decoder";
       }
     }