[cairo-png] Recheck png_info after setting transformation options.

After specifying how to transform the various colour modes into ones we
can handle, re-read the image header to confirm that the output on
reading the PNG will be RGB24 or ARGB32. This simplifies our logic
considerably as we no longer have to second guess the colour space
transformation that will be performed by libpng. (And allows for some
paranoid checks.)
This commit is contained in:
Chris Wilson 2008-04-21 19:54:48 +01:00
parent a313547f6d
commit 20b1b33c0f

View file

@ -434,7 +434,6 @@ 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,
@ -486,11 +485,8 @@ read_png (png_rw_ptr read_func,
}
/* transform transparency to alpha */
need_alpha = FALSE;
if (png_get_valid (png, info, PNG_INFO_tRNS)) {
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);
@ -508,30 +504,36 @@ read_png (png_rw_ptr read_func,
if (interlace != PNG_INTERLACE_NONE)
png_set_interlace_handling (png);
/* recheck header after setting EXPAND options */
png_read_update_info (png, info);
png_get_IHDR (png, info,
&png_width, &png_height, &depth,
&color_type, &interlace, NULL, NULL);
if (depth != 8 || interlace != PNG_INTERLACE_NONE ||
! (color_type == PNG_COLOR_TYPE_RGB ||
color_type == PNG_COLOR_TYPE_RGB_ALPHA))
{
surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_READ_ERROR));
goto BAIL;
}
switch (color_type) {
default:
case PNG_COLOR_TYPE_GRAY_ALPHA:
ASSERT_NOT_REACHED;
/* fall-through just in case ;-) */
case PNG_COLOR_TYPE_RGB_ALPHA:
format = CAIRO_FORMAT_ARGB32;
png_set_read_user_transform_fn (png, premultiply_data);
break;
case PNG_COLOR_TYPE_GRAY:
case PNG_COLOR_TYPE_RGB:
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);
}
format = CAIRO_FORMAT_RGB24;
png_set_read_user_transform_fn (png, convert_bytes_to_data);
png_set_filler (png, 0xff, PNG_FILLER_AFTER);
break;
}
png_read_update_info (png, info);
stride = cairo_format_stride_for_width (format, png_width);
if (stride < 0) {
surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_STRIDE));