Write code update

Implemented better defaulting of zlib settings based on image properties.
Implemented pass-through of png_write_rows when the rows can be used directly (a
common case) optimizing the handling of previous-row buffering.

Removed the METHODICAL filter selection method and disabled the HEURISTIC one;
the first was ridiculously slow (though useful for experiments) the second
doesn't work.  Filter selection is temporarily disabled (it defaults to the
lowest numbered filter in the list; typically 'none').

New handling of compression settings (incomplete), new PNG compression level
(not yet visible in an API).

Back ported 'PNG_FAST_FILTERS' from 1.6 (in png.h).

There are minimal API changes beyond removal of the selection options.  Work is
still to be done to investigate a filter selection mechanism that is at least as
good as the previous one.

Signed-off-by: John Bowler <jbowler@acm.org>
This commit is contained in:
John Bowler
2016-05-04 17:02:20 -07:00
parent 1fd42d849d
commit cde9b583a8
10 changed files with 1834 additions and 1330 deletions

View File

@@ -1609,10 +1609,10 @@ read_png(struct display *dp, const char *filename)
png_alloc_size_t rb = png_get_rowbytes(dp->read_pp, dp->ip);
/* The size calc can overflow. */
if (MAX_SIZE/rb < dp->h)
if ((MAX_SIZE-dp->h)/rb < dp->h)
png_error(dp->read_pp, "image too large");
dp->size = rb * dp->h;
dp->size = rb * dp->h + dp->h/*filter byte*/;
}
display_clean_read(dp);
@@ -1826,18 +1826,21 @@ write_png(struct display *dp, const char *destname)
static void
set_windowBits_hi(struct display *dp)
{
/* windowBits is in the range 8..15, but it is said that setting '8'
* prevents adequate search even if the image size is 256 bytes or less.
/* windowBits is in the range 8..15 but zlib maps '8' to '9' so it is only
* worth using if the data size is 256 byte or less.
*/
int wb = MAX_WBITS; /* for large images */
int i = VLSIZE(windowBits_IDAT);
while (wb > 9 && dp->size <= 1U<<(wb-1)) --wb;
while (wb > 8 && dp->size <= 1U<<(wb-1)) --wb;
while (--i >= 0) if (VLNAME(windowBits_IDAT)[i].name == range_hi) break;
assert(i > 0); /* vl_windowBits_IDAT always has a RANGE() */
assert(i > 1); /* vl_windowBits_IDAT always has a RANGE() */
VLNAME(windowBits_IDAT)[i].value = wb;
assert(VLNAME(windowBits_IDAT)[--i].name == range_lo);
VLNAME(windowBits_IDAT)[i].value = wb > 8 ? 9 : 8;
}
static int