[gegl] bayer-matrix, linear-sinusoid: use odd power function



commit 0f19d3bf25361a0e176bed70b8a882af36a1359e
Author: Ell <ell_se yahoo com>
Date:   Sun Feb 5 11:56:10 2017 -0500

    bayer-matrix, linear-sinusoid: use odd power function
    
    Avoids NaNs for negative values when using non-integer exponents.

 operations/workshop/bayer-matrix.c    |   21 ++++++++++++++++-----
 operations/workshop/linear-sinusoid.c |   14 ++++++++++++--
 2 files changed, 28 insertions(+), 7 deletions(-)
---
diff --git a/operations/workshop/bayer-matrix.c b/operations/workshop/bayer-matrix.c
index 7303847..8f949ad 100644
--- a/operations/workshop/bayer-matrix.c
+++ b/operations/workshop/bayer-matrix.c
@@ -52,7 +52,7 @@ property_double (offset, _("Offset"), 0.5)
   value_range (-G_MAXDOUBLE, G_MAXDOUBLE)
   ui_range    (0.0, 1.0)
 
-property_double  (exponent, _("Exponent"), 1.0)
+property_double (exponent, _("Exponent"), 1.0)
   description(_("Value exponent"))
   value_range (0.0, G_MAXDOUBLE)
   ui_range    (0.0, 10.0)
@@ -82,6 +82,16 @@ property_int (y_offset, _("Y Offset"), 0)
 
 #define GEGL_BAYER_MATRIX_MAX_LUT_SUBDIVISIONS 8
 
+static inline gfloat
+odd_powf (gfloat base,
+          gfloat exponent)
+{
+  if (base >= 0.0f)
+    return  powf ( base, exponent);
+  else
+    return -powf (-base, exponent);
+}
+
 static void
 finalize (GObject *object)
 {
@@ -102,6 +112,7 @@ value_at (GeglProperties *o,
           gint            x,
           gint            y)
 {
+  gint  i;
   guint value = 0;
 
   static const gint subdivision_value_luts[2 /* reflection */]
@@ -141,7 +152,7 @@ value_at (GeglProperties *o,
 
   subdivision_values = subdivision_value_luts[o->reflect][o->rotation];
 
-  for (gint i = 0; i < o->subdivisions; i++)
+  for (i = 0; i < o->subdivisions; i++)
     {
       value <<= 2;
       value  |= subdivision_values[y & 1][x & 1];
@@ -149,9 +160,9 @@ value_at (GeglProperties *o,
       y     >>= 1;
     }
 
-  return powf (o->offset - .5f +
-               2.f * o->amplitude * (value + .5f) / (1u << (2 * o->subdivisions)),
-               o->exponent);
+  return odd_powf (o->offset - .5f +
+                   2.f * o->amplitude * (value + .5f) / (1u << (2 * o->subdivisions)),
+                   o->exponent);
 }
 
 static void
diff --git a/operations/workshop/linear-sinusoid.c b/operations/workshop/linear-sinusoid.c
index 998d223..f1b3532 100644
--- a/operations/workshop/linear-sinusoid.c
+++ b/operations/workshop/linear-sinusoid.c
@@ -110,6 +110,16 @@ property_int (supersampling, _("Supersampling"), 1)
 #include "gegl-op.h"
 #include <math.h>
 
+static inline gdouble
+odd_pow (gdouble base,
+         gdouble exponent)
+{
+  if (base >= 0.0)
+    return  pow ( base, exponent);
+  else
+    return -pow (-base, exponent);
+}
+
 static void
 prepare (GeglOperation *operation)
 {
@@ -200,7 +210,7 @@ process (GeglOperation       *operation,
               z = o->offset                -
                   o->x_amplitude * cos (x) -
                   o->y_amplitude * cos (y);
-              z = pow (z, o->exponent);
+              z = odd_pow (z, o->exponent);
             }
           else
             {
@@ -221,7 +231,7 @@ process (GeglOperation       *operation,
                       w = o->offset                -
                           o->x_amplitude * cos (u) -
                           o->y_amplitude * cos (v);
-                      w = pow (w, o->exponent);
+                      w = odd_pow (w, o->exponent);
 
                       z += w;
 


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