From db0ed3e62dfe57811b36d4f8a00a0b4315d6de28 Mon Sep 17 00:00:00 2001 From: John Bowler Date: Wed, 18 May 2011 18:51:24 -0500 Subject: [PATCH] [devel] png_set_background+png_expand_16 did not interwork correctly. This problem is present in 1.5.2; if png_set_background is called with need_expand false and the matching 16 bit color libpng erroneously just treats it as an 8-bit color because of where png_do_expand_16 is in the transform list. This simple fix reduces the supplied colour to 8 bits, so it gets smashed, but this is better than the current behavior. --- pngrtran.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/pngrtran.c b/pngrtran.c index 35f571964..fa464494c 100644 --- a/pngrtran.c +++ b/pngrtran.c @@ -1106,10 +1106,6 @@ png_init_palette_transformations(png_structp png_ptr) (png_ptr->transformations & PNG_EXPAND)) { { - /* TODO: THIS MUST BE WRONG, because in png_init_read_transformations - * below the background red,green,blue values are used directly in the - * palette case (allowing an out-of-palette background color!) - */ png_ptr->background.red = png_ptr->palette[png_ptr->background.index].red; png_ptr->background.green = @@ -1429,6 +1425,29 @@ png_init_read_transformations(png_structp png_ptr) else png_init_rgb_transformations(png_ptr); +#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ + defined(PNG_READ_EXPAND_16_SUPPORTED) + if ((png_ptr->transformations & PNG_EXPAND_16) && + (png_ptr->transformations & PNG_COMPOSE) && + !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) && + png_ptr->bit_depth != 16) + { + /* TODO: fix this. Because the expand_16 operation is after the compose + * handling the background color must be 8, not 16, bits deep, but the + * application will supply a 16 bit value so reduce it here. + * + * The PNG_BACKGROUND_EXPAND code above does not expand to 16 bits at + * present, so that case is ok (until do_expand_16 is moved.) + */ +# define CHOP(x) ((png_uint_16)((2*(png_uint_32)(x) + 257)/514)) + png_ptr->background.red = CHOP(png_ptr->background.red); + png_ptr->background.green = CHOP(png_ptr->background.green); + png_ptr->background.blue = CHOP(png_ptr->background.blue); + png_ptr->background.gray = CHOP(png_ptr->background.gray); +# undef CHOP + } +#endif + /* NOTE: below 'PNG_READ_ALPHA_MODE_SUPPORTED' is presumed to also enable the * background support (see the comments in scripts/pnglibconf.dfa), this * allows pre-multiplication of the alpha channel to be implemented as