Permalink
Browse files

2007-07-30 Sebastien Pouliot <sebastien@ximian.com>

	* bitmap.c: Added global functions to deal with pre-multiplication.
	* bitmap-private.h: New prototypes for pre-multiplication.
	* texturebrush.c: If required by the format pre-multiply the alpha
	value of the brush bitmap before it's use as a pattern. Fix #81828.
	Cleaned-up some unused variables but there's still too much 
	duplication for my taste (added TODO).


svn path=/trunk/libgdiplus/; revision=82997
  • Loading branch information...
1 parent 00c8226 commit 981d31e926a6ad90b1662680d2a78fad24a42753 Sebastien Pouliot committed Jul 30, 2007
Showing with 220 additions and 114 deletions.
  1. +9 −0 src/ChangeLog
  2. +3 −0 src/bitmap-private.h
  3. +59 −28 src/bitmap.c
  4. +149 −86 src/texturebrush.c
View
@@ -1,3 +1,12 @@
+2007-07-30 Sebastien Pouliot <sebastien@ximian.com>
+
+ * bitmap.c: Added global functions to deal with pre-multiplication.
+ * bitmap-private.h: New prototypes for pre-multiplication.
+ * texturebrush.c: If required by the format pre-multiply the alpha
+ value of the brush bitmap before it's use as a pattern. Fix #81828.
+ Cleaned-up some unused variables but there's still too much
+ duplication for my taste (added TODO).
+
2007-07-30 Sebastien Pouliot <sebastien@ximian.com>
* graphics-cairo.c: Fix DrawPath offset (bug #82202) and correctly
View
@@ -149,6 +149,9 @@ GpStatus gdip_bitmapdata_property_find_id (BitmapData *bitmap_data, PROPID id, i
cairo_surface_t* gdip_bitmap_ensure_surface (GpBitmap *bitmap) GDIP_INTERNAL;
GpBitmap* gdip_convert_indexed_to_rgb (GpBitmap *bitmap) GDIP_INTERNAL;
+BOOL gdip_bitmap_format_needs_premultiplication (GpBitmap *bitmap) GDIP_INTERNAL;
+BYTE* gdip_bitmap_get_premultiplied_scan0 (GpBitmap *bitmap) GDIP_INTERNAL;
+
void gdip_process_bitmap_attributes (GpBitmap *bitmap, void **dest, GpImageAttributes* attr, BOOL *allocated) GDIP_INTERNAL;
ColorPalette* gdip_create_greyscale_palette (int num_colors) GDIP_INTERNAL;
View
@@ -2145,42 +2145,73 @@ GdipBitmapSetResolution (GpBitmap *bitmap, float xdpi, float ydpi)
cairo_surface_t *
gdip_bitmap_ensure_surface (GpBitmap *bitmap)
{
- BitmapData *data;
+ cairo_format_t format;
+ BitmapData *data = bitmap->active_bitmap;
- data= bitmap->active_bitmap;
+ if (bitmap->surface || !data || !data->scan0)
+ return bitmap->surface;
- if ((bitmap->surface == NULL) && (data != NULL) && (data->scan0 != NULL)) {
- switch (data->pixel_format) {
- case PixelFormat24bppRGB: {
- bitmap->surface = cairo_image_surface_create_for_data(
- (BYTE*)data->scan0,
- CAIRO_FORMAT_RGB24,
- data->width,
- data->height,
- data->stride);
- break;
- }
+ switch (data->pixel_format) {
+ case PixelFormat24bppRGB:
+ format = CAIRO_FORMAT_RGB24;
+ break;
- case PixelFormat32bppARGB:
- case PixelFormat32bppRGB:
- case PixelFormat32bppPARGB: {
- bitmap->surface = cairo_image_surface_create_for_data(
- (BYTE*)data->scan0,
- CAIRO_FORMAT_ARGB32,
- data->width,
- data->height,
- data->stride);
- break;
- }
+ case PixelFormat32bppARGB: /* premultiplication is required */
+ case PixelFormat32bppRGB: /* no alpha */
+ case PixelFormat32bppPARGB: /* alpha already premultiplied */
+ format = CAIRO_FORMAT_ARGB32;
+ break;
+
+ default:
+ g_warning ("gdip_bitmap_ensure_surface: Unable to create a surface for raw bitmap data of format 0x%08x", data->pixel_format);
+ return NULL;
+ }
- default: {
- g_warning ("gdip_bitmap_ensure_surface: Unable to create a surface for raw bitmap data of format 0x%08x", data->pixel_format);
- break;
+ bitmap->surface = cairo_image_surface_create_for_data ((BYTE*)data->scan0, format,
+ data->width, data->height, data->stride);
+ return bitmap->surface;
+}
+
+BOOL
+gdip_bitmap_format_needs_premultiplication (GpBitmap *bitmap)
+{
+ return (bitmap->active_bitmap->pixel_format == PixelFormat32bppARGB);
+}
+
+BYTE*
+gdip_bitmap_get_premultiplied_scan0 (GpBitmap *bitmap)
+{
+ BitmapData *data = bitmap->active_bitmap;
+ BYTE* premul = (BYTE*) GdipAlloc (data->height * data->stride);
+ if (!premul)
+ return NULL;
+
+ BYTE *source = (BYTE*)data->scan0;
+ BYTE *target = premul;
+ int y, x;
+ for (y = 0; y < data->height; y++) {
+ ARGB *sp = (ARGB*) source;
+ ARGB *tp = (ARGB*) target;
+ for (x = 0; x < data->width; x++) {
+ BYTE a = source [3]; /* format is BGRA */
+ if (a < 0xff) {
+ BYTE *s = (BYTE*)sp;
+ BYTE *t = (BYTE*)tp;
+ t[0] = pre_multiplied_table [s[0]][a];
+ t[1] = pre_multiplied_table [s[1]][a];
+ t[2] = pre_multiplied_table [s[2]][a];
+ t[3] = a;
+ } else {
+ *tp = *sp;
}
+ sp++;
+ tp++;
}
+ source += data->stride;
+ target += data->stride;
}
- return bitmap->surface;
+ return premul;
}
GpBitmap *
Oops, something went wrong.

0 comments on commit 981d31e

Please sign in to comment.