changeset 173:4f0f4f64cff3

Support of rendering RGB48 lookup tables (palette)
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 10 Oct 2017 13:26:15 +0200
parents 330ecfd96aec
children 81f16c5667ba
files NEWS Orthanc/Plugins/Samples/GdcmDecoder/GdcmImageDecoder.cpp Plugin/DecodedImageAdapter.cpp Plugin/DecodedImageAdapter.h
diffstat 4 files changed, 54 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Tue Oct 10 12:53:46 2017 +0200
+++ b/NEWS	Tue Oct 10 13:26:15 2017 +0200
@@ -1,6 +1,7 @@
 Pending changes in the mainline
 ===============================
 
+* Support of rendering RGB48 lookup tables (palette), if Orthanc SDK >= 1.3.1
 * Support of OpenBSD
 
 
--- a/Orthanc/Plugins/Samples/GdcmDecoder/GdcmImageDecoder.cpp	Tue Oct 10 12:53:46 2017 +0200
+++ b/Orthanc/Plugins/Samples/GdcmDecoder/GdcmImageDecoder.cpp	Tue Oct 10 13:26:15 2017 +0200
@@ -32,17 +32,6 @@
 #include <boost/iostreams/device/array.hpp>
 
 
-// This is for compatibility with Orthanc SDK <= 1.3.0
-#if !defined(ORTHANC_PLUGINS_VERSION_IS_ABOVE)
-#define ORTHANC_PLUGINS_VERSION_IS_ABOVE(major, minor, revision) \
-  (ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER > major ||               \
-   (ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER == major &&             \
-    (ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER > minor ||             \
-     (ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER == minor &&           \
-      ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER >= revision))))
-#endif
-
-
 namespace OrthancPlugins
 {
   struct GdcmImageDecoder::PImpl
@@ -214,7 +203,7 @@
 #if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 3, 1)
           return OrthancPluginPixelFormat_RGB48;
 #else
-          throw std::runtime_error("RGB48 pixel format is only supported by Orthanc >= 1.3.1");
+          throw std::runtime_error("RGB48 pixel format is only supported if compiled against Orthanc SDK >= 1.3.1");
 #endif
           
         default:
@@ -258,6 +247,11 @@
       case OrthancPluginPixelFormat_RGB24:
         return 3;
 
+#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 3, 1)
+      case OrthancPluginPixelFormat_RGB48:
+        return 6;
+#endif
+
       default:
         throw std::runtime_error("Unsupport pixel format");
     }
--- a/Plugin/DecodedImageAdapter.cpp	Tue Oct 10 12:53:46 2017 +0200
+++ b/Plugin/DecodedImageAdapter.cpp	Tue Oct 10 13:26:15 2017 +0200
@@ -157,7 +157,7 @@
     {
       if (type == CompressionType_Deflate)
       {
-        ok = EncodeUsingDeflate(json, *image, 9);
+        ok = EncodeUsingDeflate(json, *image);
       }
       else if (type == CompressionType_Jpeg)
       {
@@ -226,6 +226,7 @@
       }
 
       case PixelFormat_RGB24:
+      case PixelFormat_RGB48:
         result["minPixelValue"] = 0;
         result["maxPixelValue"] = 255;
         result["color"] = true;
@@ -281,10 +282,34 @@
   }
 
 
+  static void ConvertRGB48ToRGB24(Orthanc::ImageAccessor& target,
+                                  const Orthanc::ImageAccessor& source)
+  {
+    if (source.GetWidth() != target.GetWidth() ||
+        source.GetHeight() != target.GetHeight())
+    {
+      throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageSize);
+    }
+
+    for (unsigned int y = 0; y < source.GetHeight(); y++)
+    {
+      const uint16_t* p = reinterpret_cast<const uint16_t*>(source.GetConstRow(y));
+      uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y));
+
+      for (unsigned int x = 0; x < source.GetWidth(); x++)
+      {
+        q[0] = p[0] >> 8;
+        q[1] = p[1] >> 8;
+        q[2] = p[2] >> 8;
+        p += 3;
+        q += 3;
+      }
+    }
+  }
+
 
   bool  DecodedImageAdapter::EncodeUsingDeflate(Json::Value& result,
-                                                OrthancImageWrapper& image,
-                                                uint8_t compressionLevel  /* between 0 and 9 */)
+                                                OrthancImageWrapper& image)
   {
     Orthanc::ImageAccessor accessor;
     accessor.AssignReadOnly(OrthancPlugins::Convert(image.GetFormat()), image.GetWidth(),
@@ -300,6 +325,14 @@
         converted = accessor;
         break;
 
+      case Orthanc::PixelFormat_RGB48:
+        buffer.reset(new Orthanc::ImageBuffer(Orthanc::PixelFormat_RGB24,
+                                              accessor.GetWidth(),
+                                              accessor.GetHeight(), false));
+        converted = buffer->GetAccessor();
+        ConvertRGB48ToRGB24(converted, accessor);
+        break;
+
       case Orthanc::PixelFormat_Grayscale8:
       case Orthanc::PixelFormat_Grayscale16:
         buffer.reset(new Orthanc::ImageBuffer(Orthanc::PixelFormat_Grayscale16,
@@ -402,6 +435,16 @@
       result["Orthanc"]["Stretched"] = false;
       converted = accessor;
     }
+    else if (accessor.GetFormat() == Orthanc::PixelFormat_RGB48)
+    {
+      result["Orthanc"]["Stretched"] = false;
+
+      buffer.reset(new Orthanc::ImageBuffer(Orthanc::PixelFormat_RGB24,
+                                            accessor.GetWidth(),
+                                            accessor.GetHeight(), false));
+      converted = buffer->GetAccessor();
+      ConvertRGB48ToRGB24(converted, accessor);
+    }
     else if (accessor.GetFormat() == Orthanc::PixelFormat_Grayscale16 ||
              accessor.GetFormat() == Orthanc::PixelFormat_SignedGrayscale16)
     {
--- a/Plugin/DecodedImageAdapter.h	Tue Oct 10 12:53:46 2017 +0200
+++ b/Plugin/DecodedImageAdapter.h	Tue Oct 10 13:26:15 2017 +0200
@@ -52,8 +52,7 @@
                                        OrthancImageWrapper& image);
 
     static bool EncodeUsingDeflate(Json::Value& result,
-                                   OrthancImageWrapper& image,
-                                   uint8_t compressionLevel  /* between 0 and 9 */);
+                                   OrthancImageWrapper& image);
 
     static bool EncodeUsingJpeg(Json::Value& result,
                                 OrthancImageWrapper& image,