[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.
This commit is contained in:
Chris Wilson 2008-04-21 18:20:16 +01:00
parent ea6dbfd36f
commit f2f91db131

View file

@ -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;
}