mirror of
https://git.code.sf.net/p/libpng/code.git
synced 2025-07-10 18:04:09 +02:00
Change option (SUPPORTED) names, dummy code
The filter selection options are made more intuitive (IMO, but I am not an Intuitive User). Dummy code added for methodical filter selection. Signed-off-by: John Bowler <jbowler@acm.org>
This commit is contained in:
parent
71c5123a4d
commit
9fce04fcd6
38
png.h
38
png.h
@ -1661,22 +1661,26 @@ PNG_EXPORT(66, void, png_set_crc_action, (png_structrp png_ptr, int crit_action,
|
||||
* ignored if SUB is set; this is because these filter pairs are equivalent
|
||||
* when there is no previous row.
|
||||
*
|
||||
* PNG_WRITE_OPTIMIZE_FITLER_SUPPORTED:
|
||||
* 2) If WRITE_OPTIMIZE_FILTER is supported and it has not been disabled by
|
||||
* png_set_option(PNG_DISABLE_OPTIMIZE_FILTER, PNG_OPTION_ON) libpng tries
|
||||
* all the filters in the list and selects the one which gives the shortest
|
||||
* compressed row, favoring earlier filters.
|
||||
* 2) PNG_SELECT_FILTER_METHODICALLY_SUPPORTED:
|
||||
* If SELECT_FILTER_METHODICALLY is 'on' libpng tries all the filters in the
|
||||
* list and selects the one which gives the shortest compressed row, favoring
|
||||
* earlier filters.
|
||||
*
|
||||
* PNG_WRITE_HEURISTIC_FITLER_SUPPORTED:
|
||||
* 3) If not (2) an WRITE_HEURISTIC_FILTER is supported and has not been
|
||||
* disabled by png_set_option(PNG_DISABLE_HEURISTIC_FILTER, PNG_OPTION_ON)
|
||||
* libpng tests the start of each row (a few thousand bytes at most) to see
|
||||
* which filter is likely to produce best compression.
|
||||
* 3) PNG_SELECT_FILTER_HEURISTICALLY_SUPPORTED:
|
||||
* If SELECT_FILTER_HEURISTICALLY is 'on' libpng tests the start of each row
|
||||
* (a few thousand bytes at most) to see which filter is likely to produce
|
||||
* best compression.
|
||||
*
|
||||
* 4) If neither (2) nor (3) libpng selects the first filter in the list (there
|
||||
* is no warning that this will happen - check the #defines if you need to
|
||||
* know.)
|
||||
*
|
||||
* The seletion options are turned 'on' using png_set_option(method,
|
||||
* PNG_OPTION_ON) and turned off with PNG_OPTION_OFF. If a selection method is
|
||||
* turned off it will never be used, if neither option is turned on or off (i.e.
|
||||
* if png_set_option is not called) the first supported option (2) or (3) will
|
||||
* be used.
|
||||
*
|
||||
* If you intend to use 'previous row' filters in an image set either the UP or
|
||||
* PAETH filter before the first call to png_write_row, depending on whether you
|
||||
* want to use NONE or SUB on the first row.
|
||||
@ -1685,11 +1689,11 @@ PNG_EXPORT(66, void, png_set_crc_action, (png_structrp png_ptr, int crit_action,
|
||||
* preceding byte as a predictor and is not likely to have very good
|
||||
* performance.
|
||||
*
|
||||
* The WRITE_OPTIMIZE_FILTER option is slow and memory intensive, but it is
|
||||
* likely to produce the smallest PNG file. Depending on the image data the
|
||||
* HEURISTIC option may improve results and has little overall effect on
|
||||
* compression speed, however it can sometimes produce larger files than not
|
||||
* using any filtering.
|
||||
* The SELECT_FILTER_METHODICALLY option is slow and memory intensive, but it is
|
||||
* almost certain to produce the smallest PNG file. Depending on the image data
|
||||
* the HEURISTIC option may improve results significantly over the NONE filter
|
||||
* and it has little overall effect on compression speed, however it can
|
||||
* sometimes produce larger files than not using any filtering.
|
||||
*/
|
||||
PNG_EXPORT(67, void, png_set_filter, (png_structrp png_ptr, int method,
|
||||
int filters));
|
||||
@ -3491,8 +3495,8 @@ PNG_EXPORT(240, int, png_image_write_to_stdio, (png_imagep image, FILE *file,
|
||||
#define PNG_EXTENSIONS 0 /* BOTH: enable or disable extensions */
|
||||
#define PNG_MAXIMUM_INFLATE_WINDOW 2 /* SOFTWARE: force maximum window */
|
||||
#define PNG_SKIP_sRGB_CHECK_PROFILE 4 /* SOFTWARE: Check ICC profile for sRGB */
|
||||
#define PNG_DISABLE_HEURISTIC_FILTER 6 /* SOFTWARE: see png_set_filter */
|
||||
#define PNG_DISABLE_OPTIMIZE_FILTER 8 /* SOFTWARE: see png_set_filter */
|
||||
#define PNG_SELECT_FILTER_HEURISTICALLY 6 /* SOFTWARE: see png_set_filter */
|
||||
#define PNG_SELECT_FILTER_METHODICALLY 8 /* SOFTWARE: see png_set_filter */
|
||||
#define PNG_OPTION_NEXT 10 /* Next option - numbers must be even */
|
||||
|
||||
/* Return values: NOTE: there are four values and 'off' is *not* zero */
|
||||
|
@ -751,6 +751,9 @@ struct png_struct_def
|
||||
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 */
|
||||
# ifdef PNG_SELECT_FILTER_METHODICALLY_SUPPORTED
|
||||
png_voidp zbuffer_select;
|
||||
# endif /* SELECT_FILTER_METHODICALLY */
|
||||
# endif /* WRITE */
|
||||
# ifdef PNG_READ_SUPPORTED
|
||||
unsigned int zstream_ended:1; /* no more zlib output available [read] */
|
||||
|
104
pngwutil.c
104
pngwutil.c
@ -2375,16 +2375,16 @@ filter_row(png_structrp png_ptr, png_const_bytep prev_row,
|
||||
/* These two #defines simplify writing code that depends on one or the other of
|
||||
* the options being both supported and on:
|
||||
*/
|
||||
#ifdef PNG_WRITE_OPTIMIZE_FILTER_SUPPORTED
|
||||
# define optimize_filters\
|
||||
(((png_ptr->options >> PNG_DISABLE_OPTIMIZE_FILTER)&3) != PNG_OPTION_ON)
|
||||
#ifdef PNG_SELECT_FILTER_METHODICALLY_SUPPORTED
|
||||
# define methodical_option\
|
||||
((png_ptr->options >> PNG_SELECT_FILTER_METHODICALLY) & 3U)
|
||||
#else
|
||||
# define optimize_filters 0
|
||||
# define methodical_option PNG_OPTION_OFF
|
||||
#endif
|
||||
|
||||
#ifdef PNG_WRITE_HEURISTIC_FILTER_SUPPORTED
|
||||
# define heuristic_filters\
|
||||
(((png_ptr->options >> PNG_DISABLE_HEURISTIC_FILTER)&3) != PNG_OPTION_ON)
|
||||
#ifdef PNG_SELECT_FILTER_HEURISTICALLY_SUPPORTED
|
||||
# define heuristic_option\
|
||||
((png_ptr->options >> PNG_SELECT_FILTER_HEURISTICALLY) & 3U)
|
||||
|
||||
static unsigned int
|
||||
select_filter_heuristically(png_structrp png_ptr, png_const_bytep prev_row,
|
||||
@ -2451,9 +2451,41 @@ select_filter_heuristically(png_structrp png_ptr, png_const_bytep prev_row,
|
||||
return PNG_FILTER_MASK(best_filter);
|
||||
}
|
||||
}
|
||||
#else /* !WRITE_HEURISTIC_FILTER */
|
||||
# define heuristic_filters 0
|
||||
#endif /* !WRITE_HEURISTIC_FILTER */
|
||||
#else /* !SELECT_FILTER_HEURISTICALLY */
|
||||
# define heuristic_option PNG_OPTION_OFF
|
||||
#endif /* !SELECT_FILTER_HEURISTICALLY */
|
||||
|
||||
#ifdef PNG_SELECT_FILTER_METHODICALLY_SUPPORTED
|
||||
static void
|
||||
select_filters_methodically_init(png_structrp png_ptr)
|
||||
{
|
||||
affirm(png_ptr->zbuffer_select == NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
select_filter_methodically(png_structrp png_ptr, png_const_bytep prev_row,
|
||||
png_bytep prev_pixels, png_const_bytep unfiltered_row,
|
||||
unsigned int row_bits, unsigned int bpp, unsigned int filters_to_try,
|
||||
int end_of_image)
|
||||
{
|
||||
const unsigned int row_bytes = (row_bits+7U) >> 3;
|
||||
png_byte test_buffers[4][PNG_ROW_BUFFER_SIZE]; /* for each filter */
|
||||
|
||||
affirm(row_bytes <= PNG_ROW_BUFFER_SIZE);
|
||||
debug((row_bits % bpp) == 0U);
|
||||
|
||||
filter_block(prev_row, prev_pixels, unfiltered_row, row_bits, bpp,
|
||||
test_buffers[PNG_FILTER_VALUE_SUB-1U],
|
||||
test_buffers[PNG_FILTER_VALUE_UP-1U],
|
||||
test_buffers[PNG_FILTER_VALUE_AVG-1U],
|
||||
test_buffers[PNG_FILTER_VALUE_PAETH-1U]);
|
||||
|
||||
write_unfiltered_rowbits(png_ptr, unfiltered_row, row_bits,
|
||||
PNG_FILTER_VALUE_LAST, end_of_image);
|
||||
|
||||
return filters_to_try;
|
||||
}
|
||||
#endif /* SELECT_FILTER_METHODICALLY */
|
||||
|
||||
/* This filters the row, chooses which filter to use, if it has not already
|
||||
* been specified by the application, and then writes the row out with the
|
||||
@ -2481,8 +2513,10 @@ png_write_filter_row(png_structrp png_ptr, png_bytep prev_pixels,
|
||||
{
|
||||
/* Delaying initialization of the filter stuff. */
|
||||
if (png_ptr->filter_mask == 0U)
|
||||
png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, (optimize_filters ||
|
||||
heuristic_filters) ? PNG_ALL_FILTERS : PNG_NO_FILTERS);
|
||||
png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE,
|
||||
(methodical_option != PNG_OPTION_OFF ||
|
||||
heuristic_option != PNG_OPTION_OFF) ?
|
||||
PNG_ALL_FILTERS : PNG_NO_FILTERS);
|
||||
|
||||
/* Now work out the filters to try for this row: */
|
||||
filters_to_try = png_ptr->filter_mask; /* else caller must preserve */
|
||||
@ -2539,19 +2573,20 @@ png_write_filter_row(png_structrp png_ptr, png_bytep prev_pixels,
|
||||
# undef match
|
||||
}
|
||||
|
||||
/* Is this a list of filters which can be simplified to a single filter?
|
||||
* If there is no selection algorithm enabled do so now:
|
||||
*
|
||||
* (Errors in the logic here trigger the 'impossible' else below.)
|
||||
/* If there is no selection algorithm enabled choose the first filter
|
||||
* in the list, otherwise do algorithm-specific initialization.
|
||||
*/
|
||||
# ifdef PNG_WRITE_OPTIMIZE_FILTER_SUPPORTED
|
||||
if (((png_ptr->options >> PNG_DISABLE_OPTIMIZE_FILTER) & 3) ==
|
||||
PNG_OPTION_ON) /* optimize supported but disabled */
|
||||
# endif /* WRITE_OPTIMIZE_FILTER */
|
||||
# ifdef PNG_WRITE_HEURISTIC_FILTER_SUPPORTED
|
||||
if (((png_ptr->options >> PNG_DISABLE_HEURISTIC_FILTER) & 3) ==
|
||||
PNG_OPTION_ON) /* heuristic supported but disabled */
|
||||
# endif /* WRITE_HEURISTIC_FILTER */
|
||||
# ifdef PNG_SELECT_FILTER_METHODICALLY_SUPPORTED
|
||||
if (methodical_option == PNG_OPTION_ON ||
|
||||
(methodical_option != PNG_OPTION_OFF &&
|
||||
heuristic_option != PNG_OPTION_ON))
|
||||
select_filters_methodically_init(png_ptr);
|
||||
|
||||
else /* don't do methodical selection */
|
||||
# endif /* SELECT_FILTER_METHODICALLY */
|
||||
# ifdef PNG_SELECT_FILTER_HEURISTICALLY_SUPPORTED
|
||||
if (heuristic_option == PNG_OPTION_OFF) /* don't use heuristics */
|
||||
# endif /* SELECT_FILTER_HEURISTICALLY */
|
||||
filters_to_try &= -filters_to_try;
|
||||
} /* start of row */
|
||||
|
||||
@ -2579,25 +2614,24 @@ png_write_filter_row(png_structrp png_ptr, png_bytep prev_pixels,
|
||||
prev_pixels, unfiltered_row, row_bits, bpp, filters_to_try, x == 0,
|
||||
end_of_image);
|
||||
|
||||
# ifdef PNG_WRITE_OPTIMIZE_FILTER_SUPPORTED
|
||||
#if 0
|
||||
else if (((png_ptr->options >> PNG_DISABLE_OPTIMIZE_FILTER) & 3) !=
|
||||
PNG_OPTION_ON) /* optimize supported and not disabled */
|
||||
impossible("optimize filters NYI");
|
||||
#endif
|
||||
# endif /* WRITE_OPTIMIZE_FITLER */
|
||||
# ifdef PNG_WRITE_HEURISTIC_FILTER_SUPPORTED
|
||||
# ifdef PNG_SELECT_FILTER_METHODICALLY_SUPPORTED
|
||||
else if (png_ptr->zbuffer_select != NULL)
|
||||
filters_to_try = select_filter_methodically(png_ptr,
|
||||
first_row_in_pass ? NULL : prev_row, prev_pixels, unfiltered_row,
|
||||
row_bits, bpp, filters_to_try, end_of_image);
|
||||
# endif /* SELECT_FILTER_METHODICALLY */
|
||||
# ifdef PNG_SELECT_FILTER_HEURISTICALLY_SUPPORTED
|
||||
/* The heuristic must select a single filter based on the first block of
|
||||
* pixels:
|
||||
*/
|
||||
else if (((png_ptr->options >> PNG_DISABLE_HEURISTIC_FILTER) & 3) !=
|
||||
PNG_OPTION_ON)
|
||||
else
|
||||
filters_to_try = select_filter_heuristically(png_ptr,
|
||||
first_row_in_pass ? NULL : prev_row, prev_pixels, unfiltered_row,
|
||||
row_bits, bpp, filters_to_try, end_of_image);
|
||||
# endif /* WRITE_HEURISTIC_FITLER */
|
||||
# else /* !SELECT_FILTER_HEURISTICALLY */
|
||||
else
|
||||
impossible("bad filter select logic");
|
||||
# endif /* !SELECT_FILTER_HEURISTICALLY */
|
||||
|
||||
/* Copy the current row into the previous row buffer, if available, unless
|
||||
* this is the last row in the pass, when there is no point. Note that
|
||||
|
@ -925,24 +925,24 @@ option CONVERT_tIME requires WRITE_ANCILLARY_CHUNKS
|
||||
#
|
||||
# WRITE_FILTER
|
||||
# Enables code to do PNG row filtering on write. If not enabled rows will
|
||||
# be written without filtering, the 'NONE' filter. This enables the
|
||||
# be written without filtering; the 'NONE' filter. This enables the
|
||||
# png_set_filter interface allowing the application to select the filter
|
||||
# used for each row.
|
||||
#
|
||||
# WRITE_HEURISTIC_FILTER
|
||||
# SELECT_FILTER_HEURISTICALLY
|
||||
# Enables code to cause libpng to choose a filter from a set passed to
|
||||
# png_set_filter. Without this code libpng just chooses the first filter in
|
||||
# the list if multiple are given.
|
||||
#
|
||||
# WRITE_OPTIMIZE_FILTER
|
||||
# SELECT_FILTER_METHODICALLY
|
||||
# Enables code to try all the filters in the list passed to png_set_filter
|
||||
# and choose the one which results in the least number of compressed bytes
|
||||
# added by the current row.
|
||||
#
|
||||
# See png.h for more description of these options.
|
||||
option WRITE_FILTER requires WRITE
|
||||
option WRITE_HEURISTIC_FILTER requires WRITE_FILTER enables SET_OPTION
|
||||
option WRITE_OPTIMIZE_FILTER requires WRITE_FILTER enables SET_OPTION
|
||||
option SELECT_FILTER_HEURISTICALLY requires WRITE_FILTER enables SET_OPTION
|
||||
option SELECT_FILTER_METHODICALLY requires WRITE_FILTER enables SET_OPTION
|
||||
|
||||
# added at libpng-1.5.4
|
||||
|
||||
|
@ -134,13 +134,13 @@
|
||||
#define PNG_WRITE_FILTER_SUPPORTED
|
||||
#define PNG_WRITE_FLUSH_SUPPORTED
|
||||
#define PNG_WRITE_GET_PALETTE_MAX_SUPPORTED
|
||||
#define PNG_WRITE_HEURISTIC_FILTER_SUPPORTED
|
||||
#define PNG_SELECT_FILTER_HEURISTICALLY_SUPPORTED
|
||||
#define PNG_WRITE_INTERLACING_SUPPORTED
|
||||
#define PNG_WRITE_INT_FUNCTIONS_SUPPORTED
|
||||
#define PNG_WRITE_INVERT_ALPHA_SUPPORTED
|
||||
#define PNG_WRITE_INVERT_SUPPORTED
|
||||
#define PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
|
||||
#define PNG_WRITE_OPTIMIZE_FILTER_SUPPORTED
|
||||
#define PNG_SELECT_FILTER_METHODICALLY_SUPPORTED
|
||||
#define PNG_WRITE_PACKSWAP_SUPPORTED
|
||||
#define PNG_WRITE_PACK_SUPPORTED
|
||||
#define PNG_WRITE_PNG_SUPPORTED
|
||||
|
Loading…
x
Reference in New Issue
Block a user