From 20b1b33c0fc76d2ec2b4f83d9ce058429c4f49db Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 21 Apr 2008 19:54:48 +0100 Subject: [PATCH] [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.) --- src/cairo-png.c | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/src/cairo-png.c b/src/cairo-png.c index 3ec85c068..c1cda34a6 100644 --- a/src/cairo-png.c +++ b/src/cairo-png.c @@ -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));