[gegl] noise-hurl: special case grayscale inputs



commit 473487039abd18569695536b2d49b42f9faa3bbf
Author: Øyvind Kolås <pippin gimp org>
Date:   Thu Sep 14 16:03:27 2017 +0200

    noise-hurl: special case grayscale inputs
    
    Weighting randomized independent R,G,B to produce luminance does not gives a
    different luminance distribution compared to RGB distribution.
    
    Fixing bug #787661

 opencl/noise-hurl.cl           |   26 ++++++++++++++++++--------
 opencl/noise-hurl.cl.h         |   26 ++++++++++++++++++--------
 operations/common/noise-hurl.c |   36 ++++++++++++++++++++++++++++++++----
 3 files changed, 68 insertions(+), 20 deletions(-)
---
diff --git a/opencl/noise-hurl.cl b/opencl/noise-hurl.cl
index ccb44be..ef54343 100644
--- a/opencl/noise-hurl.cl
+++ b/opencl/noise-hurl.cl
@@ -24,6 +24,7 @@ __kernel void cl_noise_hurl(__global       float4    *src,
                                            int        whole_region_width,
                                            GeglRandom rand,
                                            float      pct_random,
+                                           int        gray,
                                            int        offset)
 {
   int gid  = get_global_id(0);
@@ -38,18 +39,27 @@ __kernel void cl_noise_hurl(__global       float4    *src,
 
   float pc          = gegl_cl_random_float_range (random_data,
                                                   rand, x, y, 0, n, 0, 100);
-  float red_noise   = gegl_cl_random_float (random_data,
-                                            rand, x, y, 0, n+1);
-  float green_noise = gegl_cl_random_float (random_data,
-                                            rand, x, y, 0, n+2);
-  float blue_noise  = gegl_cl_random_float (random_data,
-                                            rand, x, y, 0, n+3);
 
   if(pc <= pct_random)
     {
+      float red_noise   = gegl_cl_random_float (random_data,
+                                                rand, x, y, 0, n+1);
+
       src_v.x = red_noise;
-      src_v.y = green_noise;
-      src_v.z = blue_noise;
+      if (gray == 0)
+      {
+        float green_noise = gegl_cl_random_float (random_data,
+                                                  rand, x, y, 0, n+2);
+        float blue_noise  = gegl_cl_random_float (random_data,
+                                                  rand, x, y, 0, n+3);
+        src_v.y = green_noise;
+        src_v.z = blue_noise;
+      }
+      else
+      {
+        src_v.y = red_noise;
+        src_v.z = red_noise;
+      }
     }
   src[gid] = src_v;
 }
diff --git a/opencl/noise-hurl.cl.h b/opencl/noise-hurl.cl.h
index b57b32b..6aad9cb 100644
--- a/opencl/noise-hurl.cl.h
+++ b/opencl/noise-hurl.cl.h
@@ -25,6 +25,7 @@ static const char* noise_hurl_cl_source =
 "                                           int        whole_region_width,     \n"
 "                                           GeglRandom rand,                   \n"
 "                                           float      pct_random,             \n"
+"                                           int        gray,                   \n"
 "                                           int        offset)                 \n"
 "{                                                                             \n"
 "  int gid  = get_global_id(0);                                                \n"
@@ -39,18 +40,27 @@ static const char* noise_hurl_cl_source =
 "                                                                              \n"
 "  float pc          = gegl_cl_random_float_range (random_data,                \n"
 "                                                  rand, x, y, 0, n, 0, 100);  \n"
-"  float red_noise   = gegl_cl_random_float (random_data,                      \n"
-"                                            rand, x, y, 0, n+1);              \n"
-"  float green_noise = gegl_cl_random_float (random_data,                      \n"
-"                                            rand, x, y, 0, n+2);              \n"
-"  float blue_noise  = gegl_cl_random_float (random_data,                      \n"
-"                                            rand, x, y, 0, n+3);              \n"
 "                                                                              \n"
 "  if(pc <= pct_random)                                                        \n"
 "    {                                                                         \n"
+"      float red_noise   = gegl_cl_random_float (random_data,                  \n"
+"                                                rand, x, y, 0, n+1);          \n"
+"                                                                              \n"
 "      src_v.x = red_noise;                                                    \n"
-"      src_v.y = green_noise;                                                  \n"
-"      src_v.z = blue_noise;                                                   \n"
+"      if (gray == 0)                                                          \n"
+"      {                                                                       \n"
+"        float green_noise = gegl_cl_random_float (random_data,                \n"
+"                                                  rand, x, y, 0, n+2);        \n"
+"        float blue_noise  = gegl_cl_random_float (random_data,                \n"
+"                                                  rand, x, y, 0, n+3);        \n"
+"        src_v.y = green_noise;                                                \n"
+"        src_v.z = blue_noise;                                                 \n"
+"      }                                                                       \n"
+"      else                                                                    \n"
+"      {                                                                       \n"
+"        src_v.y = red_noise;                                                  \n"
+"        src_v.z = red_noise;                                                  \n"
+"      }                                                                       \n"
 "    }                                                                         \n"
 "  src[gid] = src_v;                                                           \n"
 "}                                                                             \n"
diff --git a/operations/common/noise-hurl.c b/operations/common/noise-hurl.c
index 5f2d516..5791e50 100644
--- a/operations/common/noise-hurl.c
+++ b/operations/common/noise-hurl.c
@@ -34,7 +34,7 @@ property_double (pct_random, _("Randomization (%)"), 50.0)
 property_int   (repeat, _("Repeat"), 1)
    value_range (1, 100)
 
-property_seed (seed, _("Random seed"), rand) 
+property_seed (seed, _("Random seed"), rand)
 
 #else
 
@@ -47,8 +47,25 @@ property_seed (seed, _("Random seed"), rand)
 static void
 prepare (GeglOperation *operation)
 {
+  const Babl *input_format = gegl_operation_get_source_format (operation, "input");
+  GeglProperties *o        = GEGL_PROPERTIES (operation);
+
   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"));
+
+  if (input_format)
+    {
+      if (babl_format_get_model (input_format) == babl_model ("Y'") ||
+          babl_format_get_model (input_format) == babl_model ("Y'A") ||
+          babl_format_get_model (input_format) == babl_model ("Y") ||
+          babl_format_get_model (input_format) == babl_model ("YA"))
+        o->user_data = (void*)0x1;
+
+      /* a bit hacky, signaling of data being grayscale data and only
+         temporarily in RGBA - performance could be improved by having
+         dedicated code paths for gray formats.
+       */
+    }
 }
 
 static gboolean
@@ -87,9 +104,18 @@ process (GeglOperation       *operation,
             if (gegl_random_float_range (o->rand, x, y, 0, n, 0.0, 100.0) <=
                 o->pct_random)
               {
-                red   = gegl_random_float (o->rand, x, y, 0, n+1);
-                green = gegl_random_float (o->rand, x, y, 0, n+2);
-                blue  = gegl_random_float (o->rand, x, y, 0, n+3);
+                if (o->user_data) /* input format was greyscale */
+                {
+                  red   =
+                  green =
+                  blue  = gegl_random_float (o->rand, x, y, 0, n+3);
+                }
+                else
+                {
+                  red   = gegl_random_float (o->rand, x, y, 0, n+1);
+                  green = gegl_random_float (o->rand, x, y, 0, n+2);
+                  blue  = gegl_random_float (o->rand, x, y, 0, n+3);
+                }
                 break;
               }
           }
@@ -125,6 +151,7 @@ cl_process (GeglOperation       *operation,
   cl_int      cl_err           = 0;
   cl_mem      cl_random_data   = NULL;
   cl_float    pct_random       = o->pct_random;
+  cl_int      gray             = o->user_data ? 1 : 0;
   cl_int      x_offset         = roi->x;
   cl_int      y_offset         = roi->y;
   cl_int      roi_width        = roi->width;
@@ -164,6 +191,7 @@ cl_process (GeglOperation       *operation,
                            sizeof(cl_int),   &wr_width,
                            sizeof(cl_ushort4), &rand,
                            sizeof(cl_float), &pct_random,
+                           sizeof(cl_int),   &gray,
                            NULL);
   CL_CHECK;
 


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