[gegl] noise-rgb: add linear and gaussian properties



commit 2d4f9185bf0144f9af723ee7b17745b25897df2e
Author: Øyvind Kolås <pippin gimp org>
Date:   Thu Dec 22 23:00:18 2016 +0100

    noise-rgb: add linear and gaussian properties
    
    Makes it possible to specify wheter the dithering is applied to linear RGB or
    sRGB gamm TRC image data, also makes the error distribution possibly to specify,
    a gaussina noise distribution isn't well suited for precisely adding the
    maximum amount of noise for a no side-effect round trip.
    
    This should fix bug #758236

 operations/common/noise-rgb.c |   44 ++++++++++++++++++++++++++++++++--------
 1 files changed, 35 insertions(+), 9 deletions(-)
---
diff --git a/operations/common/noise-rgb.c b/operations/common/noise-rgb.c
index a8414b7..eae0c42 100644
--- a/operations/common/noise-rgb.c
+++ b/operations/common/noise-rgb.c
@@ -17,7 +17,7 @@
  * Copyright 1996 Torsten Martinsen
  * Copyright 2000 Tim Copperfield <timecop japan co jp>
  * Copyright 2012 Maxime Nicco <maxime nicco gmail com>
- * Copyright 2012 Øyvind Kolås <pippin gimp org>
+ * Copyright 2012,2016 Øyvind Kolås <pippin gimp org>
  */
 
 #include "config.h"
@@ -28,6 +28,13 @@
 property_boolean (correlated, _("Correlated noise"), FALSE)
 
 property_boolean (independent, _("Independent RGB"), TRUE)
+   description (_("Control amount of noise for each RGB channel separately"))
+
+property_boolean (linear, _("Linear RGB"), TRUE)
+   description (_("Operate on linearized RGB color data"))
+
+property_boolean (gaussian, _("Gaussian distribution"), TRUE)
+   description (_("Use a gaussian noise distribution, when unticked a linear noise distribution is used 
instead"))
 
 property_double (red, _("Red"), 0.20)
    value_range  (0.0, 1.0)
@@ -62,10 +69,10 @@ property_seed (seed, _("Random seed"), rand)
  * Ratio method (Kinderman-Monahan); see Knuth v2, 3rd ed, p130
  * K+M, ACM Trans Math Software 3 (1977) 257-260.
 */
-static gdouble
-gauss (GeglRandom *rand, int *i, int xx, int yy)
+static gfloat
+noise_gauss (GeglRandom *rand, int *i, int xx, int yy)
 {
-  gdouble u, v, x;
+  gfloat u, v, x;
 
   do
   {
@@ -76,18 +83,33 @@ gauss (GeglRandom *rand, int *i, int xx, int yy)
     while (u == 0);
 
     /* Const 1.715... = sqrt(8/e) */
-    x = 1.71552776992141359295 * (v - 0.5) / u;
+    x = 1.71552776992141359295 * (v - 0.5f) / u;
   }
-  while (x * x > -4.0 * log (u));
+  while (x * x > -4.0f * logf (u));
 
   return x;
 }
 
+static gfloat
+noise_linear (GeglRandom *rand, int *i, int xx, int yy)
+{
+  return gegl_random_float (rand, xx, yy, 0, (*i)++) * 2 - 1.0;
+}
+
 static void
 prepare (GeglOperation *operation)
 {
-  gegl_operation_set_format (operation, "input", babl_format ("RGBA float"));
-  gegl_operation_set_format (operation, "output", babl_format ("RGBA float"));
+  GeglProperties *o  = GEGL_PROPERTIES (operation);
+  if (o->linear)
+    {
+      gegl_operation_set_format (operation, "input", babl_format ("RGBA float"));
+      gegl_operation_set_format (operation, "output", babl_format ("RGBA float"));
+    }
+  else
+    {
+      gegl_operation_set_format (operation, "input", babl_format ("R'G'B'A float"));
+      gegl_operation_set_format (operation, "output", babl_format ("R'G'B'A float"));
+    }
 }
 
 static gboolean
@@ -108,6 +130,7 @@ process (GeglOperation       *operation,
   gfloat   tmp;
   gfloat   * GEGL_ALIGNED in_pixel;
   gfloat   * GEGL_ALIGNED out_pixel;
+  gfloat   (*noise_fun) (GeglRandom *rand, int *i, int xx, int yy) = noise_gauss;
 
   in_pixel   = in_buf;
   out_pixel  = out_buf;
@@ -117,6 +140,9 @@ process (GeglOperation       *operation,
   noise[2] = o->blue;
   noise[3] = o->alpha;
 
+  if (o->gaussian == FALSE)
+    noise_fun = noise_linear;
+
   x = roi->x;
   y = roi->y;
 
@@ -125,7 +151,7 @@ process (GeglOperation       *operation,
     for (b = 0; b < 4; b++)
     {
       if (b == 0 || o->independent || b == 3 )
-         noise_coeff = noise[b] * gauss (o->rand, &rint, x, y) * 0.5;
+         noise_coeff = noise[b] * noise_fun (o->rand, &rint, x, y) * 0.5;
 
       if (noise[b] > 0.0)
       {


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