pngcp minimal configuration changes

Corrections for the pngcp minimal configuration in libpng 1.7 and corrections to
the libpng 1.7 code to fix bugs revealed by the reduced configuration.

Signed-off-by: John Bowler <jbowler@acm.org>
This commit is contained in:
John Bowler 2016-07-01 22:39:13 -07:00
parent eaf7abfdc3
commit 6a574a84bd
8 changed files with 61 additions and 40 deletions

View File

@ -14,18 +14,14 @@
everything = off everything = off
# Options to turn on png_read_png and png_write_png: # Options to turn on png_read_png and png_write_png:
option INFO_IMAGE on option WRITE_PNG on
option SEQUENTIAL_READ on option READ_PNG on
option EASY_ACCESS on option EASY_ACCESS on
option WRITE on
option WRITE_16BIT on option WRITE_16BIT on
option WRITE_FILTER on option SELECT_FILTER on
# pngcp needs this to preserve unknown chunks, switching all these on means that # pngcp needs this to preserve unknown chunks, switching all these on means that
# pngcp can work without explicit known chunk reading suppport # pngcp can work without explicit known chunk reading suppport
option UNKNOWN_CHUNKS on
option SET_UNKNOWN_CHUNKS on
option HANDLE_AS_UNKNOWN on
option SAVE_UNKNOWN_CHUNKS on option SAVE_UNKNOWN_CHUNKS on
option WRITE_UNKNOWN_CHUNKS on option WRITE_UNKNOWN_CHUNKS on
@ -33,10 +29,6 @@ option WRITE_UNKNOWN_CHUNKS on
option CHECK_FOR_INVALID_INDEX on option CHECK_FOR_INVALID_INDEX on
option GET_PALETTE_MAX on option GET_PALETTE_MAX on
# Pre-libpng 1.7 pngcp has to stash text chunks manually, post 1.7 without this
# text chunks should be handled as unknown ok.
option TEXT on
# this is used to turn off limits: # this is used to turn off limits:
option USER_LIMITS on option USER_LIMITS on
option SET_USER_LIMITS on option SET_USER_LIMITS on

View File

@ -45,8 +45,19 @@
# define SKIP 0 # define SKIP 0
#endif #endif
#if defined(PNG_INFO_IMAGE_SUPPORTED) && defined(PNG_SEQUENTIAL_READ_SUPPORTED)\ #if PNG_LIBPNG_VER < 10700
&& (defined(PNG_READ_PNG_SUPPORTED) || PNG_LIBPNG_VER < 10700) /* READ_PNG and WRITE_PNG were not defined, so: */
# ifdef PNG_INFO_IMAGE_SUPPORTED
# ifdef PNG_SEQUENTIAL_READ_SUPPORTED
# define PNG_READ_PNG_SUPPORTED
# endif /* SEQUENTIAL_READ */
# ifdef PNG_WRITE_SUPPORTED
# define PNG_WRITE_PNG_SUPPORTED
# endif /* WRITE */
# endif /* INFO_IMAGE */
#endif /* pre 1.7.0 */
#ifdef PNG_READ_PNG_SUPPORTED
/* If a transform is valid on both read and write this implies that if the /* If a transform is valid on both read and write this implies that if the
* transform is applied to read it must also be applied on write to produce * transform is applied to read it must also be applied on write to produce
* meaningful data. This is because these transforms when performed on read * meaningful data. This is because these transforms when performed on read
@ -395,7 +406,7 @@ buffer_destroy(struct buffer *buffer)
buffer_destroy_list(list); buffer_destroy_list(list);
} }
#ifdef PNG_WRITE_SUPPORTED #ifdef PNG_WRITE_PNG_SUPPORTED
static void static void
buffer_start_write(struct buffer *buffer) buffer_start_write(struct buffer *buffer)
{ {
@ -565,7 +576,7 @@ struct display
png_structp read_pp; png_structp read_pp;
png_infop read_ip; png_infop read_ip;
# ifdef PNG_WRITE_SUPPORTED # ifdef PNG_WRITE_PNG_SUPPORTED
/* Used to write a new image (the original info_ptr is used) */ /* Used to write a new image (the original info_ptr is used) */
png_structp write_pp; png_structp write_pp;
struct buffer written_file; /* where the file gets written */ struct buffer written_file; /* where the file gets written */
@ -592,7 +603,7 @@ display_init(struct display *dp)
dp->read_ip = NULL; dp->read_ip = NULL;
buffer_init(&dp->original_file); buffer_init(&dp->original_file);
# ifdef PNG_WRITE_SUPPORTED # ifdef PNG_WRITE_PNG_SUPPORTED
dp->write_pp = NULL; dp->write_pp = NULL;
buffer_init(&dp->written_file); buffer_init(&dp->written_file);
# endif # endif
@ -605,7 +616,7 @@ display_clean_read(struct display *dp)
png_destroy_read_struct(&dp->read_pp, &dp->read_ip, NULL); png_destroy_read_struct(&dp->read_pp, &dp->read_ip, NULL);
} }
#ifdef PNG_WRITE_SUPPORTED #ifdef PNG_WRITE_PNG_SUPPORTED
static void static void
display_clean_write(struct display *dp) display_clean_write(struct display *dp)
{ {
@ -617,7 +628,7 @@ display_clean_write(struct display *dp)
static void static void
display_clean(struct display *dp) display_clean(struct display *dp)
{ {
# ifdef PNG_WRITE_SUPPORTED # ifdef PNG_WRITE_PNG_SUPPORTED
display_clean_write(dp); display_clean_write(dp);
# endif # endif
display_clean_read(dp); display_clean_read(dp);
@ -635,7 +646,7 @@ static void
display_destroy(struct display *dp) display_destroy(struct display *dp)
{ {
/* Release any memory held in the display. */ /* Release any memory held in the display. */
# ifdef PNG_WRITE_SUPPORTED # ifdef PNG_WRITE_PNG_SUPPORTED
buffer_destroy(&dp->written_file); buffer_destroy(&dp->written_file);
# endif # endif
@ -1253,7 +1264,7 @@ compare_read(struct display *dp, int applied_transforms)
return 1; /* compare succeeded */ return 1; /* compare succeeded */
} }
#ifdef PNG_WRITE_SUPPORTED #ifdef PNG_WRITE_PNG_SUPPORTED
static void static void
buffer_write(struct display *dp, struct buffer *buffer, png_bytep data, buffer_write(struct display *dp, struct buffer *buffer, png_bytep data,
png_size_t size) png_size_t size)
@ -1352,7 +1363,7 @@ write_png(struct display *dp, png_infop ip, int transforms)
*/ */
display_clean_write(dp); display_clean_write(dp);
} }
#endif /* WRITE_SUPPORTED */ #endif /* WRITE_PNG */
static int static int
skip_transform(struct display *dp, int tr) skip_transform(struct display *dp, int tr)
@ -1414,7 +1425,7 @@ test_one_file(struct display *dp, const char *filename)
return; /* no point testing more */ return; /* no point testing more */
} }
#ifdef PNG_WRITE_SUPPORTED #ifdef PNG_WRITE_PNG_SUPPORTED
/* Second test: write the original PNG data out to a new file (to test the /* Second test: write the original PNG data out to a new file (to test the
* write side) then read the result back in and make sure that it hasn't * write side) then read the result back in and make sure that it hasn't
* changed. * changed.
@ -1455,7 +1466,7 @@ test_one_file(struct display *dp, const char *filename)
* out and read it back in again (without the reversible transforms) * out and read it back in again (without the reversible transforms)
* we should get back to the place where we started. * we should get back to the place where we started.
*/ */
#ifdef PNG_WRITE_SUPPORTED #ifdef PNG_WRITE_PNG_SUPPORTED
if ((current & write_transforms) == current) if ((current & write_transforms) == current)
{ {
/* All transforms reversible: write the PNG with the transformations /* All transforms reversible: write the PNG with the transformations
@ -1691,7 +1702,7 @@ main(const int argc, const char * const * const argv)
return errors != 0; return errors != 0;
} }
} }
#else /* !INFO_IMAGE || !SEQUENTIAL_READ || !READ_PNG*/ #else /* !READ_PNG */
int int
main(void) main(void)
{ {

2
png.c
View File

@ -186,7 +186,7 @@ png_user_version_check(png_structrp png_ptr, png_const_charp user_png_ver)
{ {
int library_match = 1; int library_match = 1;
int i = -1; int i = -1;
int found_dots = 0; unsigned int found_dots = 0;
do do
{ {

View File

@ -5893,7 +5893,12 @@ init_caching(png_structp png_ptr, png_transform_controlp tend)
{ {
/* This turns starts the palette caching with the next transform: */ /* This turns starts the palette caching with the next transform: */
tend->palette = tend->caching = 1U; tend->palette = tend->caching = 1U;
tend->transparent_alpha = png_ptr->transparent_palette; # ifdef PNG_READ_tRNS_SUPPORTED
tend->transparent_alpha = png_ptr->transparent_palette;
# else /* !READ_tRNS */
tend->transparent_alpha = 0;
PNG_UNUSED(png_ptr)
# endif /* !READ_tRNS */
tend->format = PNG_FORMAT_FLAG_COLOR; tend->format = PNG_FORMAT_FLAG_COLOR;
# ifdef PNG_READ_tRNS_SUPPORTED # ifdef PNG_READ_tRNS_SUPPORTED
if (png_ptr->num_trans > 0 && !(tend->invalid_info & PNG_INFO_tRNS)) if (png_ptr->num_trans > 0 && !(tend->invalid_info & PNG_INFO_tRNS))

View File

@ -777,11 +777,18 @@ png_handle_error(png_structrp png_ptr
png_chunk_benign_error(png_ptr, error); png_chunk_benign_error(png_ptr, error);
} }
#if defined (PNG_READ_gAMA_SUPPORTED) || defined (PNG_READ_sBIT_SUPPORTED) ||\
defined (PNG_READ_cHRM_SUPPORTED) || defined (PNG_READ_sRGB_SUPPORTED) ||\
defined (PNG_READ_iCCP_SUPPORTED) || defined (PNG_READ_tRNS_SUPPORTED) ||\
defined (PNG_READ_bKGD_SUPPORTED) || defined (PNG_READ_hIST_SUPPORTED) ||\
defined (PNG_READ_pHYs_SUPPORTED) || defined (PNG_READ_oFFs_SUPPORTED) ||\
defined (PNG_READ_sCAL_SUPPORTED) || defined (PNG_READ_tIME_SUPPORTED)
static void static void
png_handle_bad_length(png_structrp png_ptr) png_handle_bad_length(png_structrp png_ptr)
{ {
png_handle_error(png_ptr, "invalid length"); png_handle_error(png_ptr, "invalid length");
} }
#endif /* chunks that can generate length errors */
/* Read and check the IDHR chunk */ /* Read and check the IDHR chunk */
static void static void

View File

@ -599,20 +599,24 @@ set_palette_max(png_structrp png_ptr, png_transformp tr, unsigned int max,
png_ptr->palette_index_check != PNG_PALETTE_CHECK_OFF) png_ptr->palette_index_check != PNG_PALETTE_CHECK_OFF)
# endif /* WRITE */ # endif /* WRITE */
) )
{
# ifdef PNG_READ_SUPPORTED # ifdef PNG_READ_SUPPORTED
# ifdef PNG_WRITE_SUPPORTED # ifdef PNG_WRITE_SUPPORTED
(png_ptr->read_struct ? png_chunk_benign_error : png_error) if (png_ptr->read_struct)
# else /* !WRITE */ # endif /* WRITE */
png_chunk_benign_error png_chunk_benign_error(png_ptr, "palette index too large");
# endif /* READ */ # ifdef PNG_WRITE_SUPPORTED
# else /* !READ */ else
png_error # endif
# endif /* READ */
# ifdef PNG_WRITE_SUPPORTED
png_error(png_ptr, "palette index too large");
# endif /* WRITE */ # endif /* WRITE */
(png_ptr, "palette index too large"); }
png_ptr->palette_index_check_issued = 1; png_ptr->palette_index_check_issued = 1;
} }
# endif # endif /* CHECK_FOR_INVALID_INDEX */
# ifdef PNG_GET_PALETTE_MAX_SUPPORTED # ifdef PNG_GET_PALETTE_MAX_SUPPORTED
png_ptr->palette_index_max = png_check_byte(png_ptr, max); png_ptr->palette_index_max = png_check_byte(png_ptr, max);
# endif # endif

View File

@ -3689,7 +3689,6 @@ void /* PRIVATE */
png_write_start_IDAT(png_structrp png_ptr) png_write_start_IDAT(png_structrp png_ptr)
{ {
png_zlib_statep ps = get_zlib_state(png_ptr); png_zlib_statep ps = get_zlib_state(png_ptr);
int png_level;
/* Set up the IDAT compression state. Expect the state to have been released /* Set up the IDAT compression state. Expect the state to have been released
* by the previous owner, but it doesn't much matter if there was an error. * by the previous owner, but it doesn't much matter if there was an error.
@ -3700,12 +3699,13 @@ png_write_start_IDAT(png_structrp png_ptr)
/* This sets the buffer limits and write_row_size, which is used below. */ /* This sets the buffer limits and write_row_size, which is used below. */
png_zlib_state_set_buffer_limits(png_ptr, ps); png_zlib_state_set_buffer_limits(png_ptr, ps);
/* Now default the filter mask if it hasn't been set already: */
png_level = pz_get(ps, IDAT, png_level, PNG_DEFAULT_COMPRESSION_LEVEL);
if (ps->filter_mask == 0) if (ps->filter_mask == 0)
{ {
# ifdef PNG_SELECT_FILTER_SUPPORTED # ifdef PNG_SELECT_FILTER_SUPPORTED
/* Now default the filter mask if it hasn't been set already: */
int png_level =
pz_get(ps, IDAT, png_level, PNG_DEFAULT_COMPRESSION_LEVEL);
/* If the bit depth is less than 8, so pixels are not byte aligned, PNG /* If the bit depth is less than 8, so pixels are not byte aligned, PNG
* filtering hardly ever helps because there is no correlation between * filtering hardly ever helps because there is no correlation between
* the bytes on which the filter works and the actual pixel values. * the bytes on which the filter works and the actual pixel values.

View File

@ -939,8 +939,10 @@ option WRITE_zTXt enables WRITE_COMPRESSED_TEXT
# leave the row_pointers member out of the info structure. # leave the row_pointers member out of the info structure.
option INFO_IMAGE disabled option INFO_IMAGE disabled
option READ_PNG requires READ_IMAGE READ_TRANSFORMS enables INFO_IMAGE option READ_PNG requires READ_IMAGE READ_TRANSFORMS READ_INTERLACING,
option WRITE_PNG requires WRITE WRITE_TRANSFORMS enables INFO_IMAGE enables INFO_IMAGE
option WRITE_PNG requires WRITE WRITE_TRANSFORMS WRITE_INTERLACING,
enables INFO_IMAGE
# There are four options here, two each for read and write. By default they are # There are four options here, two each for read and write. By default they are
# all switched on. # all switched on.