[gegl] stress/c2g: add enhance-shadows options, default to off



commit eaf2754d96b30a5353493d3347cba45925f6e49b
Author: Øyvind Kolås <pippin gimp org>
Date:   Mon Jan 29 00:02:51 2018 +0100

    stress/c2g: add enhance-shadows options, default to off
    
    The local exposure adjusement only / only looking at local white-point for c2g
    results are less noisy, and for stress the result is a more useful tonemapping
    operator with this new default off state.

 operations/common/c2g.c       |   67 +++++++++++++++++++++++++++++++++++++---
 operations/common/envelopes.h |   11 ++++--
 operations/common/stress.c    |   67 ++++++++++++++++++++++++++++++++++------
 3 files changed, 126 insertions(+), 19 deletions(-)
---
diff --git a/operations/common/c2g.c b/operations/common/c2g.c
index 73b647f..46c0bbc 100644
--- a/operations/common/c2g.c
+++ b/operations/common/c2g.c
@@ -13,9 +13,9 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with GEGL; if not, see <http://www.gnu.org/licenses/>.
  *
- * Copyright 2007,2009 Øyvind Kolås     <pippin gimp org>
- *                     Ivar Farup       <ivarf hig no>
- *                     Allesandro Rizzi <rizzi dti unimi it>
+ * Copyright 2007,2009,2018 Øyvind Kolås     <pippin gimp org>
+ *           2007           Ivar Farup       <ivarf hig no>
+ *           2007           Allesandro Rizzi <rizzi dti unimi it>
  */
 
 #include "config.h"
@@ -44,6 +44,9 @@ property_int (iterations, _("Iterations"), 10)
   value_range (1, 1000)
   ui_range (1, 30)
 
+property_boolean (enhance_shadows, _("Enhance Shadows"), FALSE)
+    description(_("When enabled details in shadows are boosted at the expense of noise"))
+
 /*
 property_double (rgamma, _("Radial Gamma"), 0.0, 8.0, 2.0,
                 _("Gamma applied to radial distribution"))
@@ -81,6 +84,7 @@ static void c2g (GeglOperation       *op,
     GeglBufferIterator *i = gegl_buffer_iterator_new (dst, dst_rect, 0, babl_format("YA float"),
                                                       GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);
     GeglSampler *sampler = gegl_buffer_sampler_new_at_level (src, format, GEGL_SAMPLER_NEAREST, level);
+    GeglSamplerGetFun getfun = gegl_sampler_get_fun (sampler);
 #if 0
     float total_pix = dst_rect->width * dst_rect->height;
 #endif
@@ -92,6 +96,8 @@ static void c2g (GeglOperation       *op,
       gint    dst_offset=0;
       gfloat *dst_buf = i->data[0];
 
+      if (GEGL_PROPERTIES(op)->enhance_shadows)
+      {
       for (y=i->roi[0].y; y < i->roi[0].y + i->roi[0].height; y++)
         {
           for (x=i->roi[0].x; x < i->roi[0].x + i->roi[0].width; x++)
@@ -100,7 +106,7 @@ static void c2g (GeglOperation       *op,
               gfloat  max[4];
               gfloat  pixel[4];
 
-              compute_envelopes (src, sampler,
+              compute_envelopes (src, sampler, getfun,
                                  x, y,
                                  radius, samples,
                                  iterations,
@@ -143,10 +149,61 @@ static void c2g (GeglOperation       *op,
 
             pix_done += i->roi[0].width;
           }
+      }
+      else
+      {
+        for (y=i->roi[0].y; y < i->roi[0].y + i->roi[0].height; y++)
+          for (x=i->roi[0].x; x < i->roi[0].x + i->roi[0].width; x++)
+            {
+              gfloat  max[4];
+              gfloat  pixel[4];
+
+              compute_envelopes (src, sampler, getfun,
+                                 x, y,
+                                 radius, samples,
+                                 iterations,
+                                 FALSE, /* same spray */
+                                 rgamma,
+                                 NULL, max, pixel, format);
+              {
+                /* this should be replaced with a better/faster projection of
+                 * pixel onto the vector spanned by min -> max, currently
+                 * computed by comparing the distance to min with the sum
+                 * of the distance to min/max.
+                 */
+
+                gfloat nominator = 0;
+                gfloat denominator = 0;
+                gint c;
+                for (c=0; c<3; c++)
+                  {
+                    nominator   += pixel[c] * pixel[c];
+                    denominator += (pixel[c] - max[c]) * (pixel[c] - max[c]);
+                  }
+
+                nominator = sqrtf (nominator);
+                denominator = sqrtf (denominator);
+                denominator = nominator + denominator;
+
+                if (denominator>0.000)
+                  {
+                    dst_buf[dst_offset+0] = nominator/denominator;
+                  }
+                else
+                  {
+                    /* shouldn't happen */
+                    dst_buf[dst_offset+0] = 0.5;
+                  }
+                dst_buf[dst_offset+1] = pixel[3];
+                dst_offset+=2;
+              }
+            }
+            pix_done += i->roi[0].width;
+          }
+      }
 #if 0
         gegl_operation_progress (op, pix_done / total_pix, "");
 #endif
-    }
     g_object_unref (sampler);
   }
 }
diff --git a/operations/common/envelopes.h b/operations/common/envelopes.h
index 1cf22e9..87a7f5e 100644
--- a/operations/common/envelopes.h
+++ b/operations/common/envelopes.h
@@ -54,6 +54,7 @@ static void compute_luts(gdouble rgamma)
 static inline void
 sample_min_max (GeglBuffer  *buffer,
                 GeglSampler *sampler,
+                GeglSamplerGetFun getfun,
                 gint         x,
                 gint         y,
                 gint         radius,
@@ -109,7 +110,7 @@ retry:                      /* if we've sampled outside the valid image
 
       {
         gfloat pixel[4];
-        gegl_sampler_get (sampler, u, v, NULL, (void*)(&pixel[0]), GEGL_ABYSS_CLAMP);
+        getfun (sampler, u, v, NULL, (void*)(&pixel[0]), GEGL_ABYSS_CLAMP);
 
         if (pixel[3]>0.0) /* ignore fully transparent pixels */
           {
@@ -137,8 +138,9 @@ retry:                      /* if we've sampled outside the valid image
     }
 }
 
-static inline void compute_envelopes (GeglBuffer *buffer,
-                                      GeglSampler *sampler,
+static inline void compute_envelopes (GeglBuffer       *buffer,
+                                      GeglSampler      *sampler,
+                                      GeglSamplerGetFun getfun,
                                       gint     x,
                                       gint     y,
                                       gint     radius,
@@ -156,7 +158,7 @@ static inline void compute_envelopes (GeglBuffer *buffer,
   gfloat  range_sum[4]               = {0,0,0,0};
   gfloat  relative_brightness_sum[4] = {0,0,0,0};
 
-  gegl_sampler_get (sampler, x, y, NULL, (void*)(&pixel[0]), GEGL_ABYSS_CLAMP);
+  getfun (sampler, x, y, NULL, (void*)(&pixel[0]), GEGL_ABYSS_CLAMP);
 
   /* compute lookuptables for the gamma, currently not used/exposed
    * as a tweakable property */
@@ -174,6 +176,7 @@ static inline void compute_envelopes (GeglBuffer *buffer,
 
       sample_min_max (buffer,
                       sampler,
+                      getfun,
                       x, y,
                       radius, samples,
                       min, max, pixel, format);
diff --git a/operations/common/stress.c b/operations/common/stress.c
index 7007df5..a17e434 100644
--- a/operations/common/stress.c
+++ b/operations/common/stress.c
@@ -13,9 +13,9 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with GEGL; if not, see <http://www.gnu.org/licenses/>.
  *
- * Copyright 2007 Øyvind Kolås     <oeyvindk hig no>
- *                Ivar Farup       <ivarf hig no>
- *                Allesandro Rizzi <rizzi dti unimi it>
+ * Copyright 2007,2009,2018 Øyvind Kolås     <pippin gimp org>
+ *           2007           Ivar Farup       <ivarf hig no>
+ *           2007           Allesandro Rizzi <rizzi dti unimi it>
  */
 
 #include "config.h"
@@ -41,6 +41,9 @@ property_int (iterations, _("Iterations"), 5)
     value_range (1, 1000)
     ui_range    (1, 30)
 
+property_boolean (enhance_shadows, _("Enhance Shadows"), FALSE)
+    description(_("When enabled also enhances shadow regions - when disabled a more natural result is 
yielded"))
+
 /*
 
 property_double (rgamma, _("Radial Gamma"), 0.0, 8.0, 2.0,
@@ -73,6 +76,7 @@ static void stress (GeglBuffer          *src,
                     gint                 samples,
                     gint                 iterations,
                     gdouble              rgamma,
+                    gboolean             enhance_shadows,
                     gint                 level)
 {
   const Babl *format = babl_format ("RGBA float");
@@ -82,6 +86,7 @@ static void stress (GeglBuffer          *src,
     GeglBufferIterator *i = gegl_buffer_iterator_new (dst, dst_rect, 0, babl_format("RaGaBaA float"),
                                                       GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);
     GeglSampler *sampler = gegl_buffer_sampler_new_at_level (src, format, GEGL_SAMPLER_NEAREST, level);
+    GeglSamplerGetFun getfun = gegl_sampler_get_fun (sampler);
 
     while (gegl_buffer_iterator_next (i))
     {
@@ -89,15 +94,16 @@ static void stress (GeglBuffer          *src,
       gint    dst_offset=0;
       gfloat *dst_buf = i->data[0];
 
-      for (y=i->roi[0].y; y < i->roi[0].y + i->roi[0].height; y++)
-        {
+      if (enhance_shadows)
+      {
+        for (y=i->roi[0].y; y < i->roi[0].y + i->roi[0].height; y++)
           for (x=i->roi[0].x; x < i->roi[0].x + i->roi[0].width; x++)
             {
               gfloat  min[4];
               gfloat  max[4];
               gfloat  pixel[4];
 
-              compute_envelopes (src, sampler,
+              compute_envelopes (src, sampler, getfun,
                                  x, y,
                                  radius, samples,
                                  iterations,
@@ -117,8 +123,7 @@ static void stress (GeglBuffer          *src,
                   gfloat delta = max[c]-min[c];
                   if (delta != 0)
                     {
-                      dst_buf[dst_offset+c] =
-                         (pixel[c]-min[c])/delta;
+                      dst_buf[dst_offset+c] = (pixel[c]-min[c])/delta;
                     }
                   else
                     {
@@ -130,7 +135,47 @@ static void stress (GeglBuffer          *src,
                 dst_offset+=4;
               }
             }
-          }
+      }
+      else
+      {
+        for (y=i->roi[0].y; y < i->roi[0].y + i->roi[0].height; y++)
+          for (x=i->roi[0].x; x < i->roi[0].x + i->roi[0].width; x++)
+            {
+              gfloat  max[4];
+              gfloat  pixel[4];
+
+              compute_envelopes (src, sampler, getfun,
+                                 x, y,
+                                 radius, samples,
+                                 iterations,
+                                 FALSE, /* same spray */
+                                 rgamma,
+                                 NULL, max, pixel, format);
+              {
+                /* this should be replaced with a better/faster projection of
+                 * pixel onto the vector spanned by min -> max, currently
+                 * computed by comparing the distance to min with the sum
+                 * of the distance to min/max.
+                 */
+
+              gint c;
+              for (c=0;c<3;c++)
+                {
+                  gfloat delta = max[c];
+                  if (delta != 0)
+                    {
+                      dst_buf[dst_offset+c] = (pixel[c])/delta;
+                    }
+                  else
+                    {
+                      dst_buf[dst_offset+c] = 0.5;
+                    }
+                }
+                dst_buf[dst_offset+3] = pixel[3];
+                dst_offset+=4;
+              }
+            }
+      }
     }
     g_object_unref (sampler);
   }
@@ -172,7 +217,9 @@ process (GeglOperation       *operation,
           o->radius,
           o->samples,
           o->iterations,
-          RGAMMA /*o->rgamma,*/, level);
+          RGAMMA /*o->rgamma,*/,
+          o->enhance_shadows,
+          level);
 
   return  TRUE;
 }


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