changeset 2904:0dd54ee073db

float to integer grayscale conversion
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 30 Oct 2018 10:46:17 +0100
parents 1153b1a128fe
children ae20fccdd867
files Core/Images/ImageProcessing.cpp
diffstat 1 files changed, 100 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/Core/Images/ImageProcessing.cpp	Tue Oct 23 17:32:56 2018 +0200
+++ b/Core/Images/ImageProcessing.cpp	Tue Oct 30 10:46:17 2018 +0100
@@ -53,12 +53,15 @@
     const TargetType minValue = std::numeric_limits<TargetType>::min();
     const TargetType maxValue = std::numeric_limits<TargetType>::max();
 
-    for (unsigned int y = 0; y < source.GetHeight(); y++)
+    const unsigned int width = source.GetWidth();
+    const unsigned int height = source.GetHeight();
+    
+    for (unsigned int y = 0; y < height; y++)
     {
       TargetType* t = reinterpret_cast<TargetType*>(target.GetRow(y));
       const SourceType* s = reinterpret_cast<const SourceType*>(source.GetConstRow(y));
 
-      for (unsigned int x = 0; x < source.GetWidth(); x++, t++, s++)
+      for (unsigned int x = 0; x < width; x++, t++, s++)
       {
         if (static_cast<int32_t>(*s) < static_cast<int32_t>(minValue))
         {
@@ -83,12 +86,15 @@
   {
     assert(sizeof(float) == 4);
 
-    for (unsigned int y = 0; y < source.GetHeight(); y++)
+    const unsigned int width = source.GetWidth();
+    const unsigned int height = source.GetHeight();
+    
+    for (unsigned int y = 0; y < height; y++)
     {
       float* t = reinterpret_cast<float*>(target.GetRow(y));
       const SourceType* s = reinterpret_cast<const SourceType*>(source.GetConstRow(y));
 
-      for (unsigned int x = 0; x < source.GetWidth(); x++, t++, s++)
+      for (unsigned int x = 0; x < width; x++, t++, s++)
       {
         *t = static_cast<float>(*s);
       }
@@ -96,6 +102,30 @@
   }
 
 
+  template <PixelFormat TargetFormat>
+  static void ConvertFloatToGrayscale(ImageAccessor& target,
+                                      const ImageAccessor& source)
+  {
+    typedef typename PixelTraits<TargetFormat>::PixelType  TargetType;
+    
+    assert(sizeof(float) == 4);
+
+    const unsigned int width = source.GetWidth();
+    const unsigned int height = source.GetHeight();
+
+    for (unsigned int y = 0; y < height; y++)
+    {
+      TargetType* q = reinterpret_cast<TargetType*>(target.GetRow(y));
+      const float* p = reinterpret_cast<const float*>(source.GetConstRow(y));
+
+      for (unsigned int x = 0; x < width; x++, p++, q++)
+      {
+        PixelTraits<TargetFormat>::FloatToPixel(*q, *p);
+      }
+    }
+  }
+
+
   template <typename TargetType>
   static void ConvertColorToGrayscale(ImageAccessor& target,
                                       const ImageAccessor& source)
@@ -105,12 +135,15 @@
     const TargetType minValue = std::numeric_limits<TargetType>::min();
     const TargetType maxValue = std::numeric_limits<TargetType>::max();
 
-    for (unsigned int y = 0; y < source.GetHeight(); y++)
+    const unsigned int width = source.GetWidth();
+    const unsigned int height = source.GetHeight();
+    
+    for (unsigned int y = 0; y < height; y++)
     {
       TargetType* t = reinterpret_cast<TargetType*>(target.GetRow(y));
       const uint8_t* s = reinterpret_cast<const uint8_t*>(source.GetConstRow(y));
 
-      for (unsigned int x = 0; x < source.GetWidth(); x++, t++, s += 3)
+      for (unsigned int x = 0; x < width; x++, t++, s += 3)
       {
         // Y = 0.2126 R + 0.7152 G + 0.0722 B
         int32_t v = (2126 * static_cast<int32_t>(s[0]) +
@@ -198,9 +231,10 @@
     minValue = std::numeric_limits<PixelType>::max();
     maxValue = std::numeric_limits<PixelType>::min();
 
+    const unsigned int height = source.GetHeight();
     const unsigned int width = source.GetWidth();
 
-    for (unsigned int y = 0; y < source.GetHeight(); y++)
+    for (unsigned int y = 0; y < height; y++)
     {
       const PixelType* p = reinterpret_cast<const PixelType*>(source.GetConstRow(y));
 
@@ -233,11 +267,14 @@
     const int64_t minValue = std::numeric_limits<PixelType>::min();
     const int64_t maxValue = std::numeric_limits<PixelType>::max();
 
-    for (unsigned int y = 0; y < image.GetHeight(); y++)
+    const unsigned int width = image.GetWidth();
+    const unsigned int height = image.GetHeight();
+    
+    for (unsigned int y = 0; y < height; y++)
     {
       PixelType* p = reinterpret_cast<PixelType*>(image.GetRow(y));
 
-      for (unsigned int x = 0; x < image.GetWidth(); x++, p++)
+      for (unsigned int x = 0; x < width; x++, p++)
       {
         int64_t v = static_cast<int64_t>(*p) + constant;
 
@@ -271,9 +308,11 @@
 
     const int64_t minValue = std::numeric_limits<PixelType>::min();
     const int64_t maxValue = std::numeric_limits<PixelType>::max();
-    const unsigned int width = image.GetWidth();
 
-    for (unsigned int y = 0; y < image.GetHeight(); y++)
+    const unsigned int width = image.GetWidth();
+    const unsigned int height = image.GetHeight();
+
+    for (unsigned int y = 0; y < height; y++)
     {
       PixelType* p = reinterpret_cast<PixelType*>(image.GetRow(y));
 
@@ -385,6 +424,9 @@
       throw OrthancException(ErrorCode_IncompatibleImageSize);
     }
 
+    const unsigned int width = source.GetWidth();
+    const unsigned int height = source.GetHeight();
+
     if (source.GetFormat() == target.GetFormat())
     {
       Copy(target, source);
@@ -482,14 +524,15 @@
       return;
     }
 
+    
     if (target.GetFormat() == PixelFormat_Grayscale8 &&
         source.GetFormat() == PixelFormat_RGBA32)
     {
-      for (unsigned int y = 0; y < source.GetHeight(); y++)
+      for (unsigned int y = 0; y < height; y++)
       {
         const uint8_t* p = reinterpret_cast<const uint8_t*>(source.GetConstRow(y));
         uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y));
-        for (unsigned int x = 0; x < source.GetWidth(); x++, q++)
+        for (unsigned int x = 0; x < width; x++, q++)
         {
           *q = static_cast<uint8_t>((2126 * static_cast<uint32_t>(p[0]) +
                                      7152 * static_cast<uint32_t>(p[1]) +
@@ -504,11 +547,11 @@
     if (target.GetFormat() == PixelFormat_Grayscale8 &&
         source.GetFormat() == PixelFormat_BGRA32)
     {
-      for (unsigned int y = 0; y < source.GetHeight(); y++)
+      for (unsigned int y = 0; y < height; y++)
       {
         const uint8_t* p = reinterpret_cast<const uint8_t*>(source.GetConstRow(y));
         uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y));
-        for (unsigned int x = 0; x < source.GetWidth(); x++, q++)
+        for (unsigned int x = 0; x < width; x++, q++)
         {
           *q = static_cast<uint8_t>((2126 * static_cast<uint32_t>(p[2]) +
                                      7152 * static_cast<uint32_t>(p[1]) +
@@ -523,11 +566,11 @@
     if (target.GetFormat() == PixelFormat_RGB24 &&
         source.GetFormat() == PixelFormat_RGBA32)
     {
-      for (unsigned int y = 0; y < source.GetHeight(); y++)
+      for (unsigned int y = 0; y < height; y++)
       {
         const uint8_t* p = reinterpret_cast<const uint8_t*>(source.GetConstRow(y));
         uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y));
-        for (unsigned int x = 0; x < source.GetWidth(); x++)
+        for (unsigned int x = 0; x < width; x++)
         {
           q[0] = p[0];
           q[1] = p[1];
@@ -543,11 +586,11 @@
     if (target.GetFormat() == PixelFormat_RGB24 &&
         source.GetFormat() == PixelFormat_BGRA32)
     {
-      for (unsigned int y = 0; y < source.GetHeight(); y++)
+      for (unsigned int y = 0; y < height; y++)
       {
         const uint8_t* p = reinterpret_cast<const uint8_t*>(source.GetConstRow(y));
         uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y));
-        for (unsigned int x = 0; x < source.GetWidth(); x++)
+        for (unsigned int x = 0; x < width; x++)
         {
           q[0] = p[2];
           q[1] = p[1];
@@ -563,11 +606,11 @@
     if (target.GetFormat() == PixelFormat_RGBA32 &&
         source.GetFormat() == PixelFormat_RGB24)
     {
-      for (unsigned int y = 0; y < source.GetHeight(); y++)
+      for (unsigned int y = 0; y < height; y++)
       {
         const uint8_t* p = reinterpret_cast<const uint8_t*>(source.GetConstRow(y));
         uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y));
-        for (unsigned int x = 0; x < source.GetWidth(); x++)
+        for (unsigned int x = 0; x < width; x++)
         {
           q[0] = p[0];
           q[1] = p[1];
@@ -584,11 +627,11 @@
     if (target.GetFormat() == PixelFormat_RGB24 &&
         source.GetFormat() == PixelFormat_Grayscale8)
     {
-      for (unsigned int y = 0; y < source.GetHeight(); y++)
+      for (unsigned int y = 0; y < height; y++)
       {
         const uint8_t* p = reinterpret_cast<const uint8_t*>(source.GetConstRow(y));
         uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y));
-        for (unsigned int x = 0; x < source.GetWidth(); x++)
+        for (unsigned int x = 0; x < width; x++)
         {
           q[0] = *p;
           q[1] = *p;
@@ -605,11 +648,11 @@
          target.GetFormat() == PixelFormat_BGRA32) &&
         source.GetFormat() == PixelFormat_Grayscale8)
     {
-      for (unsigned int y = 0; y < source.GetHeight(); y++)
+      for (unsigned int y = 0; y < height; y++)
       {
         const uint8_t* p = reinterpret_cast<const uint8_t*>(source.GetConstRow(y));
         uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y));
-        for (unsigned int x = 0; x < source.GetWidth(); x++)
+        for (unsigned int x = 0; x < width; x++)
         {
           q[0] = *p;
           q[1] = *p;
@@ -626,11 +669,11 @@
     if (target.GetFormat() == PixelFormat_BGRA32 &&
         source.GetFormat() == PixelFormat_Grayscale16)
     {
-      for (unsigned int y = 0; y < source.GetHeight(); y++)
+      for (unsigned int y = 0; y < height; 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++)
+        for (unsigned int x = 0; x < width; x++)
         {
           uint8_t value = (*p < 256 ? *p : 255);
           q[0] = value;
@@ -648,11 +691,11 @@
     if (target.GetFormat() == PixelFormat_BGRA32 &&
         source.GetFormat() == PixelFormat_SignedGrayscale16)
     {
-      for (unsigned int y = 0; y < source.GetHeight(); y++)
+      for (unsigned int y = 0; y < height; y++)
       {
         const int16_t* p = reinterpret_cast<const int16_t*>(source.GetConstRow(y));
         uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y));
-        for (unsigned int x = 0; x < source.GetWidth(); x++)
+        for (unsigned int x = 0; x < width; x++)
         {
           uint8_t value;
           if (*p < 0)
@@ -683,11 +726,11 @@
     if (target.GetFormat() == PixelFormat_BGRA32 &&
         source.GetFormat() == PixelFormat_RGB24)
     {
-      for (unsigned int y = 0; y < source.GetHeight(); y++)
+      for (unsigned int y = 0; y < height; y++)
       {
         const uint8_t* p = reinterpret_cast<const uint8_t*>(source.GetConstRow(y));
         uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y));
-        for (unsigned int x = 0; x < source.GetWidth(); x++)
+        for (unsigned int x = 0; x < width; x++)
         {
           q[0] = p[2];
           q[1] = p[1];
@@ -704,11 +747,11 @@
     if (target.GetFormat() == PixelFormat_RGB24 &&
         source.GetFormat() == PixelFormat_RGB48)
     {
-      for (unsigned int y = 0; y < source.GetHeight(); y++)
+      for (unsigned int y = 0; y < height; 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++)
+        for (unsigned int x = 0; x < width; x++)
         {
           q[0] = p[0] >> 8;
           q[1] = p[1] >> 8;
@@ -721,6 +764,20 @@
       return;
     }
 
+    if (target.GetFormat() == PixelFormat_Grayscale16 &&
+        source.GetFormat() == PixelFormat_Float32)
+    {
+      ConvertFloatToGrayscale<PixelFormat_Grayscale16>(target, source);
+      return;
+    }
+
+    if (target.GetFormat() == PixelFormat_Grayscale8 &&
+        source.GetFormat() == PixelFormat_Float32)
+    {
+      ConvertFloatToGrayscale<PixelFormat_Grayscale8>(target, source);
+      return;
+    }
+
     throw OrthancException(ErrorCode_NotImplemented);
   }
 
@@ -800,11 +857,14 @@
         throw OrthancException(ErrorCode_NotImplemented);
     }    
 
-    for (unsigned int y = 0; y < image.GetHeight(); y++)
+    const unsigned int width = image.GetWidth();
+    const unsigned int height = image.GetHeight();
+
+    for (unsigned int y = 0; y < height; y++)
     {
       uint8_t* q = reinterpret_cast<uint8_t*>(image.GetRow(y));
 
-      for (unsigned int x = 0; x < image.GetWidth(); x++)
+      for (unsigned int x = 0; x < width; x++)
       {
         for (unsigned int i = 0; i < size; i++)
         {
@@ -1019,15 +1079,18 @@
 
   void ImageProcessing::Invert(ImageAccessor& image)
   {
+    const unsigned int width = image.GetWidth();
+    const unsigned int height = image.GetHeight();
+    
     switch (image.GetFormat())
     {
       case PixelFormat_Grayscale8:
       {
-        for (unsigned int y = 0; y < image.GetHeight(); y++)
+        for (unsigned int y = 0; y < height; y++)
         {
           uint8_t* p = reinterpret_cast<uint8_t*>(image.GetRow(y));
 
-          for (unsigned int x = 0; x < image.GetWidth(); x++, p++)
+          for (unsigned int x = 0; x < width; x++, p++)
           {
             *p = 255 - (*p);
           }