[libpng17] Update CHANGES and ANNOUNCE about pngcp; sync timepng.c with libpng16

This commit is contained in:
John Bowler 2016-05-06 19:09:58 -05:00 committed by Glenn Randers-Pehrson
parent 4cc89fb733
commit a70f5053de
5 changed files with 410 additions and 105 deletions

View File

@ -1,5 +1,5 @@
Libpng 1.7.0beta80 - May 5, 2016
Libpng 1.7.0beta80 - May 6, 2016
This is not intended to be a public release. It will be replaced
within a few weeks by a public version or by another test version.
@ -1264,9 +1264,10 @@ Version 1.7.0beta79 [March 9, 2016]
(Robert C. Seacord). Various other flags in png.h made unsigned as well.
Fixed some misleading indentation (Krishnaraj Bhat).
Version 1.7.0beta80 [May 5, 2016]
Version 1.7.0beta80 [May 6, 2016]
Fixed typo (missing underscore) in #define PNG_READ_16_TO_8_SUPPORTED
Bug report by (Y.Ohashik).
Quieted two Coverity issues in contrib/libtests/timepng.c.
Write code update (John Bowler):
Implemented better defaulting of zlib settings based on image properties.
Replaced pngtest.png with one compressed with the new zlib settings.
@ -1283,6 +1284,11 @@ Version 1.7.0beta80 [May 5, 2016]
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.
Minor write bug-fixes, remove unimplemented code. A debug() assert
fired if windowBits was set to 8 for the Huffman only and no-compression
cases. This commit changes it to do some extra checking. Removed
unreachable code in pz_default_settings and eliminated a spurious
warning in pngcp for small files.
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit

View File

@ -5564,9 +5564,10 @@ Version 1.7.0beta79 [March 9, 2016]
(Robert C. Seacord). Various other flags in png.h made unsigned as well.
Fixed some misleading indentation (Krishnaraj Bhat).
Version 1.7.0beta80 [May 5, 2016]
Version 1.7.0beta80 [May 6, 2016]
Fixed typo (missing underscore) in #define PNG_READ_16_TO_8_SUPPORTED
Bug report by (Y.Ohashik).
Quieted two Coverity issues in contrib/libtests/timepng.c.
Write code update (John Bowler):
Implemented better defaulting of zlib settings based on image properties.
Replaced pngtest.png with one compressed with the new zlib settings.
@ -5583,6 +5584,11 @@ Version 1.7.0beta80 [May 5, 2016]
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.
Minor write bug-fixes, remove unimplemented code. A debug() assert
fired if windowBits was set to 8 for the Huffman only and no-compression
cases. This commit changes it to do some extra checking. Removed
unreachable code in pz_default_settings and eliminated a spurious
warning in pngcp for small files.
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit

View File

@ -1199,7 +1199,7 @@ getsearchopts(struct display *dp, const char *opt_str, int *value)
else if (opt == OPTIND(dp, windowBits))
{
/* Changing windowBits for strategies that do not search the window is
* pointless. Huffman-only does not search, RLE only searchs backwards
* pointless. Huffman-only does not search, RLE only searches backwards
* one byte, so given that the maximum string length is 258, a windowBits
* of 9 is always sufficient.
*/

View File

@ -1,8 +1,8 @@
/* timepng.c
*
* Copyright (c) 2013 John Cunningham Bowler
* Copyright (c) 2013,2016 John Cunningham Bowler
*
* Last changed in libpng 1.6.1 [March 28, 2013]
* Last changed in libpng 1.6.22 [(PENDING RELEASE)]
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
@ -10,15 +10,17 @@
*
* Load an arbitrary number of PNG files (from the command line, or, if there
* are no arguments on the command line, from stdin) then run a time test by
* reading each file by row. The test does nothing with the read result and
* does no transforms. The only output is a time as a floating point number of
* seconds with 9 decimal digits.
* reading each file by row or by image (possibly with transforms in the latter
* case). The only output is a time as a floating point number of seconds with
* 9 decimal digits.
*/
#define _POSIX_C_SOURCE 199309L /* for clock_gettime */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <time.h>
@ -35,36 +37,61 @@
# include "../../png.h"
#endif
static int read_png(FILE *fp)
/* The following is to support direct compilation of this file as C++ */
#ifdef __cplusplus
# define voidcast(type, value) static_cast<type>(value)
#else
# define voidcast(type, value) (value)
#endif /* __cplusplus */
#if ((defined(PNG_SEQUENTIAL_READ_SUPPORTED)) && defined(PNG_STDIO_SUPPORTED)\
&& defined(PNG_EASY_ACCESS_SUPPORTED) && defined(PNG_INFO_IMAGE_SUPPORTED))
typedef struct
{
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,0,0,0);
png_infop info_ptr = NULL;
png_bytep row = NULL, display = NULL;
FILE *input;
FILE *output;
} io_data;
if (png_ptr == NULL)
return 0;
static PNG_CALLBACK(void, read_and_copy,
(png_structp png_ptr, png_bytep buffer, png_size_t cb))
{
io_data *io = (io_data*)png_get_io_ptr(png_ptr);
if (setjmp(png_jmpbuf(png_ptr)))
if (fread(buffer, cb, 1, io->input) != 1)
png_error(png_ptr, strerror(errno));
if (fwrite(buffer, cb, 1, io->output) != 1)
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
if (row != NULL) free(row);
if (display != NULL) free(display);
return 0;
perror("temporary file");
fprintf(stderr, "temporary file PNG write failed\n");
exit(1);
}
}
png_init_io(png_ptr, fp);
static void read_by_row(png_structp png_ptr, png_infop info_ptr,
FILE *write_ptr, FILE *read_ptr)
{
/* These don't get freed on error, this is fine; the program immediately
* exits.
*/
png_bytep row = NULL, display = NULL;
io_data io_copy;
info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == NULL)
png_error(png_ptr, "OOM allocating info structure");
if (write_ptr != NULL)
{
/* Set up for a copy to the temporary file: */
io_copy.input = read_ptr;
io_copy.output = write_ptr;
png_set_read_fn(png_ptr, &io_copy, read_and_copy);
}
png_read_info(png_ptr, info_ptr);
{
png_size_t rowbytes = png_get_rowbytes(png_ptr, info_ptr);
row = malloc(rowbytes);
display = malloc(rowbytes);
row = voidcast(png_bytep,malloc(rowbytes));
display = voidcast(png_bytep,malloc(rowbytes));
if (row == NULL || display == NULL)
png_error(png_ptr, "OOM allocating row buffers");
@ -81,7 +108,8 @@ static int read_png(FILE *fp)
png_uint_32 y = height;
/* NOTE: this trashes the row each time; interlace handling won't
* work, but this avoids memory thrashing for speed testing.
* work, but this avoids memory thrashing for speed testing and is
* somewhat representative of an application that works row-by-row.
*/
while (y-- > 0)
png_read_row(png_ptr, row, display);
@ -91,9 +119,51 @@ static int read_png(FILE *fp)
/* Make sure to read to the end of the file: */
png_read_end(png_ptr, info_ptr);
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
/* Free this up: */
free(row);
free(display);
}
static PNG_CALLBACK(void, no_warnings, (png_structp png_ptr,
png_const_charp warning))
{
(void)png_ptr;
(void)warning;
}
static int read_png(FILE *fp, png_int_32 transforms, FILE *write_file)
{
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,0,0,
no_warnings);
png_infop info_ptr = NULL;
if (png_ptr == NULL)
return 0;
if (setjmp(png_jmpbuf(png_ptr)))
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return 0;
}
# ifdef PNG_BENIGN_ERRORS_SUPPORTED
png_set_benign_errors(png_ptr, 1/*allowed*/);
# endif
png_init_io(png_ptr, fp);
info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == NULL)
png_error(png_ptr, "OOM allocating info structure");
if (transforms < 0)
read_by_row(png_ptr, info_ptr, write_file, fp);
else
png_read_png(png_ptr, info_ptr, transforms, NULL/*params*/);
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return 1;
}
@ -108,7 +178,7 @@ static int mytime(struct timespec *t)
return 0;
}
static int perform_one_test(FILE *fp, int nfiles)
static int perform_one_test(FILE *fp, int nfiles, png_int_32 transforms)
{
int i;
struct timespec before, after;
@ -120,7 +190,7 @@ static int perform_one_test(FILE *fp, int nfiles)
{
for (i=0; i<nfiles; ++i)
{
if (read_png(fp))
if (read_png(fp, transforms, NULL/*write*/))
{
if (ferror(fp))
{
@ -184,69 +254,269 @@ static int add_one_file(FILE *fp, char *name)
if (ip != NULL)
{
int ch;
for (;;)
/* Read the file using libpng; this detects errors and also deals with
* files which contain data beyond the end of the file.
*/
int ok = 0;
fpos_t pos;
if (fgetpos(fp, &pos))
{
ch = getc(ip);
if (ch == EOF) break;
putc(ch, fp);
/* Fatal error reading the start: */
perror("temporary file");
fprintf(stderr, "temporary file fgetpos error\n");
exit(1);
}
if (read_png(ip, -1/*by row*/, fp/*output*/))
{
if (ferror(ip))
{
perror(name);
fprintf(stderr, "%s: read error\n", name);
return 0;
}
else
ok = 1; /* read ok */
}
else
fprintf(stderr, "%s: file not added\n", name);
(void)fclose(ip);
/* An error in the output is fatal; exit immediately: */
if (ferror(fp))
{
perror("temporary file");
fprintf(stderr, "temporary file write error\n");
return 0;
exit(1);
}
if (ok)
return 1;
/* Did not read the file successfully, simply rewind the temporary
* file. This must happen after the ferror check above to avoid clearing
* the error.
*/
if (fsetpos(fp, &pos))
{
perror("temporary file");
fprintf(stderr, "temporary file fsetpos error\n");
exit(1);
}
}
else
{
/* file open error: */
perror(name);
fprintf(stderr, "%s: open failed\n", name);
return 0;
}
return 1;
return 0; /* file not added */
}
static void
usage(FILE *fp)
{
if (fp != NULL) fclose(fp);
fprintf(stderr,
"Usage:\n"
" timepng --assemble <assembly> {files}\n"
" Read the files into <assembly>, output the count. Options are ignored.\n"
" timepng --dissemble <assembly> <count> [options]\n"
" Time <count> files from <assembly>, additional files may not be given.\n"
" Otherwise:\n"
" Read the files into a temporary file and time the decode\n"
"Transforms:\n"
" --by-image: read by image with png_read_png\n"
" --<transform>: implies by-image, use PNG_TRANSFORM_<transform>\n"
" Otherwise: read by row using png_read_row (to a single row buffer)\n"
/* ISO C90 string length max 509 */);fprintf(stderr,
"{files}:\n"
" PNG files to copy into the assembly and time. Invalid files are skipped\n"
" with appropriate error messages. If no files are given the list of files\n"
" is read from stdin with each file name terminated by a newline\n"
"Output:\n"
" For --assemble the output is the name of the assembly file followed by the\n"
" count of the files it contains; the arguments for --dissemble. Otherwise\n"
" the output is the total decode time in seconds.\n");
exit(99);
}
int main(int argc, char **argv)
{
int ok = 0;
FILE *fp = tmpfile();
if (fp != NULL)
{
int err = 0;
int nfiles = 0;
int transforms = -1; /* by row */
const char *assembly = NULL;
FILE *fp;
if (argc > 1)
if (argc > 2 && strcmp(argv[1], "--assemble") == 0)
{
/* Just build the test file, argv[2] is the file name. */
assembly = argv[2];
fp = fopen(assembly, "wb");
if (fp == NULL)
{
perror(assembly);
fprintf(stderr, "timepng --assemble %s: could not open for write\n",
assembly);
usage(NULL);
}
argv += 2;
argc -= 2;
}
else if (argc > 3 && strcmp(argv[1], "--dissemble") == 0)
{
fp = fopen(argv[2], "rb");
if (fp == NULL)
{
perror(argv[2]);
fprintf(stderr, "timepng --dissemble %s: could not open for read\n",
argv[2]);
usage(NULL);
}
nfiles = atoi(argv[3]);
if (nfiles <= 0)
{
fprintf(stderr,
"timepng --dissemble <file> <count>: %s is not a count\n",
argv[3]);
exit(99);
}
#ifdef __COVERITY__
else
{
nfiles &= PNG_UINT_31_MAX;
}
#endif
argv += 3;
argc -= 3;
}
else /* Else use a temporary file */
{
#ifndef __COVERITY__
fp = tmpfile();
#else
/* Experimental. Coverity says tmpfile() is insecure because it
* generates predictable names.
*
* It is possible to satisfy Coverity by using mkstemp(); however,
* any platform supporting mkstemp() undoubtedly has a secure tmpfile()
* implementation as well, and doesn't need the fix. Note that
* the fix won't work on platforms that don't support mkstemp().
*
* https://www.securecoding.cert.org/confluence/display/c/
* FIO21-C.+Do+not+create+temporary+files+in+shared+directories
* says that most historic implementations of tmpfile() provide
* only a limited number of possible temporary file names
* (usually 26) before file names are recycled. That article also
* provides a secure solution that unfortunately depends upon mkstemp().
*/
char tmpfile[] = "timepng-XXXXXX";
int filedes;
umask(0177);
filedes = mkstemp(tmpfile);
if (filedes < 0)
fp = NULL;
else
{
fp = fdopen(filedes,"w+");
/* Hide the filename immediately and ensure that the file does
* not exist after the program ends
*/
(void) unlink(tmpfile);
}
#endif
if (fp == NULL)
{
perror("tmpfile");
fprintf(stderr, "timepng: could not open the temporary file\n");
exit(1); /* not a user error */
}
}
/* Handle the transforms: */
while (argc > 1 && argv[1][0] == '-' && argv[1][1] == '-')
{
const char *opt = *++argv + 2;
--argc;
/* Transforms turn on the by-image processing and maybe set some
* transforms:
*/
if (transforms == -1)
transforms = PNG_TRANSFORM_IDENTITY;
if (strcmp(opt, "by-image") == 0)
{
/* handled above */
}
# define OPT(name) else if (strcmp(opt, #name) == 0)\
transforms |= PNG_TRANSFORM_ ## name
OPT(STRIP_16);
OPT(STRIP_ALPHA);
OPT(PACKING);
OPT(PACKSWAP);
OPT(EXPAND);
OPT(INVERT_MONO);
OPT(SHIFT);
OPT(BGR);
OPT(SWAP_ALPHA);
OPT(SWAP_ENDIAN);
OPT(INVERT_ALPHA);
OPT(STRIP_FILLER);
OPT(STRIP_FILLER_BEFORE);
OPT(STRIP_FILLER_AFTER);
OPT(GRAY_TO_RGB);
OPT(EXPAND_16);
OPT(SCALE_16);
else
{
fprintf(stderr, "timepng %s: unrecognized transform\n", opt);
usage(fp);
}
}
/* Handle the files: */
if (argc > 1 && nfiles > 0)
usage(fp); /* Additional files not valid with --dissemble */
else if (argc > 1)
{
int i;
for (i=1; i<argc; ++i)
{
if (add_one_file(fp, argv[i]))
++nfiles;
else
if (nfiles == INT_MAX)
{
err = 1;
fprintf(stderr, "%s: skipped, too many files\n", argv[i]);
break;
}
else if (add_one_file(fp, argv[i]))
++nfiles;
}
}
else
else if (nfiles == 0) /* Read from stdin withoout --dissemble */
{
char filename[FILENAME_MAX+1];
@ -257,19 +527,19 @@ int main(int argc, char **argv)
if (filename[len-1] == '\n')
{
filename[len-1] = 0;
if (add_one_file(fp, filename))
++nfiles;
else
if (nfiles == INT_MAX)
{
err = 1;
fprintf(stderr, "%s: skipped, too many files\n", filename);
break;
}
else if (add_one_file(fp, filename))
++nfiles;
}
else
{
fprintf(stderr, "timepng: truncated file name ...%s\n",
fprintf(stderr, "timepng: file name too long: ...%s\n",
filename+len-32);
err = 1;
break;
@ -283,21 +553,44 @@ int main(int argc, char **argv)
}
}
/* Perform the test, or produce the --assemble output: */
if (!err)
{
if (nfiles > 0)
ok = perform_one_test(fp, nfiles);
else
fprintf(stderr, "usage: timepng {files} or ls files | timepng\n");
{
if (assembly != NULL)
{
if (fflush(fp) && !ferror(fp) && fclose(fp))
{
perror(assembly);
fprintf(stderr, "%s: close failed\n", assembly);
}
else
{
printf("%s %d\n", assembly, nfiles);
fflush(stdout);
ok = !ferror(stdout);
}
}
else
{
ok = perform_one_test(fp, nfiles, transforms);
(void)fclose(fp);
}
}
else
fprintf(stderr, "timepng: could not open temporary file\n");
usage(fp);
}
else
(void)fclose(fp);
/* Exit code 0 on success. */
return ok == 0;
}
#else /* !sufficient support */
int main(void) { return 77; }
#endif /* !sufficient support */

10
png.h
View File

@ -1,7 +1,7 @@
/* png.h - header file for PNG reference library
*
* libpng version 1.7.0beta80, May 5, 2016
* libpng version 1.7.0beta80, May 6, 2016
*
* Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
@ -12,7 +12,7 @@
* Authors and maintainers:
* libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
* libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger
* libpng versions 0.97, January 1998, through 1.7.0beta80, May 5, 2016:
* libpng versions 0.97, January 1998, through 1.7.0beta80, May 6, 2016:
* Glenn Randers-Pehrson.
* See also "Contributing Authors", below.
*/
@ -25,7 +25,7 @@
*
* This code is released under the libpng license.
*
* libpng versions 1.0.7, July 1, 2000, through 1.7.0beta80, May 5, 2016, are
* libpng versions 1.0.7, July 1, 2000, through 1.7.0beta80, May 6, 2016, are
* Copyright (c) 2000-2002, 2004, 2006-2016 Glenn Randers-Pehrson, are
* derived from libpng-1.0.6, and are distributed according to the same
* disclaimer and license as libpng-1.0.6 with the following individuals
@ -218,7 +218,7 @@
* Y2K compliance in libpng:
* =========================
*
* May 5, 2016
* May 6, 2016
*
* Since the PNG Development group is an ad-hoc body, we can't make
* an official declaration.
@ -288,7 +288,7 @@
/* Version information for png.h - this should match the version in png.c */
#define PNG_LIBPNG_VER_STRING "1.7.0beta80"
#define PNG_HEADER_VERSION_STRING \
" libpng version 1.7.0beta80 - May 5, 2016\n"
" libpng version 1.7.0beta80 - May 6, 2016\n"
#define PNG_LIBPNG_VER_SONUM 17
#define PNG_LIBPNG_VER_DLLNUM 17