mirror of https://github.com/GNOME/gimp.git
Applied patches from David Necas <yeti@physics.muni.cz> that fix incorrect
2003-03-17 Sven Neumann <sven@gimp.org> Applied patches from David Necas <yeti@physics.muni.cz> that fix incorrect RGBA resampling in a number of plug-ins: * plug-ins/common/fractaltrace.c: fixes bug #72873. * plug-ins/common/tiler.c: fixes bug #72875. * plug-ins/common/waves.c: fixes bug #72870. * plug-ins/common/whirlpinch.c: fixes bug #72871.
This commit is contained in:
parent
b417203a62
commit
21113a2fc7
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
|||
2003-03-17 Sven Neumann <sven@gimp.org>
|
||||
|
||||
Applied patches from David Necas <yeti@physics.muni.cz> that fix
|
||||
incorrect RGBA resampling in a number of plug-ins:
|
||||
|
||||
* plug-ins/common/fractaltrace.c: fixes bug #72873.
|
||||
* plug-ins/common/tiler.c: fixes bug #72875.
|
||||
* plug-ins/common/waves.c: fixes bug #72870.
|
||||
* plug-ins/common/whirlpinch.c: fixes bug #72871.
|
||||
|
||||
2003-03-17 Michael Natterer <mitch@gimp.org>
|
||||
|
||||
* app/core/core-enums.[ch]: added GIMP_UNDO_CHANNEL_COLOR.
|
||||
|
|
|
@ -337,6 +337,7 @@ pixels_get (gint x,
|
|||
}
|
||||
}
|
||||
|
||||
#include <stdio.h>
|
||||
static void
|
||||
pixels_get_biliner (gdouble x,
|
||||
gdouble y,
|
||||
|
@ -346,6 +347,7 @@ pixels_get_biliner (gdouble x,
|
|||
gdouble a, b, c, d;
|
||||
gint x1, y1, x2, y2;
|
||||
gdouble dx, dy;
|
||||
gdouble alpha;
|
||||
|
||||
x1 = (gint) floor (x);
|
||||
x2 = x1 + 1;
|
||||
|
@ -364,14 +366,25 @@ pixels_get_biliner (gdouble x,
|
|||
pixels_get (x1, y2, &C);
|
||||
pixels_get (x2, y2, &D);
|
||||
|
||||
pixel->r = (guchar) (a * (gdouble) A.r + b * (gdouble) B.r +
|
||||
c * (gdouble) C.r + d * (gdouble) D.r);
|
||||
pixel->g = (guchar) (a * (gdouble) A.g + b * (gdouble) B.g +
|
||||
c * (gdouble) C.g + d * (gdouble) D.g);
|
||||
pixel->b = (guchar) (a * (gdouble) A.b + b * (gdouble) B.b +
|
||||
c * (gdouble) C.b + d * (gdouble) D.b);
|
||||
pixel->a = (guchar) (a * (gdouble) A.a + b * (gdouble) B.a +
|
||||
c * (gdouble) C.a + d * (gdouble) D.a);
|
||||
alpha = 1.0001*(a * (gdouble) A.a + b * (gdouble) B.a
|
||||
+ c * (gdouble) C.a + d * (gdouble) D.a);
|
||||
pixel->a = (guchar) alpha;
|
||||
|
||||
if (pixel->a)
|
||||
{
|
||||
pixel->r = (guchar) ((a * (gdouble) A.r * A.a
|
||||
+ b * (gdouble) B.r * B.a
|
||||
+ c * (gdouble) C.r * C.a
|
||||
+ d * (gdouble) D.r * D.a) / alpha);
|
||||
pixel->g = (guchar) ((a * (gdouble) A.g * A.a
|
||||
+ b * (gdouble) B.g * B.a
|
||||
+ c * (gdouble) C.g * C.a
|
||||
+ d * (gdouble) D.g * D.a) / alpha);
|
||||
pixel->b = (guchar) ((a * (gdouble) A.b * A.a
|
||||
+ b * (gdouble) B.b * B.a
|
||||
+ c * (gdouble) C.b * C.a
|
||||
+ d * (gdouble) D.b * D.a) / alpha);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -531,15 +544,26 @@ dialog_preview_setpixel (gint x,
|
|||
gint y,
|
||||
pixel_t *pixel)
|
||||
{
|
||||
guchar grayshade;
|
||||
|
||||
if (pixel->a)
|
||||
grayshade = pixel->r;
|
||||
else
|
||||
grayshade =
|
||||
(((x % (GIMP_CHECK_SIZE * 2) < GIMP_CHECK_SIZE) ?
|
||||
(y % (GIMP_CHECK_SIZE * 2) < GIMP_CHECK_SIZE) :
|
||||
(y % (GIMP_CHECK_SIZE * 2) > GIMP_CHECK_SIZE)) ?
|
||||
GIMP_CHECK_LIGHT : GIMP_CHECK_DARK) * 255;
|
||||
|
||||
switch (preview.bpp)
|
||||
{
|
||||
case 1:
|
||||
preview.pixels[y][x*preview.bpp] = pixel->r;
|
||||
preview.pixels[y][x * preview.bpp] = grayshade;
|
||||
break;
|
||||
case 3:
|
||||
preview.pixels[y][x*preview.bpp] = pixel->r;
|
||||
preview.pixels[y][x*preview.bpp+1] = pixel->g;
|
||||
preview.pixels[y][x*preview.bpp+2] = pixel->b;
|
||||
preview.pixels[y][x * preview.bpp] = grayshade;
|
||||
preview.pixels[y][x * preview.bpp + 1] = pixel->a ? pixel->g : grayshade;
|
||||
preview.pixels[y][x * preview.bpp + 2] = pixel->a ? pixel->b : grayshade;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -651,9 +675,11 @@ dialog_preview_draw (void)
|
|||
break;
|
||||
case OUTSIDE_TYPE_BLACK:
|
||||
pixel.r = pixel.g = pixel.b = 0;
|
||||
pixel.a = 255;
|
||||
break;
|
||||
case OUTSIDE_TYPE_WHITE:
|
||||
pixel.r = pixel.g = pixel.b = 255;
|
||||
pixel.a = 255;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,12 +35,6 @@ static void run (gchar *name,
|
|||
GimpParam **return_vals);
|
||||
|
||||
static void tile (GimpDrawable *drawable);
|
||||
static gint scale (gint width,
|
||||
gint height,
|
||||
gint x,
|
||||
gint y,
|
||||
gint data);
|
||||
|
||||
|
||||
GimpPlugInInfo PLUG_IN_INFO =
|
||||
{
|
||||
|
@ -119,43 +113,70 @@ run (gchar *name,
|
|||
gimp_drawable_detach (drawable);
|
||||
}
|
||||
|
||||
static gint
|
||||
scale (gint width,
|
||||
gint height,
|
||||
gint x,
|
||||
gint y,
|
||||
gint data)
|
||||
static void
|
||||
weld_pixels (guchar *dest1,
|
||||
guchar *dest2,
|
||||
gint width,
|
||||
gint height,
|
||||
gint x,
|
||||
gint y,
|
||||
guint bpp,
|
||||
guchar *src1,
|
||||
guchar *src2)
|
||||
{
|
||||
gint A = width/2-1;
|
||||
gint B = height/2-1;
|
||||
gint a, b;
|
||||
gdouble a = (ABS(x - width) - 1)/ (gdouble) (width - 1);
|
||||
gdouble b = (ABS(y - height) - 1) / (gdouble) (height - 1);
|
||||
gdouble w;
|
||||
guint i;
|
||||
|
||||
if (x < width/2)
|
||||
a = width/2 - x - 1;
|
||||
/* mimic ambiguous point handling in original algorithm */
|
||||
if (a < 1e-8 && b > 0.99999999)
|
||||
w = 1.0;
|
||||
else if (a > 0.99999999 && b < 1e-8)
|
||||
w = 0.0;
|
||||
else
|
||||
a = x - width/2 - (width & 1);
|
||||
w = 1.0 - a*b/(a*b + (1.0 - a)*(1.0 - b));
|
||||
|
||||
if (y < height/2)
|
||||
b = height/2 - y -1;
|
||||
for (i = 0; i < bpp; i++)
|
||||
dest1[i] = dest2[i] = (guchar) (w * src1[i] + (1.0 - w) * src2[i]);
|
||||
}
|
||||
|
||||
static void
|
||||
weld_pixels_alpha (guchar *dest1,
|
||||
guchar *dest2,
|
||||
gint width,
|
||||
gint height,
|
||||
gint x,
|
||||
gint y,
|
||||
guint bpp,
|
||||
guchar *src1,
|
||||
guchar *src2)
|
||||
{
|
||||
gdouble a = (ABS(x - width) - 1)/ (gdouble) (width - 1);
|
||||
gdouble b = (ABS(y - height) - 1) / (gdouble) (height - 1);
|
||||
gdouble w;
|
||||
gdouble alpha;
|
||||
guint ai = bpp-1;
|
||||
guint i;
|
||||
|
||||
/* mimic ambiguous point handling in original algorithm */
|
||||
if (a < 1e-8 && b > 0.99999999)
|
||||
w = 1.0;
|
||||
else if (a > 0.99999999 && b < 1e-8)
|
||||
w = 0.0;
|
||||
else
|
||||
b = y - height/2 - (height & 1);
|
||||
|
||||
if ((B*a<A*b) || ((B*a==A*b) && (a&1)))
|
||||
w = 1.0 - a*b/(a*b + (1.0 - a)*(1.0 - b));
|
||||
|
||||
alpha = w * src1[ai] + (1.0 - w) * src2[ai];
|
||||
|
||||
dest1[ai] = dest2[ai] = (guchar) alpha;
|
||||
if (dest1[ai])
|
||||
{
|
||||
a = A-a;
|
||||
b = B-b;
|
||||
if (a==A)
|
||||
return data;
|
||||
else
|
||||
return data - data * (A*B-a*B) /(A * b + A * B - a * B);
|
||||
for (i = 0; i < ai; i++)
|
||||
dest1[i] = dest2[i] = (guchar) ((w * src1[i] * src1[ai]
|
||||
+ (1.0 - w) * src2[i] * src2[ai])
|
||||
/ alpha);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (a==A)
|
||||
return 0;
|
||||
else
|
||||
return data * (A * B - a * B) / (A * b + A * B - a * B);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -171,8 +192,11 @@ tile_region (GimpDrawable *drawable, gboolean left,
|
|||
gint max_progress;
|
||||
GimpPixelRgn src1_rgn, src2_rgn, dest1_rgn, dest2_rgn;
|
||||
gpointer pr;
|
||||
gboolean has_alpha;
|
||||
guint asymmetry_correction;
|
||||
|
||||
bpp = gimp_drawable_bpp (drawable->drawable_id);
|
||||
has_alpha = gimp_drawable_has_alpha (drawable->drawable_id);
|
||||
|
||||
height = y2 - y1;
|
||||
width = x2 - x1;
|
||||
|
@ -196,6 +220,8 @@ tile_region (GimpDrawable *drawable, gboolean left,
|
|||
off_x = -w - wodd;
|
||||
}
|
||||
|
||||
asymmetry_correction = !wodd && !left;
|
||||
|
||||
gimp_pixel_rgn_init (&src1_rgn, drawable, rgn1_x, y1, w, h, FALSE, FALSE);
|
||||
gimp_pixel_rgn_init (&dest1_rgn, drawable, rgn1_x, y1, w, h, TRUE, TRUE);
|
||||
gimp_pixel_rgn_init (&src2_rgn, drawable, rgn2_x, y1 + h + hodd,
|
||||
|
@ -224,22 +250,30 @@ tile_region (GimpDrawable *drawable, gboolean left,
|
|||
guchar *d2 = dest2;
|
||||
gint col = src1_rgn.x - x1;
|
||||
|
||||
for (x = 0; x < src1_rgn.w; x++, col++)
|
||||
{
|
||||
gint c;
|
||||
|
||||
for (c = 0; c < bpp; c++)
|
||||
{
|
||||
gint val = scale (width, height, col, row, s1[c]) +
|
||||
scale (width, height, col + off_x, row + h + hodd, s2[c]);
|
||||
|
||||
d1[c] = d2[c] = (val > 255) ? 255 : val;
|
||||
}
|
||||
s1 += bpp;
|
||||
s2 += bpp;
|
||||
d1 += bpp;
|
||||
d2 += bpp;
|
||||
}
|
||||
if (has_alpha)
|
||||
{
|
||||
for (x = 0; x < src1_rgn.w; x++, col++)
|
||||
{
|
||||
weld_pixels_alpha (d1, d2, w, h, col + asymmetry_correction,
|
||||
row, bpp, s1, s2);
|
||||
s1 += bpp;
|
||||
s2 += bpp;
|
||||
d1 += bpp;
|
||||
d2 += bpp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (x = 0; x < src1_rgn.w; x++, col++)
|
||||
{
|
||||
weld_pixels (d1, d2, w, h, col + asymmetry_correction,
|
||||
row, bpp, s1, s2);
|
||||
s1 += bpp;
|
||||
s2 += bpp;
|
||||
d1 += bpp;
|
||||
d2 += bpp;
|
||||
}
|
||||
}
|
||||
|
||||
src1 += src1_rgn.rowstride;
|
||||
src2 += src2_rgn.rowstride;
|
||||
|
|
|
@ -80,6 +80,7 @@ static void wave (guchar *src,
|
|||
gint width,
|
||||
gint height,
|
||||
gint bypp,
|
||||
gboolean has_alpha,
|
||||
gdouble amplitude,
|
||||
gdouble wavelength,
|
||||
gdouble phase,
|
||||
|
@ -216,11 +217,12 @@ pluginCore (piArgs *argp,
|
|||
gint retval=0;
|
||||
GimpPixelRgn srcPr, dstPr;
|
||||
guchar *src, *dst;
|
||||
guint width, height, bpp;
|
||||
guint width, height, bpp, has_alpha;
|
||||
|
||||
width = drawable->width;
|
||||
height = drawable->height;
|
||||
bpp = drawable->bpp;
|
||||
has_alpha = gimp_drawable_has_alpha (drawable->drawable_id);
|
||||
|
||||
src = g_new (guchar, width * height * bpp);
|
||||
dst = g_new (guchar, width * height * bpp);
|
||||
|
@ -228,8 +230,9 @@ pluginCore (piArgs *argp,
|
|||
gimp_pixel_rgn_init (&dstPr, drawable, 0, 0, width, height, TRUE, TRUE);
|
||||
gimp_pixel_rgn_get_rect (&srcPr, src, 0, 0, width, height);
|
||||
|
||||
wave (src, dst, width, height, bpp, argp->amplitude, argp->wavelength,
|
||||
argp->phase, argp->type==0, argp->reflective, 1);
|
||||
wave (src, dst, width, height, bpp, has_alpha,
|
||||
argp->amplitude, argp->wavelength, argp->phase,
|
||||
argp->type==0, argp->reflective, 1);
|
||||
gimp_pixel_rgn_set_rect (&dstPr, dst, 0, 0, width, height);
|
||||
|
||||
g_free (src);
|
||||
|
@ -416,6 +419,7 @@ waves_do_preview (void)
|
|||
dst = g_new (guchar, preview->width * preview->height * preview->bpp);
|
||||
|
||||
wave (preview->cache, dst, preview->width, preview->height, preview->bpp,
|
||||
preview->bpp == 2 || preview->bpp == 4,
|
||||
argp->amplitude * preview->scale_x,
|
||||
argp->wavelength * preview->scale_x,
|
||||
argp->phase, argp->type == 0, argp->reflective, 0);
|
||||
|
@ -464,6 +468,8 @@ mw_preview_new (GtkWidget *parent, GimpDrawable *drawable)
|
|||
gtk_widget_show (pframe);
|
||||
|
||||
preview = gimp_fixme_preview_new (drawable, FALSE);
|
||||
/* FIXME: this forces gimp_fixme_preview to set its alpha correctly */
|
||||
gimp_fixme_preview_fill_scaled (preview, drawable);
|
||||
gtk_container_add (GTK_CONTAINER (pframe), preview->widget);
|
||||
gtk_widget_show (preview->widget);
|
||||
|
||||
|
@ -501,6 +507,7 @@ wave (guchar *src,
|
|||
gint width,
|
||||
gint height,
|
||||
gint bypp,
|
||||
gboolean has_alpha,
|
||||
gdouble amplitude,
|
||||
gdouble wavelength,
|
||||
gdouble phase,
|
||||
|
@ -526,10 +533,8 @@ wave (guchar *src,
|
|||
|
||||
gint xi, yi;
|
||||
|
||||
guchar values[4];
|
||||
guchar val;
|
||||
|
||||
gint k;
|
||||
guchar *values[4];
|
||||
guchar zeroes[4] = { 0, 0, 0, 0 };
|
||||
|
||||
phase = phase * G_PI / 180;
|
||||
rowsiz = width * bypp;
|
||||
|
@ -643,32 +648,28 @@ wave (guchar *src,
|
|||
x2_in = WITHIN (0, xi + 1, width - 1);
|
||||
y2_in = WITHIN (0, yi + 1, height - 1);
|
||||
|
||||
for (k = 0; k < bypp; k++)
|
||||
{
|
||||
if (x1_in && y1_in)
|
||||
values[0] = *(p + k);
|
||||
else
|
||||
values[0] = 0;
|
||||
if (x1_in && y1_in)
|
||||
values[0] = p;
|
||||
else
|
||||
values[0] = zeroes;
|
||||
|
||||
if (x2_in && y1_in)
|
||||
values[1] = *(p + bypp + k);
|
||||
else
|
||||
values[1] = 0;
|
||||
if (x2_in && y1_in)
|
||||
values[1] = p + bypp;
|
||||
else
|
||||
values[1] = zeroes;
|
||||
|
||||
if (x1_in && y2_in)
|
||||
values[2] = *(p + rowsiz + k);
|
||||
else
|
||||
values[2] = 0;
|
||||
if (x1_in && y2_in)
|
||||
values[2] = p + rowsiz;
|
||||
else
|
||||
values[2] = zeroes;
|
||||
|
||||
if (x2_in && y2_in)
|
||||
values[3] = *(p + bypp + k + rowsiz);
|
||||
else
|
||||
values[3] = 0;
|
||||
if (x2_in && y2_in)
|
||||
values[3] = p + bypp + rowsiz;
|
||||
else
|
||||
values[3] = zeroes;
|
||||
|
||||
val = gimp_bilinear_8 (needx, needy, values);
|
||||
|
||||
*dest++ = val;
|
||||
}
|
||||
gimp_bilinear_pixels_8 (dest, needx, needy, bypp, has_alpha, values);
|
||||
dest += bypp;
|
||||
}
|
||||
|
||||
dst += rowsiz;
|
||||
|
|
|
@ -350,8 +350,7 @@ whirl_pinch (void)
|
|||
guchar *top_row, *bot_row;
|
||||
guchar *top_p, *bot_p;
|
||||
gint row, col;
|
||||
guchar pixel[4][4];
|
||||
guchar values[4];
|
||||
guchar **pixel;
|
||||
double whirl;
|
||||
double cx, cy;
|
||||
int ix, iy;
|
||||
|
@ -361,6 +360,9 @@ whirl_pinch (void)
|
|||
/* Initialize rows */
|
||||
top_row = g_malloc (img_bpp * sel_width);
|
||||
bot_row = g_malloc (img_bpp * sel_width);
|
||||
pixel = g_new (guchar *, 4);
|
||||
for (i = 0; i < 4; i++)
|
||||
pixel[i] = g_new (guchar, 4);
|
||||
|
||||
/* Initialize pixel region */
|
||||
gimp_pixel_rgn_init (&dest_rgn, drawable,
|
||||
|
@ -408,16 +410,9 @@ whirl_pinch (void)
|
|||
gimp_pixel_fetcher_get_pixel (pft, ix, iy + 1, pixel[2]);
|
||||
gimp_pixel_fetcher_get_pixel (pft, ix + 1, iy + 1, pixel[3]);
|
||||
|
||||
for (i = 0; i < img_bpp; i++)
|
||||
{
|
||||
values[0] = pixel[0][i];
|
||||
values[1] = pixel[1][i];
|
||||
values[2] = pixel[2][i];
|
||||
values[3] = pixel[3][i];
|
||||
|
||||
*top_p++ = gimp_bilinear_8 (cx, cy, values);
|
||||
}
|
||||
|
||||
gimp_bilinear_pixels_8 (top_p, cx, cy, img_bpp, img_has_alpha,
|
||||
pixel);
|
||||
top_p += img_bpp;
|
||||
/* Bottom */
|
||||
|
||||
cx = cen_x + (cen_x - cx);
|
||||
|
@ -438,17 +433,9 @@ whirl_pinch (void)
|
|||
gimp_pixel_fetcher_get_pixel (pfb, ix, iy + 1, pixel[2]);
|
||||
gimp_pixel_fetcher_get_pixel (pfb, ix + 1, iy + 1, pixel[3]);
|
||||
|
||||
for (i = 0; i < img_bpp; i++)
|
||||
{
|
||||
values[0] = pixel[0][i];
|
||||
values[1] = pixel[1][i];
|
||||
values[2] = pixel[2][i];
|
||||
values[3] = pixel[3][i];
|
||||
|
||||
*bot_p++ = gimp_bilinear_8 (cx, cy, values);
|
||||
}
|
||||
|
||||
bot_p -= 2 * img_bpp; /* We move backwards! */
|
||||
gimp_bilinear_pixels_8 (bot_p, cx, cy, img_bpp, img_has_alpha,
|
||||
pixel);
|
||||
bot_p -= img_bpp;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -492,6 +479,9 @@ whirl_pinch (void)
|
|||
gimp_pixel_fetcher_destroy (pft);
|
||||
gimp_pixel_fetcher_destroy (pfb);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
g_free (pixel[i]);
|
||||
g_free (pixel);
|
||||
g_free (top_row);
|
||||
g_free (bot_row);
|
||||
|
||||
|
|
Loading…
Reference in New Issue