[gimp] app: port gimp:shapeburst's input from u8 to float



commit 540d3bb6ae2dc8f62101600564279e6de2393362
Author: Michael Natterer <mitch gimp org>
Date:   Thu May 1 20:32:26 2014 +0200

    app: port gimp:shapeburst's input from u8 to float

 app/core/gimpdrawable-blend.c            |    6 +--
 app/operations/gimpoperationshapeburst.c |   46 +++++++++++++++++-------------
 2 files changed, 28 insertions(+), 24 deletions(-)
---
diff --git a/app/core/gimpdrawable-blend.c b/app/core/gimpdrawable-blend.c
index 7d3b91f..24bf184 100644
--- a/app/core/gimpdrawable-blend.c
+++ b/app/core/gimpdrawable-blend.c
@@ -550,12 +550,10 @@ gradient_precalc_shapeburst (GimpImage           *image,
                                  babl_format ("Y float"));
 
   /*  allocate the selection mask copy
-   *  XXX: its format should be the same of gimp:shapeburst input buffer
-   *       porting the op to 'float' should be reflected here as well
    */
   temp_buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0,
                                                  region->width, region->height),
-                                 babl_format ("Y u8"));
+                                 babl_format ("Y float"));
 
   mask = gimp_image_get_mask (image);
 
@@ -581,7 +579,7 @@ gradient_precalc_shapeburst (GimpImage           *image,
         {
           const Babl *component_format;
 
-          component_format = babl_format ("A u8");
+          component_format = babl_format ("A float");
 
           /*  extract the aplha into the temp mask  */
           gegl_buffer_set_format (temp_buffer, component_format);
diff --git a/app/operations/gimpoperationshapeburst.c b/app/operations/gimpoperationshapeburst.c
index 14a311a..f45e3f2 100644
--- a/app/operations/gimpoperationshapeburst.c
+++ b/app/operations/gimpoperationshapeburst.c
@@ -163,7 +163,7 @@ gimp_operation_shapeburst_set_property (GObject      *object,
 static void
 gimp_operation_shapeburst_prepare (GeglOperation *operation)
 {
-  gegl_operation_set_format (operation, "input",  babl_format ("Y u8"));
+  gegl_operation_set_format (operation, "input",  babl_format ("Y float"));
   gegl_operation_set_format (operation, "output", babl_format ("Y float"));
 }
 
@@ -189,7 +189,7 @@ gimp_operation_shapeburst_process (GeglOperation       *operation,
                                    const GeglRectangle *roi,
                                    gint                 level)
 {
-  const Babl *input_format   = babl_format ("Y u8");
+  const Babl *input_format   = babl_format ("Y float");
   const Babl *output_format  = babl_format ("Y float");
   gfloat      max_iterations = 0.0;
   gfloat     *distp_cur;
@@ -211,7 +211,7 @@ gimp_operation_shapeburst_process (GeglOperation       *operation,
   for (i = 0; i < roi->height; i++)
     {
       gfloat *tmp;
-      gint    src = 0;
+      gfloat  src = 0.0;
       gint    j;
 
       /*  set the current dist row to 0's  */
@@ -223,13 +223,23 @@ gimp_operation_shapeburst_process (GeglOperation       *operation,
           gfloat min_prev = MIN (distp_cur[j-1], distp_prev[j]);
           gint   min_left = MIN ((roi->width - j - 1), (roi->height - i - 1));
           gint   min      = (gint) MIN (min_left, min_prev);
-          gint   fraction = 255;
+          gfloat fraction = 1.0;
           gint   k;
 
-          /*  This might need to be changed to 0
-              instead of k = (min) ? (min - 1) : 0  */
-
-          for (k = (min) ? (min - 1) : 0; k <= min; k++)
+#define EPSILON 0.0001
+
+          /*  This loop used to start at "k = (min) ? (min - 1) : 0"
+           *  and this comment suggested it might have to be changed to
+           *  "k = 0", but "k = 0" increases processing time significantly.
+           *
+           *  When porting this to float, i noticed that starting at
+           *  "min - 2" gets rid of a lot of 8-bit artifacts, while starting
+           *  at "min - 3" or smaller would introduce different artifacts.
+           *
+           *  Note that I didn't really understand the entire algorithm,
+           *  I just "blindly" ported it to float :) --mitch
+           */
+          for (k = MAX (min - 2, 0); k <= min; k++)
             {
               gint x   = j;
               gint y   = i + k;
@@ -237,24 +247,20 @@ gimp_operation_shapeburst_process (GeglOperation       *operation,
 
               while (y >= end)
                 {
-                  guchar src_uchar;
-
 #if 1
                   /* FIXME: this should be much faster, it converts
                    * to 32 bit rgba intermediately, bah...
                    */
-                  gegl_buffer_sample (input, x, y, NULL, &src_uchar,
+                  gegl_buffer_sample (input, x, y, NULL, &src,
                                       input_format,
                                       GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
 #else
                   gegl_buffer_get (input, GEGL_RECTANGLE (x, y, 1, 1), 1.0,
-                                   input_format, &src_uchar,
+                                   input_format, &src,
                                    GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
 #endif
 
-                  src = src_uchar;
-
-                  if (src == 0)
+                  if (ABS (src) < EPSILON)
                     {
                       min = k;
                       y = -1;
@@ -269,17 +275,17 @@ gimp_operation_shapeburst_process (GeglOperation       *operation,
                 }
             }
 
-          if (src != 0)
+          if (src > EPSILON)
             {
               /*  If min_left != min_prev use the previous fraction
                *   if it is less than the one found
                */
               if (min_left != min)
                 {
-                  gint prev_frac = (int) (255 * (min_prev - min));
+                  gfloat prev_frac = min_prev - min;
 
-                  if (prev_frac == 255)
-                    prev_frac = 0;
+                  if (ABS (prev_frac - 1.0) < EPSILON)
+                    prev_frac = 0.0;
 
                   fraction = MIN (fraction, prev_frac);
                 }
@@ -287,7 +293,7 @@ gimp_operation_shapeburst_process (GeglOperation       *operation,
               min++;
             }
 
-          float_tmp = distp_cur[j] = min + fraction / 256.0;
+          float_tmp = distp_cur[j] = min + fraction * (1.0 - EPSILON);
 
           if (float_tmp > max_iterations)
             max_iterations = float_tmp;


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