[gimp/gimp-2-10] app: fix gradient dithering



commit 91c20c783abd73849457ea586f760a7ec44d1f3c
Author: Ell <ell_se yahoo com>
Date:   Fri Jul 19 21:38:18 2019 +0300

    app: fix gradient dithering
    
    In gimp:gradient, fix dithering to correspond to how we actually
    round float values to 8-bit.  In particular, this avoids
    introducing noise when a component is fixed at 0 or 1 along a
    segment.
    
    (cherry picked from commit e22fcc8942963d7a1cfca57965d0385f073d5b3a)

 app/operations/gimpoperationgradient.c | 63 ++++++++++++++++++----------------
 1 file changed, 33 insertions(+), 30 deletions(-)
---
diff --git a/app/operations/gimpoperationgradient.c b/app/operations/gimpoperationgradient.c
index a10900d115..cc5251820c 100644
--- a/app/operations/gimpoperationgradient.c
+++ b/app/operations/gimpoperationgradient.c
@@ -158,6 +158,10 @@ static void            gradient_put_pixel                        (gint
                                                                   GimpRGB               *color,
                                                                   gpointer               put_pixel_data);
 
+static void            gradient_dither_pixel                     (GimpRGB               *color,
+                                                                  GRand                 *dither_rand,
+                                                                  gfloat                *dest);
+
 static gboolean        gimp_operation_gradient_process           (GeglOperation         *operation,
                                                                   GeglBuffer            *input,
                                                                   GeglBuffer            *output,
@@ -985,22 +989,9 @@ gradient_put_pixel (gint      x,
 
   if (ppd->dither_rand)
     {
-      gfloat r, g, b, a;
-      gint   i = g_rand_int (ppd->dither_rand);
-
-      r = color->r + (gdouble) (i & 0xff) / 256.0 / 256.0; i >>= 8;
-      g = color->g + (gdouble) (i & 0xff) / 256.0 / 256.0; i >>= 8;
-      b = color->b + (gdouble) (i & 0xff) / 256.0 / 256.0; i >>= 8;
-
-      if (color->a > 0.0 && color->a < 1.0)
-        a = color->a + (gdouble) (i & 0xff) / 256.0 / 256.0;
-      else
-        a = color->a;
+      gradient_dither_pixel (color, ppd->dither_rand, dest);
 
-      *dest++ = MAX (r, 0.0);
-      *dest++ = MAX (g, 0.0);
-      *dest++ = MAX (b, 0.0);
-      *dest++ = MAX (a, 0.0);
+      dest += 4;
     }
   else
     {
@@ -1011,6 +1002,31 @@ gradient_put_pixel (gint      x,
     }
 }
 
+static void
+gradient_dither_pixel (GimpRGB *color,
+                       GRand   *dither_rand,
+                       gfloat  *dest)
+{
+  gfloat r, g, b, a;
+  guint  i;
+
+  i = g_rand_int (dither_rand);
+
+  r = color->r + (gdouble) (i & 0xff) / 256.0 / 256.0 - 0.5 / 256.0; i >>= 8;
+  g = color->g + (gdouble) (i & 0xff) / 256.0 / 256.0 - 0.5 / 256.0; i >>= 8;
+  b = color->b + (gdouble) (i & 0xff) / 256.0 / 256.0 - 0.5 / 256.0; i >>= 8;
+
+  if (color->a > 0.0 && color->a < 1.0)
+    a = color->a + (gdouble) (i & 0xff) / 256.0 / 256.0 - 0.5 / 256.0;
+  else
+    a = color->a;
+
+  *dest++ = CLAMP (r, 0.0, 1.0);
+  *dest++ = CLAMP (g, 0.0, 1.0);
+  *dest++ = CLAMP (b, 0.0, 1.0);
+  *dest++ = CLAMP (a, 0.0, 1.0);
+}
+
 static gboolean
 gimp_operation_gradient_process (GeglOperation       *operation,
                                  GeglBuffer          *input,
@@ -1138,24 +1154,11 @@ gimp_operation_gradient_process (GeglOperation       *operation,
                 for (x = roi->x; x < endx; x++)
                   {
                     GimpRGB  color = { 0.0, 0.0, 0.0, 1.0 };
-                    gfloat   r, g, b, a;
-                    gint     i = g_rand_int (dither_rand);
 
                     gradient_render_pixel (x, y, &color, &rbd);
+                    gradient_dither_pixel (&color, dither_rand, dest);
 
-                    r = color.r + (gdouble) (i & 0xff) / 256.0 / 256.0; i >>= 8;
-                    g = color.g + (gdouble) (i & 0xff) / 256.0 / 256.0; i >>= 8;
-                    b = color.b + (gdouble) (i & 0xff) / 256.0 / 256.0; i >>= 8;
-
-                    if (color.a > 0.0 && color.a < 1.0)
-                      a = color.a + (gdouble) (i & 0xff) / 256.0 / 256.0;
-                    else
-                      a = color.a;
-
-                    *dest++ = MAX (r, 0.0);
-                    *dest++ = MAX (g, 0.0);
-                    *dest++ = MAX (b, 0.0);
-                    *dest++ = MAX (a, 0.0);
+                    dest += 4;
                   }
             }
           else


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