summaryrefslogtreecommitdiff
path: root/src/cairo-png.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2008-04-21 18:20:16 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2008-04-21 18:35:07 +0100
commitf2f91db131e7c7df1e87bcd41ae17c07429bbcb8 (patch)
tree83d4e86478428a15b56469b261da3c7c58f14771 /src/cairo-png.c
parentea6dbfd36f2182fda16cb82bca92007e0f7b8d77 (diff)
[cairo-png] Create an ARGB32 surface for paletted PNGs.
jeremie54 reported a regression in the handling of transparent paletted PNGs beween 1.4.14 and 1.6.4. This was caused by the change to load opaque PNGs into a RGB24 image surface, which made the assumption that indexed PNGs were opaque. However, alpha/transparency in PNG is more complicated, as PNG uses a tRNS chunk to supply transparency data for paletted images and other image types that don't need a full alpha channel. Therefore if the PNG contains a tRNS chunk always generate an ARGB32 surface.
Diffstat (limited to 'src/cairo-png.c')
-rw-r--r--src/cairo-png.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/src/cairo-png.c b/src/cairo-png.c
index 0db4b090..3ec85c06 100644
--- a/src/cairo-png.c
+++ b/src/cairo-png.c
@@ -434,6 +434,7 @@ read_png (png_rw_ptr read_func,
unsigned int i;
cairo_format_t format;
cairo_status_t status;
+ cairo_bool_t need_alpha;
/* XXX: Perhaps we'll want some other error handlers? */
png = png_create_read_struct (PNG_LIBPNG_VER_STRING,
@@ -485,8 +486,11 @@ read_png (png_rw_ptr read_func,
}
/* transform transparency to alpha */
- if (png_get_valid (png, info, PNG_INFO_tRNS))
+ need_alpha = FALSE;
+ if (png_get_valid (png, info, PNG_INFO_tRNS)) {
png_set_tRNS_to_alpha (png);
+ need_alpha = TRUE;
+ }
if (depth == 16)
png_set_strip_16 (png);
@@ -513,11 +517,16 @@ read_png (png_rw_ptr read_func,
break;
case PNG_COLOR_TYPE_GRAY:
- case PNG_COLOR_TYPE_PALETTE:
case PNG_COLOR_TYPE_RGB:
- format = CAIRO_FORMAT_RGB24;
- png_set_read_user_transform_fn (png, convert_bytes_to_data);
- png_set_filler (png, 0xff, PNG_FILLER_AFTER);
+ case PNG_COLOR_TYPE_PALETTE:
+ if (need_alpha) {
+ format = CAIRO_FORMAT_ARGB32;
+ png_set_read_user_transform_fn (png, premultiply_data);
+ } else {
+ format = CAIRO_FORMAT_RGB24;
+ png_set_read_user_transform_fn (png, convert_bytes_to_data);
+ png_set_filler (png, 0xff, PNG_FILLER_AFTER);
+ }
break;
}