X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=contrib%2Ftools%2Fpngfix.c;h=b2043e3fbcacda656a9eda92656608402e9566ea;hb=7b7ccdda02217a442f273ef9684706ecdef2acc5;hp=068daf103d2400c8e6cd561db8e7e12f50b24273;hpb=361fb099aa967c1618d8071268abab395e67e86a;p=platform%2Fupstream%2Flibpng.git diff --git a/contrib/tools/pngfix.c b/contrib/tools/pngfix.c index 068daf1..b2043e3 100644 --- a/contrib/tools/pngfix.c +++ b/contrib/tools/pngfix.c @@ -1,15 +1,15 @@ /* pngfix.c * - * Copyright (c) 2014 John Cunningham Bowler + * Copyright (c) 2014-2016 John Cunningham Bowler * - * Last changed in libpng 1.6.10 [March 6, 2014] + * Last changed in libpng 1.6.21 [January 15, 2016] * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer * and license in png.h * - * Tool to check and fix the zlib inflate 'too far back' problem, see the usage - * message for more information. + * Tool to check and fix the zlib inflate 'too far back' problem. + * See the usage message for more information. */ #include #include @@ -49,7 +49,13 @@ # error "pngfix will not work with libpng prior to 1.6.3" #endif -#if defined(PNG_READ_SUPPORTED) && defined(PNG_EASY_ACCESS_SUPPORTED) +#ifdef PNG_SETJMP_SUPPORTED +#include + +#if defined(PNG_READ_SUPPORTED) && defined(PNG_EASY_ACCESS_SUPPORTED) &&\ + (defined(PNG_READ_DEINTERLACE_SUPPORTED) ||\ + defined(PNG_READ_INTERLACING_SUPPORTED)) + /* zlib.h defines the structure z_stream, an instance of which is included * in this structure and is required for decompressing the LZ compressed * data in PNG files. @@ -68,8 +74,8 @@ * with older builds. */ #if ZLIB_VERNUM < 0x1260 -# define PNGZ_MSG_CAST(s) png_constcast(char*,s) -# define PNGZ_INPUT_CAST(b) png_constcast(png_bytep,b) +# define PNGZ_MSG_CAST(s) constcast(char*,s) +# define PNGZ_INPUT_CAST(b) constcast(png_bytep,b) #else # define PNGZ_MSG_CAST(s) (s) # define PNGZ_INPUT_CAST(b) (b) @@ -83,17 +89,17 @@ /* Copied from pngpriv.h */ #ifdef __cplusplus -# define png_voidcast(type, value) static_cast(value) -# define png_constcast(type, value) const_cast(value) -# define png_aligncast(type, value) \ +# define voidcast(type, value) static_cast(value) +# define constcast(type, value) const_cast(value) +# define aligncast(type, value) \ static_cast(static_cast(value)) -# define png_aligncastconst(type, value) \ +# define aligncastconst(type, value) \ static_cast(static_cast(value)) #else -# define png_voidcast(type, value) (value) -# define png_constcast(type, value) ((type)(value)) -# define png_aligncast(type, value) ((void*)(value)) -# define png_aligncastconst(type, value) ((const void*)(value)) +# define voidcast(type, value) (value) +# define constcast(type, value) ((type)(value)) +# define aligncast(type, value) ((void*)(value)) +# define aligncastconst(type, value) ((const void*)(value)) #endif /* __cplusplus */ #if PNG_LIBPNG_VER < 10700 @@ -131,7 +137,7 @@ #define png_zTXt PNG_U32(122, 84, 88, 116) #endif -/* The 8 byte signature as a pair of 32 bit quantities */ +/* The 8-byte signature as a pair of 32-bit quantities */ #define sig1 PNG_U32(137, 80, 78, 71) #define sig2 PNG_U32( 13, 10, 26, 10) @@ -153,7 +159,7 @@ */ #define UNREACHED 0 -/* 80-bit number handling - a PNG image can be up to (2^31-1)x(2^31-1) 8 byte +/* 80-bit number handling - a PNG image can be up to (2^31-1)x(2^31-1) 8-byte * (16-bit RGBA) pixels in size; that's less than 2^65 bytes or 2^68 bits, so * arithmetic of 80-bit numbers is sufficient. This representation uses an * arbitrary length array of png_uint_16 digits (0..65535). The representation @@ -313,13 +319,13 @@ uarb_mult32(uarb acc, int a_digits, uarb num, int n_digits, png_uint_32 val) a_digits = uarb_mult_digit(acc, a_digits, num, n_digits, (png_uint_16)(val & 0xffff)); - /* Because n_digits and val are >0 the following must be true: */ - assert(a_digits > 0); - val >>= 16; if (val > 0) a_digits = uarb_mult_digit(acc+1, a_digits-1, num, n_digits, (png_uint_16)val) + 1; + + /* Because n_digits and val are >0 the following must be true: */ + assert(a_digits > 0); } return a_digits; @@ -443,7 +449,7 @@ static void make_random_bytes(png_uint_32* seed, void* pv, size_t size) { png_uint_32 u0 = seed[0], u1 = seed[1]; - png_bytep bytes = png_voidcast(png_bytep, pv); + png_bytep bytes = voidcast(png_bytep, pv); /* There are thirty-three bits; the next bit in the sequence is bit-33 XOR * bit-20. The top 1 bit is in u1, the bottom 32 are in u0. @@ -581,7 +587,7 @@ chunk_type_valid(png_uint_32 c) c &= ~PNG_U32(32,32,0,32); t = (c & ~0x1f1f1f1f) ^ 0x40404040; - /* Subtract 65 for each 8 bit quantity, this must not overflow + /* Subtract 65 for each 8-bit quantity, this must not overflow * and each byte must then be in the range 0-25. */ c -= PNG_U32(65,65,65,65); @@ -664,8 +670,8 @@ IDAT_list_extend(struct IDAT_list *tail) if (length < tail->length) /* arithmetic overflow */ length = tail->length; - - next = png_voidcast(IDAT_list*, malloc(IDAT_list_size(NULL, length))); + + next = voidcast(IDAT_list*, malloc(IDAT_list_size(NULL, length))); CLEAR(*next); /* The caller must handle this: */ @@ -918,7 +924,7 @@ emit_string(const char *str, FILE *out) else if (isspace(UCHAR_MAX & *str)) putc('_', out); - + else fprintf(out, "\\%.3o", *str); } @@ -1942,7 +1948,7 @@ process_IDAT(struct file *file) list->count = 0; file->idat->idat_list_tail = list; } - + /* And fill in the next IDAT information buffer. */ list->lengths[(list->count)++] = file->chunk->chunk_length; @@ -2135,7 +2141,7 @@ zlib_end(struct zlib *zlib) * * z-rc is the zlib failure code; message is the error message with * spaces replaced by '-'. The compressed byte count indicates where - * in the zlib stream the error occured. + * in the zlib stream the error occurred. */ type_name(zlib->chunk->chunk_type, stdout); printf(" SKP %s %d %s ", zlib_flevel(zlib), zlib->file_bits, @@ -2215,7 +2221,7 @@ zlib_init(struct zlib *zlib, struct IDAT *idat, struct chunk *chunk, /* These values are sticky across reset (in addition to the stuff in the * first block, which is actually constant.) */ - zlib->file_bits = 16; + zlib->file_bits = 24; zlib->ok_bits = 16; /* unset */ zlib->cksum = 0; /* set when a checksum error is detected */ @@ -2298,10 +2304,12 @@ zlib_advance(struct zlib *zlib, png_uint_32 nbytes) zlib->file_bits = file_bits; /* Check against the existing value - it may not need to be - * changed. + * changed. Note that a bogus file_bits is allowed through once, + * to see if it works, but the window_bits value is set to 15, + * the maximum. */ if (new_bits == 0) /* no change */ - zlib->window_bits = file_bits; + zlib->window_bits = ((file_bits > 15) ? 15 : file_bits); else if (new_bits != file_bits) /* rewrite required */ bIn = (png_byte)((bIn & 0xf) + ((new_bits-8) << 4)); @@ -2322,8 +2330,7 @@ zlib_advance(struct zlib *zlib, png_uint_32 nbytes) if (bIn != b2) { /* If the first byte wasn't changed this indicates an error in - * the checksum calculation; signal this by setting file_bits - * (not window_bits) to 0. + * the checksum calculation; signal this by setting 'cksum'. */ if (zlib->file_bits == zlib->window_bits) zlib->cksum = 1; @@ -2582,7 +2589,7 @@ zlib_run(struct zlib *zlib) { struct chunk *chunk = zlib->chunk; int rc; - + assert(zlib->rewrite_offset < chunk->chunk_length); rc = zlib_advance(zlib, chunk->chunk_length - zlib->rewrite_offset); @@ -3532,7 +3539,7 @@ get_control(png_const_structrp png_ptr) /* This just returns the (file*). The chunk and idat control structures * don't always exist. */ - struct control *control = png_voidcast(struct control*, + struct control *control = voidcast(struct control*, png_get_error_ptr(png_ptr)); return &control->file; } @@ -3540,7 +3547,7 @@ get_control(png_const_structrp png_ptr) static void allocate(struct file *file, int allocate_idat) { - struct control *control = png_voidcast(struct control*, file->alloc_ptr); + struct control *control = voidcast(struct control*, file->alloc_ptr); if (allocate_idat) { @@ -3574,7 +3581,6 @@ read_png(struct control *control) { png_structp png_ptr; png_infop info_ptr = NULL; - volatile png_bytep row = NULL, display = NULL; volatile int rc; png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, control, @@ -3591,6 +3597,16 @@ read_png(struct control *control) rc = setjmp(control->file.jmpbuf); if (rc == 0) { +# ifdef PNG_SET_USER_LIMITS_SUPPORTED + /* Remove any limits on the size of PNG files that can be read, + * without this we may reject files based on built-in safety + * limits. + */ + png_set_user_limits(png_ptr, 0x7fffffff, 0x7fffffff); + png_set_chunk_cache_max(png_ptr, 0); + png_set_chunk_malloc_max(png_ptr, 0); +# endif + png_set_read_fn(png_ptr, control, read_callback); info_ptr = png_create_info_struct(png_ptr); @@ -3603,32 +3619,22 @@ read_png(struct control *control) png_read_info(png_ptr, info_ptr); { - png_size_t rowbytes = png_get_rowbytes(png_ptr, info_ptr); - - row = png_voidcast(png_byte*, malloc(rowbytes)); - display = png_voidcast(png_byte*, malloc(rowbytes)); - - if (row == NULL || display == NULL) - png_error(png_ptr, "OOM allocating row buffers"); - - { - png_uint_32 height = png_get_image_height(png_ptr, info_ptr); - int passes = png_set_interlace_handling(png_ptr); - int pass; - - png_start_read_image(png_ptr); - - for (pass = 0; pass < passes; ++pass) - { - 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. - */ - while (y-- > 0) - png_read_row(png_ptr, row, display); - } - } + png_uint_32 height = png_get_image_height(png_ptr, info_ptr); + int passes = png_set_interlace_handling(png_ptr); + int pass; + + png_start_read_image(png_ptr); + + for (pass = 0; pass < passes; ++pass) + { + png_uint_32 y = height; + + /* NOTE: this skips asking libpng to return either version of + * the image row, but libpng still reads the rows. + */ + while (y-- > 0) + png_read_row(png_ptr, NULL, NULL); + } } if (control->file.global->verbose) @@ -3639,8 +3645,6 @@ read_png(struct control *control) } png_destroy_read_struct(&png_ptr, &info_ptr, NULL); - if (row != NULL) free(row); - if (display != NULL) free(display); return rc; } @@ -3702,21 +3706,21 @@ usage(const char *prog) " gAMA, sRGB [all]: These specify the gamma encoding used for the pixel", " values.", " cHRM, iCCP [color]: These specify how colors are encoded. iCCP also", -" specifies the exact encoding of a pixel value however in practice", -" most programs will ignore it.", +" specifies the exact encoding of a pixel value; however, in", +" practice most programs will ignore it.", " bKGD [transform]: This is used by libpng transforms." " --max=:", " Use IDAT chunks sized . If no number is given the the IDAT", " chunks will be the maximum size permitted; 2^31-1 bytes. If the option", " is omitted the original chunk sizes will not be changed. When the", -" option is given --strip=unsafe is set automatically, this may be", +" option is given --strip=unsafe is set automatically. This may be", " cancelled if you know that all unknown unsafe-to-copy chunks really are", " safe to copy across an IDAT size change. This is true of all chunks", " that have ever been formally proposed as PNG extensions.", " MESSAGES", " By default the program only outputs summaries for each file.", " --quiet (-q):", -" Do not output the summaries except for files which cannot be read. With", +" Do not output the summaries except for files that cannot be read. With", " two --quiets these are not output either.", " --errors (-e):", " Output errors from libpng and the program (except too-far-back).", @@ -3749,7 +3753,7 @@ usage(const char *prog) " the following codes. Notice that the results for each file are combined", " together - check one file at a time to get a meaningful error code!", " 0x01: The zlib too-far-back error existed in at least one chunk.", -" 0x02: At least once chunk had a CRC error.", +" 0x02: At least one chunk had a CRC error.", " 0x04: A chunk length was incorrect.", " 0x08: The file was truncated.", " Errors less than 16 are potentially recoverable, for a single file if the", @@ -3757,7 +3761,7 @@ usage(const char *prog) " non-zero code is returned).", " 0x10: The file could not be read, even with corrections.", " 0x20: The output file could not be written.", -" 0x40: An unexpected, potentially internal, error occured.", +" 0x40: An unexpected, potentially internal, error occurred.", " If the command line arguments are incorrect the program exits with exit", " 255. Some older operating systems only support 7-bit exit codes, on those", " systems it is suggested that this program is first tested by supplying", @@ -3817,7 +3821,7 @@ usage(const char *prog) " SKP: The chunk was skipped because of a zlib issue (zlib-rc) with", " explanation 'message'", " ERR: The read of the file was aborted. The parameters explain why.", -"$3 status: For 'ERR' the accumulate status code from 'EXIT CODES' above.", +"$3 status: For 'ERR' the accumulated status code from 'EXIT CODES' above.", " This is printed as a 2 digit hexadecimal value", " comp-level: The recorded compression level (FLEVEL) of a zlib stream", " expressed as a string {supfast,stdfast,default,maximum}", @@ -3853,6 +3857,7 @@ usage(const char *prog) int main(int argc, const char **argv) { + char temp_name[FILENAME_MAX+1]; const char * prog = *argv; const char * outfile = NULL; const char * suffix = NULL; @@ -3955,7 +3960,6 @@ main(int argc, const char **argv) else { size_t outlen = strlen(*argv); - char temp_name[FILENAME_MAX+1]; if (outfile == NULL) /* else this takes precedence */ { @@ -4030,7 +4034,16 @@ main(void) int main(void) { - fprintf(stderr, "pngfix does not work without read support\n"); + fprintf(stderr, "pngfix does not work without read deinterlace support\n"); return 77; } #endif /* PNG_READ_SUPPORTED && PNG_EASY_ACCESS_SUPPORTED */ +#else /* No setjmp support */ +int +main(void) +{ + fprintf(stderr, "pngfix does not work without setjmp support\n"); + return 77; +} +#endif /* PNG_SETJMP_SUPPORTED */ +