http://lists.cairographics.org/archives/cairo/2013-March/024195.html --- src/cairo-png.c 2012-03-29 12:05:32.000000000 +0200 +++ src/cairo-png.c 2013-03-30 09:13:50.817181600 +0100 @@ -497,6 +497,20 @@ } } +/* branches into premultiply_data or convert_bytes_to_data depending on color type */ +static void read_user_transform_func (png_structp png, png_row_infop row_info, png_bytep data) +{ + switch ((cairo_format_t) png_get_user_transform_ptr (png)) { + case CAIRO_FORMAT_ARGB32: + premultiply_data (png, row_info, data); + break; + + case CAIRO_FORMAT_RGB24: + convert_bytes_to_data (png, row_info, data); + break; + } +} + static cairo_status_t stdio_read_func (void *closure, unsigned char *data, unsigned int size) { @@ -623,6 +637,9 @@ png_set_filler (png, 0xff, PNG_FILLER_AFTER); + /* this must be stored before calling png_read_update_info */ + png_set_read_user_transform_fn (png, read_user_transform_func); + /* recheck header after setting EXPAND options */ png_read_update_info (png, info); png_get_IHDR (png, info, @@ -643,15 +660,15 @@ case PNG_COLOR_TYPE_RGB_ALPHA: format = CAIRO_FORMAT_ARGB32; - png_set_read_user_transform_fn (png, premultiply_data); break; case PNG_COLOR_TYPE_RGB: format = CAIRO_FORMAT_RGB24; - png_set_read_user_transform_fn (png, convert_bytes_to_data); break; } + png_set_user_transform_info (png, (void*) format, 0, 0); + stride = cairo_format_stride_for_width (format, png_width); if (stride < 0) { surface = _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_STRIDE));