Description: Fix broken Orthanc::ImageAccessor, which is notably used by orthanc-dicomweb
Author: Sebastien Jodogne <s.jodogne@orthanc-labs.com>
Forwarded: https://orthanc.uclouvain.be/hg/orthanc/rev/3bd8715e21bc
---
This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
Index: Orthanc-1.12.11/OrthancFramework/Sources/Enumerations.h
===================================================================
--- Orthanc-1.12.11.orig/OrthancFramework/Sources/Enumerations.h
+++ Orthanc-1.12.11/OrthancFramework/Sources/Enumerations.h
@@ -300,6 +300,12 @@ namespace Orthanc
   enum PixelFormat
   {
     /**
+     * {summary}{Invalid pixel format.}
+     * {description}{Invalid pixel format.}
+     **/
+    PixelFormat_Invalid = 0,
+
+    /**
      * {summary}{Color image in RGB24 format.}
      * {description}{This format describes a color image. The pixels are stored in 3
      * consecutive bytes. The memory layout is RGB.}
Index: Orthanc-1.12.11/OrthancFramework/Sources/Images/ImageAccessor.cpp
===================================================================
--- Orthanc-1.12.11.orig/OrthancFramework/Sources/Images/ImageAccessor.cpp
+++ Orthanc-1.12.11/OrthancFramework/Sources/Images/ImageAccessor.cpp
@@ -102,7 +102,7 @@ namespace Orthanc
 
   ImageAccessor::ImageAccessor()
   {
-    AssignEmpty(PixelFormat_Grayscale8);
+    AssignEmpty(PixelFormat_Invalid);
   }
 
   ImageAccessor::~ImageAccessor()
@@ -224,6 +224,13 @@ namespace Orthanc
                                      unsigned int pitch,
                                      const void *buffer)
   {
+    readOnly_ = true;
+    format_ = format;
+    width_ = width;
+    height_ = height;
+    pitch_ = pitch;
+    buffer_ = reinterpret_cast<uint8_t*>(const_cast<void*>(buffer));
+
     const uint64_t size = static_cast<uint64_t>(height) * static_cast<uint64_t>(pitch);
 
     if (static_cast<uint64_t>(GetBytesPerPixel() * width) > static_cast<uint64_t>(pitch) ||
@@ -231,13 +238,6 @@ namespace Orthanc
     {
       throw OrthancException(ErrorCode_ParameterOutOfRange);
     }
-
-    readOnly_ = true;
-    format_ = format;
-    width_ = width;
-    height_ = height;
-    pitch_ = pitch;
-    buffer_ = reinterpret_cast<uint8_t*>(const_cast<void*>(buffer));
   }
 
   void ImageAccessor::GetReadOnlyAccessor(ImageAccessor &target) const
@@ -252,6 +252,13 @@ namespace Orthanc
                                      unsigned int pitch,
                                      void *buffer)
   {
+    readOnly_ = false;
+    format_ = format;
+    width_ = width;
+    height_ = height;
+    pitch_ = pitch;
+    buffer_ = reinterpret_cast<uint8_t*>(buffer);
+
     const uint64_t size = static_cast<uint64_t>(height) * static_cast<uint64_t>(pitch);
 
     if (static_cast<uint64_t>(GetBytesPerPixel() * width) > static_cast<uint64_t>(pitch) ||
@@ -259,13 +266,6 @@ namespace Orthanc
     {
       throw OrthancException(ErrorCode_ParameterOutOfRange);
     }
-
-    readOnly_ = false;
-    format_ = format;
-    width_ = width;
-    height_ = height;
-    pitch_ = pitch;
-    buffer_ = reinterpret_cast<uint8_t*>(buffer);
   }
 
 
Index: Orthanc-1.12.11/OrthancFramework/UnitTestsSources/ImageTests.cpp
===================================================================
--- Orthanc-1.12.11.orig/OrthancFramework/UnitTestsSources/ImageTests.cpp
+++ Orthanc-1.12.11/OrthancFramework/UnitTestsSources/ImageTests.cpp
@@ -623,3 +623,25 @@ TEST(PngWriter, Gray16Then8)
     Orthanc::IImageWriter::WriteToMemory(w, s, image8);  // Problem here
   }  
 }
+
+
+TEST(ImageAccessor, Broken)
+{
+  // This test checks whether ImageAccessor was broken by the
+  // following changeset, which was part of Orthanc 1.12.11:
+  // https://orthanc.uclouvain.be/hg/orthanc/rev/68675600a967
+
+  std::vector<uint8_t> row(64);
+
+  {
+    Orthanc::ImageAccessor accessor;
+    accessor.AssignReadOnly(Orthanc::PixelFormat_Grayscale16, 32, 1, 64, &row[0]);
+    accessor.AssignReadOnly(Orthanc::PixelFormat_Grayscale8, 64, 1, 64, &row[0]);
+  }
+
+  {
+    Orthanc::ImageAccessor accessor;
+    accessor.AssignWritable(Orthanc::PixelFormat_Grayscale16, 32, 1, 64, &row[0]);
+    accessor.AssignWritable(Orthanc::PixelFormat_Grayscale8, 64, 1, 64, &row[0]);
+  }
+}
