Prototype implementation of filter selection

This rewrites the code used previously in the heuristics to make it easier to
debug and introduces the 'methodical' method, which is intended to be an
expensive but reliable way of reducing image size.

The code in this commit does not work; the 'methodical' test for success does
not take account of data buffered inside zlib and, anyway, it changes the
results of pngtest so that the test fails.  This commit is just a checkpoint of
the current state; another commit will temporarily disable the 'methodical'
code.

Signed-off-by: John Bowler <jbowler@acm.org>
This commit is contained in:
John Bowler 2015-12-17 17:47:29 -08:00
parent bd0bb3ca7f
commit 61acc4c9ed
7 changed files with 1533 additions and 816 deletions

7
png.c
View File

@ -315,13 +315,6 @@ png_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
if (png_ptr != NULL)
{
/* png_ptr->zstream holds a back-pointer to the png_struct, so
* this can only be done now:
*/
create_struct.zstream.zalloc = png_zalloc;
create_struct.zstream.zfree = png_zfree;
create_struct.zstream.opaque = png_ptr;
# ifdef PNG_SETJMP_SUPPORTED
/* Eliminate the local error handling: */
create_struct.jmp_buf_ptr = NULL;

View File

@ -87,13 +87,17 @@ png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size),
if (size > 0 && size <= PNG_SIZE_MAX)
#endif
{
png_voidp result;
#ifdef PNG_USER_MEM_SUPPORTED
if (png_ptr != NULL && png_ptr->malloc_fn != NULL)
return png_ptr->malloc_fn(png_constcast(png_structrp,png_ptr), size);
result = png_ptr->malloc_fn(png_constcast(png_structrp,png_ptr), size);
else
#endif
return malloc((size_t)size); /* checked for truncation above */
result = malloc((size_t)size); /* checked for truncation above */
return result;
}
else

View File

@ -620,7 +620,7 @@
* TODO: change to bit fields.
*/
#define PNG_FLAG_LIBRARY_MISMATCH 0x001U
#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x002U
/*#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x002U NO LONGER USED */
#define PNG_FLAG_CRC_ANCILLARY_USE 0x004U
#define PNG_FLAG_CRC_ANCILLARY_NOWARN 0x008U
#define PNG_FLAG_CRC_CRITICAL_USE 0x010U
@ -1225,7 +1225,7 @@ PNG_INTERNAL_FUNCTION(void, png_write_filter_row, (png_structrp png_ptr,
PNG_EMPTY);
/* Release memory used by the deflate mechanism */
PNG_INTERNAL_FUNCTION(void, png_deflate_destroy, (png_structrp png_ptr),
PNG_INTERNAL_FUNCTION(void, png_deflate_destroy, (png_structp png_ptr),
PNG_EMPTY);
#ifdef PNG_TRANSFORM_MECH_SUPPORTED

View File

@ -325,6 +325,11 @@ png_inflate_claim(png_structrp png_ptr, png_uint_32 owner)
# endif
# endif
/* Initialize the alloc/free callbacks every time: */
png_ptr->zstream.zalloc = png_zalloc;
png_ptr->zstream.zfree = png_zfree;
png_ptr->zstream.opaque = png_ptr;
/* Set this for safety, just in case the previous owner left pointers to
* memory allocations.
*/

View File

@ -63,13 +63,10 @@
#endif
#ifdef PNG_WRITE_SUPPORTED
/* The type of a compression buffer list used by the write code. */
typedef struct png_compression_buffer *png_compression_bufferp;
#endif
#ifdef PNG_SELECT_FILTER_METHODICALLY_SUPPORTED
/* Type of the data cache used when selecting filters methodicially */
typedef struct png_filter_select *png_filter_selectp;
/* The write compression control (allocated on demand).
* TODO: use this for the read state too.
*/
typedef struct png_zlib_state *png_zlib_statep;
#endif
/* Colorspace support; structures used in png_struct, png_info and in internal
@ -512,9 +509,6 @@ struct png_struct_def
unsigned int row_input_pixel_depth :8;
unsigned int row_output_pixel_depth :8;
unsigned int row_max_pixel_depth :8;
#ifdef PNG_WRITE_FILTER_SUPPORTED
unsigned int filter_mask :8; /* mask of filters to consider on write */
#endif /* WRITE_FILTER */
# define PNG_RF_BITS 9 /* Number of bits required for the row format (below) */
#ifdef PNG_TRANSFORM_MECH_SUPPORTED
@ -585,28 +579,6 @@ struct png_struct_def
uInt IDAT_size; /* limit on IDAT read and write IDAT size */
#endif /* SEQUENTIAL_READ || WRITE */
#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
int zlib_text_level; /* holds zlib compression level */
int zlib_text_method; /* holds zlib compression method */
int zlib_text_window_bits; /* holds zlib compression window bits */
int zlib_text_mem_level; /* holds zlib compression memory level */
int zlib_text_strategy; /* holds zlib compression strategy */
#endif
#ifdef PNG_WRITE_SUPPORTED
int zlib_level; /* holds zlib compression level */
int zlib_method; /* holds zlib compression method */
int zlib_window_bits; /* holds zlib compression window bits */
int zlib_mem_level; /* holds zlib compression memory level */
int zlib_strategy; /* holds zlib compression strategy */
int zlib_set_level; /* Actual values set into the zstream on write */
int zlib_set_method;
int zlib_set_window_bits;
int zlib_set_mem_level;
int zlib_set_strategy;
#endif /* WRITE */
/* ERROR HANDLING */
#ifdef PNG_SETJMP_SUPPORTED
jmp_buf *jmp_buf_ptr; /* passed to longjmp_fn */
@ -649,8 +621,6 @@ struct png_struct_def
#ifdef PNG_WRITE_FLUSH_SUPPORTED
png_flush_ptr output_flush_fn; /* Function for flushing output */
png_uint_32 flush_dist; /* how many rows apart to flush, 0 - no flush */
png_uint_32 flush_rows; /* number of rows written since last flush */
#endif
#endif /* WRITE */
@ -749,19 +719,12 @@ struct png_struct_def
* zlib expects a 'zstream' as the fundamental control structure, it allows
* all the parameters to be passed as one pointer.
*/
z_stream zstream; /* decompression structure */
png_uint_32 zowner; /* ID (chunk type) of zstream owner, 0 if none */
png_uint_32 zowner; /* ID (chunk type) of zlib owner, 0 if none */
# ifdef PNG_WRITE_SUPPORTED
png_compression_bufferp zbuffer_list; /* Created on demand during write */
png_compression_bufferp *zbuffer_end; /* 'next' field of current buffer */
png_uint_32 zbuffer_len; /* Length of data in list */
unsigned int zbuffer_start; /* Bytes written from start */
unsigned int zbuffer_filters;/*Filters for this row */
# ifdef PNG_SELECT_FILTER_METHODICALLY_SUPPORTED
png_filter_selectp zbuffer_select;
# endif /* SELECT_FILTER_METHODICALLY */
png_zlib_statep zlib_state; /* State of zlib compression */
# endif /* WRITE */
# ifdef PNG_READ_SUPPORTED
z_stream zstream; /* decompression structure */
unsigned int zstream_ended:1; /* no more zlib output available [read] */
unsigned int zstream_error:1; /* zlib error message has been output [read] */
# endif /* READ */
@ -779,6 +742,8 @@ struct png_struct_def
/* SCRATCH buffers, used when control returns to the application or a read
* loop.
*/
# ifdef PNG_READ_SUPPORTED
png_byte scratch[PNG_ROW_BUFFER_SIZE+16U];
# endif /* READ */
};
#endif /* PNGSTRUCT_H */

View File

@ -520,29 +520,9 @@ png_create_write_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr,
if (png_ptr != NULL)
{
/* Set the zlib control values to defaults; they can be overridden by the
* application after the struct has been created.
*/
/* Set the IDAT size to the default, the app can change it later. */
png_ptr->IDAT_size = PNG_ZBUF_SIZE;
/* The 'zlib_strategy' setting is irrelevant because png_default_claim in
* pngwutil.c defaults it according to whether or not filters will be
* used, and ignores this setting.
*/
png_ptr->zlib_strategy = PNG_Z_DEFAULT_STRATEGY;
png_ptr->zlib_level = PNG_Z_DEFAULT_COMPRESSION;
png_ptr->zlib_mem_level = 8;
png_ptr->zlib_window_bits = 15;
png_ptr->zlib_method = 8;
#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED
png_ptr->zlib_text_strategy = PNG_TEXT_Z_DEFAULT_STRATEGY;
png_ptr->zlib_text_level = PNG_TEXT_Z_DEFAULT_COMPRESSION;
png_ptr->zlib_text_mem_level = 8;
png_ptr->zlib_text_window_bits = 15;
png_ptr->zlib_text_method = 8;
#endif /* WRITE_COMPRESSED_TEXT */
/* This is a highly dubious configuration option; by default it is off,
* but it may be appropriate for private builds that are testing
* extensions not conformant to the current specification, or of

2248
pngwutil.c

File diff suppressed because it is too large Load Diff