[bitmap] Fixes _cogl_bitmap_fallback_unpremult

The _cogl_unpremult_alpha_{first,last} functions which
_cogl_bitmap_fallback_unpremult depends on were incorrectly casting each
of the byte components of a texel to a gulong and performing shifts as
if it were dealing with the whole texel.

It now just uses array indexing to access the byte components without
needing to cast or manually shift any bits around.

Even though we used to depend on unpremult whenever we used a
ClutterCairoTexture, clutter_cairo_texture_context_destroy had it's own
unpremult code which worked which is why this bug wouldn't have been noticed
before.
This commit is contained in:
Robert Bragg 2009-06-07 15:58:56 +01:00
parent dde3257b6c
commit 7cb4b93432

View File

@ -163,9 +163,9 @@ _cogl_unpremult_alpha_last (const guchar *src, guchar *dst)
{ {
guchar alpha = src[3]; guchar alpha = src[3];
dst[0] = ((((gulong) src[0] >> 16) & 0xff) * 255 ) / alpha; dst[0] = (src[0] * 255) / alpha;
dst[1] = ((((gulong) src[1] >> 8) & 0xff) * 255 ) / alpha; dst[1] = (src[1] * 255) / alpha;
dst[2] = ((((gulong) src[2] >> 0) & 0xff) * 255 ) / alpha; dst[2] = (src[2] * 255) / alpha;
dst[3] = alpha; dst[3] = alpha;
} }
@ -175,9 +175,9 @@ _cogl_unpremult_alpha_first (const guchar *src, guchar *dst)
guchar alpha = src[0]; guchar alpha = src[0];
dst[0] = alpha; dst[0] = alpha;
dst[1] = ((((gulong) src[1] >> 16) & 0xff) * 255 ) / alpha; dst[1] = (src[1] * 255) / alpha;
dst[2] = ((((gulong) src[2] >> 8) & 0xff) * 255 ) / alpha; dst[2] = (src[2] * 255) / alpha;
dst[3] = ((((gulong) src[3] >> 0) & 0xff) * 255 ) / alpha; dst[3] = (src[3] * 255) / alpha;
} }
/* No division form of floor((c*a + 128)/255) (I first encountered /* No division form of floor((c*a + 128)/255) (I first encountered
@ -365,35 +365,35 @@ _cogl_bitmap_fallback_unpremult (const CoglBitmap *bmp,
* dst_bmp->height * dst_bmp->height
* dst_bmp->rowstride); * dst_bmp->rowstride);
/* FIXME: Optimize */
for (y = 0; y < bmp->height; y++) for (y = 0; y < bmp->height; y++)
{ {
src = (guchar*)bmp->data + y * bmp->rowstride; src = (guchar*)bmp->data + y * bmp->rowstride;
dst = (guchar*)dst_bmp->data + y * dst_bmp->rowstride; dst = (guchar*)dst_bmp->data + y * dst_bmp->rowstride;
for (x = 0; x < bmp->width; x++) if (bmp->format & COGL_AFIRST_BIT)
{ {
/* FIXME: Would be nice to at least remove this inner for (x = 0; x < bmp->width; x++)
* branching, but not sure it can be done without {
* rewriting of the whole loop */ if (src[0] == 0)
if (bmp->format & COGL_AFIRST_BIT) _cogl_unpremult_alpha_0 (src, dst);
{ else
if (src[0] == 0) _cogl_unpremult_alpha_first (src, dst);
_cogl_unpremult_alpha_0 (src, dst); src += bpp;
else dst += bpp;
_cogl_unpremult_alpha_first (src, dst); }
} }
else else
{ {
if (src[3] == 0) for (x = 0; x < bmp->width; x++)
_cogl_unpremult_alpha_0 (src, dst); {
else if (src[0] == 0)
_cogl_unpremult_alpha_last (src, dst); _cogl_unpremult_alpha_0 (src, dst);
} else
_cogl_unpremult_alpha_last (src, dst);
src += bpp; src += bpp;
dst += bpp; dst += bpp;
} }
}
} }
return TRUE; return TRUE;