[libng16] Added palette-index checking while writing.

Relocated palette-index checking function from pngrutil.c to pngtrans.c
This commit is contained in:
Glenn Randers-Pehrson 2012-03-02 22:10:15 -06:00
parent 8e92cd51c6
commit eeb1bb678d
10 changed files with 156 additions and 115 deletions

View File

@ -1,5 +1,5 @@
Libpng 1.6.0beta16 - March 2, 2012
Libpng 1.6.0beta16 - March 3, 2012
This is not intended to be a public release. It will be replaced
within a few weeks by a public version or by another test version.
@ -258,7 +258,9 @@ Version 1.6.0beta15 [March 2, 2012]
without the necessary color data.
Removed whitespace from the end of lines in all source files and scripts.
Version 1.6.0beta16 [March 2, 2012]
Version 1.6.0beta16 [March 3, 2012]
Relocated palette-index checking function from pngrutil.c to pngtrans.c
Added palette-index checking while writing.
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit

View File

@ -4002,15 +4002,16 @@ Version 1.6.0beta15 [March 2, 2012]
allow the error numbers in pngstest to be tuned and checked. makepng
also allows generation of images with extra chunks, although this is
still work-in-progress.
Added tests for invalid palette index while reading and writing (work in
progress, the latter isn't finished).
Added check for invalid palette index while reading.
Fixed some bugs in ICC profile writing. The code should now accept
all potentially valid ICC profiles and reject obviously invalid ones.
It now uses png_error() to do so rather than casually writing a PNG
without the necessary color data.
Removed whitespace from the end of lines in all source files and scripts.
Version 1.6.0beta16 [March 2, 2012]
Version 1.6.0beta16 [March 3, 2012]
Relocated palette-index checking function from pngrutil.c to pngtrans.c
Added palette-index checking while writing.
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit

18
png.h
View File

@ -1,7 +1,7 @@
/* png.h - header file for PNG reference library
*
* libpng version 1.6.0beta16 - March 2, 2012
* libpng version 1.6.0beta16 - March 3, 2012
* Copyright (c) 1998-2012 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@ -11,7 +11,7 @@
* Authors and maintainers:
* libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
* libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger
* libpng versions 0.97, January 1998, through 1.6.0beta16 - March 2, 2012: Glenn
* libpng versions 0.97, January 1998, through 1.6.0beta16 - March 3, 2012: Glenn
* See also "Contributing Authors", below.
*
* Note about libpng version numbers:
@ -198,7 +198,7 @@
*
* This code is released under the libpng license.
*
* libpng versions 1.2.6, August 15, 2004, through 1.6.0beta16, March 2, 2012, are
* libpng versions 1.2.6, August 15, 2004, through 1.6.0beta16, March 3, 2012, are
* Copyright (c) 2004, 2006-2012 Glenn Randers-Pehrson, and are
* distributed according to the same disclaimer and license as libpng-1.2.5
* with the following individual added to the list of Contributing Authors:
@ -310,7 +310,7 @@
* Y2K compliance in libpng:
* =========================
*
* March 2, 2012
* March 3, 2012
*
* Since the PNG Development group is an ad-hoc body, we can't make
* an official declaration.
@ -376,7 +376,7 @@
/* Version information for png.h - this should match the version in png.c */
#define PNG_LIBPNG_VER_STRING "1.6.0beta16"
#define PNG_HEADER_VERSION_STRING \
" libpng version 1.6.0beta16 - March 2, 2012\n"
" libpng version 1.6.0beta16 - March 3, 2012\n"
#define PNG_LIBPNG_VER_SONUM 16
#define PNG_LIBPNG_VER_DLLNUM 16
@ -3066,6 +3066,12 @@ PNG_EXPORT(240, int, png_image_write_to_stdio, (png_imagep image, FILE *file,
* END OF SIMPLIFIED API
******************************************************************************/
#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \
defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED)
PNG_EXPORT(242, void, png_set_check_for_invalid_index,
(png_structrp png_ptr, int allowed));
#endif
/* Maintainer: Put new public prototypes here ^, in libpng.3, and project
* defs
*/
@ -3075,7 +3081,7 @@ PNG_EXPORT(240, int, png_image_write_to_stdio, (png_imagep image, FILE *file,
* scripts/symbols.def as well.
*/
#ifdef PNG_EXPORT_LAST_ORDINAL
PNG_EXPORT_LAST_ORDINAL(241);
PNG_EXPORT_LAST_ORDINAL(242);
#endif
#ifdef __cplusplus

View File

@ -1438,6 +1438,13 @@ PNG_INTERNAL_FUNCTION(void,png_check_IHDR,(png_const_structrp png_ptr,
int color_type, int interlace_type, int compression_type,
int filter_type),PNG_EMPTY);
/* Added at libpng version 1.5.10 */
#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \
defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED)
PNG_INTERNAL_FUNCTION(void,png_do_check_palette_indexes,
(png_structrp png_ptr, png_row_infop row_info),PNG_EMPTY);
#endif
#if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)
PNG_INTERNAL_FUNCTION(void,png_fixed_error,(png_const_structrp png_ptr,
png_const_charp name),PNG_NORETURN);

View File

@ -748,8 +748,7 @@ png_read_end(png_structrp png_ptr, png_inforp info_ptr)
/* Report invalid palette index; added at libng-1.5.10 */
if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
png_ptr->num_palette_max > png_ptr->num_palette)
png_warning(png_ptr, "palette index exceeded num_palette; "
"pixel(s) rendered opaque black");
png_warning(png_ptr, "Read palette index exceeding num_palette");
#endif
do

View File

@ -2296,101 +2296,8 @@ png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info)
#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
/* Added at libpng-1.5.10 */
if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
{
if (png_ptr->num_palette < (1 << png_ptr->bit_depth) &&
((png_ptr->interlaced && png_ptr->pass == 6) ||
(!png_ptr->interlaced && png_ptr->pass == 0)))
{
png_bytep rp = png_ptr->row_buf + 1 + row_info->rowbytes;
switch (row_info->bit_depth)
{
case 1:
{
/* in this case, all bytes must be 0 so we don't need
* to unpack the pixels except for the rightmost one.
*/
int padding = 8*row_info->rowbytes - png_ptr->width;
for (; rp > png_ptr->row_buf; rp--)
{
if (*rp >> padding != 0)
png_ptr->num_palette_max = 1;
padding = 0;
}
break;
}
case 2:
{
int padding = 2*(4*row_info->rowbytes - png_ptr->width);
for (; rp > png_ptr->row_buf; rp--)
{
int index = ((*rp >> padding) & 0x03);
if (index > png_ptr->num_palette_max)
png_ptr->num_palette_max = index;
index = (((*rp >> padding) >> 2) & 0x03);
if (index > png_ptr->num_palette_max)
png_ptr->num_palette_max = index;
index = (((*rp >> padding) >> 4) & 0x03);
if (index > png_ptr->num_palette_max)
png_ptr->num_palette_max = index;
index = (((*rp >> padding) >> 6) & 0x03);
if (index > png_ptr->num_palette_max)
png_ptr->num_palette_max = index;
padding = 0;
}
break;
}
case 4:
{
int padding = 4*(2*row_info->rowbytes - png_ptr->width);
for (; rp > png_ptr->row_buf; rp--)
{
int index = ((*rp >> padding) & 0x0f);
if (index > png_ptr->num_palette_max)
png_ptr->num_palette_max = index;
index = (((*rp >> padding) >> 4) & 0x0f);
if (index > png_ptr->num_palette_max)
png_ptr->num_palette_max = index;
padding = 0;
}
break;
}
case 8:
{
for (; rp > png_ptr->row_buf; rp--)
{
if (*rp >= png_ptr->num_palette_max)
png_ptr->num_palette_max = *rp;
}
break;
}
}
}
}
png_do_check_palette_indexes(png_ptr, row_info);
#endif
#ifdef PNG_READ_BGR_SUPPORTED

View File

@ -1310,4 +1310,22 @@ png_set_benign_errors(png_structrp png_ptr, int allowed)
png_ptr->flags &= ~PNG_FLAG_BENIGN_ERRORS_WARN;
}
#endif /* PNG_BENIGN_ERRORS_SUPPORTED */
#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
/* Do not report invalid palette index; added at libng-1.5.10 */
void PNGAPI
png_set_check_for_invalid_index(png_structrp png_ptr, int allowed)
{
png_debug(1, "in png_set_check_for_invalid_index");
if (allowed)
png_ptr->num_palette_max = 0;
else
png_ptr->num_palette_max = -1;
}
#endif
#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */

View File

@ -126,7 +126,7 @@ struct png_struct_def
/* Added at libpng-1.5.10 */
#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
png_uint_16 num_palette_max; /* maximum palette index found in IDAT */
int num_palette_max; /* maximum palette index found in IDAT */
#endif
png_uint_16 num_trans; /* number of transparency values */

View File

@ -619,6 +619,107 @@ png_do_bgr(png_row_infop row_info, png_bytep row)
}
#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \
defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED)
/* Added at libpng-1.5.10 */
void /* PRIVATE */
png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info)
{
if (png_ptr->num_palette < (1 << row_info->bit_depth) &&
png_ptr->num_palette_max >= 0 &&
((png_ptr->interlaced && png_ptr->pass == 6) ||
(!png_ptr->interlaced && png_ptr->pass == 0)))
{
png_bytep rp = png_ptr->row_buf + 1 + row_info->rowbytes;
switch (row_info->bit_depth)
{
case 1:
{
/* in this case, all bytes must be 0 so we don't need
* to unpack the pixels except for the rightmost one.
*/
int padding = 8*row_info->rowbytes - png_ptr->width;
for (; rp > png_ptr->row_buf; rp--)
{
if (*rp >> padding != 0)
png_ptr->num_palette_max = 1;
padding = 0;
}
break;
}
case 2:
{
int padding = 2*(4*row_info->rowbytes - png_ptr->width);
for (; rp > png_ptr->row_buf; rp--)
{
int index = ((*rp >> padding) & 0x03);
if (index > png_ptr->num_palette_max)
png_ptr->num_palette_max = index;
index = (((*rp >> padding) >> 2) & 0x03);
if (index > png_ptr->num_palette_max)
png_ptr->num_palette_max = index;
index = (((*rp >> padding) >> 4) & 0x03);
if (index > png_ptr->num_palette_max)
png_ptr->num_palette_max = index;
index = (((*rp >> padding) >> 6) & 0x03);
if (index > png_ptr->num_palette_max)
png_ptr->num_palette_max = index;
padding = 0;
}
break;
}
case 4:
{
int padding = 4*(2*row_info->rowbytes - png_ptr->width);
for (; rp > png_ptr->row_buf; rp--)
{
int index = ((*rp >> padding) & 0x0f);
if (index > png_ptr->num_palette_max)
png_ptr->num_palette_max = index;
index = (((*rp >> padding) >> 4) & 0x0f);
if (index > png_ptr->num_palette_max)
png_ptr->num_palette_max = index;
padding = 0;
}
break;
}
case 8:
{
for (; rp > png_ptr->row_buf; rp--)
{
if (*rp >= png_ptr->num_palette_max)
png_ptr->num_palette_max = (int) *rp;
}
break;
}
}
}
}
#endif /* PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED */
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED

View File

@ -308,6 +308,11 @@ png_write_end(png_structrp png_ptr, png_inforp info_ptr)
if (!(png_ptr->mode & PNG_HAVE_IDAT))
png_error(png_ptr, "No IDATs written into file");
#ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
if (png_ptr->num_palette_max > png_ptr->num_palette)
png_warning(png_ptr, "Wrote palette index exceeding num_palette");
#endif
/* See if user wants us to write information chunks */
if (info_ptr != NULL)
{
@ -734,13 +739,8 @@ png_write_row(png_structrp png_ptr, png_const_bytep row)
/* Added at libpng-1.5.10 */
#ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
/* Check for out-of-range palette index */
#if 0 /* To do: implement png_do_check_palette_indexes() */
if (png_ptr->num_palette < (1 << png_ptr->bit_depth))
png_do_check_palette_indexes(&row_info, png_ptr->row_buf + 1,
png_ptr->num_palette_max);
#endif
if (png_ptr->num_palette_max > png_ptr->num_palette + 1)
png_warning(png_ptr, "Palette index exceeded num_palette");
if(row_info.color_type == PNG_COLOR_TYPE_PALETTE)
png_do_check_palette_indexes(png_ptr, &row_info);
#endif
/* Find a filter if necessary, filter the row and write it out. */