mirror of
https://gitlab.gnome.org/GNOME/gimp.git
synced 2025-07-03 17:33:25 +00:00
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.
This commit is contained in:
parent
60554eaed9
commit
e22fcc8942
1 changed files with 33 additions and 30 deletions
|
@ -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);
|
||||
gradient_dither_pixel (color, ppd->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
|
||||
{
|
||||
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue