[gegl] shadows-highlights-correction: Prefer copysignf to SIGN



commit 8d5074b3ce64e7084b1cc841c36ed4c08986956f
Author: Debarshi Ray <debarshir gnome org>
Date:   Fri Jan 5 09:30:17 2018 +0100

    shadows-highlights-correction: Prefer copysignf to SIGN
    
    GCC optimizes copysignf much better than SIGN because it can copy the
    sign bit using bitwise boolean operations.
    
    For example, according to https://godbolt.org/g/GQHxhd, this code:
    
    #include <math.h>
    
    float
    bar (float n)
    {
        float n_sign = copysignf (1.0f, n);
        return n_sign;
    }
    
    float
    foo (float n)
    {
        float n_sign = n < 0.0f ? -1.0f : 1.0f;
        return n_sign;
    }
    
    ... generates:
    
    bar(float):
      andps xmm0, XMMWORD PTR .LC1[rip]
      orps xmm0, XMMWORD PTR .LC0[rip]
      ret
    foo(float):
      pxor xmm1, xmm1
      ucomiss xmm1, xmm0
      ja .L5
      movss xmm0, DWORD PTR .LC3[rip]
      ret
    .L5:
      movss xmm0, DWORD PTR .LC2[rip]
      ret
    .LC0:
      .long 1065353216
      .long 0
      .long 0
      .long 0
    .LC1:
      .long 2147483648
      .long 0
      .long 0
      .long 0
    .LC2:
      .long 3212836864
    .LC3:
      .long 1065353216
    
    The SIGN macro doesn't differentiate between negative and positive
    zero, and is therefore not identical to copysignf. However, in cases,
    where the variable lies within a known range and isn't expected to be
    incremented in infinitesimally small steps, the distinction between
    positive and negative zero doesn't matter. For example, the highlights
    and shadows properties. They lie between [-100.0, 100.0] and are not
    expected to be incremented in such tiny steps that would cause them to
    be rounded off to zero.

 .../common-gpl3+/shadows-highlights-correction.c   |   12 ++++++++----
 1 files changed, 8 insertions(+), 4 deletions(-)
---
diff --git a/operations/common-gpl3+/shadows-highlights-correction.c 
b/operations/common-gpl3+/shadows-highlights-correction.c
index 8d4b42d..8378a49 100644
--- a/operations/common-gpl3+/shadows-highlights-correction.c
+++ b/operations/common-gpl3+/shadows-highlights-correction.c
@@ -90,8 +90,10 @@ process (GeglOperation       *operation,
 
   gfloat shadows;
   gfloat shadows_100 = (gfloat) o->shadows / 100.0f;
+  gfloat shadows_sign;
   gfloat highlights;
   gfloat highlights_100 = (gfloat) o->highlights / 100.0f;
+  gfloat highlights_sign_negated;
   gfloat whitepoint = 1.0f - (gfloat) o->whitepoint / 100.0f;
   gfloat compress;
 
@@ -108,15 +110,17 @@ process (GeglOperation       *operation,
 
   g_return_val_if_fail (-1.0f <= highlights_100 && highlights_100 <= 1.0f, FALSE);
   highlights = 2.0f * highlights_100;
+  highlights_sign_negated = copysignf (1.0f, -highlights);
 
   g_return_val_if_fail (0.0f <= highlights_ccorrect_100 && highlights_ccorrect_100 <= 1.0f, FALSE);
-  highlights_ccorrect = (highlights_ccorrect_100 - 0.5f) * SIGN (-highlights) + 0.5f;
+  highlights_ccorrect = (highlights_ccorrect_100 - 0.5f) * highlights_sign_negated + 0.5f;
 
   g_return_val_if_fail (-1.0f <= shadows_100 && shadows_100 <= 1.0f, FALSE);
   shadows = 2.0f * shadows_100;
+  shadows_sign = copysignf (1.0f, shadows);
 
   g_return_val_if_fail (0.0f <= shadows_ccorrect_100 && shadows_ccorrect_100 <= 1.0f, FALSE);
-  shadows_ccorrect = (shadows_ccorrect_100 - 0.5f) * SIGN (shadows) + 0.5f;
+  shadows_ccorrect = (shadows_ccorrect_100 - 0.5f) * shadows_sign + 0.5f;
 
   g_return_val_if_fail (whitepoint >= 0.01f, FALSE);
 
@@ -156,7 +160,7 @@ process (GeglOperation       *operation,
               gfloat la_abs;
               gfloat la_inverted = 1.0f - la;
               gfloat la_inverted_abs;
-              gfloat lb = (tb0 - 0.5f) * SIGN(-highlights) * SIGN(la_inverted) + 0.5f;
+              gfloat lb = (tb0 - 0.5f) * highlights_sign_negated * SIGN(la_inverted) + 0.5f;
 
               la_abs = fabsf (la);
               lref = copysignf(la_abs > low_approximation ? 1.0f / la_abs : 1.0f / low_approximation, la);
@@ -198,7 +202,7 @@ process (GeglOperation       *operation,
             gfloat la_abs;
             gfloat la_inverted = 1.0f - la;
             gfloat la_inverted_abs;
-            gfloat lb = (tb0 - 0.5f) * SIGN(shadows) * SIGN(la_inverted) + 0.5f;
+            gfloat lb = (tb0 - 0.5f) * shadows_sign * SIGN(la_inverted) + 0.5f;
 
             la_abs = fabsf (la);
             lref = copysignf(la_abs > low_approximation ? 1.0f / la_abs : 1.0f / low_approximation, la);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]