diff --git a/README.txt b/README.txt index 8fd1ca2fb..cd624f830 100644 --- a/README.txt +++ b/README.txt @@ -10,7 +10,7 @@ case of any discrepancy, the copy in pngcrush.c shall prevail): * If you have modified this source, you may insert additional notices * immediately after this sentence. * - * Copyright (C) 1998-2001 Glenn Randers-Pehrson (randeg@alum.rpi.edu) + * Copyright (C) 1998-2002 Glenn Randers-Pehrson (randeg@alum.rpi.edu) * * The pngcrush computer program is supplied "AS IS". The Author disclaims all * warranties, expressed or implied, including, without limitation, the @@ -40,19 +40,17 @@ case of any discrepancy, the copy in pngcrush.c shall prevail): This is the output of "pngcrush" and "pngcrush -help": - - - | pngcrush 1.5.8, Copyright (C) 1998-2001 Glenn Randers-Pehrson + | pngcrush 1.5.9, Copyright (C) 1998-2002 Glenn Randers-Pehrson | This is a free, open-source program. Permission is irrevocably | granted to everyone to use this version of pngcrush without | payment of any fee. | Executable name is pngcrush - | It was built with libpng version 1.2.1, and is - | running with libpng version 1.2.1 - December 12, 2001 (header) - | Copyright (C) 1998-2001 Glenn Randers-Pehrson, + | It was built with libpng version 1.2.4, and is + | running with libpng version 1.2.4 - July 8, 2002 (header) + | Copyright (C) 1998-2002 Glenn Randers-Pehrson, | Copyright (C) 1996, 1997 Andreas Dilger, | Copyright (C) 1995, Guy Eric Schalnat, Group 42 Inc., - | and zlib version 1.1.3pc, Copyright (C) 1998, + | and zlib version 1.1.4pc, Copyright (C) 1998, | Jean-loup Gailly and Mark Adler. @@ -101,17 +99,166 @@ options: -p (pause) - | pngcrush 1.5.8, Copyright (C) 1998-2001 Glenn Randers-Pehrson + + | pngcrush 1.5.9, Copyright (C) 1998-2002 Glenn Randers-Pehrson | This is a free, open-source program. Permission is irrevocably | granted to everyone to use this version of pngcrush without | payment of any fee. | Executable name is pngcrush - | It was built with libpng version 1.2.1, and is - | running with libpng version 1.2.1 - December 12, 2001 (header) - | Copyright (C) 1998-2001 Glenn Randers-Pehrson, + | It was built with libpng version 1.2.4, and is + | running with libpng version 1.2.4 - July 8, 2002 (header) + | Copyright (C) 1998-2002 Glenn Randers-Pehrson, | Copyright (C) 1996, 1997 Andreas Dilger, | Copyright (C) 1995, Guy Eric Schalnat, Group 42 Inc., - | and zlib version 1.1.3pc, Copyright (C) 1998, + | and zlib version 1.1.4pc, Copyright (C) 1998, + | Jean-loup Gailly and Mark Adler. + + +usage: pngcrush [options] infile.png outfile.png + pngcrush -e ext [other options] files.png ... + pngcrush -d dir [other options] files.png ... +options: + -already already_crushed_size [e.g., 8192] + -bit_depth depth (bit_depth to use in output file) + -brute (Use brute-force, try 114 different methods [11-124]) + -c color_type of output file [0, 2, 4, or 6] + -d directory_name (where output files will go) + -double_gamma (used for fixing gamma in PhotoShop 5.0/5.02 files) + -e extension (used for creating output filename) + -f user_filter [0-5] + -fix (fix otherwise fatal conditions such as bad CRCs) + -force (Write a new output file even if larger than input) + -g gamma (float or fixed*100000, e.g., 0.45455 or 45455) + -iccp length "Profile Name" iccp_file + -itxt b[efore_IDAT]|a[fter_IDAT] "keyword" "text" + -l zlib_compression_level [0-9] + -loco ("loco crush" truecolor PNGs) + -m method [0 through 200] + -max maximum_IDAT_size [default 8192] + -nofilecheck (do not check for infile.png == outfile.png) + -n (no save; does not do compression or write output PNG) + -plte_len n (truncate PLTE) + -q (quiet) + -reduce (do lossless color type or bit depth reduction) + -rem chunkname (or "alla" or "allb") +-replace_gamma gamma (float or fixed*100000) even if gAMA is present. + -res dpi + -save (keep all copy-unsafe chunks) + -srgb [0, 1, 2, or 3] + -text b[efore_IDAT]|a[fter_IDAT] "keyword" "text" + -trns_array n trns[0] trns[1] .. trns[n-1] + -trns index red green blue gray + -v (display more detailed information) + -version (display the pngcrush version) + -w compression_window_size [32, 16, 8, 4, 2, 1, 512] + -z zlib_strategy [0, 1, or 2] + -zmem zlib_compression_mem_level [1-9, default 9] + -zitxt b[efore_IDAT]|a[fter_IDAT] "keyword" "text" + -ztxt b[efore_IDAT]|a[fter_IDAT] "keyword" "text" + -h (help and legal notices) + -p (pause) + +Copyright (C) 1998-2002 Glenn Randers-Pehrson (randeg@alum.rpi.edu) + + +DISCLAIMER: The pngcrush computer program is supplied "AS IS". +The Author disclaims all warranties, expressed or implied, including, +without limitation, the warranties of merchantability and of fitness +for any purpose. The Author assumes no liability for direct, indirect, +incidental, special, exemplary, or consequential damages, which may +result from the use of the computer program, even if advised of the +possibility of such damage. There is no warranty against interference +with your enjoyment of the computer program or against infringement. +There is no warranty that my efforts or the computer program will +fulfill any of your particular purposes or needs. This computer +program is provided with all faults, and the entire risk of satisfactory +quality, performance, accuracy, and effort is with the user. + +LICENSE: Permission is hereby irrevocably granted to everyone to use, +copy, modify, and distribute this computer program, or portions hereof, +purpose, without payment of any fee, subject to the following +restrictions: + +1. The origin of this binary or source code must not be misrepresented. + +2. Altered versions must be plainly marked as such and must not be +misrepresented as being the original binary or source. + +3. The Copyright notice, disclaimer, and license may not be removed +or altered from any source, binary, or altered source distribution. + + + + | pngcrush 1.5.9, Copyright (C) 1998-2002 Glenn Randers-Pehrson + | This is a free, open-source program. Permission is irrevocably + | granted to everyone to use this version of pngcrush without + | payment of any fee. + | Executable name is pngcrush + | It was built with libpng version 1.2.4, and is + | running with libpng version 1.2.4 - July 8, 2002 (header) + | Copyright (C) 1998-2002 Glenn Randers-Pehrson, + | Copyright (C) 1996, 1997 Andreas Dilger, + | Copyright (C) 1995, Guy Eric Schalnat, Group 42 Inc., + | and zlib version 1.1.4pc, Copyright (C) 1998, + | Jean-loup Gailly and Mark Adler. + + +usage: pngcrush [options] infile.png outfile.png + pngcrush -e ext [other options] files.png ... + pngcrush -d dir [other options] files.png ... +options: + -already already_crushed_size [e.g., 8192] + -bit_depth depth (bit_depth to use in output file) + -brute (Use brute-force, try 114 different methods [11-124]) + -c color_type of output file [0, 2, 4, or 6] + -d directory_name (where output files will go) + -double_gamma (used for fixing gamma in PhotoShop 5.0/5.02 files) + -e extension (used for creating output filename) + -f user_filter [0-5] + -fix (fix otherwise fatal conditions such as bad CRCs) + -force (Write a new output file even if larger than input) + -g gamma (float or fixed*100000, e.g., 0.45455 or 45455) + -iccp length "Profile Name" iccp_file + -itxt b[efore_IDAT]|a[fter_IDAT] "keyword" "text" + -l zlib_compression_level [0-9] + -loco ("loco crush" truecolor PNGs) + -m method [0 through 200] + -max maximum_IDAT_size [default 8192] + -nofilecheck (do not check for infile.png == outfile.png) + -n (no save; does not do compression or write output PNG) + -plte_len n (truncate PLTE) + -q (quiet) + -reduce (do lossless color type or bit depth reduction) + -rem chunkname (or "alla" or "allb") +-replace_gamma gamma (float or fixed*100000) even if gAMA is present. + -res dpi + -save (keep all copy-unsafe chunks) + -srgb [0, 1, 2, or 3] + -text b[efore_IDAT]|a[fter_IDAT] "keyword" "text" + -trns_array n trns[0] trns[1] .. trns[n-1] + -trns index red green blue gray + -v (display more detailed information) + -version (display the pngcrush version) + -w compression_window_size [32, 16, 8, 4, 2, 1, 512] + -z zlib_strategy [0, 1, or 2] + -zmem zlib_compression_mem_level [1-9, default 9] + -zitxt b[efore_IDAT]|a[fter_IDAT] "keyword" "text" + -ztxt b[efore_IDAT]|a[fter_IDAT] "keyword" "text" + -h (help and legal notices) + -p (pause) + + + | pngcrush 1.5.9, Copyright (C) 1998-2002 Glenn Randers-Pehrson + | This is a free, open-source program. Permission is irrevocably + | granted to everyone to use this version of pngcrush without + | payment of any fee. + | Executable name is pngcrush + | It was built with libpng version 1.2.4, and is + | running with libpng version 1.2.4 - July 8, 2002 (header) + | Copyright (C) 1998-2002 Glenn Randers-Pehrson, + | Copyright (C) 1996, 1997 Andreas Dilger, + | Copyright (C) 1995, Guy Eric Schalnat, Group 42 Inc., + | and zlib version 1.1.4pc, Copyright (C) 1998, | Jean-loup Gailly and Mark Adler. @@ -338,3 +485,4 @@ options (Note: any option can be spelled out for clarity, e.g., e.g., type 'pngcrush -pause -help', if the help screen scrolls out of sight. + diff --git a/png.c b/png.c index 72bd00eba..380c19c8c 100644 --- a/png.c +++ b/png.c @@ -1,8 +1,8 @@ /* png.c - location for general purpose libpng functions * - * libpng version 1.2.1 - December 12, 2001 - * Copyright (c) 1998-2001 Glenn Randers-Pehrson + * libpng version 1.2.4 - July 8, 2002 + * Copyright (c) 1998-2002 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -13,14 +13,14 @@ #include "png.h" /* Generate a compiler error if there is an old png.h in the search path. */ -typedef version_1_2_1 Your_png_h_is_not_version_1_2_1; +typedef version_1_2_4 Your_png_h_is_not_version_1_2_4; /* Version information for C files. This had better match the version * string defined in png.h. */ #ifdef PNG_USE_GLOBAL_ARRAYS /* png_libpng_ver was changed to a function in version 1.0.5c */ -const char png_libpng_ver[18] = "1.2.1"; +const char png_libpng_ver[18] = "1.2.4"; /* png_sig was changed to a function in version 1.0.5c */ /* Place to hold the signature string for a PNG file. */ @@ -135,13 +135,26 @@ png_check_sig(png_bytep sig, int num) } /* Function to allocate memory for zlib and clear it to 0. */ -voidpf /* PRIVATE */ +#ifdef PNG_1_0_X +void PNGAPI +#else +voidpf /* private */ +#endif png_zalloc(voidpf png_ptr, uInt items, uInt size) { png_uint_32 num_bytes = (png_uint_32)items * size; - png_voidp ptr = (png_voidp)png_malloc((png_structp)png_ptr, num_bytes); + png_voidp ptr; + png_structp p=png_ptr; + png_uint_32 save_flags=p->flags; + + p->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK; + ptr = (png_voidp)png_malloc((png_structp)png_ptr, num_bytes); + p->flags=save_flags; #ifndef PNG_NO_ZALLOC_ZERO + if (ptr == NULL) + return ((voidpf)ptr); + if (num_bytes > (png_uint_32)0x8000L) { png_memset(ptr, 0, (png_size_t)0x8000L); @@ -157,7 +170,11 @@ png_zalloc(voidpf png_ptr, uInt items, uInt size) } /* function to free memory for zlib */ -void /* PRIVATE */ +#ifdef PNG_1_0_X +void PNGAPI +#else +void /* private */ +#endif png_zfree(voidpf png_ptr, voidpf ptr) { png_free((png_structp)png_ptr, (png_voidp)ptr); @@ -345,6 +362,9 @@ if ((mask & PNG_FREE_TRNS) && (png_ptr->flags & PNG_FLAG_FREE_TRNS)) { png_free(png_ptr, info_ptr->trans); info_ptr->valid &= ~PNG_INFO_tRNS; +#ifndef PNG_FREE_ME_SUPPORTED + png_ptr->flags &= ~PNG_FLAG_FREE_TRNS; +#endif info_ptr->trans = NULL; } #endif @@ -488,6 +508,9 @@ if ((mask & PNG_FREE_HIST) && (png_ptr->flags & PNG_FLAG_FREE_HIST)) png_free(png_ptr, info_ptr->hist); info_ptr->hist = NULL; info_ptr->valid &= ~PNG_INFO_hIST; +#ifndef PNG_FREE_ME_SUPPORTED + png_ptr->flags &= ~PNG_FLAG_FREE_HIST; +#endif } #endif @@ -501,6 +524,9 @@ if ((mask & PNG_FREE_PLTE) && (png_ptr->flags & PNG_FLAG_FREE_PLTE)) png_zfree(png_ptr, info_ptr->palette); info_ptr->palette = NULL; info_ptr->valid &= ~PNG_INFO_PLTE; +#ifndef PNG_FREE_ME_SUPPORTED + png_ptr->flags &= ~PNG_FLAG_FREE_PLTE; +#endif info_ptr->num_palette = 0; } @@ -645,10 +671,10 @@ png_charp PNGAPI png_get_copyright(png_structp png_ptr) { if (png_ptr != NULL || png_ptr == NULL) /* silence compiler warning */ - return ((png_charp) "\n libpng version 1.2.1 - December 12, 2001\n\ - Copyright (c) 1998-2001 Glenn Randers-Pehrson\n\ - Copyright (c) 1996, 1997 Andreas Dilger\n\ - Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.\n"); + return ((png_charp) "\n libpng version 1.2.4 - July 8, 2002\n\ + Copyright (c) 1998-2002 Glenn Randers-Pehrson\n\ + Copyright (c) 1996-1997 Andreas Dilger\n\ + Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.\n"); return ((png_charp) ""); } @@ -663,8 +689,8 @@ png_get_libpng_ver(png_structp png_ptr) { /* Version of *.c files used when building libpng */ if(png_ptr != NULL) /* silence compiler warning about unused png_ptr */ - return((png_charp) "1.2.1"); - return((png_charp) "1.2.1"); + return((png_charp) "1.2.4"); + return((png_charp) "1.2.4"); } png_charp PNGAPI @@ -686,7 +712,7 @@ png_get_header_version(png_structp png_ptr) } #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -int /* PRIVATE */ +int PNGAPI png_handle_as_unknown(png_structp png_ptr, png_bytep chunk_name) { /* check chunk_name and return "keep" value if it's on the list, else 0 */ @@ -714,10 +740,11 @@ png_uint_32 PNGAPI png_access_version_number(void) { /* Version of *.c files used when building libpng */ - return((png_uint_32) 10201L); + return((png_uint_32) 10204L); } +#if !defined(PNG_1_0_X) #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) /* GRR: could add this: && defined(PNG_MMX_CODE_SUPPORTED) */ /* this INTERNAL function was added to libpng 1.2.0 */ @@ -775,3 +802,4 @@ png_mmx_support(void) return -1; } #endif +#endif /* PNG_1_0_X */ diff --git a/png.h b/png.h index 77fc42078..365c80b39 100644 --- a/png.h +++ b/png.h @@ -1,15 +1,14 @@ - /* png.h - header file for PNG reference library * - * libpng version 1.2.1 - December 12, 2001 - * Copyright (c) 1998-2001 Glenn Randers-Pehrson + * libpng version 1.2.4 - July 8, 2002 + * Copyright (c) 1998-2002 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * * Authors and maintainers: * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat * libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger - * libpng versions 0.97, January 1998, through 1.2.1 - December 12, 2001: Glenn + * libpng versions 0.97, January 1998, through 1.2.4 - July 8, 2002: Glenn * See also "Contributing Authors", below. * * Note about libpng version numbers: @@ -81,6 +80,19 @@ * 1.2.1beta1-4 3 10201 3.1.2.1beta1-4 * 1.2.1rc1-2 3 10201 3.1.2.1rc1-2 * 1.2.1 3 10201 3.1.2.1 + * 1.2.2beta1-6 12 10202 12.so.0.1.2.2beta1-6 + * 1.0.13beta1 10 10013 10.so.0.1.0.13beta1 + * 1.0.13rc1 10 10013 10.so.0.1.0.13rc1 + * 1.2.2rc1 12 10202 12.so.0.1.2.2rc1 + * 1.0.13 10 10013 10.so.0.1.0.13 + * 1.2.2 12 10202 12.so.0.1.2.2 + * 1.2.3rc1-6 12 10203 12.so.0.1.2.3rc1-6 + * 1.2.3 12 10203 12.so.0.1.2.3 + * 1.2.4beta1-3 13 10204 12.so.0.1.2.4beta1-3 + * 1.0.14rc1 13 10014 10.so.0.1.0.14rc1 + * 1.2.4rc1 13 10204 12.so.0.1.2.4rc1 + * 1.0.14 10 10014 10.so.0.1.0.14 + * 1.2.4 13 10204 12.so.0.1.2.4 * * Henceforth the source version will match the shared-library major * and minor numbers; the shared-library major version number will be @@ -110,8 +122,8 @@ * If you modify libpng you may insert additional notices immediately following * this sentence. * - * libpng versions 1.0.7, July 1, 2000, through 1.2.1, December 12, 2001, are - * Copyright (c) 2000, 2001 Glenn Randers-Pehrson, and are + * libpng versions 1.0.7, July 1, 2000, through 1.2.4, July 8, 2002, are + * Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are * distributed according to the same disclaimer and license as libpng-1.0.6 * with the following individuals added to the list of Contributing Authors * @@ -215,13 +227,13 @@ * Y2K compliance in libpng: * ========================= * - * December 12, 2001 + * July 8, 2002 * * Since the PNG Development group is an ad-hoc body, we can't make * an official declaration. * * This is your unofficial assurance that libpng from version 0.71 and - * upward through 1.2.1 are Y2K compliant. It is my belief that earlier + * upward through 1.2.4 are Y2K compliant. It is my belief that earlier * versions were also Y2K compliant. * * Libpng only has three year fields. One is a 2-byte unsigned integer @@ -277,15 +289,15 @@ */ /* Version information for png.h - this should match the version in png.c */ -#define PNG_LIBPNG_VER_STRING "1.2.1" +#define PNG_LIBPNG_VER_STRING "1.2.4" -#define PNG_LIBPNG_VER_SONUM 3 +#define PNG_LIBPNG_VER_SONUM 0 #define PNG_LIBPNG_VER_DLLNUM %DLLNUM% /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */ #define PNG_LIBPNG_VER_MAJOR 1 #define PNG_LIBPNG_VER_MINOR 2 -#define PNG_LIBPNG_VER_RELEASE 1 +#define PNG_LIBPNG_VER_RELEASE 4 /* This should match the numeric part of the final component of * PNG_LIBPNG_VER_STRING, omitting any leading zero: */ @@ -304,7 +316,7 @@ * Versions 0.7 through 1.0.0 were in the range 0 to 100 here (only * version 1.0.0 was mis-numbered 100 instead of 10000). From * version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release */ -#define PNG_LIBPNG_VER 10201 /* 1.2.1 */ +#define PNG_LIBPNG_VER 10204 /* 1.2.4 */ #ifndef PNG_VERSION_INFO_ONLY @@ -366,7 +378,7 @@ extern "C" { */ #ifdef PNG_USE_GLOBAL_ARRAYS PNG_EXPORT_VAR (const char) png_libpng_ver[18]; - /* need room for 99.99.99beta99z*/ + /* need room for 99.99.99beta99z */ #else #define png_libpng_ver png_get_header_ver(NULL) #endif @@ -592,7 +604,7 @@ typedef struct png_info_struct png_byte interlace_type; /* One of PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */ /* The following is informational only on read, and not used on writes. */ - png_byte channels; /* number of data channels per pixel (1, 2, 3, 4)*/ + png_byte channels; /* number of data channels per pixel (1, 2, 3, 4) */ png_byte pixel_depth; /* number of bits per pixel */ png_byte spare_byte; /* to align the data, and for future use */ png_byte signature[8]; /* magic bytes read by libpng from start of file */ @@ -882,7 +894,7 @@ typedef png_info FAR * FAR * png_infopp; #define PNG_KEYWORD_MAX_LENGTH 79 /* Maximum number of entries in PLTE/sPLT/tRNS arrays */ -#define PNG_MAX_PALETTE_LENGTH 256 +#define PNG_MAX_PALETTE_LENGTH 256 /* These determine if an ancillary chunk's data has been successfully read * from the PNG header, or if the application has filled in the corresponding @@ -1001,7 +1013,7 @@ struct png_struct_def png_voidp error_ptr; /* user supplied struct for error functions */ png_rw_ptr write_data_fn; /* function for writing output data */ png_rw_ptr read_data_fn; /* function for reading input data */ - png_voidp io_ptr; /* ptr to application struct for I/O functions*/ + png_voidp io_ptr; /* ptr to application struct for I/O functions */ #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) png_user_transform_ptr read_user_transform_fn; /* user read transform */ @@ -1215,7 +1227,11 @@ struct png_struct_def defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \ defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) /* changed from png_byte to png_uint_32 at version 1.2.0 */ +#ifdef PNG_1_0_X + png_byte mng_features_permitted; +#else png_uint_32 mng_features_permitted; +#endif /* PNG_1_0_X */ #endif /* New member added in libpng-1.0.7 */ @@ -1228,13 +1244,13 @@ struct png_struct_def png_byte filter_type; #endif -#if defined(PNG_DEBUG) && defined(PNG_USE_PNGGCCRD) +#if defined(PNG_1_0_X) || (defined(PNG_DEBUG) && defined(PNG_USE_PNGGCCRD)) /* New member added in libpng-1.0.10, ifdef'ed out in 1.2.0 */ png_uint_32 row_buf_size; #endif /* New members added in libpng-1.2.0 */ -#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) +#if !defined(PNG_1_0_X) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) png_byte mmx_bitdepth_threshold; png_uint_32 mmx_rowbytes_threshold; png_uint_32 asm_flags; @@ -1247,15 +1263,25 @@ struct png_struct_def png_free_ptr free_fn; /* function for freeing memory */ #endif +/* New member added in libpng-1.0.13 and 1.2.0 */ png_bytep big_row_buf; /* buffer to save current (unfiltered) row */ +#if defined(PNG_READ_DITHER_SUPPORTED) +/* The following three members were added at version 1.0.14 and 1.2.4 */ + png_bytep dither_sort; /* working sort array */ + png_bytep index_to_palette; /* where the original index currently is */ + /* in the palette */ + png_bytep palette_to_index; /* which original index points to this */ + /* palette color */ +#endif + }; -/* This prevents a compiler error in png_get_copyright() in png.c if png.c - and png.h are both at version 1.2.1 +/* This prevents a compiler error in png.c if png.c and png.h are both at + version 1.2.4 */ -typedef png_structp version_1_2_1; +typedef png_structp version_1_2_4; typedef png_struct FAR * FAR * png_structpp; @@ -1339,6 +1365,7 @@ extern PNG_EXPORT(png_infop,png_create_info_struct) /* Initialize the info structure (old interface - DEPRECATED) */ extern PNG_EXPORT(void,png_info_init) PNGARG((png_infop info_ptr)); +#undef png_info_init #define png_info_init(info_ptr) png_info_init_3(&info_ptr, sizeof(png_info)); extern PNG_EXPORT(void,png_info_init_3) PNGARG((png_infopp info_ptr, png_size_t png_info_struct_size)); @@ -1514,11 +1541,11 @@ extern PNG_EXPORT(void,png_start_read_image) PNGARG((png_structp png_ptr)); extern PNG_EXPORT(void,png_read_update_info) PNGARG((png_structp png_ptr, png_infop info_ptr)); -/* read a one or more rows of image data.*/ +/* read one or more rows of image data. */ extern PNG_EXPORT(void,png_read_rows) PNGARG((png_structp png_ptr, png_bytepp row, png_bytepp display_row, png_uint_32 num_rows)); -/* read a row of data.*/ +/* read a row of data. */ extern PNG_EXPORT(void,png_read_row) PNGARG((png_structp png_ptr, png_bytep row, png_bytep display_row)); @@ -1563,9 +1590,6 @@ extern void png_read_destroy PNGARG((png_structp png_ptr, png_infop info_ptr, extern PNG_EXPORT(void,png_destroy_write_struct) PNGARG((png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)); -/* free any memory used in info_ptr struct (old method - NOT DLL EXPORTED) */ -extern void png_write_destroy_info PNGARG((png_infop info_ptr)); - /* free any memory used in png_ptr struct (old method - NOT DLL EXPORTED) */ extern void png_write_destroy PNGARG((png_structp png_ptr)); @@ -1807,9 +1831,26 @@ extern PNG_EXPORT(void,png_progressive_combine_row) PNGARG((png_structp png_ptr, extern PNG_EXPORT(png_voidp,png_malloc) PNGARG((png_structp png_ptr, png_uint_32 size)); +#if defined(PNG_1_0_X) +# define png_malloc_warn png_malloc +#else +/* Added at libpng version 1.2.4 */ +extern PNG_EXPORT(png_voidp,png_malloc_warn) PNGARG((png_structp png_ptr, + png_uint_32 size)); +#endif + /* frees a pointer allocated by png_malloc() */ extern PNG_EXPORT(void,png_free) PNGARG((png_structp png_ptr, png_voidp ptr)); +#if defined(PNG_1_0_X) +/* Function to allocate memory for zlib. */ +extern PNG_EXPORT(voidpf,png_zalloc) PNGARG((voidpf png_ptr, uInt items, + uInt size)); + +/* Function to free memory for zlib */ +extern PNG_EXPORT(void,png_zfree) PNGARG((voidpf png_ptr, voidpf ptr)); +#endif + /* Free data that was allocated internally */ extern PNG_EXPORT(void,png_free_data) PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 free_me, int num)); @@ -1858,19 +1899,19 @@ extern void *png_far_to_near PNGARG((png_structp png_ptr,png_voidp ptr, /* Fatal error in PNG image of libpng - can't continue */ extern PNG_EXPORT(void,png_error) PNGARG((png_structp png_ptr, - png_const_charp error)); + png_const_charp error_message)); /* The same, but the chunk name is prepended to the error string. */ extern PNG_EXPORT(void,png_chunk_error) PNGARG((png_structp png_ptr, - png_const_charp error)); + png_const_charp error_message)); /* Non-fatal error in libpng. Can continue, but may have a problem. */ extern PNG_EXPORT(void,png_warning) PNGARG((png_structp png_ptr, - png_const_charp message)); + png_const_charp warning_message)); /* Non-fatal error in libpng, chunk name is prepended to message. */ extern PNG_EXPORT(void,png_chunk_warning) PNGARG((png_structp png_ptr, - png_const_charp message)); + png_const_charp warning_message)); /* The png_set_ functions are for storing values in the png_info_struct. * Similarly, the png_get_ calls are used to read values from the @@ -2217,6 +2258,10 @@ extern PNG_EXPORT(void, png_set_unknown_chunk_location) extern PNG_EXPORT(png_uint_32,png_get_unknown_chunks) PNGARG((png_structp png_ptr, png_infop info_ptr, png_unknown_chunkpp entries)); #endif +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +PNG_EXPORT(int,png_handle_as_unknown) PNGARG((png_structp png_ptr, png_bytep + chunk_name)); +#endif /* Png_free_data() will turn off the "valid" flag for anything it frees. If you need to turn it off for a chunk that your application has freed, @@ -2301,15 +2346,15 @@ extern PNG_EXPORT(png_uint_32,png_permit_mng_features) PNGARG((png_structp /* Added to version 1.2.0 */ #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) -#define PNG_ASM_FLAG_MMX_SUPPORT_COMPILED 0x01 /* not user-settable */ -#define PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU 0x02 /* not user-settable */ +#define PNG_ASM_FLAG_MMX_SUPPORT_COMPILED 0x01 /* not user-settable */ +#define PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU 0x02 /* not user-settable */ #define PNG_ASM_FLAG_MMX_READ_COMBINE_ROW 0x04 #define PNG_ASM_FLAG_MMX_READ_INTERLACE 0x08 #define PNG_ASM_FLAG_MMX_READ_FILTER_SUB 0x10 #define PNG_ASM_FLAG_MMX_READ_FILTER_UP 0x20 #define PNG_ASM_FLAG_MMX_READ_FILTER_AVG 0x40 #define PNG_ASM_FLAG_MMX_READ_FILTER_PAETH 0x80 -#define PNG_ASM_FLAGS_INITIALIZED 0x80000000 /* not user-settable */ +#define PNG_ASM_FLAGS_INITIALIZED 0x80000000 /* not user-settable */ #define PNG_MMX_READ_FLAGS ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \ | PNG_ASM_FLAG_MMX_READ_INTERLACE \ @@ -2328,6 +2373,7 @@ extern PNG_EXPORT(png_uint_32,png_permit_mng_features) PNGARG((png_structp #define PNG_SELECT_WRITE 2 +#if !defined(PNG_1_0_X) /* pngget.c */ extern PNG_EXPORT(png_uint_32,png_get_mmx_flagmask) PNGARG((int flag_select, int *compilerID)); @@ -2357,8 +2403,10 @@ extern PNG_EXPORT(void,png_set_mmx_thresholds) PNGARG((png_structp png_ptr, png_byte mmx_bitdepth_threshold, png_uint_32 mmx_rowbytes_threshold)); +#endif /* PNG_1_0_X */ #endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ +#if !defined(PNG_1_0_X) /* png.c, pnggccrd.c, or pngvcrd.c */ extern PNG_EXPORT(int,png_mmx_support) PNGARG((void)); @@ -2368,11 +2416,12 @@ extern PNG_EXPORT(int,png_mmx_support) PNGARG((void)); extern PNG_EXPORT(void,png_set_strip_error_numbers) PNGARG((png_structp png_ptr, png_uint_32 strip_mode)); #endif +#endif /* PNG_1_0_X */ /* Maintainer: Put new public prototypes here ^, in libpng.3, and project defs */ #define PNG_HEADER_VERSION_STRING \ - " libpng version 1.2.1 - December 12, 2001 (header)\n" + " libpng version 1.2.4 - July 8, 2002 (header)\n" #ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED /* With these routines we avoid an integer divide, which will be slower on @@ -2497,6 +2546,7 @@ extern PNG_EXPORT(void,png_set_strip_error_numbers) PNGARG((png_structp #define PNG_FLAG_LIBRARY_MISMATCH 0x20000L #define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000L #define PNG_FLAG_STRIP_ERROR_TEXT 0x80000L +#define PNG_FLAG_MALLOC_NULL_MEM_OK 0x100000L /* For use in png_set_keep_unknown, png_handle_as_unknown */ #define HANDLE_CHUNK_AS_DEFAULT 0 @@ -2605,6 +2655,7 @@ PNG_EXTERN png_uint_16 png_get_uint_16 PNGARG((png_bytep buf)); * (old interface - DEPRECATED - use png_create_read_struct instead). */ extern PNG_EXPORT(void,png_read_init) PNGARG((png_structp png_ptr)); +#undef png_read_init #define png_read_init(png_ptr) png_read_init_3(&png_ptr, \ PNG_LIBPNG_VER_STRING, sizeof(png_struct)); extern PNG_EXPORT(void,png_read_init_3) PNGARG((png_structpp ptr_ptr, @@ -2617,6 +2668,7 @@ extern PNG_EXPORT(void,png_read_init_2) PNGARG((png_structp png_ptr, * (old interface - DEPRECATED - use png_create_write_struct instead). */ extern PNG_EXPORT(void,png_write_init) PNGARG((png_structp png_ptr)); +#undef png_write_init #define png_write_init(png_ptr) png_write_init_3(&png_ptr, \ PNG_LIBPNG_VER_STRING, sizeof(png_struct)); extern PNG_EXPORT(void,png_write_init_3) PNGARG((png_structpp ptr_ptr, @@ -2640,12 +2692,39 @@ PNG_EXTERN void png_destroy_struct_2 PNGARG((png_voidp struct_ptr, PNG_EXTERN void png_info_destroy PNGARG((png_structp png_ptr, png_infop info_ptr)); +#ifndef PNG_1_0_X /* Function to allocate memory for zlib. */ PNG_EXTERN voidpf png_zalloc PNGARG((voidpf png_ptr, uInt items, uInt size)); /* Function to free memory for zlib */ PNG_EXTERN void png_zfree PNGARG((voidpf png_ptr, voidpf ptr)); +/* Next four functions are used internally as callbacks. PNGAPI is required + * but not PNG_EXPORT. PNGAPI added at libpng version 1.2.3. */ + +PNG_EXTERN void PNGAPI png_default_read_data PNGARG((png_structp png_ptr, + png_bytep data, png_size_t length)); + +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +PNG_EXTERN void PNGAPI png_push_fill_buffer PNGARG((png_structp png_ptr, + png_bytep buffer, png_size_t length)); +#endif + +PNG_EXTERN void PNGAPI png_default_write_data PNGARG((png_structp png_ptr, + png_bytep data, png_size_t length)); + +#if defined(PNG_WRITE_FLUSH_SUPPORTED) +#if !defined(PNG_NO_STDIO) +PNG_EXTERN void PNGAPI png_default_flush PNGARG((png_structp png_ptr)); +#endif +#endif +#else /* PNG_1_0_X */ +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +PNG_EXTERN void png_push_fill_buffer PNGARG((png_structp png_ptr, + png_bytep buffer, png_size_t length)); +#endif +#endif /* PNG_1_0_X */ + /* Reset the CRC variable */ PNG_EXTERN void png_reset_crc PNGARG((png_structp png_ptr)); @@ -2686,6 +2765,7 @@ PNG_EXTERN void png_calculate_crc PNGARG((png_structp png_ptr, png_bytep ptr, PNG_EXTERN void png_flush PNGARG((png_structp png_ptr)); #endif + /* Place a 32-bit number into a buffer in PNG byte order (big-endian). * The only currently known PNG chunks that use signed numbers are * the ancillary extension chunks, oFFs and pCAL. @@ -2808,6 +2888,11 @@ PNG_EXTERN void png_write_iTXt PNGARG((png_structp png_ptr, png_charp text)); #endif +#if defined(PNG_TEXT_SUPPORTED) /* Added at version 1.0.14 and 1.2.4 */ +PNG_EXTERN int png_set_text_2 PNGARG((png_structp png_ptr, + png_infop info_ptr, png_textp text_ptr, int num_text)); +#endif + #if defined(PNG_WRITE_oFFs_SUPPORTED) PNG_EXTERN void png_write_oFFs PNGARG((png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset, int unit_type)); @@ -3108,11 +3193,6 @@ PNG_EXTERN void png_handle_zTXt PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); #endif -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -PNG_EXTERN int png_handle_as_unknown PNGARG((png_structp png_ptr, png_bytep - chunk_name)); -#endif - PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); @@ -3134,8 +3214,6 @@ PNG_EXTERN void png_push_check_crc PNGARG((png_structp png_ptr)); PNG_EXTERN void png_push_crc_skip PNGARG((png_structp png_ptr, png_uint_32 length)); PNG_EXTERN void png_push_crc_finish PNGARG((png_structp png_ptr)); -PNG_EXTERN void png_push_fill_buffer PNGARG((png_structp png_ptr, - png_bytep buffer, png_size_t length)); PNG_EXTERN void png_push_save_buffer PNGARG((png_structp png_ptr)); PNG_EXTERN void png_push_restore_buffer PNGARG((png_structp png_ptr, png_bytep buffer, png_size_t buffer_length)); diff --git a/pngasmrd.h b/pngasmrd.h index b96a46417..a19d4ae5a 100644 --- a/pngasmrd.h +++ b/pngasmrd.h @@ -1,8 +1,8 @@ /* pngasmrd.h - assembler version of utilities to read a PNG file * - * libpng 1.2.1 - December 12, 2001 + * libpng 1.2.4 - July 8, 2002 * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 2001 Glenn Randers-Pehrson + * Copyright (c) 2002 Glenn Randers-Pehrson * */ diff --git a/pngconf.h b/pngconf.h index bcd746458..a0ca483ce 100644 --- a/pngconf.h +++ b/pngconf.h @@ -1,8 +1,8 @@ /* pngconf.h - machine configurable file for libpng * - * libpng 1.2.1 - December 12, 2001 + * libpng 1.2.4 - July 8, 2002 * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2001 Glenn Randers-Pehrson + * Copyright (c) 1998-2002 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) */ @@ -49,7 +49,7 @@ /* Enabled by default in 1.2.0. You can disable this if you don't need to support PNGs that are embedded in MNG datastreams */ -#ifndef PNG_NO_MNG_FEATURES +#if !defined(PNG_1_0_X) && !defined(PNG_NO_MNG_FEATURES) # ifndef PNG_MNG_FEATURES_SUPPORTED # define PNG_MNG_FEATURES_SUPPORTED # endif @@ -80,12 +80,12 @@ * (no define) -- building static library, or building an * application and linking to the static lib * 'Cygwin' defines/defaults: - * PNG_BUILD_DLL -- building the dll - * (no define) -- building an application, linking to the dll - * PNG_STATIC -- building the static lib, or building an application - * that links to the static lib. - * ALL_STATIC -- building various static libs, or building an application - * that links to the static libs. + * PNG_BUILD_DLL -- (ignored) building the dll + * (no define) -- (ignored) building an application, linking to the dll + * PNG_STATIC -- (ignored) building the static lib, or building an + * application that links to the static lib. + * ALL_STATIC -- (ignored) building various static libs, or building an + * application that links to the static libs. * Thus, * a cygwin user should define either PNG_BUILD_DLL or PNG_STATIC, and * this bit of #ifdefs will define the 'correct' config variables based on @@ -96,7 +96,15 @@ * ALL_STATIC (since we can't #undef something outside our namespace) * PNG_BUILD_DLL * PNG_STATIC - * (nothing) == PNG_USE_DLL + * (nothing) == PNG_USE_DLL + * + * CYGWIN (2002-01-20): The preceding is now obsolete. With the advent + * of auto-import in binutils, we no longer need to worry about + * __declspec(dllexport) / __declspec(dllimport) and friends. Therefore, + * we don't need to worry about PNG_STATIC or ALL_STATIC when it comes + * to __declspec() stuff. However, we DO need to worry about + * PNG_BUILD_DLL and PNG_STATIC because those change some defaults + * such as CONSOLE_IO and whether GLOBAL_ARRAYS are allowed. */ #if defined(__CYGWIN__) # if defined(ALL_STATIC) @@ -593,9 +601,11 @@ # define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED #endif +#ifndef PNG_1_0_X #ifndef PNG_NO_ERROR_NUMBERS #define PNG_ERROR_NUMBERS_SUPPORTED #endif +#endif /* PNG_1_0_X */ #ifndef PNG_NO_WRITE_FLUSH # define PNG_WRITE_FLUSH_SUPPORTED @@ -649,9 +659,11 @@ #define PNG_THREAD_UNSAFE_OK */ +#if !defined(PNG_1_0_X) #if !defined(PNG_NO_USER_MEM) && !defined(PNG_USER_MEM_SUPPORTED) # define PNG_USER_MEM_SUPPORTED #endif +#endif /* PNG_1_0_X */ /* These are currently experimental features, define them if you want */ @@ -1147,10 +1159,23 @@ typedef z_stream FAR * png_zstreamp; # endif #endif +#if defined(__CYGWIN__) +# undef PNGAPI +# define PNGAPI __cdecl +# undef PNG_IMPEXP +# define PNG_IMPEXP +#endif + +/* If you define PNGAPI, e.g., with compiler option "-DPNGAPI=__stdcall", + * you may get warnings regarding the linkage of png_zalloc and png_zfree. + * Don't ignore those warnings; you must also reset the default calling + * convention in your compiler to match your PNGAPI, and you must build + * zlib and your applications the same way you build libpng. + */ #ifndef PNGAPI -#if defined(__MINGW32__) || defined(__CYGWIN__) && !defined(PNG_MODULEDEF) +#if defined(__MINGW32__) && !defined(PNG_MODULEDEF) # ifndef PNG_NO_MODULEDEF # define PNG_NO_MODULEDEF # endif @@ -1162,8 +1187,7 @@ typedef z_stream FAR * png_zstreamp; #if defined(PNG_DLL) || defined(_DLL) || defined(__DLL__ ) || \ (( defined(_Windows) || defined(_WINDOWS) || \ - defined(WIN32) || defined(_WIN32) || defined(__WIN32__) \ - ) && !defined(__CYGWIN__)) + defined(WIN32) || defined(_WIN32) || defined(__WIN32__) )) # if defined(__GNUC__) || (defined (_MSC_VER) && (_MSC_VER >= 800)) # define PNGAPI __cdecl @@ -1190,8 +1214,8 @@ typedef z_stream FAR * png_zstreamp; # if defined(PNG_BUILD_DLL) # define PNG_IMPEXP __export # else -# define PNG_IMPEXP /*__import*/ /* doesn't exist AFAIK in - VC++*/ +# define PNG_IMPEXP /*__import */ /* doesn't exist AFAIK in + VC++ */ # endif /* Exists in Borland C++ for C++ classes (== huge) */ # endif @@ -1206,12 +1230,6 @@ typedef z_stream FAR * png_zstreamp; # endif # endif /* PNG_IMPEXP */ #else /* !(DLL || non-cygwin WINDOWS) */ -# if defined(__CYGWIN__) && !defined(PNG_DLL) -# if !defined(PNG_IMPEXP) -# define PNG_IMPEXP -# endif -# define PNGAPI __cdecl -# else # if (defined(__IBMC__) || defined(IBMCPP__)) && defined(__OS2__) # define PNGAPI _System # define PNG_IMPEXP @@ -1222,7 +1240,6 @@ typedef z_stream FAR * png_zstreamp; # define PNG_IMPEXP # endif # endif -# endif #endif #endif diff --git a/pngcrush.c b/pngcrush.c index 22c87c43a..f1678a22d 100644 --- a/pngcrush.c +++ b/pngcrush.c @@ -1,5 +1,5 @@ /* pngcrush.c - recompresses png files - * Copyright (C) 1998-2001 Glenn Randers-Pehrson (randeg@alum.rpi.edu) + * Copyright (C) 1998-2002 Glenn Randers-Pehrson (randeg@alum.rpi.edu) * * The most recent version of pngcrush can be found at SourceForge in * http://pmt.sf.net/pngcrush/ @@ -25,7 +25,7 @@ * */ -#define PNGCRUSH_VERSION "1.5.8" +#define PNGCRUSH_VERSION "1.5.9" /* #define PNGCRUSH_COUNT_COLORS @@ -37,7 +37,7 @@ * If you have modified this source, you may insert additional notices * immediately after this sentence. * - * Copyright (C) 1998-2001 Glenn Randers-Pehrson (randeg@alum.rpi.edu) + * Copyright (C) 1998-2002 Glenn Randers-Pehrson (randeg@alum.rpi.edu) * * The pngcrush computer program is supplied "AS IS". The Author disclaims all * warranties, expressed or implied, including, without limitation, the @@ -53,8 +53,9 @@ * the user. * * Permission is hereby irrevocably granted to everyone to use, copy, modify, - * and distribute this source code, or portions hereof, for any purpose, - * without payment of any fee, subject to the following restrictions: + * and distribute this source code, or portions hereof, or executable programs + * compiled from it, for any purpose, without payment of any fee, subject to + * the following restrictions: * * 1. The origin of this source code must not be misrepresented. * @@ -66,6 +67,16 @@ */ /* Change log: + * + * Version 1.5.9 (built with libpng-1.2.4beta3 and zlib-1.1.4pc) + * + * Work around CPU timer wraparound at 2G microseconds. + * + * Upgraded zlib from 1.1.3 to 1.1.4. Pngcrush is believed not to + * be vulnerable to the zlib-1.1.3 buffer-overflow bug. + * + * Choose the first instance of smallest IDAT instead of the last, + * for faster final recompression, suggested by TSamuel. * * Version 1.5.8 (built with libpng-1.2.1) * @@ -701,7 +712,7 @@ png_uint_32 png_measure_idat(png_structp png_ptr); static png_uint_32 idat_length[MAX_METHODSP1]; static int filter_type, zlib_level; static png_bytep png_row_filters=NULL; -static TIME_T t_start, t_stop, t_decode, t_encode, t_misc; +static float t_start, t_stop, t_decode, t_encode, t_misc; static png_uint_32 max_idat_size = 524288L; /* increases the IDAT size */ static png_uint_32 crushed_idat_size = 0x3ffffffL; @@ -1071,6 +1082,12 @@ show_result(void) } t_stop = (TIME_T)clock(); t_misc += (t_stop - t_start); + if (t_stop < t_start) + { + t_misc+= PNG_MAX_UINT; + if (t_stop < 0) + t_misc+= PNG_MAX_UINT; + } t_start = t_stop; fprintf(STDERR," CPU time used = %.3f seconds", (t_misc+t_decode+t_encode)/(float)CLOCKS_PER_SEC); @@ -1678,10 +1695,11 @@ main(int argc, char *argv[]) fprintf(STDERR, PNGCRUSH_VERSION ); fprintf(STDERR,", uses libpng "); fprintf(STDERR, PNG_LIBPNG_VER_STRING ); - fprintf(STDERR,"and zlib "); + fprintf(STDERR," and zlib "); fprintf(STDERR, ZLIB_VERSION ); fprintf(STDERR, "\n Check http://pmt.sf.net\n"); fprintf(STDERR, " for the most recent version.\n"); + verbose=0; } else if(!strncmp(argv[i],"-v",2)) { @@ -1743,7 +1761,7 @@ main(int argc, char *argv[]) /* If you have modified this source, you may insert additional notices * immediately after this sentence. */ fprintf(STDERR, - "\n | pngcrush %s, Copyright (C) 1998-2001 Glenn Randers-Pehrson\n", + "\n | pngcrush %s, Copyright (C) 1998-2002 Glenn Randers-Pehrson\n", PNGCRUSH_VERSION); fprintf(STDERR, " | This is a free, open-source program. Permission is irrevocably\n"); @@ -1762,7 +1780,7 @@ main(int argc, char *argv[]) #endif #if PNG_LIBPNG_VER > 96 fprintf(STDERR, - " | Copyright (C) 1998-2001 Glenn Randers-Pehrson,\n"); + " | Copyright (C) 1998-2002 Glenn Randers-Pehrson,\n"); #endif #if PNG_LIBPNG_VER > 89 fprintf(STDERR, @@ -1820,8 +1838,8 @@ main(int argc, char *argv[]) inname= argv[names]; } - if((nosave == 0 && pngcrush_mode == DEFAULT_MODE && argc - names != 2) || - help > 0) + if((verbose && nosave == 0 && pngcrush_mode == DEFAULT_MODE + && argc - names != 2) || help > 0) { fprintf(STDERR, "\nusage: %s [options] infile.png outfile.png\n",progname); @@ -2265,7 +2283,7 @@ main(int argc, char *argv[]) /* If you have modified this source, you may insert additional notices * immediately after this sentence. */ fprintf (STDERR, - "\nCopyright (C) 1998-2001 Glenn Randers-Pehrson (randeg@alum.rpi.edu)\n\n"); + "\nCopyright (C) 1998-2002 Glenn Randers-Pehrson (randeg@alum.rpi.edu)\n\n"); fprintf(STDERR, "\nDISCLAIMER: The pngcrush computer program is supplied \"AS IS\".\n"); fprintf(STDERR, @@ -2554,14 +2572,14 @@ main(int argc, char *argv[]) best=0; best_length=(png_uint_32)0xffffffff; for (ntrial=things_have_changed; ntrialflags&(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) { int offset = 0; - if (*message == '#') + if (*error_message == '#') { for (offset=1; offset<15; offset++) - if (*(message+offset) == ' ') + if (*(error_message+offset) == ' ') break; if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT) { int i; for (i=0; ierror_fn != NULL) - (*(png_ptr->error_fn))(png_ptr, message); + (*(png_ptr->error_fn))(png_ptr, error_message); /* if the following returns or doesn't exist, use the default function, which will not return */ - png_default_error(png_ptr, message); + png_default_error(png_ptr, error_message); } /* This function is called whenever there is a non-fatal error. This function @@ -77,24 +77,25 @@ png_error(png_structp png_ptr, png_const_charp message) * png_set_error_fn() to replace the warning function at run-time. */ void PNGAPI -png_warning(png_structp png_ptr, png_const_charp message) +png_warning(png_structp png_ptr, png_const_charp warning_message) { int offset = 0; #ifdef PNG_ERROR_NUMBERS_SUPPORTED if (png_ptr->flags&(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) #endif { - if (*message == '#') + if (*warning_message == '#') { for (offset=1; offset<15; offset++) - if (*(message+offset) == ' ') + if (*(warning_message+offset) == ' ') break; } } if (png_ptr->warning_fn != NULL) - (*(png_ptr->warning_fn))(png_ptr, (png_const_charp)(message+offset)); + (*(png_ptr->warning_fn))(png_ptr, + (png_const_charp)(warning_message+offset)); else - png_default_warning(png_ptr, (png_const_charp)(message+offset)); + png_default_warning(png_ptr, (png_const_charp)(warning_message+offset)); } /* These utilities are used internally to build an error message that relates @@ -110,7 +111,7 @@ static PNG_CONST char png_digit[16] = { static void /* PRIVATE */ png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp - message) + error_message) { int iout = 0, iin = 0; @@ -130,30 +131,30 @@ png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp } } - if (message == NULL) + if (error_message == NULL) buffer[iout] = 0; else { buffer[iout++] = ':'; buffer[iout++] = ' '; - png_memcpy(buffer+iout, message, 64); + png_memcpy(buffer+iout, error_message, 64); buffer[iout+63] = 0; } } void PNGAPI -png_chunk_error(png_structp png_ptr, png_const_charp message) +png_chunk_error(png_structp png_ptr, png_const_charp error_message) { char msg[18+64]; - png_format_buffer(png_ptr, msg, message); + png_format_buffer(png_ptr, msg, error_message); png_error(png_ptr, msg); } void PNGAPI -png_chunk_warning(png_structp png_ptr, png_const_charp message) +png_chunk_warning(png_structp png_ptr, png_const_charp warning_message) { char msg[18+64]; - png_format_buffer(png_ptr, msg, message); + png_format_buffer(png_ptr, msg, warning_message); png_warning(png_ptr, msg); } @@ -163,33 +164,34 @@ png_chunk_warning(png_structp png_ptr, png_const_charp message) * error function pointer in png_set_error_fn(). */ static void /* PRIVATE */ -png_default_error(png_structp png_ptr, png_const_charp message) +png_default_error(png_structp png_ptr, png_const_charp error_message) { #ifndef PNG_NO_CONSOLE_IO #ifdef PNG_ERROR_NUMBERS_SUPPORTED - if (*message == '#') + if (*error_message == '#') { int offset; char error_number[16]; for (offset=0; offset<15; offset++) { - error_number[offset] = *(message+offset+1); - if (*(message+offset) == ' ') + error_number[offset] = *(error_message+offset+1); + if (*(error_message+offset) == ' ') break; } if((offset > 1) && (offset < 15)) { error_number[offset-1]='\0'; - fprintf(stderr, "libpng error no. %s: %s\n", error_number, message+offset); + fprintf(stderr, "libpng error no. %s: %s\n", error_number, + error_message+offset); } else - fprintf(stderr, "libpng error: %s, offset=%d\n", message,offset); + fprintf(stderr, "libpng error: %s, offset=%d\n", error_message,offset); } else #endif - fprintf(stderr, "libpng error: %s\n", message); + fprintf(stderr, "libpng error: %s\n", error_message); #else - if (message) + if (error_message) /* make compiler happy */ ; #endif @@ -216,34 +218,34 @@ png_default_error(png_structp png_ptr, png_const_charp message) * not used, but it is passed in case it may be useful. */ static void /* PRIVATE */ -png_default_warning(png_structp png_ptr, png_const_charp message) +png_default_warning(png_structp png_ptr, png_const_charp warning_message) { #ifndef PNG_NO_CONSOLE_IO # ifdef PNG_ERROR_NUMBERS_SUPPORTED - if (*message == '#') + if (*warning_message == '#') { int offset; char warning_number[16]; for (offset=0; offset<15; offset++) { - warning_number[offset]=*(message+offset+1); - if (*(message+offset) == ' ') + warning_number[offset]=*(warning_message+offset+1); + if (*(warning_message+offset) == ' ') break; } if((offset > 1) && (offset < 15)) { warning_number[offset-1]='\0'; fprintf(stderr, "libpng warning no. %s: %s\n", warning_number, - message+offset); + warning_message+offset); } else - fprintf(stderr, "libpng warning: %s\n", message); + fprintf(stderr, "libpng warning: %s\n", warning_message); } else # endif - fprintf(stderr, "libpng warning: %s\n", message); + fprintf(stderr, "libpng warning: %s\n", warning_message); #else - if (message) + if (warning_message) /* appease compiler */ ; #endif if (png_ptr) @@ -277,7 +279,7 @@ png_get_error_ptr(png_structp png_ptr) #ifdef PNG_ERROR_NUMBERS_SUPPORTED -void +void PNGAPI png_set_strip_error_numbers(png_structp png_ptr, png_uint_32 strip_mode) { if(png_ptr != NULL) diff --git a/pnggccrd.c b/pnggccrd.c index e4540c511..2d1d1d3b3 100644 --- a/pnggccrd.c +++ b/pnggccrd.c @@ -6,9 +6,9 @@ * and http://www.intel.com/drg/pentiumII/appnotes/923/923.htm * for Intel's performance analysis of the MMX vs. non-MMX code. * - * libpng version 1.2.1 - December 12, 2001 + * libpng version 1.2.4 - July 8, 2002 * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2001 Glenn Randers-Pehrson + * Copyright (c) 1998-2002 Glenn Randers-Pehrson * Copyright (c) 1998, Intel Corporation * * Based on MSVC code contributed by Nirav Chhatrapati, Intel Corp., 1998. @@ -220,6 +220,9 @@ * 20010310: * - fixed buffer-overrun bug in png_combine_row() C code (non-MMX) * + * 20020304: + * - eliminated incorrect use of width_mmx in pixel_bytes == 8 case + * * STILL TO DO: * - test png_do_read_interlace() 64-bit case (pixel_bytes == 8) * - write MMX code for 48-bit case (pixel_bytes == 6) @@ -335,7 +338,7 @@ static unsigned long long _const6 = 0x00000000000000FFLL; static png_uint_32 _FullLength; static png_uint_32 _MMXLength; static int _dif; -static int _patemp; // temp variables for Paeth routine +static int _patemp; // temp variables for Paeth routine static int _pbtemp; static int _pctemp; #endif @@ -383,9 +386,9 @@ static int _mmx_supported = 2; #if defined(PNG_HAVE_ASSEMBLER_COMBINE_ROW) #define BPP2 2 -#define BPP3 3 /* bytes per pixel (a.k.a. pixel_bytes) */ +#define BPP3 3 /* bytes per pixel (a.k.a. pixel_bytes) */ #define BPP4 4 -#define BPP6 6 /* (defined only to help avoid cut-and-paste errors) */ +#define BPP6 6 /* (defined only to help avoid cut-and-paste errors) */ #define BPP8 8 /* Combines the row recently read in with the previous row. @@ -597,8 +600,12 @@ png_combine_row(png_structp png_ptr, png_bytep row, int mask) png_bytep dstptr; #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) +#if !defined(PNG_1_0_X) if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) /* && _mmx_supported */ ) +#else + if (_mmx_supported) +#endif { png_uint_32 len; int diff; @@ -731,8 +738,12 @@ png_combine_row(png_structp png_ptr, png_bytep row, int mask) png_bytep dstptr; #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) +#if !defined(PNG_1_0_X) if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) /* && _mmx_supported */ ) +#else + if (_mmx_supported) +#endif { png_uint_32 len; int diff; @@ -880,8 +891,12 @@ png_combine_row(png_structp png_ptr, png_bytep row, int mask) png_bytep dstptr; #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) +#if !defined(PNG_1_0_X) if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) /* && _mmx_supported */ ) +#else + if (_mmx_supported) +#endif { png_uint_32 len; int diff; @@ -1044,8 +1059,12 @@ png_combine_row(png_structp png_ptr, png_bytep row, int mask) png_bytep dstptr; #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) +#if !defined(PNG_1_0_X) if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) /* && _mmx_supported */ ) +#else + if (_mmx_supported) +#endif { png_uint_32 len; int diff; @@ -1215,8 +1234,12 @@ png_combine_row(png_structp png_ptr, png_bytep row, int mask) png_bytep dstptr; #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) +#if !defined(PNG_1_0_X) if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) /* && _mmx_supported */ ) +#else + if (_mmx_supported) +#endif { png_uint_32 len; int diff; @@ -1481,8 +1504,10 @@ png_do_read_interlace(png_structp png_ptr) #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) if (_mmx_supported == 2) { +#if !defined(PNG_1_0_X) /* this should have happened in png_init_mmx_flags() already */ png_warning(png_ptr, "asm_flags may not have been initialized"); +#endif png_mmx_support(); } #endif @@ -1691,8 +1716,12 @@ png_do_read_interlace(png_structp png_ptr) /* New code by Nirav Chhatrapati - Intel Corporation */ #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) +#if !defined(PNG_1_0_X) if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_INTERLACE) /* && _mmx_supported */ ) +#else + if (_mmx_supported) +#endif { //-------------------------------------------------------------- if (pixel_bytes == 3) @@ -2464,9 +2493,8 @@ png_do_read_interlace(png_structp png_ptr) { // source is 8-byte RRGGBBAA // dest is 32-byte RRGGBBAA RRGGBBAA RRGGBBAA RRGGBBAA - int width_mmx = ((width >> 1) << 1) ; - width -= width_mmx; - if (width_mmx) + // (recall that expansion is _in place_: sptr and dp + // both point at locations within same row buffer) { int dummy_value_c; // fix 'forbidden register spilled' int dummy_value_S; @@ -2505,9 +2533,6 @@ png_do_read_interlace(png_structp png_ptr) { // source is 8-byte RRGGBBAA // dest is 16-byte RRGGBBAA RRGGBBAA - int width_mmx = ((width >> 1) << 1) ; - width -= width_mmx; - if (width_mmx) { int dummy_value_c; // fix 'forbidden register spilled' int dummy_value_S; @@ -4802,7 +4827,7 @@ png_read_filter_row_mmx_sub(png_row_infop row_info, png_bytep row) } break; - default: // bpp greater than 8 bytes GRR BOGUS + default: // bpp greater than 8 bytes GRR BOGUS { __asm__ __volatile__ ( "movl _dif, %%edx \n\t" @@ -4895,6 +4920,9 @@ png_read_filter_row_mmx_up(png_row_infop row_info, png_bytep row, __asm__ __volatile__ ( //pre "movl row, %%edi \n\t" // get # of bytes to alignment +#ifdef __PIC__ + "pushl %%ebx \n\t" +#endif "movl %%edi, %%ecx \n\t" "xorl %%ebx, %%ebx \n\t" "addl $0x7, %%ecx \n\t" @@ -4994,6 +5022,9 @@ png_read_filter_row_mmx_up(png_row_infop row_info, png_bytep row, "up_end: \n\t" "EMMS \n\t" // conversion of filtered row complete +#ifdef __PIC__ + "popl %%ebx \n\t" +#endif : "=d" (dummy_value_d), // 0 // output regs (dummy) "=S" (dummy_value_S), // 1 @@ -5057,26 +5088,34 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep break; case 1: sprintf(filnm, "sub-%s", #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) +#if !defined(PNG_1_0_X) (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_SUB)? "MMX" : #endif +#endif "x86"); break; case 2: sprintf(filnm, "up-%s", #ifdef PNG_ASSEMBLER_CODE_SUPPORTED +#if !defined(PNG_1_0_X) (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_UP)? "MMX" : +#endif #endif "x86"); break; case 3: sprintf(filnm, "avg-%s", #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) +#if !defined(PNG_1_0_X) (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_AVG)? "MMX" : +#endif #endif "x86"); break; case 4: sprintf(filnm, "Paeth-%s", #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) +#if !defined(PNG_1_0_X) (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_PAETH)? "MMX": #endif +#endif "x86"); break; default: sprintf(filnm, "unknw"); @@ -5096,9 +5135,13 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep case PNG_FILTER_VALUE_SUB: #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) +#if !defined(PNG_1_0_X) if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_SUB) && (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) +#else + if (_mmx_supported) +#endif { png_read_filter_row_mmx_sub(row_info, row); } @@ -5121,9 +5164,13 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep case PNG_FILTER_VALUE_UP: #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) +#if !defined(PNG_1_0_X) if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_UP) && (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) +#else + if (_mmx_supported) +#endif { png_read_filter_row_mmx_up(row_info, row, prev_row); } @@ -5145,9 +5192,13 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep case PNG_FILTER_VALUE_AVG: #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) +#if !defined(PNG_1_0_X) if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_AVG) && (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) +#else + if (_mmx_supported) +#endif { png_read_filter_row_mmx_avg(row_info, row, prev_row); } @@ -5179,9 +5230,13 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep case PNG_FILTER_VALUE_PAETH: #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) +#if !defined(PNG_1_0_X) if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_PAETH) && (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) +#else + if (_mmx_supported) +#endif { png_read_filter_row_mmx_paeth(row_info, row, prev_row); } diff --git a/pngget.c b/pngget.c index f180f3dd2..d3805a6e0 100644 --- a/pngget.c +++ b/pngget.c @@ -1,9 +1,9 @@ /* pngget.c - retrieval of values from info struct * - * libpng 1.2.1 - December 12, 2001 + * libpng 1.2.4 - July 8, 2002 * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2001 Glenn Randers-Pehrson + * Copyright (c) 1998-2002 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) */ @@ -547,7 +547,11 @@ png_get_IHDR(png_structp png_ptr, png_infop info_ptr, *width = info_ptr->width; *height = info_ptr->height; *bit_depth = info_ptr->bit_depth; + if (info_ptr->bit_depth < 1 || info_ptr->bit_depth > 16) + png_error(png_ptr, "Invalid bit depth"); *color_type = info_ptr->color_type; + if (info_ptr->color_type > 6) + png_error(png_ptr, "Invalid color type"); if (compression_type != NULL) *compression_type = info_ptr->compression_type; if (filter_type != NULL) @@ -566,9 +570,13 @@ png_get_IHDR(png_structp png_ptr, png_infop info_ptr, channels++; pixel_depth = *bit_depth * channels; rowbytes_per_pixel = (pixel_depth + 7) >> 3; - if ((*width > PNG_MAX_UINT/rowbytes_per_pixel)) + if (width == 0 || *width > PNG_MAX_UINT) + png_error(png_ptr, "Invalid image width"); + if (height == 0 || *height > PNG_MAX_UINT) + png_error(png_ptr, "Invalid image height"); + if (*width > PNG_MAX_UINT/rowbytes_per_pixel - 64) { - png_warning(png_ptr, + png_error(png_ptr, "Width too large for libpng to process image data."); } return (1); @@ -827,8 +835,9 @@ png_get_compression_buffer_size(png_structp png_ptr) } +#ifndef PNG_1_0_X #ifdef PNG_ASSEMBLER_CODE_SUPPORTED -/* this function was added to libpng 1.2.0 and should exist by default*/ +/* this function was added to libpng 1.2.0 and should exist by default */ png_uint_32 PNGAPI png_get_asm_flags (png_structp png_ptr) { @@ -915,3 +924,4 @@ png_get_mmx_rowbytes_threshold (png_structp png_ptr) return (png_uint_32)(png_ptr? png_ptr->mmx_rowbytes_threshold : 0L); } #endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ +#endif /* PNG_1_0_X */ diff --git a/pngmem.c b/pngmem.c index b1741a407..feb8a5dfc 100644 --- a/pngmem.c +++ b/pngmem.c @@ -1,9 +1,9 @@ /* pngmem.c - stub functions for memory allocation * - * libpng 1.2.1 - December 12, 2001 + * libpng 1.2.4 - July 8, 2002 * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2001 Glenn Randers-Pehrson + * Copyright (c) 1998-2002 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -43,7 +43,7 @@ png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr) else if (type == PNG_STRUCT_PNG) size = sizeof(png_struct); else - return (NULL); + return (png_get_copyright()); #ifdef PNG_USER_MEM_SUPPORTED if(malloc_fn != NULL) @@ -110,12 +110,12 @@ png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn, * result, we would be truncating potentially larger memory requests * (which should cause a fatal error) and introducing major problems. */ + png_voidp PNGAPI png_malloc(png_structp png_ptr, png_uint_32 size) { -#ifndef PNG_USER_MEM_SUPPORTED png_voidp ret; -#endif + if (png_ptr == NULL || size == 0) return (NULL); @@ -123,7 +123,7 @@ png_malloc(png_structp png_ptr, png_uint_32 size) if(png_ptr->malloc_fn != NULL) { ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size)); - if (ret == NULL) + if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) png_error(png_ptr, "Out of memory!"); return (ret); } @@ -177,12 +177,22 @@ png_malloc_default(png_structp png_ptr, png_uint_32 size) if (table == NULL) { - png_error(png_ptr, "Out Of Memory."); /* Note "O" and "M" */ + if (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) + png_error(png_ptr, "Out Of Memory."); /* Note "O" and "M" */ + else + png_warning(png_ptr, "Out Of Memory."); + return (NULL); } if ((png_size_t)table & 0xfff0) { - png_error(png_ptr, "Farmalloc didn't return normalized pointer"); + if (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) + png_error(png_ptr, + "Farmalloc didn't return normalized pointer"); + else + png_warning(png_ptr, + "Farmalloc didn't return normalized pointer"); + return (NULL); } png_ptr->offset_table = table; @@ -191,7 +201,11 @@ png_malloc_default(png_structp png_ptr, png_uint_32 size) if (png_ptr->offset_table_ptr == NULL) { - png_error(png_ptr, "Out Of memory."); + if (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) + png_error(png_ptr, "Out Of memory."); /* Note "O" and "M" */ + else + png_warning(png_ptr, "Out Of memory."); + return (NULL); } hptr = (png_byte huge *)table; @@ -213,7 +227,13 @@ png_malloc_default(png_structp png_ptr, png_uint_32 size) } if (png_ptr->offset_table_count >= png_ptr->offset_table_number) - png_error(png_ptr, "Out of Memory."); + { + if (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) + png_error(png_ptr, "Out of Memory."); /* Note "o" and "M" */ + else + png_warning(png_ptr, "Out of Memory."); + return (NULL); + } ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++]; } @@ -222,7 +242,10 @@ png_malloc_default(png_structp png_ptr, png_uint_32 size) if (ret == NULL) { - png_error(png_ptr, "Out of memory."); /* Note "o" and "m" */ + if (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) + png_error(png_ptr, "Out of memory."); /* Note "o" and "m" */ + else + png_warning(png_ptr, "Out of memory."); /* Note "o" and "m" */ } return (ret); @@ -283,7 +306,7 @@ png_free_default(png_structp png_ptr, png_voidp ptr) /* Allocate memory for a png_struct or a png_info. The malloc and memset can be replaced by a single call to calloc() if this is thought - to improve performance noticably.*/ + to improve performance noticably. */ png_voidp /* PRIVATE */ png_create_struct(int type) { @@ -293,7 +316,7 @@ png_create_struct(int type) /* Allocate memory for a png_struct or a png_info. The malloc and memset can be replaced by a single call to calloc() if this is thought - to improve performance noticably.*/ + to improve performance noticably. */ png_voidp /* PRIVATE */ png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr) { @@ -376,7 +399,6 @@ png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn, } } - /* Allocate memory. For reasonable files, size should never exceed 64K. However, zlib may allocate more then 64K if you don't tell it not to. See zconf.h and png.h for more information. zlib does @@ -387,21 +409,23 @@ png_voidp PNGAPI png_malloc(png_structp png_ptr, png_uint_32 size) { png_voidp ret; + if (png_ptr == NULL || size == 0) return (NULL); #ifdef PNG_USER_MEM_SUPPORTED if(png_ptr->malloc_fn != NULL) { - ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, size)); - if (ret == NULL) + ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size)); + if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) png_error(png_ptr, "Out of Memory!"); return (ret); } else return (png_malloc_default(png_ptr, size)); } -png_voidp /* PRIVATE */ + +png_voidp PNGAPI png_malloc_default(png_structp png_ptr, png_uint_32 size) { png_voidp ret; @@ -409,7 +433,12 @@ png_malloc_default(png_structp png_ptr, png_uint_32 size) #ifdef PNG_MAX_MALLOC_64K if (size > (png_uint_32)65536L) - png_error(png_ptr, "Cannot Allocate > 64K"); + { + if(png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) + png_error(png_ptr, "Cannot Allocate > 64K"); + else + return NULL; + } #endif #if defined(__TURBOC__) && !defined(__FLAT__) @@ -422,7 +451,7 @@ png_malloc_default(png_structp png_ptr, png_uint_32 size) # endif #endif - if (ret == NULL) + if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) png_error(png_ptr, "Out of Memory"); return (ret); @@ -444,7 +473,7 @@ png_free(png_structp png_ptr, png_voidp ptr) } else png_free_default(png_ptr, ptr); } -void /* PRIVATE */ +void PNGAPI png_free_default(png_structp png_ptr, png_voidp ptr) { if (png_ptr == NULL || ptr == NULL) @@ -465,7 +494,27 @@ png_free_default(png_structp png_ptr, png_voidp ptr) #endif /* Not Borland DOS special memory handler */ -png_voidp /* PRIVATE */ +#if defined(PNG_1_0_X) +# define png_malloc_warn png_malloc +#else +/* This function was added at libpng version 1.2.3. The png_malloc_warn() + * function will issue a png_warning and return NULL instead of issuing a + * png_error, if it fails to allocate the requested memory. + */ +png_voidp PNGAPI +png_malloc_warn(png_structp png_ptr, png_uint_32 size) +{ + png_voidp ptr; + png_uint_32 save_flags=png_ptr->flags; + + png_ptr->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK; + ptr = (png_voidp)png_malloc((png_structp)png_ptr, size); + png_ptr->flags=save_flags; + return(ptr); +} +#endif + +png_voidp PNGAPI png_memcpy_check (png_structp png_ptr, png_voidp s1, png_voidp s2, png_uint_32 length) { @@ -478,7 +527,7 @@ png_memcpy_check (png_structp png_ptr, png_voidp s1, png_voidp s2, return(png_memcpy (s1, s2, size)); } -png_voidp /* PRIVATE */ +png_voidp PNGAPI png_memset_check (png_structp png_ptr, png_voidp s1, int value, png_uint_32 length) { diff --git a/pngpread.c b/pngpread.c index 9207cbd4e..9a5b54dfb 100644 --- a/pngpread.c +++ b/pngpread.c @@ -1,9 +1,9 @@ /* pngpread.c - read a png file in push mode * - * libpng 1.2.1 - December 12, 2001 + * libpng 1.2.4 - July 8, 2002 * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2001 Glenn Randers-Pehrson + * Copyright (c) 1998-2002 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) */ @@ -221,7 +221,6 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } - png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length); } else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) @@ -231,7 +230,6 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } - png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length); } else if (!png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4)) @@ -240,6 +238,12 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) * header chunks, and we can start reading the image (or if this * is called after the image has been read - we have an error). */ + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before IDAT"); + else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && + !(png_ptr->mode & PNG_HAVE_PLTE)) + png_error(png_ptr, "Missing PLTE before IDAT"); + if (png_ptr->mode & PNG_HAVE_IDAT) { if (png_ptr->push_length == 0) @@ -264,8 +268,8 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } - png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length); + png_ptr->process_mode = PNG_READ_DONE_MODE; png_push_have_end(png_ptr, info_ptr); } @@ -277,7 +281,6 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } - png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length); } #endif @@ -289,7 +292,6 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } - png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length); } #endif @@ -301,7 +303,6 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } - png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length); } #endif @@ -313,7 +314,6 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } - png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length); } #endif @@ -325,7 +325,6 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } - png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length); } #endif @@ -337,7 +336,6 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } - png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length); } #endif @@ -349,7 +347,6 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } - png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length); } #endif @@ -361,7 +358,6 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } - png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length); } #endif @@ -373,7 +369,6 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } - png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length); } #endif @@ -385,7 +380,6 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } - png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length); } #endif @@ -397,7 +391,6 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } - png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length); } #endif @@ -409,7 +402,6 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } - png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length); } #endif @@ -421,7 +413,6 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } - png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length); } #endif @@ -433,30 +424,49 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } - png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length); } #endif #if defined(PNG_READ_tEXt_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4)) { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length); } #endif #if defined(PNG_READ_zTXt_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4)) { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length); } #endif #if defined(PNG_READ_iTXt_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4)) { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length); } #endif else { + if (png_ptr->push_length + 4 > png_ptr->buffer_size) + { + png_push_save_buffer(png_ptr); + return; + } png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length); } @@ -518,7 +528,7 @@ png_push_crc_finish(png_structp png_ptr) } } -void /* PRIVATE */ +void PNGAPI png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length) { png_bytep ptr; @@ -736,6 +746,13 @@ png_process_IDAT_data(png_structp png_ptr, png_bytep buffer, } if (!(png_ptr->zstream.avail_out)) { + if (( +#if defined(PNG_READ_INTERLACING_SUPPORTED) + png_ptr->interlaced && png_ptr->pass > 6) || + (!png_ptr->interlaced && +#endif + png_ptr->row_number == png_ptr->num_rows-1)) + png_error(png_ptr, "Too much data in IDAT chunks"); png_push_process_row(png_ptr); png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes; png_ptr->zstream.next_out = png_ptr->row_buf; @@ -796,13 +813,13 @@ png_push_process_row(png_structp png_ptr) png_read_push_finish_row(png_ptr); } } - if (png_ptr->pass == 4 && png_ptr->height <= 4) - { - for (i = 0; i < 2 && png_ptr->pass == 4; i++) - { - png_push_have_row(png_ptr, png_bytep_NULL); - png_read_push_finish_row(png_ptr); - } + if (png_ptr->pass == 4 && png_ptr->height <= 4) + { + for (i = 0; i < 2 && png_ptr->pass == 4; i++) + { + png_push_have_row(png_ptr, png_bytep_NULL); + png_read_push_finish_row(png_ptr); + } } if (png_ptr->pass == 6 && png_ptr->height <= 4) { @@ -1045,6 +1062,7 @@ png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr) png_textp text_ptr; png_charp text; png_charp key; + int ret; if (png_ptr->buffer_size < 4) { @@ -1060,7 +1078,6 @@ png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr) #endif key = png_ptr->current_text; - png_ptr->current_text = 0; for (text = key; *text; text++) /* empty loop */ ; @@ -1077,10 +1094,14 @@ png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr) #endif text_ptr->text = text; - png_set_text(png_ptr, info_ptr, text_ptr, 1); + ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); png_free(png_ptr, key); png_free(png_ptr, text_ptr); + png_ptr->current_text = NULL; + + if (ret) + png_warning(png_ptr, "Insufficient memory to store text chunk."); } } #endif @@ -1151,7 +1172,6 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr) png_push_crc_finish(png_ptr); key = png_ptr->current_text; - png_ptr->current_text = 0; for (text = key; *text; text++) /* empty loop */ ; @@ -1159,6 +1179,7 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr) /* zTXt can't have zero text */ if (text == key + png_ptr->current_text_size) { + png_ptr->current_text = NULL; png_free(png_ptr, key); return; } @@ -1167,6 +1188,7 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr) if (*text != PNG_TEXT_COMPRESSION_zTXt) /* check compression byte */ { + png_ptr->current_text = NULL; png_free(png_ptr, key); return; } @@ -1191,6 +1213,7 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr) { inflateReset(&png_ptr->zstream); png_ptr->zstream.avail_in = 0; + png_ptr->current_text = NULL; png_free(png_ptr, key); png_free(png_ptr, text); return; @@ -1244,11 +1267,13 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr) if (ret != Z_STREAM_END) { + png_ptr->current_text = NULL; png_free(png_ptr, key); png_free(png_ptr, text); return; } + png_ptr->current_text = NULL; png_free(png_ptr, key); key = text; text += key_size; @@ -1262,10 +1287,13 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr) #endif text_ptr->text = text; - png_set_text(png_ptr, info_ptr, text_ptr, 1); + ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); png_free(png_ptr, key); png_free(png_ptr, text_ptr); + + if (ret) + png_warning(png_ptr, "Insufficient memory to store text chunk."); } } #endif @@ -1326,6 +1354,7 @@ png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr) png_charp lang; png_charp lang_key; png_charp text; + int ret; if (png_ptr->buffer_size < 4) { @@ -1341,7 +1370,6 @@ png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr) #endif key = png_ptr->current_text; - png_ptr->current_text = 0; for (lang = key; *lang; lang++) /* empty loop */ ; @@ -1371,9 +1399,13 @@ png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr) text_ptr->text_length = 0; text_ptr->itxt_length = png_strlen(text); - png_set_text(png_ptr, info_ptr, text_ptr, 1); + ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); + + png_ptr->current_text = NULL; png_free(png_ptr, text_ptr); + if (ret) + png_warning(png_ptr, "Insufficient memory to store iTXt chunk."); } } #endif diff --git a/pngread.c b/pngread.c index c47df62b5..24ddeb5c7 100644 --- a/pngread.c +++ b/pngread.c @@ -1,9 +1,9 @@ /* pngread.c - read a PNG file * - * libpng 1.2.1 - December 12, 2001 + * libpng 1.2.4 - July 8, 2002 * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2001 Glenn Randers-Pehrson + * Copyright (c) 1998-2002 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -45,16 +45,19 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, png_debug(1, "in png_create_read_struct\n"); #ifdef PNG_USER_MEM_SUPPORTED - if ((png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG, - (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr)) == NULL) + png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG, + (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr); #else - if ((png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG)) == NULL) + png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); #endif + if (png_ptr == NULL) return (NULL); +#if !defined(PNG_1_0_X) #ifdef PNG_ASSEMBLER_CODE_SUPPORTED png_init_mmx_flags(png_ptr); /* 1.2.0 addition */ #endif +#endif /* PNG_1_0_X */ #ifdef PNG_SETJMP_SUPPORTED #ifdef USE_FAR_KEYWORD @@ -65,7 +68,12 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, { png_free(png_ptr, png_ptr->zbuf); png_ptr->zbuf=NULL; - png_destroy_struct(png_ptr); +#ifdef PNG_USER_MEM_SUPPORTED + png_destroy_struct_2((png_voidp)png_ptr, + (png_free_ptr)free_fn, (png_voidp)mem_ptr); +#else + png_destroy_struct((png_voidp)png_ptr); +#endif return (NULL); } #ifdef USE_FAR_KEYWORD @@ -139,6 +147,19 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL); +#ifdef PNG_SETJMP_SUPPORTED +/* Applications that neglect to set up their own setjmp() and then encounter + a png_error() will longjmp here. Since the jmpbuf is then meaningless we + abort instead of returning. */ +#ifdef USE_FAR_KEYWORD + if (setjmp(jmpbuf)) + PNG_ABORT(); + png_memcpy(png_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf)); +#else + if (setjmp(png_ptr->jmpbuf)) + PNG_ABORT(); +#endif +#endif return (png_ptr); } @@ -153,7 +174,6 @@ png_read_init(png_structp png_ptr) png_read_init_2(png_ptr, "1.0.6 or earlier", 0, 0); } -#undef png_read_init_2 void PNGAPI png_read_init_2(png_structp png_ptr, png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t png_info_size) @@ -280,7 +300,6 @@ void PNGAPI png_read_info(png_structp png_ptr, png_infop info_ptr) { png_debug(1, "in png_read_info\n"); - /* save jump buffer and error functions */ /* If we haven't checked all of the PNG signature bytes, do so now. */ if (png_ptr->sig_bytes < 8) { @@ -373,6 +392,9 @@ png_read_info(png_structp png_ptr, png_infop info_ptr) png_debug2(0, "Reading %s chunk, length=%lu.\n", png_ptr->chunk_name, length); + if (length > PNG_MAX_UINT) + png_error(png_ptr, "Invalid chunk length."); + /* This should be a binary subdivision search or a hash for * matching the chunk name rather than a linear search. */ @@ -491,7 +513,6 @@ void PNGAPI png_read_update_info(png_structp png_ptr, png_infop info_ptr) { png_debug(1, "in png_read_update_info\n"); - /* save jump buffer and error functions */ if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) png_read_start_row(png_ptr); else @@ -509,7 +530,6 @@ void PNGAPI png_start_read_image(png_structp png_ptr) { png_debug(1, "in png_start_read_image\n"); - /* save jump buffer and error functions */ if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) png_read_start_row(png_ptr); } @@ -525,7 +545,6 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) int ret; png_debug2(1, "in png_read_row (row %lu, pass %d)\n", png_ptr->row_number, png_ptr->pass); - /* save jump buffer and error functions */ if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) png_read_start_row(png_ptr); if (png_ptr->row_number == 0 && png_ptr->pass == 0) @@ -656,6 +675,9 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) png_read_data(png_ptr, chunk_length, 4); png_ptr->idat_size = png_get_uint_32(chunk_length); + if (png_ptr->idat_size > PNG_MAX_UINT) + png_error(png_ptr, "Invalid chunk length."); + png_reset_crc(png_ptr); png_crc_read(png_ptr, png_ptr->chunk_name, 4); if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) @@ -767,7 +789,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) * not called png_set_interlace_handling(), the display_row buffer will * be ignored, so pass NULL to it. * - * [*] png_handle_alpha() does not exist yet, as of libpng version 1.2.1 + * [*] png_handle_alpha() does not exist yet, as of libpng version 1.2.4 */ void PNGAPI @@ -779,7 +801,6 @@ png_read_rows(png_structp png_ptr, png_bytepp row, png_bytepp dp; png_debug(1, "in png_read_rows\n"); - /* save jump buffer and error functions */ rp = row; dp = display_row; if (rp != NULL && dp != NULL) @@ -816,7 +837,7 @@ png_read_rows(png_structp png_ptr, png_bytepp row, * only call this function once. If you desire to have an image for * each pass of a interlaced image, use png_read_rows() instead. * - * [*] png_handle_alpha() does not exist yet, as of libpng version 1.2.1 + * [*] png_handle_alpha() does not exist yet, as of libpng version 1.2.4 */ void PNGAPI png_read_image(png_structp png_ptr, png_bytepp image) @@ -826,7 +847,6 @@ png_read_image(png_structp png_ptr, png_bytepp image) png_bytepp rp; png_debug(1, "in png_read_image\n"); - /* save jump buffer and error functions */ #ifdef PNG_READ_INTERLACING_SUPPORTED pass = png_set_interlace_handling(png_ptr); @@ -863,7 +883,6 @@ png_read_end(png_structp png_ptr, png_infop info_ptr) png_uint_32 length; png_debug(1, "in png_read_end\n"); - /* save jump buffer and error functions */ png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */ do @@ -934,6 +953,9 @@ png_read_end(png_structp png_ptr, png_infop info_ptr) png_debug1(0, "Reading %s chunk.\n", png_ptr->chunk_name); + if (length > PNG_MAX_UINT) + png_error(png_ptr, "Invalid chunk length."); + if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4)) png_handle_IHDR(png_ptr, info_ptr, length); else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4)) @@ -1050,7 +1072,6 @@ png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr, #endif png_debug(1, "in png_destroy_read_struct\n"); - /* save jump buffer and error functions */ if (png_ptr_ptr != NULL) png_ptr = *png_ptr_ptr; @@ -1123,7 +1144,6 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr #endif png_debug(1, "in png_read_destroy\n"); - /* save jump buffer and error functions */ if (info_ptr != NULL) png_info_destroy(png_ptr, info_ptr); @@ -1219,6 +1239,12 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr png_free(png_ptr, png_ptr->save_buffer); #endif +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED +#ifdef PNG_TEXT_SUPPORTED + png_free(png_ptr, png_ptr->current_text); +#endif /* PNG_TEXT_SUPPORTED */ +#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ + /* Save the important info out of the png_struct, in case it is * being used again. */ diff --git a/pngrio.c b/pngrio.c index 79755b492..bb4197d2b 100644 --- a/pngrio.c +++ b/pngrio.c @@ -1,9 +1,9 @@ /* pngrio.c - functions for data input * - * libpng 1.2.1 - December 12, 2001 + * libpng 1.2.4 - July 8, 2002 * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2001 Glenn Randers-Pehrson + * Copyright (c) 1998-2002 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -39,7 +39,7 @@ png_read_data(png_structp png_ptr, png_bytep data, png_size_t length) read_data function and use it at run time with png_set_read_fn(), rather than changing the library. */ #ifndef USE_FAR_KEYWORD -static void /* PRIVATE */ +void PNGAPI png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length) { png_size_t check; diff --git a/pngrtran.c b/pngrtran.c index 2d62779cf..f8142ebfc 100644 --- a/pngrtran.c +++ b/pngrtran.c @@ -1,9 +1,9 @@ /* pngrtran.c - transforms the data in a row for PNG readers * - * libpng 1.2.1 - December 12, 2001 + * libpng 1.2.4 - July 8, 2002 * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2001 Glenn Randers-Pehrson + * Copyright (c) 1998-2002 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -167,15 +167,14 @@ png_set_dither(png_structp png_ptr, png_colorp palette, Perhaps not the best solution, but good enough. */ int i; - png_bytep sort; /* initialize an array to sort colors */ - sort = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_palette - * sizeof (png_byte))); + png_ptr->dither_sort = (png_bytep)png_malloc(png_ptr, + (png_uint_32)(num_palette * sizeof (png_byte))); - /* initialize the sort array */ + /* initialize the dither_sort array */ for (i = 0; i < num_palette; i++) - sort[i] = (png_byte)i; + png_ptr->dither_sort[i] = (png_byte)i; /* Find the least used palette entries by starting a bubble sort, and running it until we have sorted @@ -191,13 +190,14 @@ png_set_dither(png_structp png_ptr, png_colorp palette, done = 1; for (j = 0; j < i; j++) { - if (histogram[sort[j]] < histogram[sort[j + 1]]) + if (histogram[png_ptr->dither_sort[j]] + < histogram[png_ptr->dither_sort[j + 1]]) { png_byte t; - t = sort[j]; - sort[j] = sort[j + 1]; - sort[j + 1] = t; + t = png_ptr->dither_sort[j]; + png_ptr->dither_sort[j] = png_ptr->dither_sort[j + 1]; + png_ptr->dither_sort[j + 1] = t; done = 0; } } @@ -214,11 +214,11 @@ png_set_dither(png_structp png_ptr, png_colorp palette, move the others */ for (i = 0; i < maximum_colors; i++) { - if ((int)sort[i] >= maximum_colors) + if ((int)png_ptr->dither_sort[i] >= maximum_colors) { do j--; - while ((int)sort[j] >= maximum_colors); + while ((int)png_ptr->dither_sort[j] >= maximum_colors); palette[i] = palette[j]; } } @@ -232,13 +232,13 @@ png_set_dither(png_structp png_ptr, png_colorp palette, for (i = 0; i < maximum_colors; i++) { /* only move the colors we need to */ - if ((int)sort[i] >= maximum_colors) + if ((int)png_ptr->dither_sort[i] >= maximum_colors) { png_color tmp_color; do j--; - while ((int)sort[j] >= maximum_colors); + while ((int)png_ptr->dither_sort[j] >= maximum_colors); tmp_color = palette[j]; palette[j] = palette[i]; @@ -276,7 +276,8 @@ png_set_dither(png_structp png_ptr, png_colorp palette, } } } - png_free(png_ptr, sort); + png_free(png_ptr, png_ptr->dither_sort); + png_ptr->dither_sort=NULL; } else { @@ -291,23 +292,22 @@ png_set_dither(png_structp png_ptr, png_colorp palette, int i; int max_d; int num_new_palette; + png_dsortp t; png_dsortpp hash; - png_bytep index_to_palette; - /* where the original index currently is in the palette */ - png_bytep palette_to_index; - /* which original index points to this palette color */ + + t=NULL; /* initialize palette index arrays */ - index_to_palette = (png_bytep)png_malloc(png_ptr, + png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_palette * sizeof (png_byte))); - palette_to_index = (png_bytep)png_malloc(png_ptr, + png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_palette * sizeof (png_byte))); /* initialize the sort array */ for (i = 0; i < num_palette; i++) { - index_to_palette[i] = (png_byte)i; - palette_to_index[i] = (png_byte)i; + png_ptr->index_to_palette[i] = (png_byte)i; + png_ptr->palette_to_index[i] = (png_byte)i; } hash = (png_dsortpp)png_malloc(png_ptr, (png_uint_32)(769 * @@ -342,18 +342,22 @@ png_set_dither(png_structp png_ptr, png_colorp palette, if (d <= max_d) { - png_dsortp t; - t = (png_dsortp)png_malloc(png_ptr, (png_uint_32)(sizeof - (png_dsort))); + t = (png_dsortp)png_malloc_warn(png_ptr, + (png_uint_32)(sizeof(png_dsort))); + if (t == NULL) + break; t->next = hash[d]; t->left = (png_byte)i; t->right = (png_byte)j; hash[d] = t; } } + if (t == NULL) + break; } + if (t != NULL) for (i = 0; i <= max_d; i++) { if (hash[i] != NULL) @@ -362,8 +366,10 @@ png_set_dither(png_structp png_ptr, png_colorp palette, for (p = hash[i]; p; p = p->next) { - if ((int)index_to_palette[p->left] < num_new_palette && - (int)index_to_palette[p->right] < num_new_palette) + if ((int)png_ptr->index_to_palette[p->left] + < num_new_palette && + (int)png_ptr->index_to_palette[p->right] + < num_new_palette) { int j, next_j; @@ -379,7 +385,8 @@ png_set_dither(png_structp png_ptr, png_colorp palette, } num_new_palette--; - palette[index_to_palette[j]] = palette[num_new_palette]; + palette[png_ptr->index_to_palette[j]] + = palette[num_new_palette]; if (!full_dither) { int k; @@ -387,23 +394,23 @@ png_set_dither(png_structp png_ptr, png_colorp palette, for (k = 0; k < num_palette; k++) { if (png_ptr->dither_index[k] == - index_to_palette[j]) + png_ptr->index_to_palette[j]) png_ptr->dither_index[k] = - index_to_palette[next_j]; + png_ptr->index_to_palette[next_j]; if ((int)png_ptr->dither_index[k] == num_new_palette) png_ptr->dither_index[k] = - index_to_palette[j]; + png_ptr->index_to_palette[j]; } } - index_to_palette[palette_to_index[num_new_palette]] = - index_to_palette[j]; - palette_to_index[index_to_palette[j]] = - palette_to_index[num_new_palette]; + png_ptr->index_to_palette[png_ptr->palette_to_index + [num_new_palette]] = png_ptr->index_to_palette[j]; + png_ptr->palette_to_index[png_ptr->index_to_palette[j]] + = png_ptr->palette_to_index[num_new_palette]; - index_to_palette[j] = (png_byte)num_new_palette; - palette_to_index[num_new_palette] = (png_byte)j; + png_ptr->index_to_palette[j] = (png_byte)num_new_palette; + png_ptr->palette_to_index[num_new_palette] = (png_byte)j; } if (num_new_palette <= maximum_colors) break; @@ -420,8 +427,6 @@ png_set_dither(png_structp png_ptr, png_colorp palette, png_dsortp p = hash[i]; while (p) { - png_dsortp t; - t = p->next; png_free(png_ptr, p); p = t; @@ -432,8 +437,10 @@ png_set_dither(png_structp png_ptr, png_colorp palette, max_d += 96; } png_free(png_ptr, hash); - png_free(png_ptr, palette_to_index); - png_free(png_ptr, index_to_palette); + png_free(png_ptr, png_ptr->palette_to_index); + png_free(png_ptr, png_ptr->index_to_palette); + png_ptr->palette_to_index=NULL; + png_ptr->index_to_palette=NULL; } num_palette = maximum_colors; } @@ -510,13 +517,19 @@ png_set_dither(png_structp png_ptr, png_colorp palette, * only do transformations on images where the file_gamma and screen_gamma * are not close reciprocals, otherwise it slows things down slightly, and * also needlessly introduces small errors. + * + * We will turn off gamma transformation later if no semitransparent entries + * are present in the tRNS array for palette images. We can't do it here + * because we don't necessarily have the tRNS chunk yet. */ void PNGAPI png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma) { png_debug(1, "in png_set_gamma\n"); - if (fabs(scrn_gamma * file_gamma - 1.0) > PNG_GAMMA_THRESHOLD) - png_ptr->transformations |= PNG_GAMMA; + if ((fabs(scrn_gamma * file_gamma - 1.0) > PNG_GAMMA_THRESHOLD) || + (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) || + (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) + png_ptr->transformations |= PNG_GAMMA; png_ptr->gamma = (float)file_gamma; png_ptr->screen_gamma = (float)scrn_gamma; } @@ -692,23 +705,23 @@ png_init_read_transformations(png_structp png_ptr) { case 1: png_ptr->background.gray *= (png_uint_16)0xff; - png_ptr->background.red = png_ptr->background.green = - png_ptr->background.blue = png_ptr->background.gray; + png_ptr->background.red = png_ptr->background.green + = png_ptr->background.blue = png_ptr->background.gray; break; case 2: png_ptr->background.gray *= (png_uint_16)0x55; - png_ptr->background.red = png_ptr->background.green = - png_ptr->background.blue = png_ptr->background.gray; + png_ptr->background.red = png_ptr->background.green + = png_ptr->background.blue = png_ptr->background.gray; break; case 4: png_ptr->background.gray *= (png_uint_16)0x11; - png_ptr->background.red = png_ptr->background.green = - png_ptr->background.blue = png_ptr->background.gray; + png_ptr->background.red = png_ptr->background.green + = png_ptr->background.blue = png_ptr->background.gray; break; case 8: case 16: - png_ptr->background.red = png_ptr->background.green = - png_ptr->background.blue = png_ptr->background.gray; + png_ptr->background.red = png_ptr->background.green + = png_ptr->background.blue = png_ptr->background.gray; break; } } @@ -746,6 +759,22 @@ png_init_read_transformations(png_structp png_ptr) png_ptr->background_1 = png_ptr->background; #endif #if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED) + + if ((color_type == PNG_COLOR_TYPE_PALETTE && png_ptr->num_trans != 0) + && (fabs(png_ptr->screen_gamma * png_ptr->gamma - 1.0) + < PNG_GAMMA_THRESHOLD)) + { + int i,k; + k=0; + for (i=0; inum_trans; i++) + { + if (png_ptr->trans[i] != 0 && png_ptr->trans[i] != 0xff) + k=1; /* partial transparency is present */ + } + if (k == 0) + png_ptr->transformations &= (~PNG_GAMMA); + } + if (png_ptr->transformations & (PNG_GAMMA | PNG_RGB_TO_GRAY)) { png_build_gamma_table(png_ptr); @@ -754,6 +783,8 @@ png_init_read_transformations(png_structp png_ptr) { if (color_type == PNG_COLOR_TYPE_PALETTE) { + /* could skip if no transparency and + */ png_color back, back_1; png_colorp palette = png_ptr->palette; int num_palette = png_ptr->num_palette; @@ -848,7 +879,7 @@ png_init_read_transformations(png_structp png_ptr) } } } - /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN)*/ + /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */ else /* color_type != PNG_COLOR_TYPE_PALETTE */ { @@ -873,9 +904,16 @@ png_init_read_transformations(png_structp png_ptr) break; } - if (color_type & PNG_COLOR_MASK_COLOR) + png_ptr->background_1.gray = (png_uint_16)(pow( + (double)png_ptr->background.gray / m, g) * m + .5); + png_ptr->background.gray = (png_uint_16)(pow( + (double)png_ptr->background.gray / m, gs) * m + .5); + + if ((png_ptr->background.red != png_ptr->background.green) || + (png_ptr->background.red != png_ptr->background.blue) || + (png_ptr->background.red != png_ptr->background.gray)) { - /* RGB or RGBA */ + /* RGB or RGBA with color background */ png_ptr->background_1.red = (png_uint_16)(pow( (double)png_ptr->background.red / m, g) * m + .5); png_ptr->background_1.green = (png_uint_16)(pow( @@ -891,11 +929,11 @@ png_init_read_transformations(png_structp png_ptr) } else { - /* GRAY or GRAY ALPHA */ - png_ptr->background_1.gray = (png_uint_16)(pow( - (double)png_ptr->background.gray / m, g) * m + .5); - png_ptr->background.gray = (png_uint_16)(pow( - (double)png_ptr->background.gray / m, gs) * m + .5); + /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */ + png_ptr->background_1.red = png_ptr->background_1.green + = png_ptr->background_1.blue = png_ptr->background_1.gray; + png_ptr->background.red = png_ptr->background.green + = png_ptr->background.blue = png_ptr->background.gray; } } } @@ -2315,7 +2353,7 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) * paletted. Most useful for gamma correction and simplification * of code. */ -void /* PRIVATE */ +void PNGAPI png_build_grayscale_palette(int bit_depth, png_colorp palette) { int num_palette; @@ -3150,17 +3188,17 @@ png_do_background(png_row_infop row_info, png_bytep row, png_uint_16 v, w, x; v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; - png_composite_16(w, v, a, background->red); + png_composite_16(w, v, a, background_1->red); x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8]; *dp = (png_byte)((x >> 8) & 0xff); *(dp + 1) = (png_byte)(x & 0xff); v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)]; - png_composite_16(w, v, a, background->green); + png_composite_16(w, v, a, background_1->green); x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8]; *(dp + 2) = (png_byte)((x >> 8) & 0xff); *(dp + 3) = (png_byte)(x & 0xff); v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)]; - png_composite_16(w, v, a, background->blue); + png_composite_16(w, v, a, background_1->blue); x = gamma_16_from_1[(w & 0xff) >> gamma_shift][w >> 8]; *(dp + 4) = (png_byte)((x >> 8) & 0xff); *(dp + 5) = (png_byte)(x & 0xff); diff --git a/pngrutil.c b/pngrutil.c index dca7c655d..974006311 100644 --- a/pngrutil.c +++ b/pngrutil.c @@ -1,9 +1,9 @@ /* pngrutil.c - utilities to read a PNG file * - * libpng 1.2.1 - December 12, 2001 + * libpng 1.2.4 - July 8, 2002 * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2001 Glenn Randers-Pehrson + * Copyright (c) 1998-2002 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -200,7 +200,12 @@ png_decompress_chunk(png_structp png_ptr, int comp_type, if (text == NULL) { text_size = prefix_size + sizeof(msg) + 1; - text = (png_charp)png_malloc(png_ptr, text_size); + text = (png_charp)png_malloc_warn(png_ptr, text_size); + if (text == NULL) + { + png_free(png_ptr,chunkdata); + png_error(png_ptr,"Not enough memory to decompress chunk"); + } png_memcpy(text, chunkdata, prefix_size); } @@ -218,7 +223,12 @@ png_decompress_chunk(png_structp png_ptr, int comp_type, { text_size = prefix_size + png_ptr->zbuf_size - png_ptr->zstream.avail_out; - text = (png_charp)png_malloc(png_ptr, text_size + 1); + text = (png_charp)png_malloc_warn(png_ptr, text_size + 1); + if (text == NULL) + { + png_free(png_ptr,chunkdata); + png_error(png_ptr,"Not enough memory to decompress chunk."); + } png_memcpy(text + prefix_size, png_ptr->zbuf, text_size - prefix_size); png_memcpy(text, chunkdata, prefix_size); @@ -229,8 +239,15 @@ png_decompress_chunk(png_structp png_ptr, int comp_type, png_charp tmp; tmp = text; - text = (png_charp)png_malloc(png_ptr, (png_uint_32)(text_size + + text = (png_charp)png_malloc_warn(png_ptr, + (png_uint_32)(text_size + png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1)); + if (text == NULL) + { + png_free(png_ptr, tmp); + png_free(png_ptr, chunkdata); + png_error(png_ptr,"Not enough memory to decompress chunk.."); + } png_memcpy(text, tmp, text_size); png_free(png_ptr, tmp); png_memcpy(text + text_size, png_ptr->zbuf, @@ -269,7 +286,12 @@ png_decompress_chunk(png_structp png_ptr, int comp_type, text_size=prefix_size; if (text == NULL) { - text = (png_charp)png_malloc(png_ptr, text_size+1); + text = (png_charp)png_malloc_warn(png_ptr, text_size+1); + if (text == NULL) + { + png_free(png_ptr, chunkdata); + png_error(png_ptr,"Not enough memory for text."); + } png_memcpy(text, chunkdata, prefix_size); } *(text + text_size) = 0x00; @@ -691,6 +713,8 @@ png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green, int_y_green, int_x_blue, int_y_blue; + png_uint_32 uint_x, uint_y; + png_debug(1, "in png_handle_cHRM\n"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) @@ -724,60 +748,69 @@ png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } png_crc_read(png_ptr, buf, 4); - int_x_white = (png_fixed_point)png_get_uint_32(buf); + uint_x = png_get_uint_32(buf); png_crc_read(png_ptr, buf, 4); - int_y_white = (png_fixed_point)png_get_uint_32(buf); + uint_y = png_get_uint_32(buf); - if (int_x_white > 80000L || int_y_white > 80000L || - int_x_white + int_y_white > 100000L) + if (uint_x > 80000L || uint_y > 80000L || + uint_x + uint_y > 100000L) { png_warning(png_ptr, "Invalid cHRM white point"); png_crc_finish(png_ptr, 24); return; } + int_x_white = (png_fixed_point)uint_x; + int_y_white = (png_fixed_point)uint_y; png_crc_read(png_ptr, buf, 4); - int_x_red = (png_fixed_point)png_get_uint_32(buf); + uint_x = png_get_uint_32(buf); png_crc_read(png_ptr, buf, 4); - int_y_red = (png_fixed_point)png_get_uint_32(buf); + uint_y = png_get_uint_32(buf); - if (int_x_red > 80000L || int_y_red > 80000L || - int_x_red + int_y_red > 100000L) + if (uint_x > 80000L || uint_y > 80000L || + uint_x + uint_y > 100000L) { png_warning(png_ptr, "Invalid cHRM red point"); png_crc_finish(png_ptr, 16); return; } + int_x_red = (png_fixed_point)uint_x; + int_y_red = (png_fixed_point)uint_y; png_crc_read(png_ptr, buf, 4); - int_x_green = (png_fixed_point)png_get_uint_32(buf); + uint_x = png_get_uint_32(buf); png_crc_read(png_ptr, buf, 4); - int_y_green = (png_fixed_point)png_get_uint_32(buf); + uint_y = png_get_uint_32(buf); - if (int_x_green > 80000L || int_y_green > 80000L || - int_x_green + int_y_green > 100000L) + if (uint_x > 80000L || uint_y > 80000L || + uint_x + uint_y > 100000L) { png_warning(png_ptr, "Invalid cHRM green point"); png_crc_finish(png_ptr, 8); return; } + int_x_green = (png_fixed_point)uint_x; + int_y_green = (png_fixed_point)uint_y; png_crc_read(png_ptr, buf, 4); - int_x_blue = (png_fixed_point)png_get_uint_32(buf); + uint_x = png_get_uint_32(buf); png_crc_read(png_ptr, buf, 4); - int_y_blue = (png_fixed_point)png_get_uint_32(buf); + uint_y = png_get_uint_32(buf); - if (int_x_blue > 80000L || int_y_blue > 80000L || - int_x_blue + int_y_blue > 100000L) + if (uint_x > 80000L || uint_y > 80000L || + uint_x + uint_y > 100000L) { png_warning(png_ptr, "Invalid cHRM blue point"); png_crc_finish(png_ptr, 0); return; } + int_x_blue = (png_fixed_point)uint_x; + int_y_blue = (png_fixed_point)uint_y; + #ifdef PNG_FLOATING_POINT_SUPPORTED white_x = (float)int_x_white / (float)100000.0; white_y = (float)int_y_white / (float)100000.0; @@ -894,17 +927,6 @@ png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) # ifdef PNG_FLOATING_POINT_SUPPORTED igamma=(int)(info_ptr->gamma * 100000.); # endif -#endif -#if 0 && defined(PNG_cHRM_SUPPORTED) && !defined(PNG_FIXED_POINT_SUPPORTED) -/* We need to define these here because they aren't in png.h */ - png_fixed_point int_x_white; - png_fixed_point int_y_white; - png_fixed_point int_x_red; - png_fixed_point int_y_red; - png_fixed_point int_x_green; - png_fixed_point int_y_green; - png_fixed_point int_x_blue; - png_fixed_point int_y_blue; #endif if(igamma < 45000L || igamma > 46000L) { @@ -952,6 +974,7 @@ png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { png_charp chunkdata; png_byte compression_type; + png_bytep pC; png_charp profile; png_uint_32 skip = 0; png_uint_32 profile_size = 0; @@ -1037,10 +1060,11 @@ png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } /* Check the profile_size recorded in the first 32 bits of the ICC profile */ - profile_size = ((*(chunkdata+prefix_length))<<24) | - ((*(chunkdata+prefix_length+1))<<16) | - ((*(chunkdata+prefix_length+2))<< 8) | - ((*(chunkdata+prefix_length+3)) ); + pC = (png_bytep)(chunkdata+prefix_length); + profile_size = ((*(pC ))<<24) | + ((*(pC+1))<<16) | + ((*(pC+2))<< 8) | + ((*(pC+3)) ); if(profile_size < profile_length) profile_length = profile_size; @@ -1191,7 +1215,7 @@ png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) void /* PRIVATE */ png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { - png_byte readbuf[PNG_MAX_PALETTE_LENGTH]; + png_byte readbuf[PNG_MAX_PALETTE_LENGTH]; png_debug(1, "in png_handle_tRNS\n"); @@ -1374,7 +1398,7 @@ void /* PRIVATE */ png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { int num, i; - png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH]; + png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH]; png_debug(1, "in png_handle_hIST\n"); @@ -1540,7 +1564,12 @@ png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)\n", length + 1); - purpose = (png_charp)png_malloc(png_ptr, length + 1); + purpose = (png_charp)png_malloc_warn(png_ptr, length + 1); + if (purpose == NULL) + { + png_warning(png_ptr, "No memory for pCAL purpose."); + return; + } slength = (png_size_t)length; png_crc_read(png_ptr, (png_bytep)purpose, slength); @@ -1595,8 +1624,14 @@ png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) /* Empty loop to move past the units string. */ ; png_debug(3, "Allocating pCAL parameters array\n"); - params = (png_charpp)png_malloc(png_ptr, (png_uint_32)(nparams + params = (png_charpp)png_malloc_warn(png_ptr, (png_uint_32)(nparams *sizeof(png_charp))) ; + if (params == NULL) + { + png_free(png_ptr, purpose); + png_warning(png_ptr, "No memory for pCAL params."); + return; + } /* Get pointers to the start of each parameter string. */ for (i = 0; i < (int)nparams; i++) @@ -1660,7 +1695,12 @@ png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)\n", length + 1); - buffer = (png_charp)png_malloc(png_ptr, length + 1); + buffer = (png_charp)png_malloc_warn(png_ptr, length + 1); + if (buffer == NULL) + { + png_warning(png_ptr, "Out of memory while processing sCAL chunk"); + return; + } slength = (png_size_t)length; png_crc_read(png_ptr, (png_bytep)buffer, slength); @@ -1683,7 +1723,12 @@ png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } #else #ifdef PNG_FIXED_POINT_SUPPORTED - swidth = (png_charp)png_malloc(png_ptr, png_strlen(ep) + 1); + swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1); + if (swidth == NULL) + { + png_warning(png_ptr, "Out of memory while processing sCAL chunk width"); + return; + } png_memcpy(swidth, ep, (png_size_t)png_strlen(ep)); #endif #endif @@ -1701,7 +1746,12 @@ png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } #else #ifdef PNG_FIXED_POINT_SUPPORTED - sheight = (png_charp)png_malloc(png_ptr, png_strlen(ep) + 1); + sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1); + if (swidth == NULL) + { + png_warning(png_ptr, "Out of memory while processing sCAL chunk height"); + return; + } png_memcpy(sheight, ep, (png_size_t)png_strlen(ep)); #endif #endif @@ -1791,6 +1841,7 @@ png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_charp text; png_uint_32 skip = 0; png_size_t slength; + int ret; png_debug(1, "in png_handle_tEXt\n"); @@ -1809,7 +1860,12 @@ png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } #endif - key = (png_charp)png_malloc(png_ptr, length + 1); + key = (png_charp)png_malloc_warn(png_ptr, length + 1); + if (key == NULL) + { + png_warning(png_ptr, "No memory to process text chunk."); + return; + } slength = (png_size_t)length; png_crc_read(png_ptr, (png_bytep)key, slength); @@ -1827,7 +1883,13 @@ png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) if (text != key + slength) text++; - text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text)); + text_ptr = (png_textp)png_malloc_warn(png_ptr, (png_uint_32)sizeof(png_text)); + if (text_ptr == NULL) + { + png_warning(png_ptr, "Not enough memory to process text chunk."); + png_free(png_ptr, key); + return; + } text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; text_ptr->key = key; #ifdef PNG_iTXt_SUPPORTED @@ -1838,10 +1900,12 @@ png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) text_ptr->text = text; text_ptr->text_length = png_strlen(text); - png_set_text(png_ptr, info_ptr, text_ptr, 1); + ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1); png_free(png_ptr, key); png_free(png_ptr, text_ptr); + if (ret) + png_warning(png_ptr, "Insufficient memory to process text chunk."); } #endif @@ -1854,6 +1918,7 @@ png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_charp chunkdata; png_charp text; int comp_type; + int ret; png_size_t slength, prefix_len, data_len; png_debug(1, "in png_handle_zTXt\n"); @@ -1874,8 +1939,13 @@ png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } #endif - chunkdata = (png_charp)png_malloc(png_ptr, length + 1); - slength = (png_size_t)length; + chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); + if (chunkdata == NULL) + { + png_warning(png_ptr,"Out of memory processing zTXt chunk."); + return; + } + slength = (png_size_t)length; png_crc_read(png_ptr, (png_bytep)chunkdata, slength); if (png_crc_finish(png_ptr, 0)) { @@ -1909,7 +1979,13 @@ png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) chunkdata = (png_charp)png_decompress_chunk(png_ptr, comp_type, chunkdata, (png_size_t)length, prefix_len, &data_len); - text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text)); + text_ptr = (png_textp)png_malloc_warn(png_ptr, (png_uint_32)sizeof(png_text)); + if (text_ptr == NULL) + { + png_warning(png_ptr,"Not enough memory to process zTXt chunk."); + png_free(png_ptr, chunkdata); + return; + } text_ptr->compression = comp_type; text_ptr->key = chunkdata; #ifdef PNG_iTXt_SUPPORTED @@ -1920,10 +1996,12 @@ png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) text_ptr->text = chunkdata + prefix_len; text_ptr->text_length = data_len; - png_set_text(png_ptr, info_ptr, text_ptr, 1); + ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1); png_free(png_ptr, text_ptr); png_free(png_ptr, chunkdata); + if (ret) + png_error(png_ptr, "Insufficient memory to store zTXt chunk."); } #endif @@ -1937,6 +2015,7 @@ png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_charp key, lang, text, lang_key; int comp_flag; int comp_type = 0; + int ret; png_size_t slength, prefix_len, data_len; png_debug(1, "in png_handle_iTXt\n"); @@ -1958,7 +2037,12 @@ png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } #endif - chunkdata = (png_charp)png_malloc(png_ptr, length + 1); + chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); + if (chunkdata == NULL) + { + png_warning(png_ptr, "No memory to process iTXt chunk."); + return; + } slength = (png_size_t)length; png_crc_read(png_ptr, (png_bytep)chunkdata, slength); if (png_crc_finish(png_ptr, 0)) @@ -2004,7 +2088,13 @@ png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) (size_t)length, prefix_len, &data_len); else data_len=png_strlen(chunkdata + prefix_len); - text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text)); + text_ptr = (png_textp)png_malloc_warn(png_ptr, (png_uint_32)sizeof(png_text)); + if (text_ptr == NULL) + { + png_warning(png_ptr,"Not enough memory to process iTXt chunk."); + png_free(png_ptr, chunkdata); + return; + } text_ptr->compression = (int)comp_flag + 1; text_ptr->lang_key = chunkdata+(lang_key-key); text_ptr->lang = chunkdata+(lang-key); @@ -2013,10 +2103,12 @@ png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) text_ptr->key = chunkdata; text_ptr->text = chunkdata + prefix_len; - png_set_text(png_ptr, info_ptr, text_ptr, 1); + ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1); png_free(png_ptr, text_ptr); png_free(png_ptr, chunkdata); + if (ret) + png_error(png_ptr, "Insufficient memory to store iTXt chunk."); } #endif @@ -2082,7 +2174,10 @@ png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) if (!(png_ptr->chunk_name[0] & 0x20)) if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != HANDLE_CHUNK_ALWAYS) + { + png_free(png_ptr, chunk.data); png_chunk_error(png_ptr, "unknown critical chunk"); + } png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1); } } diff --git a/pngset.c b/pngset.c index 7878f3708..c691f9e60 100644 --- a/pngset.c +++ b/pngset.c @@ -1,9 +1,9 @@ /* pngset.c - storage of image information into info struct * - * libpng 1.2.1 - December 12, 2001 + * libpng 1.2.4 - July 8, 2002 * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2001 Glenn Randers-Pehrson + * Copyright (c) 1998-2002 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -40,6 +40,25 @@ png_set_cHRM(png_structp png_ptr, png_infop info_ptr, if (png_ptr == NULL || info_ptr == NULL) return; + if (white_x < 0.0 || white_y < 0.0 || + red_x < 0.0 || red_y < 0.0 || + green_x < 0.0 || green_y < 0.0 || + blue_x < 0.0 || blue_y < 0.0) + { + png_warning(png_ptr, + "Ignoring attempt to set negative chromaticity value"); + return; + } + if (white_x > 21474.83 || white_y > 21474.83 || + red_x > 21474.83 || red_y > 21474.83 || + green_x > 21474.83 || green_y > 21474.83 || + blue_x > 21474.83 || blue_y > 21474.83) + { + png_warning(png_ptr, + "Ignoring attempt to set chromaticity value exceeding 21474.83"); + return; + } + info_ptr->x_white = (float)white_x; info_ptr->y_white = (float)white_y; info_ptr->x_red = (float)red_x; @@ -51,12 +70,12 @@ png_set_cHRM(png_structp png_ptr, png_infop info_ptr, #ifdef PNG_FIXED_POINT_SUPPORTED info_ptr->int_x_white = (png_fixed_point)(white_x*100000.+0.5); info_ptr->int_y_white = (png_fixed_point)(white_y*100000.+0.5); - info_ptr->int_x_red = (png_fixed_point)(red_x*100000.+0.5); - info_ptr->int_y_red = (png_fixed_point)(red_y*100000.+0.5); + info_ptr->int_x_red = (png_fixed_point)( red_x*100000.+0.5); + info_ptr->int_y_red = (png_fixed_point)( red_y*100000.+0.5); info_ptr->int_x_green = (png_fixed_point)(green_x*100000.+0.5); info_ptr->int_y_green = (png_fixed_point)(green_y*100000.+0.5); - info_ptr->int_x_blue = (png_fixed_point)(blue_x*100000.+0.5); - info_ptr->int_y_blue = (png_fixed_point)(blue_y*100000.+0.5); + info_ptr->int_x_blue = (png_fixed_point)( blue_x*100000.+0.5); + info_ptr->int_y_blue = (png_fixed_point)( blue_y*100000.+0.5); #endif info_ptr->valid |= PNG_INFO_cHRM; } @@ -72,6 +91,24 @@ png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr, if (png_ptr == NULL || info_ptr == NULL) return; + if (white_x < 0 || white_y < 0 || + red_x < 0 || red_y < 0 || + green_x < 0 || green_y < 0 || + blue_x < 0 || blue_y < 0) + { + png_warning(png_ptr, + "Ignoring attempt to set negative chromaticity value"); + return; + } + if (white_x > (double) PNG_MAX_UINT || white_y > (double) PNG_MAX_UINT || + red_x > (double) PNG_MAX_UINT || red_y > (double) PNG_MAX_UINT || + green_x > (double) PNG_MAX_UINT || green_y > (double) PNG_MAX_UINT || + blue_x > (double) PNG_MAX_UINT || blue_y > (double) PNG_MAX_UINT) + { + png_warning(png_ptr, + "Ignoring attempt to set chromaticity value exceeding 21474.83"); + return; + } info_ptr->int_x_white = white_x; info_ptr->int_y_white = white_y; info_ptr->int_x_red = red_x; @@ -83,12 +120,12 @@ png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr, #ifdef PNG_FLOATING_POINT_SUPPORTED info_ptr->x_white = (float)(white_x/100000.); info_ptr->y_white = (float)(white_y/100000.); - info_ptr->x_red = (float)(red_x/100000.); - info_ptr->y_red = (float)(red_y/100000.); + info_ptr->x_red = (float)( red_x/100000.); + info_ptr->y_red = (float)( red_y/100000.); info_ptr->x_green = (float)(green_x/100000.); info_ptr->y_green = (float)(green_y/100000.); - info_ptr->x_blue = (float)(blue_x/100000.); - info_ptr->y_blue = (float)(blue_y/100000.); + info_ptr->x_blue = (float)( blue_x/100000.); + info_ptr->y_blue = (float)( blue_y/100000.); #endif info_ptr->valid |= PNG_INFO_cHRM; } @@ -100,16 +137,25 @@ png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr, void PNGAPI png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma) { + double gamma; png_debug1(1, "in %s storage function\n", "gAMA"); if (png_ptr == NULL || info_ptr == NULL) return; - info_ptr->gamma = (float)file_gamma; + /* Check for overflow */ + if (file_gamma > 21474.83) + { + png_warning(png_ptr, "Limiting gamma to 21474.83"); + gamma=21474.83; + } + else + gamma=file_gamma; + info_ptr->gamma = (float)gamma; #ifdef PNG_FIXED_POINT_SUPPORTED - info_ptr->int_gamma = (int)(file_gamma*100000.+.5); + info_ptr->int_gamma = (int)(gamma*100000.+.5); #endif info_ptr->valid |= PNG_INFO_gAMA; - if(file_gamma == 0.0) + if(gamma == 0.0) png_warning(png_ptr, "Setting gamma=0"); } #endif @@ -117,18 +163,35 @@ void PNGAPI png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point int_gamma) { + png_fixed_point gamma; + png_debug1(1, "in %s storage function\n", "gAMA"); if (png_ptr == NULL || info_ptr == NULL) return; + if (int_gamma > (png_fixed_point) PNG_MAX_UINT) + { + png_warning(png_ptr, "Limiting gamma to 21474.83"); + gamma=PNG_MAX_UINT; + } + else + { + if (int_gamma < 0) + { + png_warning(png_ptr, "Setting negative gamma to zero"); + gamma=0; + } + else + gamma=int_gamma; + } #ifdef PNG_FLOATING_POINT_SUPPORTED - info_ptr->gamma = (float)(int_gamma/100000.); + info_ptr->gamma = (float)(gamma/100000.); #endif #ifdef PNG_FIXED_POINT_SUPPORTED - info_ptr->int_gamma = int_gamma; + info_ptr->int_gamma = gamma; #endif info_ptr->valid |= PNG_INFO_gAMA; - if(int_gamma == 0) + if(gamma == 0) png_warning(png_ptr, "Setting gamma=0"); } #endif @@ -137,7 +200,7 @@ png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point void PNGAPI png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p hist) { - int i; + int i; png_debug1(1, "in %s storage function\n", "hIST"); if (png_ptr == NULL || info_ptr == NULL) @@ -153,8 +216,13 @@ png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p hist) png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0); #endif /* Changed from info->num_palette to 256 in version 1.2.1 */ - png_ptr->hist = (png_uint_16p)png_malloc(png_ptr, + png_ptr->hist = (png_uint_16p)png_malloc_warn(png_ptr, (png_uint_32)(256 * sizeof (png_uint_16))); + if (png_ptr->hist == NULL) + { + png_warning(png_ptr, "Insufficient memory for hIST chunk data."); + return; + } for (i = 0; i < info_ptr->num_palette; i++) png_ptr->hist[i] = hist[i]; @@ -254,7 +322,7 @@ png_set_IHDR(png_structp png_ptr, png_infop info_ptr, /* check for overflow */ rowbytes_per_pixel = (info_ptr->pixel_depth + 7) >> 3; - if (( width > PNG_MAX_UINT/rowbytes_per_pixel)) + if ( width > PNG_MAX_UINT/rowbytes_per_pixel - 64) { png_warning(png_ptr, "Width too large to process image data; rowbytes will overflow."); @@ -295,7 +363,12 @@ png_set_pCAL(png_structp png_ptr, png_infop info_ptr, length = png_strlen(purpose) + 1; png_debug1(3, "allocating purpose for info (%lu bytes)\n", length); - info_ptr->pcal_purpose = (png_charp)png_malloc(png_ptr, length); + info_ptr->pcal_purpose = (png_charp)png_malloc_warn(png_ptr, length); + if (info_ptr->pcal_purpose == NULL) + { + png_warning(png_ptr, "Insufficient memory for pCAL purpose."); + return; + } png_memcpy(info_ptr->pcal_purpose, purpose, (png_size_t)length); png_debug(3, "storing X0, X1, type, and nparams in info\n"); @@ -306,11 +379,21 @@ png_set_pCAL(png_structp png_ptr, png_infop info_ptr, length = png_strlen(units) + 1; png_debug1(3, "allocating units for info (%lu bytes)\n", length); - info_ptr->pcal_units = (png_charp)png_malloc(png_ptr, length); + info_ptr->pcal_units = (png_charp)png_malloc_warn(png_ptr, length); + if (info_ptr->pcal_units == NULL) + { + png_warning(png_ptr, "Insufficient memory for pCAL units."); + return; + } png_memcpy(info_ptr->pcal_units, units, (png_size_t)length); - info_ptr->pcal_params = (png_charpp)png_malloc(png_ptr, + info_ptr->pcal_params = (png_charpp)png_malloc_warn(png_ptr, (png_uint_32)((nparams + 1) * sizeof(png_charp))); + if (info_ptr->pcal_params == NULL) + { + png_warning(png_ptr, "Insufficient memory for pCAL params."); + return; + } info_ptr->pcal_params[nparams] = NULL; @@ -318,7 +401,12 @@ png_set_pCAL(png_structp png_ptr, png_infop info_ptr, { length = png_strlen(params[i]) + 1; png_debug2(3, "allocating parameter %d for info (%lu bytes)\n", i, length); - info_ptr->pcal_params[i] = (png_charp)png_malloc(png_ptr, length); + info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length); + if (info_ptr->pcal_params[i] == NULL) + { + png_warning(png_ptr, "Insufficient memory for pCAL parameter."); + return; + } png_memcpy(info_ptr->pcal_params[i], params[i], (png_size_t)length); } @@ -415,6 +503,8 @@ png_set_PLTE(png_structp png_ptr, png_infop info_ptr, in case of an invalid PNG file that has too-large sample values. */ png_ptr->palette = (png_colorp)png_zalloc(png_ptr, (uInt)256, sizeof (png_color)); + if (png_ptr->palette == NULL) + png_error(png_ptr, "Unable to malloc palette"); png_memcpy(png_ptr->palette, palette, num_palette * sizeof (png_color)); info_ptr->palette = png_ptr->palette; info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette; @@ -562,6 +652,16 @@ png_set_iCCP(png_structp png_ptr, png_infop info_ptr, void PNGAPI png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, int num_text) +{ + int ret; + ret=png_set_text_2(png_ptr, info_ptr, text_ptr, num_text); + if (ret) + png_error(png_ptr, "Insufficient memory to store text"); +} + +int /* PRIVATE */ +png_set_text_2(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, + int num_text) { int i; @@ -569,7 +669,7 @@ png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, "text" : (png_const_charp)png_ptr->chunk_name)); if (png_ptr == NULL || info_ptr == NULL || num_text == 0) - return; + return(0); /* Make sure we have enough space in the "text" array in info_struct * to hold all of the incoming text_ptr objects. @@ -584,8 +684,13 @@ png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, old_max = info_ptr->max_text; info_ptr->max_text = info_ptr->num_text + num_text + 8; old_text = info_ptr->text; - info_ptr->text = (png_textp)png_malloc(png_ptr, + info_ptr->text = (png_textp)png_malloc_warn(png_ptr, (png_uint_32)(info_ptr->max_text * sizeof (png_text))); + if (info_ptr->text == NULL) + { + png_free(png_ptr, old_text); + return(1); + } png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max * sizeof(png_text))); png_free(png_ptr, old_text); @@ -594,8 +699,10 @@ png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, { info_ptr->max_text = num_text + 8; info_ptr->num_text = 0; - info_ptr->text = (png_textp)png_malloc(png_ptr, + info_ptr->text = (png_textp)png_malloc_warn(png_ptr, (png_uint_32)(info_ptr->max_text * sizeof (png_text))); + if (info_ptr->text == NULL) + return(1); #ifdef PNG_FREE_ME_SUPPORTED info_ptr->free_me |= PNG_FREE_TEXT; #endif @@ -623,7 +730,7 @@ png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, #ifdef PNG_iTXt_SUPPORTED { /* set iTXt data */ - if (text_ptr[i].key != NULL) + if (text_ptr[i].lang != NULL) lang_len = png_strlen(text_ptr[i].lang); else lang_len = 0; @@ -655,8 +762,10 @@ png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, textp->compression = text_ptr[i].compression; } - textp->key = (png_charp)png_malloc(png_ptr, + textp->key = (png_charp)png_malloc_warn(png_ptr, (png_uint_32)(key_len + text_length + lang_len + lang_key_len + 4)); + if (textp->key == NULL) + return(1); png_debug2(2, "Allocated %lu bytes at %x in png_set_text\n", (png_uint_32)(key_len + lang_len + lang_key_len + text_length + 4), (int)textp->key); @@ -707,6 +816,7 @@ png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, info_ptr->num_text++; png_debug1(3, "transferred text chunk %d\n", info_ptr->num_text); } + return(0); } #endif @@ -736,10 +846,10 @@ png_set_tRNS(png_structp png_ptr, png_infop info_ptr, if (trans != NULL) { /* - * It may not actually be necessary to set png_ptr->trans here; - * we do it for backward compatibility with the way the png_handle_tRNS - * function used to do the allocation. - */ + * It may not actually be necessary to set png_ptr->trans here; + * we do it for backward compatibility with the way the png_handle_tRNS + * function used to do the allocation. + */ #ifdef PNG_FREE_ME_SUPPORTED png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0); #endif @@ -774,8 +884,13 @@ png_set_sPLT(png_structp png_ptr, png_sPLT_tp np; int i; - np = (png_sPLT_tp)png_malloc(png_ptr, + np = (png_sPLT_tp)png_malloc_warn(png_ptr, (info_ptr->splt_palettes_num + nentries) * sizeof(png_sPLT_t)); + if (np == NULL) + { + png_warning(png_ptr, "No memory for sPLT palettes."); + return; + } png_memcpy(np, info_ptr->splt_palettes, info_ptr->splt_palettes_num * sizeof(png_sPLT_t)); @@ -818,9 +933,14 @@ png_set_unknown_chunks(png_structp png_ptr, if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0) return; - np = (png_unknown_chunkp)png_malloc(png_ptr, + np = (png_unknown_chunkp)png_malloc_warn(png_ptr, (info_ptr->unknown_chunks_num + num_unknowns) * sizeof(png_unknown_chunk)); + if (np == NULL) + { + png_warning(png_ptr, "Out of memory while processing unknown chunk."); + return; + } png_memcpy(np, info_ptr->unknown_chunks, info_ptr->unknown_chunks_num * sizeof(png_unknown_chunk)); @@ -834,11 +954,16 @@ png_set_unknown_chunks(png_structp png_ptr, png_strcpy((png_charp)to->name, (png_charp)from->name); to->data = (png_bytep)png_malloc(png_ptr, from->size); - png_memcpy(to->data, from->data, from->size); - to->size = from->size; + if (to->data == NULL) + png_warning(png_ptr, "Out of memory while processing unknown chunk."); + else + { + png_memcpy(to->data, from->data, from->size); + to->size = from->size; - /* note our location in the read or write sequence */ - to->location = (png_byte)(png_ptr->mode & 0xff); + /* note our location in the read or write sequence */ + to->location = (png_byte)(png_ptr->mode & 0xff); + } } info_ptr->unknown_chunks = np; @@ -977,6 +1102,7 @@ png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask) } +#ifndef PNG_1_0_X #ifdef PNG_ASSEMBLER_CODE_SUPPORTED /* this function was added to libpng 1.2.0 and should always exist by default */ void PNGAPI @@ -1015,8 +1141,8 @@ png_set_asm_flags (png_structp png_ptr, png_uint_32 asm_flags) * so first zero them out of the master copy, then logical-OR in the * allowed subset that was requested */ - png_ptr->asm_flags &= ~settable_asm_flags; /* zero them */ - png_ptr->asm_flags |= (asm_flags & settable_asm_flags); /* set them */ + png_ptr->asm_flags &= ~settable_asm_flags; /* zero them */ + png_ptr->asm_flags |= (asm_flags & settable_asm_flags); /* set them */ } #endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */ @@ -1031,3 +1157,4 @@ png_set_mmx_thresholds (png_structp png_ptr, png_ptr->mmx_rowbytes_threshold = mmx_rowbytes_threshold; } #endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */ +#endif /* ?PNG_1_0_X */ diff --git a/pngtrans.c b/pngtrans.c index 6eee9fb1e..d850ee7ac 100644 --- a/pngtrans.c +++ b/pngtrans.c @@ -1,9 +1,9 @@ /* pngtrans.c - transforms the data in a row (used by both readers and writers) * - * libpng 1.2.1 - December 12, 2001 + * libpng 1.2.4 - July 8, 2002 * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2001 Glenn Randers-Pehrson + * Copyright (c) 1998-2002 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) */ diff --git a/pngvcrd.c b/pngvcrd.c index d0aa58b15..72c441213 100644 --- a/pngvcrd.c +++ b/pngvcrd.c @@ -2,9 +2,9 @@ * * For Intel x86 CPU and Microsoft Visual C++ compiler * - * libpng version 1.2.1 - December 12, 2001 + * libpng version 1.2.4 - July 8, 2002 * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2001 Glenn Randers-Pehrson + * Copyright (c) 1998-2002 Glenn Randers-Pehrson * Copyright (c) 1998, Intel Corporation * * Contributed by Nirav Chhatrapati, Intel Corporation, 1998 diff --git a/pngwio.c b/pngwio.c index 01ebbcf01..f356b7d4a 100644 --- a/pngwio.c +++ b/pngwio.c @@ -1,9 +1,9 @@ /* pngwio.c - functions for data output * - * libpng 1.2.1 - December 12, 2001 + * libpng 1.2.4 - July 8, 2002 * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2001 Glenn Randers-Pehrson + * Copyright (c) 1998-2002 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -40,7 +40,7 @@ png_write_data(png_structp png_ptr, png_bytep data, png_size_t length) write_data function and use it at run time with png_set_write_fn(), rather than changing the library. */ #ifndef USE_FAR_KEYWORD -static void /* PRIVATE */ +void PNGAPI png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) { png_uint_32 check; @@ -63,7 +63,7 @@ png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) #define NEAR_BUF_SIZE 1024 #define MIN(a,b) (a <= b ? a : b) -static void /* PRIVATE */ +void PNGAPI png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) { png_uint_32 check; @@ -126,7 +126,7 @@ png_flush(png_structp png_ptr) } #if !defined(PNG_NO_STDIO) -static void /* PRIVATE */ +void PNGAPI png_default_flush(png_structp png_ptr) { #if !defined(_WIN32_WCE) diff --git a/pngwrite.c b/pngwrite.c index f46ce0f6b..ff62395cf 100644 --- a/pngwrite.c +++ b/pngwrite.c @@ -1,9 +1,9 @@ /* pngwrite.c - general routines to write a PNG file * - * libpng 1.2.1 - December 12, 2001 + * libpng 1.2.4 - July 8, 2002 * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2001 Glenn Randers-Pehrson + * Copyright (c) 1998-2002 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) */ @@ -443,16 +443,19 @@ png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, int i; png_debug(1, "in png_create_write_struct\n"); #ifdef PNG_USER_MEM_SUPPORTED - if ((png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG, - (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr)) == NULL) + png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG, + (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr); #else - if ((png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG)) == NULL) + png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); #endif /* PNG_USER_MEM_SUPPORTED */ + if (png_ptr == NULL) return (NULL); +#if !defined(PNG_1_0_X) #ifdef PNG_ASSEMBLER_CODE_SUPPORTED png_init_mmx_flags(png_ptr); /* 1.2.0 addition */ #endif +#endif /* PNG_1_0_X */ #ifdef PNG_SETJMP_SUPPORTED #ifdef USE_FAR_KEYWORD @@ -527,7 +530,20 @@ png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, 1, png_doublep_NULL, png_doublep_NULL); #endif - return ((png_structp)png_ptr); +#ifdef PNG_SETJMP_SUPPORTED +/* Applications that neglect to set up their own setjmp() and then encounter + a png_error() will longjmp here. Since the jmpbuf is then meaningless we + abort instead of returning. */ +#ifdef USE_FAR_KEYWORD + if (setjmp(jmpbuf)) + PNG_ABORT(); + png_memcpy(png_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf)); +#else + if (setjmp(png_ptr->jmpbuf)) + PNG_ABORT(); +#endif +#endif + return (png_ptr); } /* Initialize png_ptr structure, and allocate any memory needed */ @@ -539,7 +555,6 @@ png_write_init(png_structp png_ptr) png_write_init_2(png_ptr, "1.0.6 or earlier", 0, 0); } -#undef png_write_init_2 void PNGAPI png_write_init_2(png_structp png_ptr, png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t png_info_size) @@ -624,9 +639,11 @@ png_write_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver, /* reset all variables to 0 */ png_memset(png_ptr, 0, sizeof (png_struct)); +#if !defined(PNG_1_0_X) #ifdef PNG_ASSEMBLER_CODE_SUPPORTED png_init_mmx_flags(png_ptr); /* 1.2.0 addition */ #endif +#endif /* PNG_1_0_X */ #ifdef PNG_SETJMP_SUPPORTED /* restore jump buffer */ @@ -948,6 +965,7 @@ png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr) png_ptr = *png_ptr_ptr; #ifdef PNG_USER_MEM_SUPPORTED free_fn = png_ptr->free_fn; + mem_ptr = png_ptr->mem_ptr; #endif } diff --git a/pngwtran.c b/pngwtran.c index 55e691d28..d15c0c55c 100644 --- a/pngwtran.c +++ b/pngwtran.c @@ -1,9 +1,9 @@ /* pngwtran.c - transforms the data in a row for PNG writers * - * libpng 1.2.1 - December 12, 2001 + * libpng 1.2.4 - July 8, 2002 * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2001 Glenn Randers-Pehrson + * Copyright (c) 1998-2002 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) */ diff --git a/pngwutil.c b/pngwutil.c index 1f2d72442..22155e93f 100644 --- a/pngwutil.c +++ b/pngwutil.c @@ -1,9 +1,9 @@ /* pngwutil.c - utilities to write a PNG file * - * libpng 1.2.1 - December 12, 2001 + * libpng 1.2.4 - July 8, 2002 * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2001 Glenn Randers-Pehrson + * Copyright (c) 1998-2002 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) */ @@ -1349,22 +1349,28 @@ png_write_iTXt(png_structp png_ptr, int compression, png_charp key, png_warning(png_ptr, "Empty keyword in iTXt chunk"); return; } - if (lang == NULL || (lang_len = png_check_keyword(png_ptr, lang, - &new_lang))==0) + if (lang == NULL || (lang_len = png_check_keyword(png_ptr, lang, &new_lang))==0) { png_warning(png_ptr, "Empty language field in iTXt chunk"); - return; + new_lang = NULL; + lang_len = 0; } - lang_key_len = png_strlen(lang_key); - text_len = png_strlen(text); - if (text == NULL || *text == '\0') + if (lang_key == NULL) + lang_key_len = 0; + else + lang_key_len = png_strlen(lang_key); + + if (text == NULL) text_len = 0; + else + text_len = png_strlen(text); /* compute the compressed data; do it now for the length */ text_len = png_text_compress(png_ptr, text, text_len, compression-2, &comp); + /* make sure we include the compression flag, the compression byte, * and the NULs after the key, lang, and lang_key parts */ @@ -1394,15 +1400,15 @@ png_write_iTXt(png_structp png_ptr, int compression, png_charp key, cbuf[1] = 0; png_write_chunk_data(png_ptr, cbuf, 2); - png_write_chunk_data(png_ptr, (png_bytep)new_lang, lang_len + 1); - png_write_chunk_data(png_ptr, (png_bytep)lang_key, lang_key_len+1); - png_write_chunk_data(png_ptr, '\0', 1); - + cbuf[0] = 0; + png_write_chunk_data(png_ptr, (new_lang ? (png_bytep)new_lang : cbuf), lang_len + 1); + png_write_chunk_data(png_ptr, (lang_key ? (png_bytep)lang_key : cbuf), lang_key_len + 1); png_write_compressed_data_out(png_ptr, &comp); png_write_chunk_end(png_ptr); png_free(png_ptr, new_key); - png_free(png_ptr, new_lang); + if (new_lang) + png_free(png_ptr, new_lang); } #endif diff --git a/zlib.h b/zlib.h index f06812208..00456bc52 100644 --- a/zlib.h +++ b/zlib.h @@ -1,7 +1,7 @@ /* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.1.3pc, May 2000 + version 1.1.4pc, March 2002 - Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler + Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -28,7 +28,7 @@ (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). */ -/* Changes from version 1.1.3 to version 1.1.3pc +/* Changes from version 1.1.4 to version 1.1.4pc * * The default value of TOO_FAR has been changed to 32767 in deflate.c * Glenn Randers-Pehrson, February 2000. @@ -51,7 +51,7 @@ extern "C" { #endif -#define ZLIB_VERSION "1.1.3pc" +#define ZLIB_VERSION "1.1.4pc" /* The 'zlib' compression library provides in-memory compression and