changeset 4532:11bfea08341a Orthanc-1.9.1

fix ParsedDicomImage::EmbedImage() on big-endian
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 25 Feb 2021 16:52:32 +0100
parents d64e6f401a8a
children 409cba9c1dba
files OrthancFramework/Sources/DicomParsing/ParsedDicomFile.cpp OrthancFramework/UnitTestsSources/FromDcmtkTests.cpp
diffstat 2 files changed, 39 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancFramework/Sources/DicomParsing/ParsedDicomFile.cpp	Thu Feb 25 12:15:18 2021 +0100
+++ b/OrthancFramework/Sources/DicomParsing/ParsedDicomFile.cpp	Thu Feb 25 16:52:32 2021 +0100
@@ -104,6 +104,7 @@
 #include <dcmtk/dcmdata/dcuid.h>
 #include <dcmtk/dcmdata/dcmetinf.h>
 #include <dcmtk/dcmdata/dcdeftag.h>
+#include <dcmtk/dcmdata/dcswap.h>
 
 #include <dcmtk/dcmdata/dcvrae.h>
 #include <dcmtk/dcmdata/dcvras.h>
@@ -1389,39 +1390,52 @@
     const unsigned int height = accessor.GetHeight();
     const unsigned int width = accessor.GetWidth();
 
-    for (unsigned int y = 0; y < height; y++)
     {
-      switch (accessor.GetFormat())
+      Uint8* q = target;
+      for (unsigned int y = 0; y < height; y++)
       {
-        case PixelFormat_RGB24:
-        case PixelFormat_Grayscale8:
-        case PixelFormat_Grayscale16:
-        case PixelFormat_SignedGrayscale16:
+        switch (accessor.GetFormat())
         {
-          memcpy(target, reinterpret_cast<const Uint8*>(accessor.GetConstRow(y)), pitch);
-          target += pitch;
-          break;
-        }
-
-        case PixelFormat_RGBA32:
-        {
-          // The alpha channel is not supported by the DICOM standard
-          const Uint8* source = reinterpret_cast<const Uint8*>(accessor.GetConstRow(y));
-          for (unsigned int x = 0; x < width; x++, target += 3, source += 4)
+          case PixelFormat_RGB24:
+          case PixelFormat_Grayscale8:
+          case PixelFormat_Grayscale16:
+          case PixelFormat_SignedGrayscale16:
           {
-            target[0] = source[0];
-            target[1] = source[1];
-            target[2] = source[2];
+            memcpy(q, reinterpret_cast<const Uint8*>(accessor.GetConstRow(y)), pitch);
+            q += pitch;
+            break;
           }
 
-          break;
-        }
+          case PixelFormat_RGBA32:
+          {
+            // The alpha channel is not supported by the DICOM standard
+            const Uint8* source = reinterpret_cast<const Uint8*>(accessor.GetConstRow(y));
+            for (unsigned int x = 0; x < width; x++, q += 3, source += 4)
+            {
+              q[0] = source[0];
+              q[1] = source[1];
+              q[2] = source[2];
+            }
+
+            break;
+          }
           
-        default:
-          throw OrthancException(ErrorCode_NotImplemented);
+          default:
+            throw OrthancException(ErrorCode_NotImplemented);
+        }
       }
     }
 
+    static const Endianness ENDIANNESS = Toolbox::DetectEndianness();
+    if (ENDIANNESS == Endianness_Big &&
+        (accessor.GetFormat() == PixelFormat_Grayscale16 ||
+         accessor.GetFormat() == PixelFormat_SignedGrayscale16))
+    {
+      // New in Orthanc 1.9.1
+      assert(pitch % 2 == 0);
+      swapBytes(target, accessor.GetHeight() * pitch, sizeof(uint16_t));
+    }
+
     if (!GetDcmtkObject().getDataset()->insert(pixels.release(), false, false).good())
     {
       throw OrthancException(ErrorCode_InternalError);
--- a/OrthancFramework/UnitTestsSources/FromDcmtkTests.cpp	Thu Feb 25 12:15:18 2021 +0100
+++ b/OrthancFramework/UnitTestsSources/FromDcmtkTests.cpp	Thu Feb 25 16:52:32 2021 +0100
@@ -921,7 +921,7 @@
     uint16_t *p = reinterpret_cast<uint16_t*>(image.GetRow(y));
     for (int x = 0; x < 256; x++, v++, p++)
     {
-      *p = htole16(v);   // Orthanc uses Little-Endian transfer syntax to encode images
+      *p = v;
     }
   }
 
@@ -976,7 +976,7 @@
     int16_t *p = reinterpret_cast<int16_t*>(image.GetRow(y));
     for (int x = 0; x < 256; x++, v++, p++)
     {
-      *p = htole16(v);   // Orthanc uses Little-Endian transfer syntax to encode images
+      *p = v;
     }
   }