Make png_struct palette, trans_alpha private

This removes the side-effect on the png_struct palette of calling png_set_PLTE
or png_set_tRNS.  NOTE: this is a quiet API change, it was possible before to
alter the palette on a PNG image by using png_set_PLTE, but this was unintended
and inconsistent with the other png_set APIs.

Fix a bug in palette index checking; png_struct::num_palette could, in
principle, get changed by the transformations (e.g. png_set_quantize) and this
would invalidate the check.  The palette checking init function now makes a copy
of png_struct::num_palette.

Fix a bug in pngvalid error handling.  A png_error in png_write_info is not
continuable (a valid image cannot necessarily be written afterward) because the
png_error aborts the write of subsequent pre-IDAT chunks.  In particular an
abort as a result of a bogus colorspace information (gAMA, cHRM, sBIT etc)
prevents the write of the PLTE chunk.

Signed-off-by: John Bowler <jbowler@acm.org>
This commit is contained in:
John Bowler
2015-12-01 08:16:53 -08:00
parent 8fe2eac47f
commit 84a8bb8244
8 changed files with 137 additions and 139 deletions

View File

@@ -5985,21 +5985,15 @@ setup_palette_cache(png_structp png_ptr, png_byte cache[8*256])
static void
png_remove_PLTE_and_tRNS(png_structrp png_ptr)
{
if ((png_ptr->free_me & PNG_FREE_PLTE) != 0)
{
png_ptr->free_me &= PNG_BIC_MASK(PNG_FREE_PLTE);
if (png_ptr->palette != NULL)
png_free(png_ptr, png_ptr->palette);
}
png_ptr->palette = NULL;
png_ptr->num_palette = 0;
# ifdef PNG_READ_tRNS_SUPPORTED
if ((png_ptr->free_me & PNG_FREE_TRNS) != 0)
{
png_ptr->free_me &= PNG_BIC_MASK(PNG_FREE_TRNS);
if (png_ptr->trans_alpha != NULL)
png_free(png_ptr, png_ptr->trans_alpha);
}
png_ptr->trans_alpha = NULL;
png_ptr->num_trans = 0;
@@ -6102,13 +6096,10 @@ update_palette(png_structp png_ptr, png_cache_paramsp cp,
* entries were shifted or inverted. This could be fixed, but it would
* complicate the libpng API to expose the information.
*/
png_ptr->palette = png_voidcast(png_colorp, png_calloc(png_ptr,
PNG_MAX_PALETTE_LENGTH * (sizeof (png_color))));
png_ptr->free_me |= PNG_FREE_PLTE;
/* Write the transformed palette: */
{
png_colorp palette = png_ptr->palette;
png_colorp palette = png_voidcast(png_colorp, png_calloc(png_ptr,
sizeof (png_color[PNG_MAX_PALETTE_LENGTH])));
png_const_bytep p;
const int is_color = (cp->tend.format & PNG_FORMAT_FLAG_COLOR) != 0;
unsigned int i;
@@ -6118,6 +6109,10 @@ update_palette(png_structp png_ptr, png_cache_paramsp cp,
png_byte trans_alpha[PNG_MAX_PALETTE_LENGTH];
# endif /* READ_tRNS */
memset(palette, 0xFFU, sizeof (png_color[PNG_MAX_PALETTE_LENGTH]));
png_free(png_ptr, png_ptr->palette);
png_ptr->palette = palette;
for (i=0, p=cache.b8; i<cp->tend.width; ++i)
{
if (is_color)
@@ -6148,12 +6143,17 @@ update_palette(png_structp png_ptr, png_cache_paramsp cp,
# ifdef PNG_READ_tRNS_SUPPORTED
if (num_trans > 0)
{
png_ptr->trans_alpha = png_voidcast(png_bytep, png_malloc(png_ptr,
PNG_MAX_PALETTE_LENGTH));
png_ptr->free_me |= PNG_FREE_TRNS;
memcpy(png_ptr->trans_alpha, trans_alpha, num_trans);
memset(png_ptr->trans_alpha+num_trans, 0xFFU,
PNG_MAX_PALETTE_LENGTH-num_trans);
png_bytep tRNS = png_voidcast(png_bytep, png_malloc(png_ptr,
PNG_MAX_PALETTE_LENGTH));
memset(tRNS, 0xFFU, PNG_MAX_PALETTE_LENGTH);
if (png_ptr->trans_alpha != NULL)
png_free(png_ptr, png_ptr->trans_alpha);
png_ptr->trans_alpha = tRNS;
memcpy(tRNS, trans_alpha, num_trans);
png_ptr->num_trans = png_check_bits(png_ptr, num_trans, 9);
}
# endif /* READ_tRNS */