Compression changes/fixes

Simplified API: change handling of PNG_IMAGE_FLAG_FAST to use
PNG_COMPRESSION_HIGH_SPEED, and PNG_COMPRESSION_HIGH otherwise.

Compression: add missing break statements that caused some compression settings
to fall through to the 'HIGH' setting.

Internal: remove png_struct::flags, it only stored the 'library mismatch' flag
and that could never be accessed (because immediately after it was set the
png_struct, which was on the stack, was eliminated.)

Signed-off-by: John Bowler <jbowler@acm.org>
This commit is contained in:
John Bowler 2016-06-08 08:37:20 -07:00
parent b70b51ba17
commit d52c8eba99
5 changed files with 29 additions and 56 deletions

37
png.c
View File

@ -175,16 +175,16 @@ png_calculate_crc(png_structrp png_ptr, png_const_voidp ptr, png_size_t length)
/* Check a user supplied version number, called from both read and write
* functions that create a png_struct.
*/
int
static int
png_user_version_check(png_structrp png_ptr, png_const_charp user_png_ver)
{
/* Libpng versions 1.0.0 and later are binary compatible if the version
* string matches through the second '.'; we must recompile any
* applications that use any older library version.
*/
/* Libpng versions 1.0.0 and later are binary compatible if the version
* string matches through the second '.'; we must recompile any applications
* that use any older library version.
*/
if (user_png_ver != NULL)
{
int library_match = 1;
int i = -1;
int found_dots = 0;
@ -192,36 +192,36 @@ png_user_version_check(png_structrp png_ptr, png_const_charp user_png_ver)
{
i++;
if (user_png_ver[i] != PNG_LIBPNG_VER_STRING[i])
png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
library_match = 0;
if (user_png_ver[i] == '.')
found_dots++;
} while (found_dots < 2 && user_png_ver[i] != 0 &&
} while (library_match && found_dots < 2 && user_png_ver[i] != 0 &&
PNG_LIBPNG_VER_STRING[i] != 0);
if (library_match)
return 1; /* Library matches ok */
}
else
png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
if ((png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH) != 0)
{
/* Failure: mismatched library major version number */
#ifdef PNG_WARNINGS_SUPPORTED
{
size_t pos = 0;
char m[128];
pos = png_safecat(m, (sizeof m), pos,
"Application built with libpng-");
/* This is ok if user_png_ver is NULL, it appends nothing: */
pos = png_safecat(m, (sizeof m), pos, user_png_ver);
pos = png_safecat(m, (sizeof m), pos, " but running with ");
pos = png_safecat(m, (sizeof m), pos, PNG_LIBPNG_VER_STRING);
PNG_UNUSED(pos)
png_warning(png_ptr, m);
#endif
return 0;
png_app_warning(png_ptr, m);
}
#endif
/* Success return. */
return 1;
return 0; /* Failure */
PNG_UNUSED(png_ptr) /* if no warning */
}
/* Generic function to create a png_struct for either read or write - this
@ -3431,6 +3431,7 @@ png_setting(png_structrp png_ptr, png_uint_32 setting, png_uint_32 parameter,
/* No write options at present */
result = PNG_OPTION_UNSET; /* i.e. ignore it */
break;
# endif /* SET_OPTION */
default:

View File

@ -618,22 +618,6 @@
#define PNG_HAVE_IEND 0x10U
#define PNG_HAVE_PNG_SIGNATURE 0x20U
/* Flags for the png_ptr->flags.
* TODO: change to bit fields.
*/
#define PNG_FLAG_LIBRARY_MISMATCH 0x001U
/*#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x002U NO LONGER USED */
/*#define PNG_FLAG_CRC_ANCILLARY_USE 0x004U NO LONGER USED */
/*#define PNG_FLAG_CRC_ANCILLARY_NOWARN 0x008U NO LONGER USED */
/*#define PNG_FLAG_CRC_CRITICAL_USE 0x010U NO LONGER USED */
/*#define PNG_FLAG_CRC_CRITICAL_IGNORE 0x020U NO LONGER USED */
/*#define PNG_FLAG_STRIP_ERROR_NUMBERS 0x040U NEVER USED */
/*#define PNG_FLAG_STRIP_ERROR_TEXT 0x080U NEVER USED */
/*#define PNG_FLAG_IDAT_ERRORS_WARN 0x100U NEVER SET */
/*#define PNG_FLAG_BENIGN_ERRORS_WARN 0x200U NO LONGER USED */
/*#define PNG_FLAG_APP_WARNINGS_WARN 0x400U NO LONGER USED */
/*#define PNG_FLAG_APP_ERRORS_WARN 0x800U NO LONGER USED */
#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
/* See below for the definitions of the tables used in these macros */
@ -968,12 +952,6 @@ PNG_INTERNAL_FUNCTION(png_fixed_point,png_fixed,(png_const_structrp png_ptr,
double fp, png_const_charp text),PNG_EMPTY);
#endif
/* Check the user version string for compatibility, returns false if the version
* numbers aren't compatible.
*/
PNG_INTERNAL_FUNCTION(int,png_user_version_check,(png_structrp png_ptr,
png_const_charp user_png_ver),PNG_EMPTY);
/* Internal base allocator - no messages, NULL on failure to allocate. This
* does, however, call the application provided allocator and that could call
* png_error (although that would be a bug in the application implementation.)

View File

@ -394,7 +394,6 @@ struct png_struct_def
png_uint_32 chunk_length; /* Length (possibly remaining) in said chunk. */
png_uint_32 crc; /* current chunk CRC value */
unsigned int flags; /* flags (should be bit fields) */
unsigned int mode :6; /* where we are in the PNG file */
unsigned int read_struct :1; /* this is a read (not write) struct */
unsigned int num_palette :9; /* number of color entries in palette */

View File

@ -1910,21 +1910,12 @@ png_image_write_main(png_voidp argument)
display->row_bytes = row_bytes;
}
/* Apply 'fast' options if the flag is set. */
if ((image->flags & PNG_IMAGE_FLAG_FAST) != 0)
{
# ifdef PNG_WRITE_FILTER_SUPPORTED
png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, PNG_NO_FILTERS);
# endif /* WRITE_FILTER */
/* NOTE: determined by experiment using pngstest, this reflects some
* balance between the time to write the image once and the time to read
* it about 50 times. The speed-up in pngstest was about 10-20% of the
* total (user) time on a heavily loaded system.
*/
# ifdef PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
png_set_compression_level(png_ptr, 3);
# endif /* WRITE_CUSTOMIZE_COMPRESSION */
}
/* Select the right compression mode based on the presence or absence of the
* 'fast' flag, this will use whatever options are available in the libpng
* build. It is always supported.
*/
png_set_compression(png_ptr, (image->flags & PNG_IMAGE_FLAG_FAST) != 0 ?
PNG_COMPRESSION_HIGH_SPEED : PNG_COMPRESSION_HIGH);
/* Check for the cases that currently require a pre-transform on the row
* before it is written. This only applies when the input is 16-bit and

View File

@ -3076,6 +3076,7 @@ png_write_IDAT(png_structrp png_ptr, int flush)
default:
case PNG_COMPRESSION_MEDIUM:
IDAT_size = PNG_ZBUF_SIZE;
break;
case PNG_COMPRESSION_HIGH_READ_SPEED:
/* Assume the reader reads partial IDAT chunks (pretty much a
@ -3817,12 +3818,15 @@ png_write_start_IDAT(png_structrp png_ptr)
default: /* For GCC */
case PNG_COMPRESSION_LOW:
ps->filter_mask = PNG_FILTER_NONE+PNG_FILTER_SUB;
break;
case PNG_COMPRESSION_MEDIUM:
ps->filter_mask = PNG_FAST_FILTERS;
break;
case PNG_COMPRESSION_HIGH:
ps->filter_mask = PNG_ALL_FILTERS;
break;
}
# else /* !SELECT_FILTER */
ps->filter_mask = PNG_FILTER_NONE;