diff Core/Images/ImageProcessing.cpp @ 2482:509041cb57db

speedup by truncating instead of rounding
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 01 Mar 2018 09:29:06 +0100
parents 878b59270859
children be1dbb1dcdd6
line wrap: on
line diff
--- a/Core/Images/ImageProcessing.cpp	Tue Feb 20 11:16:49 2018 +0100
+++ b/Core/Images/ImageProcessing.cpp	Thu Mar 01 09:29:06 2018 +0100
@@ -166,11 +166,13 @@
     minValue = std::numeric_limits<PixelType>::max();
     maxValue = std::numeric_limits<PixelType>::min();
 
+    const unsigned int width = source.GetWidth();
+
     for (unsigned int y = 0; y < source.GetHeight(); y++)
     {
       const PixelType* p = reinterpret_cast<const PixelType*>(source.GetConstRow(y));
 
-      for (unsigned int x = 0; x < source.GetWidth(); x++, p++)
+      for (unsigned int x = 0; x < width; x++, p++)
       {
         if (*p < minValue)
         {
@@ -236,14 +238,19 @@
 
     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++)
     {
       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 = boost::math::llround(static_cast<float>(*p) * factor);
+        // The "round" operation is extremely costly. We use
+        // truncation instead since Orthanc 1.3.2.
+          
+        //int64_t v = boost::math::llround(static_cast<float>(*p) * factor);
+        int64_t v = static_cast<int64_t>(static_cast<float>(*p) * factor);
 
         if (v > maxValue)
         {
@@ -267,28 +274,37 @@
                           float offset,
                           float scaling)
   {
-    const float minValue = static_cast<float>(std::numeric_limits<PixelType>::min());
-    const float maxValue = static_cast<float>(std::numeric_limits<PixelType>::max());
+    const float minFloatValue = static_cast<float>(std::numeric_limits<PixelType>::min());
+    const float maxFloatValue = static_cast<float>(std::numeric_limits<PixelType>::max());
+    const PixelType minPixelValue = std::numeric_limits<PixelType>::min();
+    const PixelType maxPixelValue = std::numeric_limits<PixelType>::max();
 
-    for (unsigned int y = 0; y < image.GetHeight(); y++)
+    const unsigned int height = image.GetHeight();
+    const unsigned int width = image.GetWidth();
+    
+    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++)
       {
         float v = (static_cast<float>(*p) + offset) * scaling;
 
-        if (v > maxValue)
+        if (v > maxFloatValue)
         {
-          *p = std::numeric_limits<PixelType>::max();
+          *p = maxPixelValue;
         }
-        else if (v < minValue)
+        else if (v < minFloatValue)
         {
-          *p = std::numeric_limits<PixelType>::min();
+          *p = minPixelValue;
         }
         else
         {
-          *p = static_cast<PixelType>(boost::math::iround(v));
+          // The "round" operation is extremely costly. We use
+          // truncation instead since Orthanc 1.3.2.
+          
+          //*p = static_cast<PixelType>(boost::math::iround(v));
+          *p = static_cast<PixelType>(v);
         }
       }
     }