Sven Neumann <sven@gimp.org>

2004-12-15  Michael Natterer  <mitch@gimp.org>
	    Sven Neumann  <sven@gimp.org>

	* app/core/gimpdrawable-preview.c (gimp_drawable_preview_scale):
	fixed RGBA resampling by using premultiplied values for the
	intermediate accumulation buffer. Fixes bugs #72880 and #72881.
This commit is contained in:
Michael Natterer 2004-12-15 01:36:22 +00:00 committed by Michael Natterer
parent 4d908e46c6
commit 1a752a6d54
2 changed files with 73 additions and 14 deletions

View File

@ -1,3 +1,10 @@
2004-12-15 Michael Natterer <mitch@gimp.org>
Sven Neumann <sven@gimp.org>
* app/core/gimpdrawable-preview.c (gimp_drawable_preview_scale):
fixed RGBA resampling by using premultiplied values for the
intermediate accumulation buffer. Fixes bugs #72880 and #72881.
2004-12-14 Michael Natterer <mitch@gimp.org>
* app/plug-in/plug-in-proc-frame.[ch]: added "gint ref_count" to

View File

@ -238,6 +238,7 @@ gimp_drawable_preview_scale (GimpImageBaseType type,
gint i, j;
gint frac;
gboolean advance_dest;
gboolean has_alpha;
g_return_if_fail (type != GIMP_INDEXED || cmap != NULL);
@ -250,6 +251,8 @@ gimp_drawable_preview_scale (GimpImageBaseType type,
bytes = destPR->bytes;
destwidth = destPR->rowstride;
has_alpha = ((bytes == 2) || (bytes == 4));
/* the data pointers... */
src = g_new (guchar, orig_width * bytes);
dest = destPR->data;
@ -332,19 +335,44 @@ gimp_drawable_preview_scale (GimpImageBaseType type,
{
gint index = *s * 3;
r[RED_PIX] += cmap[index++] * tot_frac;
r[GREEN_PIX] += cmap[index++] * tot_frac;
r[BLUE_PIX] += cmap[index++] * tot_frac;
if (bytes == 4)
r[ALPHA_PIX] += ((s[ALPHA_I_PIX] & 0x80 ?
OPAQUE_OPACITY : TRANSPARENT_OPACITY)
* tot_frac);
}
if (has_alpha)
{
if (s[ALPHA_I_PIX] & 0x80)
{
r[RED_PIX] += cmap[index++] * tot_frac;
r[GREEN_PIX] += cmap[index++] * tot_frac;
r[BLUE_PIX] += cmap[index++] * tot_frac;
r[ALPHA_PIX] += tot_frac;
}
/* else the pixel contributes nothing and needs
* not to be added
*/
}
else
{
r[RED_PIX] += cmap[index++] * tot_frac;
r[GREEN_PIX] += cmap[index++] * tot_frac;
r[BLUE_PIX] += cmap[index++] * tot_frac;
}
}
else
{
for (b = 0; b < bytes; b++)
r[b] += s[b] * tot_frac;
if (has_alpha)
{
/* premultiply */
gdouble local_frac = tot_frac * (gdouble) s[bytes - 1] / 255.0;
for (b = 0; b < (bytes - 1); b++)
r[b] += s[b] * local_frac;
r[bytes - 1] += local_frac;
}
else
{
for (b = 0; b < bytes; b++)
r[b] += s[b] * tot_frac;
}
}
/* increment the destination */
@ -373,9 +401,33 @@ gimp_drawable_preview_scale (GimpImageBaseType type,
j = width;
while (j--)
{
b = bytes;
while (b--)
*d++ = (guchar) ((*r++ * tot_frac) + 0.5);
if (has_alpha)
{
/* unpremultiply */
gdouble alpha = r[bytes - 1];
if (alpha > EPSILON)
{
for (b = 0; b < (bytes - 1); b++)
d[b] = (guchar) ((r[b] / alpha) + 0.5);
d[bytes - 1] = (guchar) ((alpha * tot_frac * 255.0) + 0.5);
}
else
{
for (b = 0; b < bytes; b++)
d[b] = 0;
}
}
else
{
for (b = 0; b < bytes; b++)
d[b] = (guchar) ((r[b] * tot_frac) + 0.5);
}
r += bytes;
d += bytes;
}
dest += destwidth;