From ce85ad6640b8718fd05f58a47c1f83d9e98aad94 Mon Sep 17 00:00:00 2001 From: Glenn Randers-Pehrson Date: Tue, 7 Dec 1999 09:44:50 -0600 Subject: [PATCH] Imported from pngcrush-1.2.1.tar --- INSTALL | 23 ++ README.txt | 36 ++- png.c | 251 ++++++++++++++----- png.h | 670 +++++++++++++++++++++++++++++++++---------------- pngconf.h | 148 ++++++++++- pngcrush.c | 64 ++++- pngerror.c | 2 +- pngget.c | 71 +++++- pngmem.c | 2 +- pngpread.c | 215 +++++++++++++++- pngread.c | 170 ++++++++++++- pngrio.c | 4 +- pngrtran.c | 10 +- pngrutil.c | 649 ++++++++++++++++++++++++++++++++++++++--------- pngset.c | 133 ++++++++-- pngtrans.c | 2 +- pngtypes.h | 31 +++ pngvcrd.c | 32 ++- pngwio.c | 2 +- pngwrite.c | 85 +++++-- pngwtran.c | 5 +- pngwutil.c | 723 +++++++++++++++++++++++++++++++++++++++-------------- 22 files changed, 2638 insertions(+), 690 deletions(-) create mode 100644 INSTALL create mode 100644 pngtypes.h diff --git a/INSTALL b/INSTALL new file mode 100644 index 000000000..021dd38cb --- /dev/null +++ b/INSTALL @@ -0,0 +1,23 @@ + +There's no makefile or "configure" for pngcrush. + +All you should need to do is enter the pngcrush-1.2.l +directory and type + + cc -O -o pngcrush *.c -lm + cp pngcrush /usr/local/bin # or wherever you want + +You might want to create a makefile if you are planning to do +something more complicated, like loading with your own shared +libraries for libpng and zlib. + +Here's the command for compiling on SGI IRIX: + + cc -n32 -fullwarn -O2 -IPA:plimit=256 -OPT:Olimit=0 -o pngcrush *.c -lm + cp pngcrush /usr/local/bin + +On a PC with DJGCC, you can type + + gcc -O3 -Wall -funroll-loops -o pngcrush *.c + copy /B pmodstub.exe + pngcrush pngcrush.exe + then put pngcrush.exe wherever you want. diff --git a/README.txt b/README.txt index 1bb345141..534ade417 100644 --- a/README.txt +++ b/README.txt @@ -1,8 +1,8 @@ - | pngcrush 1.2.0, Copyright (C) 1998, 1999, Glenn Randers-Pehrson + | pngcrush 1.2.1, Copyright (C) 1998, 1999, Glenn Randers-Pehrson | This is a free, open-source program. Permission is | granted to everyone to use pngcrush without fee. - | This program was built with libpng version 1.0.5a, + | This program was built with libpng version 1.0.5f, | Copyright (C) 1995, Guy Eric Schalnat, Group 42 Inc., | Copyright (C) 1996, 1997 Andreas Dilger, | Copyright (C) 1998, 1999, Glenn Randers-Pehrson, @@ -13,6 +13,31 @@ usage: pngcrush [options] infile.png outfile.png pngcrush -e ext [other options] files.png ... pngcrush -d dir [other options] files.png ... +options: + -brute (Use brute-force, try 114 different methods) + -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] + -force (Write a new output file even if larger than input) + -g gamma_value (float, e.g., 0.45455) + -l zlib_compression_level [0-9] + -m method [0 through 200] + -max maximum_IDAT_size [1 through 524288] + -n (no save; does not do compression or write output PNG) + -plte_len n (truncate PLTE) + -q (quiet) + -rem chunkname (or "alla" or "allb") +-replace_gamma gamma_value (float) even when file has a gAMA chunk. + -res dpi + -srgb [0, 1, 2, or 3] + -text b[efore_IDAT]|a[fter_IDAT] "keyword" "text" + -trns index red green blue gray + -verbose (write more detailed information) + -w compression_window_size [32, 16, 8, 4, 2, 1, 512, 256] + -h (help) + -p (pause) options: -brute (Use brute-force, try 114 different methods) @@ -89,6 +114,11 @@ options: Useful in conjunction with -v option to get info. + -plte_len n (truncate PLTE) + + Truncates the PLTE. Be sure not to truncate it to + + less than the greatest index present in IDAT. -q (quiet) @@ -146,7 +176,7 @@ options: -z zlib_strategy [0, 1, or 2] zlib compression strategy to use with the preceding - preceding '-m method' argument. + '-m method' argument. -h (help) diff --git a/png.c b/png.c index 563d0b625..340d261a8 100644 --- a/png.c +++ b/png.c @@ -1,7 +1,7 @@ /* png.c - location for general purpose libpng functions * - * libpng version 1.0.5a - October 23, 1999 + * libpng version 1.0.5f - December 6, 1999 * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. * Copyright (c) 1996, 1997 Andreas Dilger * Copyright (c) 1998, 1999 Glenn Randers-Pehrson @@ -12,38 +12,40 @@ #define PNG_NO_EXTERN #include "png.h" -PNG_GET_HEADER - /* Version information for C files. This had better match the version * string defined in png.h. */ -char png_libpng_ver[12] = "1.0.5a"; +#ifdef PNG_USE_GLOBAL_ARRAYS +/* png_libpng_ver was changed to a function in version 1.0.5c */ +char png_libpng_ver[12] = "1.0.5f"; +/* png_sig was changed to a function in version 1.0.5c */ /* Place to hold the signature string for a PNG file. */ png_byte FARDATA png_sig[8] = {137, 80, 78, 71, 13, 10, 26, 10}; - -/* Constant strings for known chunk types. If you need to add a chunk, - * add a string holding the name here. If you want to make the code - * portable to EBCDIC machines, use ASCII numbers, not characters. - */ -png_byte FARDATA png_IHDR[5] = { 73, 72, 68, 82, '\0'}; -png_byte FARDATA png_IDAT[5] = { 73, 68, 65, 84, '\0'}; -png_byte FARDATA png_IEND[5] = { 73, 69, 78, 68, '\0'}; -png_byte FARDATA png_PLTE[5] = { 80, 76, 84, 69, '\0'}; -png_byte FARDATA png_bKGD[5] = { 98, 75, 71, 68, '\0'}; -png_byte FARDATA png_cHRM[5] = { 99, 72, 82, 77, '\0'}; -png_byte FARDATA png_gAMA[5] = {103, 65, 77, 65, '\0'}; -png_byte FARDATA png_hIST[5] = {104, 73, 83, 84, '\0'}; -png_byte FARDATA png_oFFs[5] = {111, 70, 70, 115, '\0'}; -png_byte FARDATA png_pCAL[5] = {112, 67, 65, 76, '\0'}; -png_byte FARDATA png_pHYs[5] = {112, 72, 89, 115, '\0'}; -png_byte FARDATA png_sBIT[5] = {115, 66, 73, 84, '\0'}; -png_byte FARDATA png_sRGB[5] = {115, 82, 71, 66, '\0'}; -png_byte FARDATA png_tEXt[5] = {116, 69, 88, 116, '\0'}; -png_byte FARDATA png_tIME[5] = {116, 73, 77, 69, '\0'}; -png_byte FARDATA png_tRNS[5] = {116, 82, 78, 83, '\0'}; -png_byte FARDATA png_zTXt[5] = {122, 84, 88, 116, '\0'}; + +/* Invoke global declarations for constant strings for known chunk types */ +PNG_IHDR; +PNG_IDAT; +PNG_IEND; +PNG_PLTE; +PNG_bKGD; +PNG_cHRM; +PNG_gAMA; +PNG_hIST; +PNG_iCCP; +PNG_iTXt; +PNG_oFFs; +PNG_pCAL; +PNG_sCAL; +PNG_pHYs; +PNG_sBIT; +PNG_sPLT; +PNG_sRGB; +PNG_tEXt; +PNG_tIME; +PNG_tRNS; +PNG_zTXt; /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ @@ -75,6 +77,8 @@ int FARDATA png_pass_mask[] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff}; /* Mask to determine which pixels to overwrite while displaying */ int FARDATA png_pass_dsp_mask[] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff}; +#endif + /* Tells libpng that we have already handled the first "num_bytes" bytes * of the PNG file signature. If the PNG data is embedded into another * stream we can set num_bytes = 8 so that libpng will not attempt to read @@ -102,6 +106,7 @@ png_set_sig_bytes(png_structp png_ptr, int num_bytes) int png_sig_cmp(png_bytep sig, png_size_t start, png_size_t num_to_check) { + png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; if (num_to_check > 8) num_to_check = 8; else if (num_to_check < 1) @@ -113,7 +118,7 @@ png_sig_cmp(png_bytep sig, png_size_t start, png_size_t num_to_check) if (start + num_to_check > 8) num_to_check = 8 - start; - return ((int)(png_memcmp(&sig[start], &png_sig[start], num_to_check))); + return ((int)(png_memcmp(&sig[start], &png_signature[start], num_to_check))); } /* (Obsolete) function to check signature bytes. It does not allow one @@ -253,6 +258,108 @@ png_info_init(png_infop info_ptr) png_memset(info_ptr, 0, sizeof (png_info)); } +#if defined(PNG_TEXT_SUPPORTED) +/* free text item num or (if num == -1) all text items */ +void +png_free_text(png_structp png_ptr, png_infop info_ptr, int num) +{ + if (num != -1) + { + if (info_ptr->text[num].key) + { + png_free(png_ptr, info_ptr->text[num].key); + info_ptr->text[num].key = NULL; + } + if (info_ptr->text[num].lang) + { + png_free(png_ptr, info_ptr->text[num].lang); + info_ptr->text[num].lang = NULL; + } + } + else if (info_ptr->text != NULL) + { + int i; + for (i = 0; i < info_ptr->num_text; i++) + png_free_text(png_ptr, info_ptr, i); + png_free(png_ptr, info_ptr->text); + info_ptr->text = NULL; + } +} +#endif + +#if defined(PNG_sCAL_SUPPORTED) +/* free any sCAL entry */ +void +png_free_sCAL(png_structp png_ptr, png_infop info_ptr) +{ + if (info_ptr->valid & PNG_INFO_sCAL) + { + png_free(png_ptr, info_ptr->scal_unit); + info_ptr->valid &= ~PNG_INFO_sCAL; + } +} +#endif + +#if defined(PNG_pCAL_SUPPORTED) +/* free any pCAL entry */ +void +png_free_pCAL(png_structp png_ptr, png_infop info_ptr) +{ + if (info_ptr->valid & PNG_INFO_pCAL) + { + png_free(png_ptr, info_ptr->pcal_purpose); + png_free(png_ptr, info_ptr->pcal_units); + if (info_ptr->pcal_params != NULL) + { + int i; + for (i = 0; i < (int)info_ptr->pcal_nparams; i++) + { + png_free(png_ptr, info_ptr->pcal_params[i]); + } + png_free(png_ptr, info_ptr->pcal_params); + } + info_ptr->valid &= ~PNG_INFO_pCAL; + } +} +#endif + +#if defined(PNG_iCCP_SUPPORTED) +/* free any pCAL entry */ +void +png_free_iCCP(png_structp png_ptr, png_infop info_ptr) +{ + if (info_ptr->valid & PNG_INFO_iCCP) + { + png_free(png_ptr, info_ptr->iccp_name); + png_free(png_ptr, info_ptr->iccp_profile); + info_ptr->valid &= ~PNG_INFO_iCCP; + } +} +#endif + +#if defined(PNG_sPLT_SUPPORTED) +/* free a given sPLT entry, or (if num == -1) all sPLT entries */ +void +png_free_spalettes(png_structp png_ptr, png_infop info_ptr, int num) +{ + if (num != -1) + { + png_free(png_ptr, info_ptr->splt_palettes[num].name); + png_free(png_ptr, info_ptr->splt_palettes[num].entries); + } + else + { + png_uint_32 i; + + for (i = 0; i < info_ptr->splt_palettes_num; i++) + png_free_spalettes(png_ptr, info_ptr, num); + + png_free(png_ptr, info_ptr->splt_palettes); + info_ptr->splt_palettes_num = 0; + } +} +#endif + /* This is an internal routine to free any memory that the info struct is * pointing to before re-using it or freeing the struct itself. Recall * that png_free() checks for NULL pointers for us. @@ -260,39 +367,22 @@ png_info_init(png_infop info_ptr) void png_info_destroy(png_structp png_ptr, png_infop info_ptr) { -#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED) png_debug(1, "in png_info_destroy\n"); - if (info_ptr->text != NULL) - { - int i; - for (i = 0; i < info_ptr->num_text; i++) - { - if(info_ptr->text[i].key != NULL) - { - png_free(png_ptr, info_ptr->text[i].key); - info_ptr->text[i].key = NULL; - } - } - png_free(png_ptr, info_ptr->text); - info_ptr->text = NULL; - } +#if defined(PNG_READ_TEXT_SUPPORTED) + png_free_text(png_ptr, info_ptr, -1); +#endif +#if defined(PNG_READ_sCAL_SUPPORTED) + png_free_sCAL(png_ptr, info_ptr); #endif #if defined(PNG_READ_pCAL_SUPPORTED) - png_free(png_ptr, info_ptr->pcal_purpose); - png_free(png_ptr, info_ptr->pcal_units); - if (info_ptr->pcal_params != NULL) - { - int i; - for (i = 0; i < (int)info_ptr->pcal_nparams; i++) - { - png_free(png_ptr, info_ptr->pcal_params[i]); - info_ptr->pcal_params[i]=NULL; - } - png_free(png_ptr, info_ptr->pcal_params); - info_ptr->pcal_params = NULL; - } + png_free_pCAL(png_ptr, info_ptr); +#endif +#if defined(PNG_READ_iCCP_SUPPORTED) + png_free_iCCP(png_ptr, info_ptr); +#endif +#if defined(PNG_READ_sPLT_SUPPORTED) + png_free_spalettes(png_ptr, info_ptr, -1); #endif - png_info_init(info_ptr); } @@ -356,22 +446,65 @@ png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime) } #endif /* PNG_TIME_RFC1123_SUPPORTED */ +/* Signature string for a PNG file. */ +png_bytep +png_sig_bytes(png_structp png_ptr) +{ + const png_byte png_sig_numbers[9] = {137, 80, 78, 71, 13, 10, 26, 10, 0}; + if (png_ptr == NULL) /* silence compiler warning */ + return ((png_bytep) strdup((png_const_charp)png_sig_numbers)); + return ((png_bytep) strdup((png_const_charp)png_sig_numbers)); +} + png_charp png_get_copyright(png_structp png_ptr) { if (png_ptr != NULL || png_ptr == NULL) /* silence compiler warning */ - return ("\n libpng version 1.0.5a - October 23, 1999\n\ + return ("\n libpng version 1.0.5f - December 6, 1999\n\ Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.\n\ Copyright (c) 1996, 1997 Andreas Dilger\n\ Copyright (c) 1998, 1999 Glenn Randers-Pehrson\n"); return (""); } +/* The following return the library version as a short string in the + * format 1.0.0 through 99.99.99zz. To get the version of *.h files used + * with your application, print out PNG_LIBPNG_VER_STRING, which is defined + * in png.h. + */ + +png_charp +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("1.0.5f"); + return("1.0.5f"); +} + +png_charp +png_get_header_ver(png_structp png_ptr) +{ + /* Version of *.h files used when building libpng */ + if(png_ptr != NULL) /* silence compiler warning about unused png_ptr */ + return(PNG_LIBPNG_VER_STRING); + return(PNG_LIBPNG_VER_STRING); +} + +png_charp +png_get_header_version(png_structp png_ptr) +{ + /* Returns longer string containing both version and date */ + if(png_ptr != NULL) /* silence compiler warning about unused png_ptr */ + return(PNG_HEADER_VERSION_STRING); + return(PNG_HEADER_VERSION_STRING); +} + /* Generate a compiler error if there is an old png.h in the search path. */ void png_check_version - (version_1_0_5a png_h_is_not_version_1_0_5a) + (version_1_0_5f png_h_is_not_version_1_0_5f) { - if(png_h_is_not_version_1_0_5a == NULL) + if(png_h_is_not_version_1_0_5f == NULL) return; } diff --git a/png.h b/png.h index a2638bf56..6da95a215 100644 --- a/png.h +++ b/png.h @@ -1,7 +1,7 @@ /* png.h - header file for PNG reference library * - * libpng version 1.0.5a - October 23, 1999 + * libpng version 1.0.5f - December 6, 1999 * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. * Copyright (c) 1996, 1997 Andreas Dilger * Copyright (c) 1998, 1999 Glenn Randers-Pehrson @@ -9,19 +9,19 @@ * Authors and maintainers: * libpng versions 0.71, May 1995, through 0.89c, May 1996: Guy Schalnat * libpng versions 0.90, December 1996, through 0.96, May 1997: Andreas Dilger - * libpng versions 0.97, January 1998, through 1.0.5a - October 23, 1999: Glenn + * libpng versions 0.97, January 1998, through 1.0.5f - December 6, 1999: Glenn * See also "Contributing Authors", below. * * Y2K compliance in libpng: * ========================= * - * October 23, 1999 + * December 6, 1999 * * 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.0.5a are Y2K compliant. It is my belief that earlier + * upward through 1.0.5f 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 @@ -97,7 +97,9 @@ * 1.0.4 1.0.4 10004 2.1.0.4 * 1.0.4a-f 1.0.4a-f 10005 2.1.0.4a-f * 1.0.5 1.0.5 10005 2.1.0.5 - * 1.0.5a 1.0.5a 10006 2.1.0.5a + * 1.0.5a-d 1.0.5a-d 10006 2.1.0.5a-d + * 1.0.5e-f 1.0.5e-f 10100 2.1.0.5e-f + * 1.1.0 1.1.0 10100 3.1.0.0 * * Henceforth the source version will match the shared-library minor * and patch numbers; the shared-library major version number will be @@ -121,7 +123,7 @@ * Copyright (c) 1996, 1997 Andreas Dilger * (libpng versions 0.90, December 1996, through 0.96, May 1997) * Copyright (c) 1998, 1999 Glenn Randers-Pehrson - * (libpng versions 0.97, January 1998, through 1.0.5a, October 23, 1999) + * (libpng versions 0.97, January 1998, through 1.0.5f, December 6, 1999) * * For the purposes of this copyright and license, "Contributing Authors" * is defined as the following set of individuals: @@ -134,6 +136,7 @@ * Tom Lane * Dave Martindale * Glenn Randers-Pehrson + * Eric S. Raymond * Greg Roelofs * Guy Eric Schalnat * Paul Schmidt @@ -221,14 +224,14 @@ extern "C" { */ /* Version information for png.h - this should match the version in png.c */ -#define PNG_LIBPNG_VER_STRING "1.0.5a" +#define PNG_LIBPNG_VER_STRING "1.0.5f" /* Careful here. At one time, Guy wanted to use 082, but that would be octal. * We must not include leading zeros. * 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=bugfix */ -#define PNG_LIBPNG_VER 10006 /* 1.0.6 */ +#define PNG_LIBPNG_VER 10100 /* 1.1.0 */ /* Note to maintainer: update this number in scripts/pngdef.pas as well */ @@ -237,19 +240,26 @@ extern "C" { /* Version information for C files, stored in png.c. This had better match * the version above. */ -extern char png_libpng_ver[12]; /* need room for 99.99.99aa */ +#ifdef PNG_USE_GLOBAL_ARRAYS +PNG_EXPORT_VAR (char) png_libpng_ver[12]; /* need room for 99.99.99aa */ +#else +#define png_libpng_ver png_get_header_ver(NULL) +#endif +#ifdef PNG_USE_GLOBAL_ARRAYS +/* This was removed in version 1.0.5c */ /* Structures to facilitate easy interlacing. See png.c for more details */ -extern int FARDATA png_pass_start[7]; -extern int FARDATA png_pass_inc[7]; -extern int FARDATA png_pass_ystart[7]; -extern int FARDATA png_pass_yinc[7]; -extern int FARDATA png_pass_mask[7]; -extern int FARDATA png_pass_dsp_mask[7]; +PNG_EXPORT_VAR (int FARDATA) png_pass_start[7]; +PNG_EXPORT_VAR (int FARDATA) png_pass_inc[7]; +PNG_EXPORT_VAR (int FARDATA) png_pass_ystart[7]; +PNG_EXPORT_VAR (int FARDATA) png_pass_yinc[7]; +PNG_EXPORT_VAR (int FARDATA) png_pass_mask[7]; +PNG_EXPORT_VAR (int FARDATA) png_pass_dsp_mask[7]; /* These aren't currently used. If you need them, see png.c for more details -extern int FARDATA png_pass_width[7]; -extern int FARDATA png_pass_height[7]; +PNG_EXPORT_VAR (int FARDATA) png_pass_width[7]; +PNG_EXPORT_VAR (int FARDATA) png_pass_height[7]; */ +#endif #endif /* PNG_NO_EXTERN */ @@ -288,17 +298,47 @@ typedef struct png_color_8_struct typedef png_color_8 FAR * png_color_8p; typedef png_color_8 FAR * FAR * png_color_8pp; -/* png_text holds the text in a PNG file, and whether they are compressed - in the PNG file or not. The "text" field points to a regular C string. */ +/* + * The following two structures are used for the in-core representation + * of sPLT chunks. + */ +typedef struct png_spalette_entry_struct +{ + png_uint_16 red; + png_uint_16 green; + png_uint_16 blue; + png_uint_16 alpha; + png_uint_16 frequency; +} png_spalette_entry; +typedef png_spalette_entry FAR * png_spalette_entryp; +typedef png_spalette_entry FAR * FAR * png_spalette_entrypp; + +typedef struct png_spalette_struct +{ + png_charp name; /* palette name */ + png_byte depth; /* depth of palette samples */ + png_spalette_entryp entries; /* palette entries */ + png_int_32 nentries; /* number of palette entries */ +} png_spalette; +typedef png_spalette FAR * png_spalette_p; +typedef png_spalette FAR * FAR * png_spalette_pp; + +#ifdef PNG_TEXT_SUPPORTED +/* png_text holds the contents of a text chunk in a PNG file, and whether + * that contents is compressed or not. The "keyword" field points to a + * regular C string. */ typedef struct png_text_struct { int compression; /* compression value, see PNG_TEXT_COMPRESSION_ */ png_charp key; /* keyword, 1-79 character description of "text" */ + png_charp lang; /* language code, 1-79 characters */ png_charp text; /* comment, may be an empty string (ie "") */ - png_size_t text_length; /* length of "text" field */ + /* text_length is no longer used, and now present for compatibility only */ + png_size_t text_length; /* length of "text" field (not used any more) */ } png_text; typedef png_text FAR * png_textp; typedef png_text FAR * FAR * png_textpp; +#endif /* Supported compression types for text in PNG files (tEXt, and zTXt). * The values of the PNG_TEXT_COMPRESSION_ defines should NOT be changed. */ @@ -346,6 +386,21 @@ typedef png_time FAR * FAR * png_timepp; * In any case, the order of the parameters in png_info_struct should NOT * be changed for as long as possible to keep compatibility with applications * that use the old direct-access method with png_info_struct. + * + * The following members may have allocated storage attached that should be + * cleaned up before the structure is discarded: palette, text, pcal_purpose, + * pcal_units, pcal_params, iccp_name, iccp_profile, splt_palettes, and + * scal_unit. Of these, the text, pcal_*, iccp_*, splt_*, and scal_unit + * members are automatically freed when the info structure is deallocated. + * The palette member is not. + * + * More allocation details: all the chunk-reading functions that change these + * members go through the corresponding png_set_* functions. Functions to + * clear these members are available: see png_free_*. The png_set_* functions + * do not depend on being able to point info structure members to any of the + * storage they are passed (they make their own copies), EXCEPT that the + * png_set_text function uses the same storage passed to them + * in the text_ptr or itxt_ptr structure argument. */ typedef struct png_info_struct { @@ -375,41 +430,42 @@ typedef struct png_info_struct * and initialize the appropriate fields below. */ -#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_WRITE_gAMA_SUPPORTED) || \ - defined(PNG_READ_GAMMA_SUPPORTED) +#if defined(PNG_gAMA_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED) /* The gAMA chunk describes the gamma characteristics of the system * on which the image was created, normally in the range [1.0, 2.5]. * Data is valid if (valid & PNG_INFO_gAMA) is non-zero. */ float gamma; /* gamma value of image, if (valid & PNG_INFO_gAMA) */ -#endif /* PNG_READ_gAMA_SUPPORTED || PNG_WRITE_gAMA_SUPPORTED */ +#endif -#if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED) +#if defined(PNG_sRGB_SUPPORTED) /* GR-P, 0.96a */ /* Data valid if (valid & PNG_INFO_sRGB) non-zero. */ png_byte srgb_intent; /* sRGB rendering intent [0, 1, 2, or 3] */ -#endif /* PNG_READ_sRGB_SUPPORTED || PNG_WRITE_sRGB_SUPPORTED */ +#endif -#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \ - defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED) - /* The tEXt and zTXt chunks contain human-readable textual data in - * uncompressed and compressed forms, respectively. The data in "text" - * is an array of pointers to uncompressed, null-terminated C strings. - * Each chunk has a keyword that describes the textual data contained - * in that chunk. Keywords are not required to be unique, and the text - * string may be empty. Any number of text chunks may be in an image. +#if defined(PNG_TEXT_SUPPORTED) + /* The tEXt, and zTXt chunks contain human-readable textual data in + * uncompressed, compressed, and optionally compressed forms, respectively. + * The data in "text" is an array of pointers to uncompressed, + * null-terminated C strings. Each chunk has a keyword that describes the + * textual data contained in that chunk. Keywords are not required to be + * unique, and the text string may be empty. Any number of text chunks may + * be in an image. */ int num_text; /* number of comments read/to write */ int max_text; /* current size of text array */ png_textp text; /* array of comments read/to write */ -#endif /* PNG_READ_OR_WRITE_tEXt_OR_zTXt_SUPPORTED */ -#if defined(PNG_READ_tIME_SUPPORTED) || defined(PNG_WRITE_tIME_SUPPORTED) +#endif /* PNG_TEXT_SUPPORTED */ + +#if defined(PNG_tIME_SUPPORTED) /* The tIME chunk holds the last time the displayed image data was * modified. See the png_time struct for the contents of this struct. */ png_time mod_time; -#endif /* PNG_READ_tIME_SUPPORTED || PNG_WRITE_tIME_SUPPORTED */ -#if defined(PNG_READ_sBIT_SUPPORTED) || defined(PNG_WRITE_sBIT_SUPPORTED) +#endif + +#if defined(PNG_sBIT_SUPPORTED) /* The sBIT chunk specifies the number of significant high-order bits * in the pixel data. Values are in the range [1, bit_depth], and are * only specified for the channels in the pixel data. The contents of @@ -417,9 +473,10 @@ typedef struct png_info_struct * (valid & PNG_INFO_sBIT) is non-zero. */ png_color_8 sig_bit; /* significant bits in color channels */ -#endif /* PNG_READ_sBIT_SUPPORTED || PNG_WRITE_sBIT_SUPPORTED */ -#if defined(PNG_READ_tRNS_SUPPORTED) || defined(PNG_WRITE_tRNS_SUPPORTED) || \ - defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) +#endif + +#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_EXPAND_SUPPORTED) || \ +defined(PNG_READ_BACKGROUND_SUPPORTED) /* The tRNS chunk supplies transparency data for paletted images and * other image types that don't need a full alpha channel. There are * "num_trans" transparency values for a paletted image, stored in the @@ -431,9 +488,9 @@ typedef struct png_info_struct */ png_bytep trans; /* transparent values for paletted image */ png_color_16 trans_values; /* transparent color for non-palette image */ -#endif /* PNG_READ_tRNS_SUPPORTED || PNG_WRITE_tRNS_SUPPORTED */ -#if defined(PNG_READ_bKGD_SUPPORTED) || defined(PNG_WRITE_bKGD_SUPPORTED) || \ - defined(PNG_READ_BACKGROUND_SUPPORTED) +#endif + +#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) /* The bKGD chunk gives the suggested image background color if the * display program does not have its own background color and the image * is needs to composited onto a background before display. The colors @@ -441,18 +498,20 @@ typedef struct png_info_struct * pixel data. Data is valid if (valid & PNG_INFO_bKGD) is non-zero. */ png_color_16 background; -#endif /* PNG_READ_bKGD_SUPPORTED || PNG_WRITE_bKGD_SUPPORTED */ -#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED) +#endif + +#if defined(PNG_oFFs_SUPPORTED) /* The oFFs chunk gives the offset in "offset_unit_type" units rightwards * and downwards from the top-left corner of the display, page, or other * application-specific co-ordinate space. See the PNG_OFFSET_ defines * below for the unit types. Valid if (valid & PNG_INFO_oFFs) non-zero. */ - png_uint_32 x_offset; /* x offset on page */ - png_uint_32 y_offset; /* y offset on page */ + png_int_32 x_offset; /* x offset on page */ + png_int_32 y_offset; /* y offset on page */ png_byte offset_unit_type; /* offset units type */ -#endif /* PNG_READ_oFFs_SUPPORTED || PNG_WRITE_oFFs_SUPPORTED */ -#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED) +#endif + +#if defined(PNG_pHYs_SUPPORTED) /* The pHYs chunk gives the physical pixel density of the image for * display or printing in "phys_unit_type" units (see PNG_RESOLUTION_ * defines below). Data is valid if (valid & PNG_INFO_pHYs) is non-zero. @@ -460,8 +519,9 @@ typedef struct png_info_struct png_uint_32 x_pixels_per_unit; /* horizontal pixel density */ png_uint_32 y_pixels_per_unit; /* vertical pixel density */ png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */ -#endif /* PNG_READ_pHYs_SUPPORTED || PNG_WRITE_pHYs_SUPPORTED */ -#if defined(PNG_READ_hIST_SUPPORTED) || defined(PNG_WRITE_hIST_SUPPORTED) +#endif + +#if defined(PNG_hIST_SUPPORTED) /* The hIST chunk contains the relative frequency or importance of the * various palette entries, so that a viewer can intelligently select a * reduced-color palette, if required. Data is an array of "num_palette" @@ -469,8 +529,9 @@ typedef struct png_info_struct * is non-zero. */ png_uint_16p hist; -#endif /* PNG_READ_hIST_SUPPORTED || PNG_WRITE_hIST_SUPPORTED */ -#if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED) +#endif + +#if defined(PNG_cHRM_SUPPORTED) /* The cHRM chunk describes the CIE color characteristics of the monitor * on which the PNG was created. This data allows the viewer to do gamut * mapping of the input image to ensure that the viewer sees the same @@ -485,10 +546,11 @@ typedef struct png_info_struct float y_green; float x_blue; float y_blue; -#endif /* PNG_READ_cHRM_SUPPORTED || PNG_WRITE_cHRM_SUPPORTED */ -#if defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) +#endif + +#if defined(PNG_pCAL_SUPPORTED) /* The pCAL chunk describes a transformation between the stored pixel - * values and original physcical data values used to create the image. + * values and original physical data values used to create the image. * The integer range [0, 2^bit_depth - 1] maps to the floating-point * range given by [pcal_X0, pcal_X1], and are further transformed by a * (possibly non-linear) transformation function given by "pcal_type" @@ -506,8 +568,37 @@ typedef struct png_info_struct png_charpp pcal_params; /* ASCII strings containing parameter values */ png_byte pcal_type; /* equation type (see PNG_EQUATION_ below) */ png_byte pcal_nparams; /* number of parameters given in pcal_params */ -#endif /* PNG_READ_pCAL_SUPPORTED || PNG_WRITE_pCAL_SUPPORTED */ +#endif + +#if defined(PNG_iCCP_SUPPORTED) + /* iCCP chunk data. */ + png_charp iccp_name; /* profile name */ + png_charp iccp_profile; /* International Color Consortium profile data */ + png_uint_32 iccp_proflen; /* ICC profile data length */ + png_byte iccp_compression; /* Always zero */ +#endif + +#if defined(PNG_sPLT_SUPPORTED) + /* data on sPLT chunks (there may be more than one). */ + png_spalette_p splt_palettes; + png_uint_32 splt_palettes_num; +#endif + +#if defined(PNG_sCAL_SUPPORTED) + /* The sCAL chunk describes the actual physical dimensions of the + * subject matter of the graphic. The chunk contains a unit specification + * (an ASCII string), and two ASCII strings representing floating-point + * values. The values are width and height corresponsing to one pixel + * in the image. This external representation is converted to double + * here. Data values are valid if (valid & PNG_INFO_sCAL) is non-zero. + */ + png_charp scal_unit; /* unit of physical scale */ + double scal_pixel_width; /* width of one pixel */ + double scal_pixel_height; /* height of one pixel */ +#endif + } png_info; + typedef png_info FAR * png_infop; typedef png_info FAR * FAR * png_infopp; @@ -558,12 +649,14 @@ typedef png_info FAR * FAR * png_infopp; #define PNG_RESOLUTION_LAST 2 /* Not a valid value */ /* These are for the sRGB chunk. These values should NOT be changed. */ -#define PNG_sRGB_INTENT_SATURATION 0 -#define PNG_sRGB_INTENT_PERCEPTUAL 1 -#define PNG_sRGB_INTENT_ABSOLUTE 2 -#define PNG_sRGB_INTENT_RELATIVE 3 +#define PNG_sRGB_INTENT_PERCEPTUAL 0 +#define PNG_sRGB_INTENT_RELATIVE 1 +#define PNG_sRGB_INTENT_SATURATION 2 +#define PNG_sRGB_INTENT_ABSOLUTE 3 #define PNG_sRGB_INTENT_LAST 4 /* Not a valid value */ +/* This is for text chunks */ +#define PNG_KEYWORD_MAX_LENGTH 79 /* These determine if an ancillary chunk's data has been successfully read @@ -583,6 +676,9 @@ typedef png_info FAR * FAR * png_infopp; #define PNG_INFO_tIME 0x0200 #define PNG_INFO_pCAL 0x0400 #define PNG_INFO_sRGB 0x0800 /* GR-P, 0.96a */ +#define PNG_INFO_iCCP 0x1000 /* ESR, 1.0.6 */ +#define PNG_INFO_sPLT 0x2000 /* ESR, 1.0.6 */ +#define PNG_INFO_sCAL 0x4000 /* ESR, 1.0.6 */ /* This is used for the transformation routines, as some of them * change these values for the row. It also should enable using @@ -615,18 +711,19 @@ typedef void (*png_rw_ptr) PNGARG((png_structp, png_bytep, png_size_t)); typedef void (*png_flush_ptr) PNGARG((png_structp)); typedef void (*png_read_status_ptr) PNGARG((png_structp, png_uint_32, int)); typedef void (*png_write_status_ptr) PNGARG((png_structp, png_uint_32, int)); + #ifdef PNG_PROGRESSIVE_READ_SUPPORTED typedef void (*png_progressive_info_ptr) PNGARG((png_structp, png_infop)); typedef void (*png_progressive_end_ptr) PNGARG((png_structp, png_infop)); typedef void (*png_progressive_row_ptr) PNGARG((png_structp, png_bytep, png_uint_32, int)); -#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ +#endif #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) typedef void (*png_user_transform_ptr) PNGARG((png_structp, png_row_infop, png_bytep)); -#endif /* PNG_READ|WRITE_USER_TRANSFORM_SUPPORTED */ +#endif typedef png_voidp (*png_malloc_ptr) PNGARG((png_structp, png_size_t)); typedef void (*png_free_ptr) PNGARG((png_structp, png_voidp)); @@ -648,12 +745,15 @@ struct png_struct_def 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*/ + #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) png_user_transform_ptr read_user_transform_fn; /* user read transform */ #endif + #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) png_user_transform_ptr write_user_transform_fn; /* user write transform */ #endif + #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) png_voidp user_transform_ptr; /* user supplied struct for user transform */ @@ -711,25 +811,29 @@ struct png_struct_def #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) png_uint_16 filler; /* filler bytes for pixel expansion */ -#endif /* PNG_READ_FILLER_SUPPORTED */ +#endif + #if defined(PNG_READ_bKGD_SUPPORTED) png_byte background_gamma_type; float background_gamma; png_color_16 background; /* background color in screen gamma space */ -#if defined(PNG_READ_GAMMA_SUPPORTED) - png_color_16 background_1; /* background normalized to gamma 1.0 */ -#endif /* PNG_READ_GAMMA && PNG_READ_bKGD_SUPPORTED */ +# if defined(PNG_READ_GAMMA_SUPPORTED) + png_color_16 background_1; /* background normalized to gamma 1.0 */ +# endif /* PNG_READ_GAMMA && PNG_READ_bKGD_SUPPORTED */ #endif /* PNG_READ_bKGD_SUPPORTED */ + #if defined(PNG_WRITE_FLUSH_SUPPORTED) png_flush_ptr output_flush_fn;/* Function for flushing output */ png_uint_32 flush_dist; /* how many rows apart to flush, 0 - no flush */ png_uint_32 flush_rows; /* number of rows written since last flush */ -#endif /* PNG_WRITE_FLUSH_SUPPORTED */ +#endif + #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) int gamma_shift; /* number of "insignificant" bits 16-bit gamma */ float gamma; /* file gamma value */ float screen_gamma; /* screen gamma value (display_exponent) */ -#endif /* PNG_READ_GAMMA_SUPPORTED */ +#endif + #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) png_bytep gamma_table; /* gamma table for 8-bit depth files */ png_bytep gamma_from_1; /* converts from 1.0 to screen */ @@ -737,18 +841,22 @@ struct png_struct_def png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */ png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */ png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */ -#endif /* PNG_READ_GAMMA_SUPPORTED || PNG_WRITE_GAMMA_SUPPORTED */ +#endif + #if defined(PNG_READ_GAMMA_SUPPORTED) || defined (PNG_READ_sBIT_SUPPORTED) png_color_8 sig_bit; /* significant bits in each available channel */ -#endif /* PNG_READ_GAMMA_SUPPORTED || PNG_READ_sBIT_SUPPORTED */ +#endif + #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) png_color_8 shift; /* shift for significant bit tranformation */ -#endif /* PNG_READ_SHIFT_SUPPORTED || PNG_WRITE_SHIFT_SUPPORTED */ +#endif + #if defined(PNG_READ_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \ || defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) png_bytep trans; /* transparency values for paletted files */ png_color_16 trans_values; /* transparency values for non-paletted files */ -#endif /* PNG_READ|WRITE_tRNS_SUPPORTED||PNG_READ_EXPAND|BACKGROUND_SUPPORTED */ +#endif + png_read_status_ptr read_row_fn; /* called after each row is decoded */ png_write_status_ptr write_row_fn; /* called after each row is encoded */ #ifdef PNG_PROGRESSIVE_READ_SUPPORTED @@ -767,13 +875,16 @@ struct png_struct_def png_size_t current_buffer_size; /* amount of data now in current_buffer */ int process_mode; /* what push library is currently doing */ int cur_palette; /* current push library palette index */ -#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED) - png_size_t current_text_size; /* current size of text input data */ - png_size_t current_text_left; /* how much text left to read in input */ - png_charp current_text; /* current text chunk buffer */ - png_charp current_text_ptr; /* current location in current_text */ -#endif /* PNG_PROGRESSIVE_READ_SUPPORTED && PNG_READ_tEXt/zTXt_SUPPORTED */ + +# if defined(PNG_READ_TEXT_SUPPORTED) + png_size_t current_text_size; /* current size of text input data */ + png_size_t current_text_left; /* how much text left to read in input */ + png_charp current_text; /* current text chunk buffer */ + png_charp current_text_ptr; /* current location in current_text */ +# endif /* PNG_PROGRESSIVE_READ_SUPPORTED && PNG_READ_TEXT_SUPPORTED */ + #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ + #if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__) /* for the Borland special 64K segment handler */ png_bytepp offset_table_ptr; @@ -781,14 +892,17 @@ struct png_struct_def png_uint_16 offset_table_number; png_uint_16 offset_table_count; png_uint_16 offset_table_count_free; -#endif /* __TURBOC__&&!_Windows&&!__FLAT__ */ +#endif + #if defined(PNG_READ_DITHER_SUPPORTED) png_bytep palette_lookup; /* lookup table for dithering */ png_bytep dither_index; /* index translation for palette files */ -#endif /* PNG_READ_DITHER_SUPPORTED */ +#endif + #if defined(PNG_READ_DITHER_SUPPORTED) || defined(PNG_READ_hIST_SUPPORTED) png_uint_16p hist; /* histogram */ #endif + #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) png_byte heuristic_method; /* heuristic for row filter selection */ png_byte num_prev_filters; /* number of weights for previous rows */ @@ -797,21 +911,25 @@ struct png_struct_def png_uint_16p inv_filter_weights; /* 1/weight(s) for previous line(s) */ png_uint_16p filter_costs; /* relative filter calculation cost */ png_uint_16p inv_filter_costs; /* 1/relative filter calculation cost */ -#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */ +#endif + #if defined(PNG_TIME_RFC1123_SUPPORTED) png_charp time_buffer; /* String to hold RFC 1123 time text */ -#endif /* PNG_TIME_RFC1123_SUPPORTED */ +#endif + #ifdef PNG_USER_MEM_SUPPORTED png_voidp mem_ptr; /* user supplied struct for mem functions */ png_malloc_ptr malloc_fn; /* function for allocating memory */ png_free_ptr free_fn; /* function for freeing memory */ -#endif /* PNG_USER_MEM_SUPPORTED */ +#endif + #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) png_byte rgb_to_gray_status; png_byte rgb_to_gray_red_coeff; png_byte rgb_to_gray_green_coeff; png_byte rgb_to_gray_blue_coeff; #endif + #if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \ defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) png_byte empty_plte_permitted; @@ -819,9 +937,9 @@ struct png_struct_def }; /* This prevents a compiler error in png_get_copyright() in png.c if png.c -and png.h are both at * version 1.0.5a +and png.h are both at * version 1.0.5f */ -typedef png_structp version_1_0_5a; +typedef png_structp version_1_0_5f; typedef png_struct FAR * FAR * png_structpp; @@ -894,6 +1012,8 @@ extern PNG_EXPORT(png_infop,png_create_info_struct) extern void png_info_init PNGARG((png_infop info_ptr)); /* Writes all the PNG information before the image. */ +extern PNG_EXPORT(void,png_write_info_before_PLTE) PNGARG((png_structp png_ptr, + png_infop info_ptr)); extern PNG_EXPORT(void,png_write_info) PNGARG((png_structp png_ptr, png_infop info_ptr)); @@ -904,7 +1024,7 @@ extern PNG_EXPORT(void,png_read_info) PNGARG((png_structp png_ptr, #if defined(PNG_TIME_RFC1123_SUPPORTED) extern PNG_EXPORT(png_charp,png_convert_to_rfc1123) PNGARG((png_structp png_ptr, png_timep ptime)); -#endif /* PNG_TIME_RFC1123_SUPPORTED */ +#endif #if defined(PNG_WRITE_tIME_SUPPORTED) /* convert from a struct tm to png_time */ @@ -922,17 +1042,17 @@ extern PNG_EXPORT(void,png_set_expand) PNGARG((png_structp png_ptr)); extern PNG_EXPORT(void,png_set_gray_1_2_4_to_8) PNGARG((png_structp png_ptr)); extern PNG_EXPORT(void,png_set_palette_to_rgb) PNGARG((png_structp png_ptr)); extern PNG_EXPORT(void,png_set_tRNS_to_alpha) PNGARG((png_structp png_ptr)); -#endif /* PNG_READ_EXPAND_SUPPORTED */ +#endif #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) /* Use blue, green, red order for pixels. */ extern PNG_EXPORT(void,png_set_bgr) PNGARG((png_structp png_ptr)); -#endif /* PNG_READ_BGR_SUPPORTED || PNG_WRITE_BGR_SUPPORTED */ +#endif #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) /* Expand the grayscale to 24-bit RGB if necessary. */ extern PNG_EXPORT(void,png_set_gray_to_rgb) PNGARG((png_structp png_ptr)); -#endif /* PNG_READ_GRAY_TO_RGB_SUPPORTED */ +#endif #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) /* Reduce RGB to grayscale. */ @@ -940,30 +1060,29 @@ extern PNG_EXPORT(void,png_set_rgb_to_gray) PNGARG((png_structp png_ptr, int error_action, double red, double green )); extern PNG_EXPORT(png_byte,png_get_rgb_to_gray_status) PNGARG((png_structp png_ptr)); -#endif /* PNG_READ_RGB_TO_GRAY_SUPPORTED */ +#endif extern PNG_EXPORT(void,png_build_grayscale_palette) PNGARG((int bit_depth, png_colorp palette)); #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED) extern PNG_EXPORT(void,png_set_strip_alpha) PNGARG((png_structp png_ptr)); -#endif /* PNG_READ_STRIP_ALPHA_SUPPORTED */ +#endif #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) extern PNG_EXPORT(void,png_set_swap_alpha) PNGARG((png_structp png_ptr)); -#endif /* PNG_READ_SWAP_ALPHA_SUPPORTED || PNG_WRITE_SWAP_ALPHA_SUPPORTED */ +#endif #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \ defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) extern PNG_EXPORT(void,png_set_invert_alpha) PNGARG((png_structp png_ptr)); -#endif /* PNG_READ_INVERT_ALPHA_SUPPORTED || PNG_WRITE_INVERT_ALPHA_SUPPORTED */ +#endif #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) /* Add a filler byte to 24-bit RGB images. */ extern PNG_EXPORT(void,png_set_filler) PNGARG((png_structp png_ptr, png_uint_32 filler, int flags)); - /* The values of the PNG_FILLER_ defines should NOT be changed */ #define PNG_FILLER_BEFORE 0 #define PNG_FILLER_AFTER 1 @@ -972,34 +1091,34 @@ extern PNG_EXPORT(void,png_set_filler) PNGARG((png_structp png_ptr, #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) /* Swap bytes in 16-bit depth files. */ extern PNG_EXPORT(void,png_set_swap) PNGARG((png_structp png_ptr)); -#endif /* PNG_READ_SWAP_SUPPORTED || PNG_WRITE_SWAP_SUPPORTED */ +#endif #if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) /* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */ extern PNG_EXPORT(void,png_set_packing) PNGARG((png_structp png_ptr)); -#endif /* PNG_READ_PACK_SUPPORTED || PNG_WRITE_PACK_SUPPORTED */ +#endif #if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED) /* Swap packing order of pixels in bytes. */ extern PNG_EXPORT(void,png_set_packswap) PNGARG((png_structp png_ptr)); -#endif /* PNG_READ_PACKSWAP_SUPPORTED || PNG_WRITE_PACKSWAP_SUPPORTED */ +#endif #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) /* Converts files to legal bit depths. */ extern PNG_EXPORT(void,png_set_shift) PNGARG((png_structp png_ptr, png_color_8p true_bits)); -#endif /* PNG_READ_SHIFT_SUPPORTED || PNG_WRITE_SHIFT_SUPPORTED */ +#endif #if defined(PNG_READ_INTERLACING_SUPPORTED) || \ defined(PNG_WRITE_INTERLACING_SUPPORTED) /* Have the code handle the interlacing. Returns the number of passes. */ extern PNG_EXPORT(int,png_set_interlace_handling) PNGARG((png_structp png_ptr)); -#endif /* PNG_READ_INTERLACING_SUPPORTED || PNG_WRITE_INTERLACING_SUPPORTED */ +#endif #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) /* Invert monocrome files */ extern PNG_EXPORT(void,png_set_invert_mono) PNGARG((png_structp png_ptr)); -#endif /* PNG_READ_INVERT_SUPPORTED || PNG_WRITE_INVERT_SUPPORTED */ +#endif #if defined(PNG_READ_BACKGROUND_SUPPORTED) /* Handle alpha and tRNS by replacing with a background color. */ @@ -1010,40 +1129,39 @@ extern PNG_EXPORT(void,png_set_background) PNGARG((png_structp png_ptr, #define PNG_BACKGROUND_GAMMA_SCREEN 1 #define PNG_BACKGROUND_GAMMA_FILE 2 #define PNG_BACKGROUND_GAMMA_UNIQUE 3 -#endif /* PNG_READ_BACKGROUND_SUPPORTED */ +#endif #if defined(PNG_READ_16_TO_8_SUPPORTED) /* strip the second byte of information from a 16-bit depth file. */ extern PNG_EXPORT(void,png_set_strip_16) PNGARG((png_structp png_ptr)); -#endif /* PNG_READ_16_TO_8_SUPPORTED */ +#endif #if defined(PNG_READ_DITHER_SUPPORTED) /* Turn on dithering, and reduce the palette to the number of colors available. */ extern PNG_EXPORT(void,png_set_dither) PNGARG((png_structp png_ptr, png_colorp palette, int num_palette, int maximum_colors, png_uint_16p histogram, int full_dither)); -#endif /* PNG_READ_DITHER_SUPPORTED */ +#endif #if defined(PNG_READ_GAMMA_SUPPORTED) /* Handle gamma correction. Screen_gamma=(display_exponent) */ extern PNG_EXPORT(void,png_set_gamma) PNGARG((png_structp png_ptr, double screen_gamma, double default_file_gamma)); -#endif /* PNG_READ_GAMMA_SUPPORTED */ +#endif #if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \ defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) /* Permit or disallow empty PLTE (0: not permitted, 1: permitted) */ extern PNG_EXPORT(void,png_permit_empty_plte) PNGARG((png_structp png_ptr, int empty_plte_permitted)); -#endif /* PNG_READ_EMPTY_PLTE_SUPPORTED */ +#endif #if defined(PNG_WRITE_FLUSH_SUPPORTED) /* Set how many lines between output flushes - 0 for no flushing */ extern PNG_EXPORT(void,png_set_flush) PNGARG((png_structp png_ptr, int nrows)); - /* Flush the current PNG output buffer */ extern PNG_EXPORT(void,png_write_flush) PNGARG((png_structp png_ptr)); -#endif /* PNG_WRITE_FLUSH_SUPPORTED */ +#endif /* optional update palette with requested transformations */ extern PNG_EXPORT(void,png_start_read_image) PNGARG((png_structp png_ptr)); @@ -1282,10 +1400,9 @@ extern PNG_EXPORT(void,png_set_write_status_fn) PNGARG((png_structp png_ptr, /* Replace the default memory allocation functions with user supplied one(s). */ extern PNG_EXPORT(void,png_set_mem_fn) PNGARG((png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn)); - /* Return the user pointer associated with the memory functions */ extern PNG_EXPORT(png_voidp,png_get_mem_ptr) PNGARG((png_structp png_ptr)); -#endif /* PNG_USER_MEM_SUPPORTED */ +#endif #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED extern PNG_EXPORT(void,png_set_read_user_transform_fn) PNGARG((png_structp @@ -1342,7 +1459,7 @@ extern PNG_EXPORT(png_voidp,png_malloc_default) PNGARG((png_structp png_ptr, png_uint_32 size)); extern PNG_EXPORT(void,png_free_default) PNGARG((png_structp png_ptr, png_voidp ptr)); -#endif /* PNG_USER_MEM_SUPPORTED */ +#endif extern PNG_EXPORT(png_voidp,png_memcpy_check) PNGARG((png_structp png_ptr, png_voidp s1, png_voidp s2, png_uint_32 size)); @@ -1455,45 +1572,45 @@ png_infop info_ptr)); #if defined(PNG_READ_bKGD_SUPPORTED) extern PNG_EXPORT(png_uint_32,png_get_bKGD) PNGARG((png_structp png_ptr, png_infop info_ptr, png_color_16p *background)); -#endif /* PNG_READ_bKGD_SUPPORTED */ +#endif -#if defined(PNG_READ_bKGD_SUPPORTED) || defined(PNG_WRITE_bKGD_SUPPORTED) +#if defined(PNG_bKGD_SUPPORTED) extern PNG_EXPORT(void,png_set_bKGD) PNGARG((png_structp png_ptr, png_infop info_ptr, png_color_16p background)); -#endif /* PNG_READ_bKGD_SUPPORTED || PNG_WRITE_bKGD_SUPPORTED */ +#endif #if defined(PNG_READ_cHRM_SUPPORTED) extern PNG_EXPORT(png_uint_32,png_get_cHRM) PNGARG((png_structp png_ptr, png_infop info_ptr, double *white_x, double *white_y, double *red_x, double *red_y, double *green_x, double *green_y, double *blue_x, double *blue_y)); -#endif /* PNG_READ_cHRM_SUPPORTED */ +#endif -#if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED) +#if defined(PNG_cHRM_SUPPORTED) extern PNG_EXPORT(void,png_set_cHRM) PNGARG((png_structp png_ptr, png_infop info_ptr, double white_x, double white_y, double red_x, double red_y, double green_x, double green_y, double blue_x, double blue_y)); -#endif /* PNG_READ_cHRM_SUPPORTED || PNG_WRITE_cHRM_SUPPORTED */ +#endif #if defined(PNG_READ_gAMA_SUPPORTED) extern PNG_EXPORT(png_uint_32,png_get_gAMA) PNGARG((png_structp png_ptr, png_infop info_ptr, double *file_gamma)); -#endif /* PNG_READ_gAMA_SUPPORTED */ +#endif -#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_WRITE_gAMA_SUPPORTED) +#if defined(PNG_gAMA_SUPPORTED) extern PNG_EXPORT(void,png_set_gAMA) PNGARG((png_structp png_ptr, png_infop info_ptr, double file_gamma)); -#endif /* PNG_READ_gAMA_SUPPORTED || PNG_WRITE_gAMA_SUPPORTED */ +#endif #if defined(PNG_READ_hIST_SUPPORTED) extern PNG_EXPORT(png_uint_32,png_get_hIST) PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_16p *hist)); -#endif /* PNG_READ_hIST_SUPPORTED */ +#endif -#if defined(PNG_READ_hIST_SUPPORTED) || defined(PNG_WRITE_hIST_SUPPORTED) +#if defined(PNG_hIST_SUPPORTED) extern PNG_EXPORT(void,png_set_hIST) PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_16p hist)); -#endif /* PNG_READ_hIST_SUPPORTED || PNG_WRITE_hIST_SUPPORTED */ +#endif extern PNG_EXPORT(png_uint_32,png_get_IHDR) PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 *width, png_uint_32 *height, @@ -1506,37 +1623,42 @@ extern PNG_EXPORT(void,png_set_IHDR) PNGARG((png_structp png_ptr, #if defined(PNG_READ_oFFs_SUPPORTED) extern PNG_EXPORT(png_uint_32,png_get_oFFs) PNGARG((png_structp png_ptr, - png_infop info_ptr, png_uint_32 *offset_x, png_uint_32 *offset_y, + png_infop info_ptr, png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type)); -#endif /* PNG_READ_oFFs_SUPPORTED */ +#endif -#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED) +#if defined(PNG_oFFs_SUPPORTED) extern PNG_EXPORT(void,png_set_oFFs) PNGARG((png_structp png_ptr, - png_infop info_ptr, png_uint_32 offset_x, png_uint_32 offset_y, + png_infop info_ptr, png_int_32 offset_x, png_int_32 offset_y, int unit_type)); -#endif /* PNG_READ_oFFs_SUPPORTED || PNG_WRITE_oFFs_SUPPORTED */ +#endif #if defined(PNG_READ_pCAL_SUPPORTED) extern PNG_EXPORT(png_uint_32,png_get_pCAL) PNGARG((png_structp png_ptr, png_infop info_ptr, png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams, png_charp *units, png_charpp *params)); -#endif /* PNG_READ_pCAL_SUPPORTED */ +#endif -#if defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) +#if defined(PNG_pCAL_SUPPORTED) extern PNG_EXPORT(void,png_set_pCAL) PNGARG((png_structp png_ptr, png_infop info_ptr, png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams, png_charp units, png_charpp params)); -#endif /* PNG_READ_pCAL_SUPPORTED || PNG_WRITE_pCAL_SUPPORTED */ +#endif + +#if defined(PNG_pCAL_SUPPORTED) +extern PNG_EXPORT(void,png_free_pCAL) PNGARG((png_structp png_ptr, + png_infop info_ptr)); +#endif #if defined(PNG_READ_pHYs_SUPPORTED) extern PNG_EXPORT(png_uint_32,png_get_pHYs) PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)); -#endif /* PNG_READ_pHYs_SUPPORTED */ +#endif -#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED) +#if defined(PNG_pHYs_SUPPORTED) extern PNG_EXPORT(void,png_set_pHYs) PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type)); -#endif /* PNG_READ_pHYs_SUPPORTED || PNG_WRITE_pHYs_SUPPORTED */ +#endif extern PNG_EXPORT(png_uint_32,png_get_PLTE) PNGARG((png_structp png_ptr, png_infop info_ptr, png_colorp *palette, int *num_palette)); @@ -1547,58 +1669,101 @@ extern PNG_EXPORT(void,png_set_PLTE) PNGARG((png_structp png_ptr, #if defined(PNG_READ_sBIT_SUPPORTED) extern PNG_EXPORT(png_uint_32,png_get_sBIT) PNGARG((png_structp png_ptr, png_infop info_ptr, png_color_8p *sig_bit)); -#endif /* PNG_READ_sBIT_SUPPORTED */ +#endif -#if defined(PNG_READ_sBIT_SUPPORTED) || defined(PNG_WRITE_sBIT_SUPPORTED) +#if defined(PNG_sBIT_SUPPORTED) extern PNG_EXPORT(void,png_set_sBIT) PNGARG((png_structp png_ptr, png_infop info_ptr, png_color_8p sig_bit)); -#endif /* PNG_READ_sBIT_SUPPORTED || PNG_WRITE_sBIT_SUPPORTED */ +#endif #if defined(PNG_READ_sRGB_SUPPORTED) extern PNG_EXPORT(png_uint_32,png_get_sRGB) PNGARG((png_structp png_ptr, png_infop info_ptr, int *intent)); -#endif /* PNG_READ_sRGB_SUPPORTED */ +#endif -#if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED) +#if defined(PNG_sRGB_SUPPORTED) extern PNG_EXPORT(void,png_set_sRGB) PNGARG((png_structp png_ptr, png_infop info_ptr, int intent)); extern PNG_EXPORT(void,png_set_sRGB_gAMA_and_cHRM) PNGARG((png_structp png_ptr, png_infop info_ptr, int intent)); -#endif /* PNG_READ_sRGB_SUPPORTED || PNG_WRITE_sRGB_SUPPORTED */ +#endif -#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED) -/* png_get_text also returns the number of text chunks in text_ptr */ +#if defined(PNG_READ_iCCP_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_iCCP) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_charpp name, int *compression_type, + png_charpp profile, png_int_32 *proflen)); +#endif + +#if defined(PNG_iCCP_SUPPORTED) +extern PNG_EXPORT(void,png_set_iCCP) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_charp name, int compression_type, + png_charp profile, int proflen)); +#endif + +#if defined(PNG_READ_sPLT_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_spalettes) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_spalette_pp entries)); +#endif + +#if defined(PNG_sPLT_SUPPORTED) +extern PNG_EXPORT(void,png_set_spalettes) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_spalette_p entries, int nentries)); +#endif + +#if defined(PNG_sPLT_SUPPORTED) +extern PNG_EXPORT(void,png_free_spallettes) PNGARG((png_structp png_ptr, + png_infop info_ptr, int num)); +#endif + +#if defined(PNG_READ_TEXT_SUPPORTED) +/* png_get_text also returns the number of text chunks in *num_text */ extern PNG_EXPORT(png_uint_32,png_get_text) PNGARG((png_structp png_ptr, png_infop info_ptr, png_textp *text_ptr, int *num_text)); -#endif /* PNG_READ_tEXt_SUPPORTED || PNG_READ_zTXt_SUPPORTED */ +#endif -#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \ - defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED) +#if defined(PNG_TEXT_SUPPORTED) extern PNG_EXPORT(void,png_set_text) PNGARG((png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, int num_text)); -#endif /* PNG_READ_OR_WRITE_tEXt_OR_zTXt_SUPPORTED */ +extern PNG_EXPORT(void,png_free_text) PNGARG((png_structp png_ptr, + png_infop info_ptr, int num_text)); +#endif #if defined(PNG_READ_tIME_SUPPORTED) extern PNG_EXPORT(png_uint_32,png_get_tIME) PNGARG((png_structp png_ptr, png_infop info_ptr, png_timep *mod_time)); -#endif /* PNG_READ_tIME_SUPPORTED */ +#endif -#if defined(PNG_READ_tIME_SUPPORTED) || defined(PNG_WRITE_tIME_SUPPORTED) +#if defined(PNG_tIME_SUPPORTED) extern PNG_EXPORT(void,png_set_tIME) PNGARG((png_structp png_ptr, png_infop info_ptr, png_timep mod_time)); -#endif /* PNG_READ_tIME_SUPPORTED || PNG_WRITE_tIME_SUPPORTED */ +#endif #if defined(PNG_READ_tRNS_SUPPORTED) extern PNG_EXPORT(png_uint_32,png_get_tRNS) PNGARG((png_structp png_ptr, png_infop info_ptr, png_bytep *trans, int *num_trans, png_color_16p *trans_values)); -#endif /* PNG_READ_tRNS_SUPPORTED */ +#endif -#if defined(PNG_READ_tRNS_SUPPORTED) || defined(PNG_WRITE_tRNS_SUPPORTED) +#if defined(PNG_tRNS_SUPPORTED) extern PNG_EXPORT(void,png_set_tRNS) PNGARG((png_structp png_ptr, png_infop info_ptr, png_bytep trans, int num_trans, png_color_16p trans_values)); -#endif /* PNG_READ_tRNS_SUPPORTED || PNG_WRITE_tRNS_SUPPORTED */ +#endif + +#if defined(PNG_READ_sCAL_SUPPORTED) +extern PNG_EXPORT(png_uint_32,png_get_sCAL) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_charpp unit, double *width, double *height)); +#endif /* PNG_READ_sCAL_SUPPORTED */ + +#if defined(PNG_READ_sCAL_SUPPORTED) || defined(PNG_WRITE_sCAL_SUPPORTED) +extern PNG_EXPORT(void,png_set_sCAL) PNGARG((png_structp png_ptr, + png_infop info_ptr, png_charp unit, double width, double height)); +#endif /* PNG_READ_sCAL_SUPPORTED || PNG_WRITE_sCAL_SUPPORTED */ + +#if defined(PNG_READ_sCAL_SUPPORTED) || defined(PNG_WRITE_sCAL_SUPPORTED) +extern PNG_EXPORT(void,png_free_sCAL) PNGARG((png_structp png_ptr, + png_infop info_ptr)); +#endif /* PNG_READ_sCAL_SUPPORTED || PNG_WRITE_sCAL_SUPPORTED */ /* Define PNG_DEBUG at compile time for debugging information. Higher * numbers for PNG_DEBUG mean more debugging information. This has @@ -1632,21 +1797,14 @@ extern PNG_EXPORT(void,png_set_tRNS) PNGARG((png_structp png_ptr, #define png_debug2(l, m, p1, p2) #endif +extern PNG_EXPORT(png_bytep,png_sig_bytes) PNGARG((png_structp png_ptr)); + extern PNG_EXPORT(png_charp,png_get_copyright) PNGARG((png_structp png_ptr)); +extern PNG_EXPORT(png_charp,png_get_header_ver) PNGARG((png_structp png_ptr)); extern PNG_EXPORT(png_charp,png_get_header_version) PNGARG((png_structp png_ptr)); +extern PNG_EXPORT(png_charp,png_get_libpng_ver) PNGARG((png_structp png_ptr)); -#ifdef PNG_NO_EXTERN -/* this only gets included in png.c */ - -#define PNG_GET_HEADER \ -png_charp \ -png_get_header_version(png_structp png_ptr) \ -{ \ - if(png_ptr != NULL) /* silence compiler warning about unused png_ptr */ \ - return("\n libpng version 1.0.5a - October 23, 1999 (header)\n"); \ - return("\n libpng version 1.0.5a - October 23, 1999 (header)\n"); \ -} -#endif +#define PNG_HEADER_VERSION_STRING " libpng version 1.0.5f - December 6, 1999 (header)\n" #ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED /* With these routines we avoid an integer divide, which will be slower on @@ -1700,25 +1858,19 @@ png_get_header_version(png_structp png_ptr) \ /* Various modes of operation. Note that after an init, mode is set to * zero automatically when the structure is created. */ -#define PNG_BEFORE_IHDR 0x00 -#define PNG_HAVE_IHDR 0x01 -#define PNG_HAVE_PLTE 0x02 -#define PNG_HAVE_IDAT 0x04 -#define PNG_AFTER_IDAT 0x08 -#define PNG_HAVE_IEND 0x10 -#define PNG_HAVE_gAMA 0x20 -#define PNG_HAVE_cHRM 0x40 -#define PNG_HAVE_sRGB 0x80 - -/* push model modes */ -#define PNG_READ_SIG_MODE 0 -#define PNG_READ_CHUNK_MODE 1 -#define PNG_READ_IDAT_MODE 2 -#define PNG_SKIP_MODE 3 -#define PNG_READ_tEXt_MODE 4 -#define PNG_READ_zTXt_MODE 5 -#define PNG_READ_DONE_MODE 6 -#define PNG_ERROR_MODE 7 +#define PNG_BEFORE_IHDR 0x00 +#define PNG_HAVE_IHDR 0x01 +#define PNG_HAVE_PLTE 0x02 +#define PNG_HAVE_IDAT 0x04 +#define PNG_AFTER_IDAT 0x08 +#define PNG_HAVE_IEND 0x10 +#define PNG_HAVE_gAMA 0x20 +#define PNG_HAVE_cHRM 0x40 +#define PNG_HAVE_sRGB 0x80 +#define PNG_HAVE_CHUNK_HEADER 0x100 +#define PNG_WROTE_tIME 0x200 +#define PNG_WROTE_INFO_BEFORE_PLTE 0x400 +#define PNG_BACKGROUND_IS_GRAY 0x800 /* flags for the transformations the PNG library does on the image data */ #define PNG_BGR 0x0001 @@ -1772,9 +1924,7 @@ png_get_header_version(png_structp png_ptr) \ #define PNG_FLAG_FREE_PALETTE 0x1000 #define PNG_FLAG_FREE_TRANS 0x2000 #define PNG_FLAG_FREE_HIST 0x4000 -#define PNG_FLAG_HAVE_CHUNK_HEADER 0x8000L -#define PNG_FLAG_WROTE_tIME 0x10000L -#define PNG_FLAG_BACKGROUND_IS_GRAY 0x20000L + #define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \ PNG_FLAG_CRC_ANCILLARY_NOWARN) @@ -1793,30 +1943,61 @@ png_get_header_version(png_structp png_ptr) \ /* variables declared in png.c - only it needs to define PNG_NO_EXTERN */ #if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN) /* place to hold the signature string for a PNG file. */ -extern png_byte FARDATA png_sig[8]; +#ifdef PNG_USE_GLOBAL_ARRAYS + PNG_EXPORT_VAR (png_byte FARDATA) png_sig[8]; +#else +#define png_sig png_sig_bytes(NULL) +#endif /* Constant strings for known chunk types. If you need to add a chunk, - * add a string holding the name here. See png.c for more details. We - * can't selectively include these, since we still check for chunk in the - * wrong locations with these labels. + * define the name here, and add an invocation of the macro in png.c and + * wherever it's needed. */ -extern png_byte FARDATA png_IHDR[5]; -extern png_byte FARDATA png_IDAT[5]; -extern png_byte FARDATA png_IEND[5]; -extern png_byte FARDATA png_PLTE[5]; -extern png_byte FARDATA png_bKGD[5]; -extern png_byte FARDATA png_cHRM[5]; -extern png_byte FARDATA png_gAMA[5]; -extern png_byte FARDATA png_hIST[5]; -extern png_byte FARDATA png_oFFs[5]; -extern png_byte FARDATA png_pCAL[5]; -extern png_byte FARDATA png_pHYs[5]; -extern png_byte FARDATA png_sBIT[5]; -extern png_byte FARDATA png_sRGB[5]; -extern png_byte FARDATA png_tEXt[5]; -extern png_byte FARDATA png_tIME[5]; -extern png_byte FARDATA png_tRNS[5]; -extern png_byte FARDATA png_zTXt[5]; +#define PNG_IHDR const png_byte png_IHDR[5] = { 73, 72, 68, 82, '\0'} +#define PNG_IDAT const png_byte png_IDAT[5] = { 73, 68, 65, 84, '\0'} +#define PNG_IEND const png_byte png_IEND[5] = { 73, 69, 78, 68, '\0'} +#define PNG_PLTE const png_byte png_PLTE[5] = { 80, 76, 84, 69, '\0'} +#define PNG_bKGD const png_byte png_bKGD[5] = { 98, 75, 71, 68, '\0'} +#define PNG_cHRM const png_byte png_cHRM[5] = { 99, 72, 82, 77, '\0'} +#define PNG_gAMA const png_byte png_gAMA[5] = {103, 65, 77, 65, '\0'} +#define PNG_hIST const png_byte png_hIST[5] = {104, 73, 83, 84, '\0'} +#define PNG_iCCP const png_byte png_iCCP[5] = {105, 67, 67, 80, '\0'} +#define PNG_iTXt const png_byte png_iTXt[5] = {105, 84, 88, 116, '\0'} +#define PNG_oFFs const png_byte png_oFFs[5] = {111, 70, 70, 115, '\0'} +#define PNG_pCAL const png_byte png_pCAL[5] = {112, 67, 65, 76, '\0'} +#define PNG_sCAL const png_byte png_sCAL[5] = {115, 67, 65, 76, '\0'} +#define PNG_pHYs const png_byte png_pHYs[5] = {112, 72, 89, 115, '\0'} +#define PNG_sBIT const png_byte png_sBIT[5] = {115, 66, 73, 84, '\0'} +#define PNG_sPLT const png_byte png_sPLT[5] = {115, 80, 76, 84, '\0'} +#define PNG_sRGB const png_byte png_sRGB[5] = {115, 82, 71, 66, '\0'} +#define PNG_tEXt const png_byte png_tEXt[5] = {116, 69, 88, 116, '\0'} +#define PNG_tIME const png_byte png_tIME[5] = {116, 73, 77, 69, '\0'} +#define PNG_tRNS const png_byte png_tRNS[5] = {116, 82, 78, 83, '\0'} +#define PNG_zTXt const png_byte png_zTXt[5] = {122, 84, 88, 116, '\0'} + +#ifdef PNG_USE_GLOBAL_ARRAYS +PNG_EXPORT_VAR (const png_byte FARDATA) png_IHDR[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_IDAT[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_IEND[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_PLTE[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_bKGD[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_cHRM[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_gAMA[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_hIST[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_iCCP[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_iTXt[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_oFFs[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_pCAL[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_sCAL[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_pHYs[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_sBIT[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_sPLT[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_sRGB[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_tEXt[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_tIME[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_tRNS[5]; +PNG_EXPORT_VAR (const png_byte FARDATA) png_zTXt[5]; +#endif /* PNG_USE_GLOBAL_ARRAYS */ #endif /* PNG_NO_EXTERN */ @@ -1852,10 +2033,10 @@ extern void png_read_init PNGARG((png_structp png_ptr)); */ extern void png_write_init PNGARG((png_structp png_ptr)); -/* allocate memory for an internal libpng struct */ +/* Allocate memory for an internal libpng struct */ PNG_EXTERN png_voidp png_create_struct PNGARG((int type)); -/* free memory from internal libpng struct */ +/* Free memory from internal libpng struct */ PNG_EXTERN void png_destroy_struct PNGARG((png_voidp struct_ptr)); PNG_EXTERN png_voidp png_create_struct_2 PNGARG((int type, png_malloc_ptr @@ -1863,17 +2044,17 @@ PNG_EXTERN png_voidp png_create_struct_2 PNGARG((int type, png_malloc_ptr PNG_EXTERN void png_destroy_struct_2 PNGARG((png_voidp struct_ptr, png_free_ptr free_fn)); -/* free any memory that info_ptr points to and reset struct. */ +/* Free any memory that info_ptr points to and reset struct. */ PNG_EXTERN void png_info_destroy PNGARG((png_structp png_ptr, png_infop info_ptr)); /* 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 */ +/* Function to free memory for zlib */ PNG_EXTERN void png_zfree PNGARG((voidpf png_ptr, voidpf ptr)); -/* reset the CRC variable */ +/* Reset the CRC variable */ PNG_EXTERN void png_reset_crc PNGARG((png_structp png_ptr)); /* Write the "data" buffer to whatever output you are using. */ @@ -1884,14 +2065,22 @@ PNG_EXTERN void png_write_data PNGARG((png_structp png_ptr, png_bytep data, PNG_EXTERN void png_read_data PNGARG((png_structp png_ptr, png_bytep data, png_size_t length)); -/* read bytes into buf, and update png_ptr->crc */ +/* Read bytes into buf, and update png_ptr->crc */ PNG_EXTERN void png_crc_read PNGARG((png_structp png_ptr, png_bytep buf, png_size_t length)); -/* read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */ +/* Decompress data in a chunk that uses compression */ +#if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \ + defined(PNG_READ_iCCP_SUPPORTED) || defined(PNG_READ_sPLT_SUPPORTED) +PNG_EXTERN png_charp png_decompress_chunk PNGARG((png_structp png_ptr, + int comp_type, png_charp chunkdata, png_size_t chunklength, + png_size_t prefix_size)); +#endif + +/* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */ PNG_EXTERN int png_crc_finish PNGARG((png_structp png_ptr, png_uint_32 skip)); -/* read the CRC from the file and compare it to the libpng calculated CRC */ +/* Read the CRC from the file and compare it to the libpng calculated CRC */ PNG_EXTERN int png_crc_error PNGARG((png_structp png_ptr)); /* Calculate the CRC over a section of data. Note that we are only @@ -1963,6 +2152,17 @@ PNG_EXTERN void png_write_sRGB PNGARG((png_structp png_ptr, int intent)); #endif +#if defined(PNG_WRITE_iCCP_SUPPORTED) +PNG_EXTERN void png_write_iCCP PNGARG((png_structp png_ptr, + png_charp name, int compression_type, + png_charp profile, int proflen)); +#endif + +#if defined(PNG_WRITE_sPLT_SUPPORTED) +PNG_EXTERN void png_write_sPLT PNGARG((png_structp png_ptr, + png_spalette_p palette)); +#endif + #if defined(PNG_WRITE_tRNS_SUPPORTED) PNG_EXTERN void png_write_tRNS PNGARG((png_structp png_ptr, png_bytep trans, png_color_16p values, int number, int color_type)); @@ -1978,8 +2178,8 @@ PNG_EXTERN void png_write_hIST PNGARG((png_structp png_ptr, png_uint_16p hist, int num_hist)); #endif -#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED) || \ - defined(PNG_WRITE_pCAL_SUPPORTED) +#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \ + defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) PNG_EXTERN png_size_t png_check_keyword PNGARG((png_structp png_ptr, png_charp key, png_charpp new_key)); #endif @@ -1994,6 +2194,11 @@ PNG_EXTERN void png_write_zTXt PNGARG((png_structp png_ptr, png_charp key, png_charp text, png_size_t text_len, int compression)); #endif +#if defined(PNG_WRITE_iTXt_SUPPORTED) +PNG_EXTERN void png_write_iTXt PNGARG((png_structp png_ptr, + int compression, png_charp key, png_charp lang, png_charp text)); +#endif + #if defined(PNG_WRITE_oFFs_SUPPORTED) PNG_EXTERN void png_write_oFFs PNGARG((png_structp png_ptr, png_uint_32 x_offset, png_uint_32 y_offset, int unit_type)); @@ -2016,6 +2221,11 @@ PNG_EXTERN void png_write_tIME PNGARG((png_structp png_ptr, png_timep mod_time)); #endif +#if defined(PNG_WRITE_sCAL_SUPPORTED) +PNG_EXTERN void png_write_sCAL PNGARG((png_structp png_ptr, + png_charp unit, double width, double height)); +#endif + /* Called when finished processing a row of data */ PNG_EXTERN void png_write_finish_row PNGARG((png_structp png_ptr)); @@ -2207,6 +2417,16 @@ PNG_EXTERN void png_handle_sRGB PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); #endif +#if defined(PNG_READ_iCCP_SUPPORTED) +extern void png_handle_iCCP PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif /* PNG_READ_iCCP_SUPPORTED */ + +#if defined(PNG_READ_sPLT_SUPPORTED) +extern void png_handle_sPLT PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif /* PNG_READ_sPLT_SUPPORTED */ + #if defined(PNG_READ_tRNS_SUPPORTED) PNG_EXTERN void png_handle_tRNS PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); @@ -2232,6 +2452,11 @@ PNG_EXTERN void png_handle_pCAL PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); #endif +#if defined(PNG_READ_sCAL_SUPPORTED) +PNG_EXTERN void png_handle_sCAL PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + #if defined(PNG_READ_pHYs_SUPPORTED) PNG_EXTERN void png_handle_pHYs PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); @@ -2252,6 +2477,11 @@ PNG_EXTERN void png_handle_zTXt PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); #endif +#if defined(PNG_READ_iTXt_SUPPORTED) +PNG_EXTERN void png_handle_iTXt PNGARG((png_structp png_ptr, png_infop info_ptr, + png_uint_32 length)); +#endif + PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); @@ -2306,6 +2536,12 @@ PNG_EXTERN void png_push_handle_zTXt PNGARG((png_structp png_ptr, PNG_EXTERN void png_push_read_zTXt PNGARG((png_structp png_ptr, png_infop info_ptr)); #endif +#if defined(PNG_READ_iTXt_SUPPORTED) +PNG_EXTERN void png_push_handle_iTXt PNGARG((png_structp png_ptr, + png_infop info_ptr, png_uint_32 length)); +PNG_EXTERN void png_push_read_iTXt PNGARG((png_structp png_ptr, + png_infop info_ptr)); +#endif #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ diff --git a/pngconf.h b/pngconf.h index 6c810557e..9884d049b 100644 --- a/pngconf.h +++ b/pngconf.h @@ -1,7 +1,7 @@ /* pngconf.h - machine configurable file for libpng * - * libpng 1.0.5a - October 23, 1999 + * libpng 1.0.5f - December 6, 1999 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. * Copyright (c) 1996, 1997 Andreas Dilger @@ -17,7 +17,9 @@ #ifndef PNGCONF_H #define PNGCONF_H -#define PNG_ZBUF_SIZE 524288 +#define PNG_NO_EASY_ACCESS +#define PNG_NO_READ_EMPTY_PLTE +#define PNG_NO_WRITE_TRANSFORMS #define PNG_READ_USER_TRANSFORM_SUPPORTED #define PNG_READ_STRIP_ALPHA_SUPPORTED #define PNG_READ_EXPAND_SUPPORTED @@ -26,8 +28,10 @@ #define PNG_READ_RGB_TO_GRAY_SUPPORTED #define PNG_READ_BACKGROUND_SUPPORTED #define PNG_READ_GAMMA_SUPPORTED -#define PNG_NO_WRITE_TRANSFORMS -#define PNG_NO_READ_EMPTY_PLTE +#define PNG_ZBUF_SIZE 524288 +/* +#define PNG_NO_GLOBAL_ARRAYS +*/ /* This is the size of the compression buffer, and thus the size of * an IDAT chunk. Make this whatever size you feel is best for your @@ -430,6 +434,16 @@ __dont__ include it again #define PNG_ASSEMBLER_CODE_SUPPORTED #endif +/* Do not use global arrays (helps with building DLL's) + * They are no longer used in libpng itself, since version 1.0.5c, + * but might be required for some pre-1.0.5c applications. + */ +#ifdef PNG_NO_GLOBAL_ARRAYS +#define PNG_USE_LOCAL_ARRAYS +#else +#define PNG_USE_GLOBAL_ARRAYS +#endif + /* These are currently experimental features, define them if you want */ /* very little testing */ @@ -468,87 +482,191 @@ __dont__ include it again #ifdef PNG_READ_ANCILLARY_CHUNKS_SUPPORTED #ifndef PNG_NO_READ_bKGD #define PNG_READ_bKGD_SUPPORTED +#define PNG_bKGD_SUPPORTED #endif #ifndef PNG_NO_READ_cHRM #define PNG_READ_cHRM_SUPPORTED +#define PNG_cHRM_SUPPORTED #endif #ifndef PNG_NO_READ_gAMA #define PNG_READ_gAMA_SUPPORTED +#define PNG_gAMA_SUPPORTED #endif #ifndef PNG_NO_READ_hIST #define PNG_READ_hIST_SUPPORTED +#define PNG_hIST_SUPPORTED +#endif +#ifndef PNG_NO_READ_iCCP +#define PNG_READ_iCCP_SUPPORTED +#define PNG_iCCP_SUPPORTED +#endif +#ifndef PNG_NO_READ_iTXt +#define PNG_READ_iTXt_SUPPORTED +#define PNG_iTXt_SUPPORTED #endif #ifndef PNG_NO_READ_oFFs #define PNG_READ_oFFs_SUPPORTED +#define PNG_oFFs_SUPPORTED #endif #ifndef PNG_NO_READ_pCAL #define PNG_READ_pCAL_SUPPORTED +#define PNG_pCAL_SUPPORTED +#endif +#ifndef PNG_NO_READ_sCAL +#define PNG_READ_sCAL_SUPPORTED +#define PNG_sCAL_SUPPORTED #endif #ifndef PNG_NO_READ_pHYs #define PNG_READ_pHYs_SUPPORTED +#define PNG_pHYs_SUPPORTED #endif #ifndef PNG_NO_READ_sBIT #define PNG_READ_sBIT_SUPPORTED +#define PNG_sBIT_SUPPORTED +#endif +#ifndef PNG_NO_READ_sPLT +#define PNG_READ_sPLT_SUPPORTED +#define PNG_sPLT_SUPPORTED #endif #ifndef PNG_NO_READ_sRGB #define PNG_READ_sRGB_SUPPORTED +#define PNG_sRGB_SUPPORTED #endif #ifndef PNG_NO_READ_tEXt #define PNG_READ_tEXt_SUPPORTED +#define PNG_tEXt_SUPPORTED #endif #ifndef PNG_NO_READ_tIME #define PNG_READ_tIME_SUPPORTED +#define PNG_tIME_SUPPORTED #endif #ifndef PNG_NO_READ_tRNS #define PNG_READ_tRNS_SUPPORTED +#define PNG_tRNS_SUPPORTED #endif #ifndef PNG_NO_READ_zTXt #define PNG_READ_zTXt_SUPPORTED +#define PNG_zTXt_SUPPORTED #endif #ifndef PNG_NO_READ_OPT_PLTE #define PNG_READ_OPT_PLTE_SUPPORTED /* only affects support of the optional */ #endif /* PLTE chunk in RGB and RGBA images */ +#if defined(PNG_READ_iTXt_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) || \ + defined(PNG_READ_zTXt_SUPPORTED) +#define PNG_READ_TEXT_SUPPORTED +#define PNG_TEXT_SUPPORTED +#endif #endif /* PNG_READ_ANCILLARY_CHUNKS_SUPPORTED */ #ifdef PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED #ifndef PNG_NO_WRITE_bKGD #define PNG_WRITE_bKGD_SUPPORTED +#ifndef PNG_bKGD_SUPPORTED +# define PNG_bKGD_SUPPORTED +#endif #endif #ifndef PNG_NO_WRITE_cHRM #define PNG_WRITE_cHRM_SUPPORTED +#ifndef PNG_cHRM_SUPPORTED +# define PNG_cHRM_SUPPORTED +#endif #endif #ifndef PNG_NO_WRITE_gAMA #define PNG_WRITE_gAMA_SUPPORTED +#ifndef PNG_gAMA_SUPPORTED +# define PNG_gAMA_SUPPORTED +#endif #endif #ifndef PNG_NO_WRITE_hIST #define PNG_WRITE_hIST_SUPPORTED +#ifndef PNG_hIST_SUPPORTED +# define PNG_hIST_SUPPORTED +#endif +#endif +#ifndef PNG_NO_WRITE_iCCP +#define PNG_WRITE_iCCP_SUPPORTED +#ifndef PNG_iCCP_SUPPORTED +# define PNG_iCCP_SUPPORTED +#endif +#endif +#ifndef PNG_NO_WRITE_iTXt +#define PNG_WRITE_iTXt_SUPPORTED +#ifndef PNG_iTXt_SUPPORTED +# define PNG_iTXt_SUPPORTED +#endif #endif #ifndef PNG_NO_WRITE_oFFs #define PNG_WRITE_oFFs_SUPPORTED +#ifndef PNG_oFFs_SUPPORTED +# define PNG_oFFs_SUPPORTED +#endif #endif #ifndef PNG_NO_WRITE_pCAL #define PNG_WRITE_pCAL_SUPPORTED +#ifndef PNG_pCAL_SUPPORTED +# define PNG_pCAL_SUPPORTED +#endif +#endif +#ifndef PNG_NO_WRITE_sCAL +#define PNG_WRITE_sCAL_SUPPORTED +#ifndef PNG_sCAL_SUPPORTED +# define PNG_sCAL_SUPPORTED +#endif #endif #ifndef PNG_NO_WRITE_pHYs #define PNG_WRITE_pHYs_SUPPORTED +#ifndef PNG_pHYs_SUPPORTED +# define PNG_pHYs_SUPPORTED +#endif #endif #ifndef PNG_NO_WRITE_sBIT #define PNG_WRITE_sBIT_SUPPORTED +#ifndef PNG_sBIT_SUPPORTED +# define PNG_sBIT_SUPPORTED +#endif +#endif +#ifndef PNG_NO_WRITE_sPLT +#define PNG_WRITE_sPLT_SUPPORTED +#ifndef PNG_sPLT_SUPPORTED +# define PNG_sPLT_SUPPORTED +#endif #endif #ifndef PNG_NO_WRITE_sRGB #define PNG_WRITE_sRGB_SUPPORTED +#ifndef PNG_sRGB_SUPPORTED +# define PNG_sRGB_SUPPORTED +#endif #endif #ifndef PNG_NO_WRITE_tEXt #define PNG_WRITE_tEXt_SUPPORTED +#ifndef PNG_tEXt_SUPPORTED +# define PNG_tEXt_SUPPORTED +#endif #endif #ifndef PNG_NO_WRITE_tIME #define PNG_WRITE_tIME_SUPPORTED +#ifndef PNG_tIME_SUPPORTED +# define PNG_tIME_SUPPORTED +#endif #endif #ifndef PNG_NO_WRITE_tRNS #define PNG_WRITE_tRNS_SUPPORTED +#ifndef PNG_tRNS_SUPPORTED +# define PNG_tRNS_SUPPORTED +#endif #endif #ifndef PNG_NO_WRITE_zTXt #define PNG_WRITE_zTXt_SUPPORTED +#ifndef PNG_zTXt_SUPPORTED +# define PNG_zTXt_SUPPORTED +#endif +#endif +#if defined(PNG_WRITE_iTXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \ + defined(PNG_WRITE_zTXt_SUPPORTED) +#define PNG_WRITE_TEXT_SUPPORTED +#ifndef PNG_TEXT_SUPPORTED +# define PNG_TEXT_SUPPORTED +#endif #endif #endif /* PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED */ @@ -696,6 +814,28 @@ typedef z_stream FAR * png_zstreamp; # define PNG_EXPORT(type,symbol) type symbol #endif +#if defined(__MINGW32__) || defined(__CYGWIN32__) +# define PNG_ATTR_DLLIMP +#endif + +#ifndef PNG_EXPORT_VAR +# ifdef PNG_DECL_DLLEXP +# define PNG_EXPORT_VAR(type) extern __declspec(dllexport) type +# endif +# ifdef PNG_ATTR_DLLEXP +# define PNG_EXPORT_VAR(type) extern type __attribute__((dllexport)) +# endif +# ifdef PNG_DECL_DLLIMP +# define PNG_EXPORT_VAR(type) extern __declspec(dllimport) type +# endif +# ifdef PNG_ATTR_DLLIMP +# define PNG_EXPORT_VAR(type) extern type __attribute__((dllimport)) +# endif +#endif + +#ifndef PNG_EXPORT_VAR +# define PNG_EXPORT_VAR(type) extern type +#endif /* User may want to use these so not in PNG_INTERNAL. Any library functions * that are passed far data must be model independent. diff --git a/pngcrush.c b/pngcrush.c index 617d65f4e..2a5f11039 100644 --- a/pngcrush.c +++ b/pngcrush.c @@ -14,7 +14,7 @@ * occasionally creating Linux executables. */ -#define PNGCRUSH_VERSION "1.2.0" +#define PNGCRUSH_VERSION "1.2.1" /* * COPYRIGHT NOTICE, DISCLAIMER, AND LICENSE: @@ -41,12 +41,26 @@ * or altered from any source or altered source distribution. */ -/* Version 1.2.*: check for unused alpha channel and ok-to-reduce-depth - * rearrange palette to put most-used color first and - * transparent color second. +/* To do: + * + * Version 1.2.*: check for unused alpha channel and ok-to-reduce-depth. + * Rearrange palette to put most-used color first and + * transparent color second. + * + * Version 1.2.2: Add iCCP, iTXt, sCAL, and sPLT support, which are + * now supported by libpng. + * + * Change log: + * + * Version 1.2.1: Fixed -srgb parameter so it really does take an argument, + * and so it continues to use "0" if an integer does not follow the -srgb. + * Added "-plte_len n" argument for truncating the PLTE. Be sure not to + * truncate it to less than the greatest index actually appearing in IDAT. * * Version 1.2.0: Removed registration requirement. Added open source - * license. Redefined TOO_FAR=32k in deflate.c + * license. Redefined TOO_FAR=32k in deflate.c. + * + * Changes prior to going "open source": * * Version 1.1.8: built with libpng-1.0.5a. Runs OK with pngvcrd.c. * @@ -165,6 +179,7 @@ static int z_strategy; static int best_of_three; static int methods_specified=0; static int intent=-1; +static int plte_len=-1; static double specified_gamma=0.; static double force_specified_gamma=0.; static int double_gamma=0; @@ -697,6 +712,11 @@ main(int argc, char *argv[]) nosave++; pngcrush_mode=EXTENSION_MODE; } + else if(!strncmp(argv[i],"-plte_len",9)) + { + names++; + plte_len=atoi(argv[++i]); + } else if(!strncmp(argv[i],"-p",2)) { pauses++; @@ -721,10 +741,19 @@ main(int argc, char *argv[]) else if( !strncmp(argv[i],"-srgb",5) || !strncmp(argv[i],"-sRGB",5)) { - names++; specified_gamma=.45455; intent=0; i++; + if(!strncmp(argv[i],"0",1) || + !strncmp(argv[i],"1",1) || + !strncmp(argv[i],"2",1) || + !strncmp(argv[i],"3",1)) + { + names++; + intent=(int)atoi(argv[i]); + } + else + i--; } else if(!strncmp(argv[i],"-s",2)) { @@ -1053,6 +1082,16 @@ main(int argc, char *argv[]) fprintf(STDERR, "\n Useful in conjunction with -v option to get info.\n\n"); + fprintf(STDERR, + " -plte_len n (truncate PLTE)\n"); + if(verbose > 1) + { + fprintf(STDERR, + "\n Truncates the PLTE. Be sure not to truncate it to\n"); + fprintf(STDERR, + "\n less than the greatest index present in IDAT.\n"); + + } fprintf(STDERR, " -q (quiet)\n"); if(verbose > 1) @@ -1173,7 +1212,7 @@ main(int argc, char *argv[]) fprintf(STDERR, "\n zlib compression strategy to use with the preceding\n"); fprintf(STDERR, - " preceding '-m method' argument.\n\n"); + " '-m method' argument.\n\n"); } #if 0 fprintf(STDERR, @@ -1558,7 +1597,7 @@ main(int argc, char *argv[]) (png_bytep)png_malloc(read_ptr, (png_uint_32)read_ptr->zbuf_size); } if(nosave == 0) - if(write_ptr->zbuf_size < (png_size_t)max_idat_size) + if(write_ptr->zbuf_size > (png_size_t)max_idat_size) { if(verbose > 2) printf("reinitializing write zbuf.\n"); @@ -1697,6 +1736,7 @@ main(int argc, char *argv[]) png_set_compression_window_bits(write_ptr, compression_window); } + if(verbose > 1) fprintf(STDERR, " Setting IHDR\n"); @@ -1833,7 +1873,7 @@ main(int argc, char *argv[]) #endif #if defined(PNG_READ_oFFs_SUPPORTED) && defined(PNG_WRITE_oFFs_SUPPORTED) { - png_uint_32 offset_x, offset_y; + png_int_32 offset_x, offset_y; int unit_type; if (png_get_oFFs(read_ptr, read_info_ptr,&offset_x,&offset_y,&unit_type)) @@ -1993,6 +2033,8 @@ main(int argc, char *argv[]) if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette)) { + if (plte_len > 0) + num_palette=plte_len; if(output_color_type == 3) png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette); else if(keep_chunk("PLTE",argv)) @@ -2477,6 +2519,10 @@ png_measure_idat(png_structp png_ptr, png_infop info_ptr) for(;;) { +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_IDAT; + PNG_IEND; +#endif png_byte chunk_length[4]; png_byte chunk_name[5]; png_uint_32 length; diff --git a/pngerror.c b/pngerror.c index b10072d67..b1674eb18 100644 --- a/pngerror.c +++ b/pngerror.c @@ -1,7 +1,7 @@ /* pngerror.c - stub functions for i/o and memory allocation * - * libpng 1.0.5a - October 23, 1999 + * libpng 1.0.5f - December 6, 1999 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. * Copyright (c) 1996, 1997 Andreas Dilger diff --git a/pngget.c b/pngget.c index 96204f11f..dd92fb01f 100644 --- a/pngget.c +++ b/pngget.c @@ -1,7 +1,7 @@ /* pngget.c - retrieval of values from info struct * - * libpng 1.0.5a - October 23, 1999 + * libpng 1.0.5f - December 6, 1999 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. * Copyright (c) 1996, 1997 Andreas Dilger @@ -104,7 +104,7 @@ png_get_compression_type(png_structp png_ptr, png_infop info_ptr) png_uint_32 png_get_x_pixels_per_meter(png_structp png_ptr, png_infop info_ptr) { -#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED) +#if defined(PNG_pHYs_SUPPORTED) if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) { png_debug1(1, "in %s retrieval function\n", "png_get_x_pixels_per_meter"); @@ -120,7 +120,7 @@ png_get_x_pixels_per_meter(png_structp png_ptr, png_infop info_ptr) png_uint_32 png_get_y_pixels_per_meter(png_structp png_ptr, png_infop info_ptr) { -#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED) +#if defined(PNG_pHYs_SUPPORTED) if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) { png_debug1(1, "in %s retrieval function\n", "png_get_y_pixels_per_meter"); @@ -136,7 +136,7 @@ png_get_y_pixels_per_meter(png_structp png_ptr, png_infop info_ptr) png_uint_32 png_get_pixels_per_meter(png_structp png_ptr, png_infop info_ptr) { -#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED) +#if defined(PNG_pHYs_SUPPORTED) if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) { png_debug1(1, "in %s retrieval function\n", "png_get_pixels_per_meter"); @@ -153,7 +153,7 @@ png_get_pixels_per_meter(png_structp png_ptr, png_infop info_ptr) float png_get_pixel_aspect_ratio(png_structp png_ptr, png_infop info_ptr) { -#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED) +#if defined(PNG_pHYs_SUPPORTED) if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) { png_debug1(1, "in %s retrieval function\n", "png_get_aspect_ratio"); @@ -171,7 +171,7 @@ png_get_pixel_aspect_ratio(png_structp png_ptr, png_infop info_ptr) png_uint_32 png_get_x_offset_microns(png_structp png_ptr, png_infop info_ptr) { -#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED) +#if defined(PNG_oFFs_SUPPORTED) if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) { png_debug1(1, "in %s retrieval function\n", "png_get_x_offset_microns"); @@ -187,7 +187,7 @@ png_get_x_offset_microns(png_structp png_ptr, png_infop info_ptr) png_uint_32 png_get_y_offset_microns(png_structp png_ptr, png_infop info_ptr) { -#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED) +#if defined(PNG_oFFs_SUPPORTED) if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) { png_debug1(1, "in %s retrieval function\n", "png_get_y_offset_microns"); @@ -203,7 +203,7 @@ png_get_y_offset_microns(png_structp png_ptr, png_infop info_ptr) png_uint_32 png_get_x_offset_pixels(png_structp png_ptr, png_infop info_ptr) { -#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED) +#if defined(PNG_oFFs_SUPPORTED) if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) { png_debug1(1, "in %s retrieval function\n", "png_get_x_offset_microns"); @@ -219,7 +219,7 @@ png_get_x_offset_pixels(png_structp png_ptr, png_infop info_ptr) png_uint_32 png_get_y_offset_pixels(png_structp png_ptr, png_infop info_ptr) { -#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED) +#if defined(PNG_oFFs_SUPPORTED) if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) { png_debug1(1, "in %s retrieval function\n", "png_get_y_offset_microns"); @@ -403,6 +403,39 @@ png_get_sRGB(png_structp png_ptr, png_infop info_ptr, int *file_srgb_intent) } #endif +#if defined(PNG_READ_iCCP_SUPPORTED) +png_uint_32 +png_get_iCCP(png_structp png_ptr, png_infop info_ptr, + png_charpp name, int *compression_type, + png_charpp profile, png_int_32 *proflen) +{ + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP) + && name != NULL && profile != NULL && proflen != NULL) + { + png_debug1(1, "in %s retrieval function\n", "iCCP"); + *name = info_ptr->iccp_name; + *profile = info_ptr->iccp_profile; + /* compression_type is a dummy so the API won't have to change + if we introduce multiple compression types later. */ + *proflen = (int)info_ptr->iccp_proflen; + *compression_type = (int)info_ptr->iccp_compression; + return (PNG_INFO_iCCP); + } + return (0); +} +#endif + +#if defined(PNG_READ_sPLT_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED) +png_uint_32 +png_get_spalettes(png_structp png_ptr, png_infop info_ptr, + png_spalette_pp spalettes) +{ + if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL) + *spalettes = info_ptr->splt_palettes; + return ((png_uint_32)info_ptr->splt_palettes_num); +} +#endif + #if defined(PNG_READ_hIST_SUPPORTED) png_uint_32 png_get_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p *hist) @@ -467,7 +500,7 @@ png_get_IHDR(png_structp png_ptr, png_infop info_ptr, #if defined(PNG_READ_oFFs_SUPPORTED) png_uint_32 png_get_oFFs(png_structp png_ptr, png_infop info_ptr, - png_uint_32 *offset_x, png_uint_32 *offset_y, int *unit_type) + png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type) { if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs) && offset_x != NULL && offset_y != NULL && unit_type != NULL) @@ -506,6 +539,22 @@ png_get_pCAL(png_structp png_ptr, png_infop info_ptr, } #endif +#if defined(PNG_READ_sCAL_SUPPORTED) || defined(PNG_WRITE_sCAL_SUPPORTED) +png_uint_32 +png_get_sCAL(png_structp png_ptr, png_infop info_ptr, + png_charpp unit, double *width, double *height) +{ + if (png_ptr != NULL && info_ptr != NULL && info_ptr->valid & PNG_INFO_sCAL) + { + *unit = info_ptr->scal_unit; + *width = info_ptr->scal_pixel_width; + *height = info_ptr->scal_pixel_height; + return (PNG_INFO_sCAL); + } + return(0); +} +#endif + #if defined(PNG_READ_pHYs_SUPPORTED) png_uint_32 png_get_pHYs(png_structp png_ptr, png_infop info_ptr, @@ -567,7 +616,7 @@ png_get_sBIT(png_structp png_ptr, png_infop info_ptr, png_color_8p *sig_bit) } #endif -#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED) +#if defined(PNG_READ_TEXT_SUPPORTED) png_uint_32 png_get_text(png_structp png_ptr, png_infop info_ptr, png_textp *text_ptr, int *num_text) diff --git a/pngmem.c b/pngmem.c index 35f49801a..18f7d9836 100644 --- a/pngmem.c +++ b/pngmem.c @@ -1,7 +1,7 @@ /* pngmem.c - stub functions for memory allocation * - * libpng 1.0.5a - October 23, 1999 + * libpng 1.0.5f - December 6, 1999 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. * Copyright (c) 1996, 1997 Andreas Dilger diff --git a/pngpread.c b/pngpread.c index 98108f327..691936c39 100644 --- a/pngpread.c +++ b/pngpread.c @@ -1,7 +1,7 @@ /* pngpread.c - read a png file in push mode * - * libpng 1.0.5a - October 23, 1999 + * libpng 1.0.5f - December 6, 1999 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. * Copyright (c) 1996, 1997 Andreas Dilger @@ -13,6 +13,17 @@ #ifdef PNG_PROGRESSIVE_READ_SUPPORTED +/* push model modes */ +#define PNG_READ_SIG_MODE 0 +#define PNG_READ_CHUNK_MODE 1 +#define PNG_READ_IDAT_MODE 2 +#define PNG_SKIP_MODE 3 +#define PNG_READ_tEXt_MODE 4 +#define PNG_READ_zTXt_MODE 5 +#define PNG_READ_DONE_MODE 6 +#define PNG_READ_iTXt_MODE 7 +#define PNG_ERROR_MODE 8 + void png_process_data(png_structp png_ptr, png_infop info_ptr, png_bytep buffer, png_size_t buffer_size) @@ -61,6 +72,13 @@ png_process_some_data(png_structp png_ptr, png_infop info_ptr) png_push_read_zTXt(png_ptr, info_ptr); break; } +#endif +#if defined(PNG_READ_iTXt_SUPPORTED) + case PNG_READ_iTXt_MODE: + { + png_push_read_iTXt(png_ptr, info_ptr); + break; + } #endif case PNG_SKIP_MODE: { @@ -116,13 +134,58 @@ png_push_read_sig(png_structp png_ptr, png_infop info_ptr) void png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) { +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_IHDR; + PNG_IDAT; + PNG_IEND; + PNG_PLTE; +#if defined(PNG_READ_bKGD_SUPPORTED) + PNG_bKGD; +#endif +#if defined(PNG_READ_cHRM_SUPPORTED) + PNG_cHRM; +#endif +#if defined(PNG_READ_gAMA_SUPPORTED) + PNG_gAMA; +#endif +#if defined(PNG_READ_hIST_SUPPORTED) + PNG_hIST; +#endif +#if defined(PNG_READ_oFFs_SUPPORTED) + PNG_oFFs; +#endif +#if defined(PNG_READ_pCAL_SUPPORTED) + PNG_pCAL; +#endif +#if defined(PNG_READ_pHYs_SUPPORTED) + PNG_pHYs; +#endif +#if defined(PNG_READ_sBIT_SUPPORTED) + PNG_sBIT; +#endif +#if defined(PNG_READ_sRGB_SUPPORTED) + PNG_sRGB; +#endif +#if defined(PNG_READ_tEXt_SUPPORTED) + PNG_tEXt; +#endif +#if defined(PNG_READ_tIME_SUPPORTED) + PNG_tIME; +#endif +#if defined(PNG_READ_tRNS_SUPPORTED) + PNG_tRNS; +#endif +#if defined(PNG_READ_zTXt_SUPPORTED) + PNG_zTXt; +#endif +#endif /* PNG_USE_LOCAL_ARRAYS */ /* First we make sure we have enough data for the 4 byte chunk name * and the 4 byte chunk length before proceeding with decoding the * chunk data. To fully decode each of these chunks, we also make * sure we have enough data in the buffer for the 4 byte CRC at the * end of every chunk (except IDAT, which is handled separately). */ - if (!(png_ptr->flags & PNG_FLAG_HAVE_CHUNK_HEADER)) + if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER)) { png_byte chunk_length[4]; @@ -136,7 +199,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_ptr->push_length = png_get_uint_32(chunk_length); png_reset_crc(png_ptr); png_crc_read(png_ptr, png_ptr->chunk_name, 4); - png_ptr->flags |= PNG_FLAG_HAVE_CHUNK_HEADER; + png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; } if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4)) @@ -159,7 +222,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length); } - else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) + else if (!png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4)) { /* If we reach an IDAT chunk, this means we have read all of the * header chunks, and we can start reading the image (or if this @@ -337,13 +400,19 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) { 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_zTXt, 4)) + { + png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length); + } #endif else { png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length); } - png_ptr->flags &= ~PNG_FLAG_HAVE_CHUNK_HEADER; + png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; } void @@ -496,7 +565,10 @@ png_push_restore_buffer(png_structp png_ptr, png_bytep buffer, void png_push_read_IDAT(png_structp png_ptr) { - if (!(png_ptr->flags & PNG_FLAG_HAVE_CHUNK_HEADER)) +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_IDAT; +#endif + if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER)) { png_byte chunk_length[4]; @@ -511,9 +583,9 @@ png_push_read_IDAT(png_structp png_ptr) png_reset_crc(png_ptr); png_crc_read(png_ptr, png_ptr->chunk_name, 4); - png_ptr->flags |= PNG_FLAG_HAVE_CHUNK_HEADER; + png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; - if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) + if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4)) { png_ptr->process_mode = PNG_READ_CHUNK_MODE; if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) @@ -576,7 +648,7 @@ png_push_read_IDAT(png_structp png_ptr) } png_crc_finish(png_ptr, 0); - png_ptr->flags &= ~PNG_FLAG_HAVE_CHUNK_HEADER; + png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; } } @@ -767,6 +839,32 @@ png_push_process_row(png_structp png_ptr) void png_read_push_finish_row(png_structp png_ptr) { +#ifdef PNG_USE_LOCAL_ARRAYS + /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* start of interlace block */ + const int png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; + + /* offset to next interlace block */ + const int png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; + + /* start of interlace block in the y direction */ + const int png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; + + /* offset to next interlace block in the y direction */ + const int png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; + + /* Width of interlace block. This is not currently used - if you need + * it, uncomment it here and in png.h + const int png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; + */ + + /* Height of interlace block. This is not currently used - if you need + * it, uncomment it here and in png.h + const int png_pass_height[] = {8, 8, 4, 4, 2, 2, 1}; + */ +#endif + png_ptr->row_number++; if (png_ptr->row_number < png_ptr->num_rows) return; @@ -878,6 +976,7 @@ png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr) text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text)); text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; + text_ptr->lang = (char *)NULL; text_ptr->key = key; text_ptr->text = text; @@ -1057,6 +1156,101 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr) text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text)); text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt; + text_ptr->lang = (char *)NULL; + text_ptr->key = key; + text_ptr->text = text; + + png_set_text(png_ptr, info_ptr, text_ptr, 1); + + png_free(png_ptr, text_ptr); + } +} +#endif + +#if defined(PNG_READ_iTXt_SUPPORTED) +void +png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + if (png_ptr->mode == PNG_BEFORE_IHDR || png_ptr->mode & PNG_HAVE_IEND) + { + png_error(png_ptr, "Out of place iTXt"); + /* to quiet some compiler warnings */ + if(info_ptr == NULL) return; + } + +#ifdef PNG_MAX_MALLOC_64K + png_ptr->skip_length = 0; /* This may not be necessary */ + + if (length > (png_uint_32)65535L) /* Can't hold the entire string in memory */ + { + png_warning(png_ptr, "iTXt chunk too large to fit in memory"); + png_ptr->skip_length = length - (png_uint_32)65535L; + length = (png_uint_32)65535L; + } +#endif + + png_ptr->current_text = (png_charp)png_malloc(png_ptr, + (png_uint_32)(length+1)); + png_ptr->current_text[length] = '\0'; + png_ptr->current_text_ptr = png_ptr->current_text; + png_ptr->current_text_size = (png_size_t)length; + png_ptr->current_text_left = (png_size_t)length; + png_ptr->process_mode = PNG_READ_iTXt_MODE; +} + +void +png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr) +{ + if (png_ptr->buffer_size && png_ptr->current_text_left) + { + png_size_t text_size; + + if (png_ptr->buffer_size < png_ptr->current_text_left) + text_size = png_ptr->buffer_size; + else + text_size = png_ptr->current_text_left; + png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size); + png_ptr->current_text_left -= text_size; + png_ptr->current_text_ptr += text_size; + } + if (!(png_ptr->current_text_left)) + { + png_textp text_ptr; + png_charp text; + png_charp lang; + png_charp key; + + if (png_ptr->buffer_size < 4) + { + png_push_save_buffer(png_ptr); + return; + } + + png_push_crc_finish(png_ptr); + +#if defined(PNG_MAX_MALLOC_64K) + if (png_ptr->skip_length) + return; +#endif + + lang = png_ptr->current_text; + png_ptr->current_text = 0; + + for (key = lang; *key; key++) + /* empty loop */ ; + + if (key != lang + png_ptr->current_text_size) + key++; + + for (text = key; *text; text++) + /* empty loop */ ; + + if (text != key + png_ptr->current_text_size) + text++; + + text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text)); + text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; + text_ptr->lang = lang; text_ptr->key = key; text_ptr->text = text; @@ -1115,6 +1309,9 @@ void png_progressive_combine_row (png_structp png_ptr, png_bytep old_row, png_bytep new_row) { +#ifdef PNG_USE_LOCAL_ARRAYS + const int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff}; +#endif if (new_row != NULL) /* new_row must == png_ptr->row_buf here. */ png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]); } diff --git a/pngread.c b/pngread.c index cd07bb4b6..ddad58134 100644 --- a/pngread.c +++ b/pngread.c @@ -1,7 +1,7 @@ /* pngread.c - read a PNG file * - * libpng 1.0.5a - October 23, 1999 + * libpng 1.0.5f - December 6, 1999 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. * Copyright (c) 1996, 1997 Andreas Dilger @@ -63,7 +63,7 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, #ifdef PNG_USER_MEM_SUPPORTED png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn); -#endif /* PNG_USER_MEM_SUPPORTED */ +#endif png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn); @@ -179,6 +179,63 @@ png_read_info(png_structp png_ptr, png_infop info_ptr) for(;;) { +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_IHDR; + PNG_IDAT; + PNG_IEND; + PNG_PLTE; +#if defined(PNG_READ_bKGD_SUPPORTED) + PNG_bKGD; +#endif +#if defined(PNG_READ_cHRM_SUPPORTED) + PNG_cHRM; +#endif +#if defined(PNG_READ_gAMA_SUPPORTED) + PNG_gAMA; +#endif +#if defined(PNG_READ_hIST_SUPPORTED) + PNG_hIST; +#endif +#if defined(PNG_READ_iCCP_SUPPORTED) + PNG_iCCP; +#endif +#if defined(PNG_READ_iTXt_SUPPORTED) + PNG_iTXt; +#endif +#if defined(PNG_READ_oFFs_SUPPORTED) + PNG_oFFs; +#endif +#if defined(PNG_READ_pCAL_SUPPORTED) + PNG_pCAL; +#endif +#if defined(PNG_READ_pHYs_SUPPORTED) + PNG_pHYs; +#endif +#if defined(PNG_READ_sBIT_SUPPORTED) + PNG_sBIT; +#endif +#if defined(PNG_READ_pCAL_SUPPORTED) + PNG_sCAL; +#endif +#if defined(PNG_READ_sPLT_SUPPORTED) + PNG_sPLT; +#endif +#if defined(PNG_READ_sRGB_SUPPORTED) + PNG_sRGB; +#endif +#if defined(PNG_READ_tEXt_SUPPORTED) + PNG_tEXt; +#endif +#if defined(PNG_READ_tIME_SUPPORTED) + PNG_tIME; +#endif +#if defined(PNG_READ_tRNS_SUPPORTED) + PNG_tRNS; +#endif +#if defined(PNG_READ_zTXt_SUPPORTED) + PNG_zTXt; +#endif +#endif /* PNG_GLOBAL_ARRAYS */ png_byte chunk_length[4]; png_uint_32 length; @@ -236,6 +293,10 @@ png_read_info(png_structp png_ptr, png_infop info_ptr) else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4)) png_handle_pCAL(png_ptr, info_ptr, length); #endif +#if defined(PNG_READ_sCAL_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4)) + png_handle_sCAL(png_ptr, info_ptr, length); +#endif #if defined(PNG_READ_pHYs_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4)) png_handle_pHYs(png_ptr, info_ptr, length); @@ -248,6 +309,14 @@ png_read_info(png_structp png_ptr, png_infop info_ptr) else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4)) png_handle_sRGB(png_ptr, info_ptr, length); #endif +#if defined(PNG_READ_iCCP_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4)) + png_handle_iCCP(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_sPLT_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4)) + png_handle_sPLT(png_ptr, info_ptr, length); +#endif #if defined(PNG_READ_tEXt_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4)) png_handle_tEXt(png_ptr, info_ptr, length); @@ -263,6 +332,10 @@ png_read_info(png_structp png_ptr, png_infop info_ptr) #if defined(PNG_READ_zTXt_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4)) png_handle_zTXt(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_iTXt_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4)) + png_handle_iTXt(png_ptr, info_ptr, length); #endif else png_handle_unknown(png_ptr, info_ptr, length); @@ -297,6 +370,11 @@ png_start_read_image(png_structp png_ptr) void png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) { +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_IDAT; + const int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff}; + const int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff}; +#endif int ret; png_debug2(1, "in png_read_row (row %d, pass %d)\n", png_ptr->row_number, png_ptr->pass); @@ -529,7 +607,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.0.5a. + * [*] png_handle_alpha() does not exist yet, as of libpng version 1.0.5f. */ void @@ -578,7 +656,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.0.5a. + * [*] png_handle_alpha() does not exist yet, as of libpng version 1.0.5f. */ void png_read_image(png_structp png_ptr, png_bytepp image) @@ -630,6 +708,64 @@ png_read_end(png_structp png_ptr, png_infop info_ptr) do { +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_IHDR; + PNG_IDAT; + PNG_IEND; + PNG_PLTE; +#if defined(PNG_READ_bKGD_SUPPORTED) + PNG_bKGD; +#endif +#if defined(PNG_READ_cHRM_SUPPORTED) + PNG_cHRM; +#endif +#if defined(PNG_READ_gAMA_SUPPORTED) + PNG_gAMA; +#endif +#if defined(PNG_READ_hIST_SUPPORTED) + PNG_hIST; +#endif +#if defined(PNG_READ_iCCP_SUPPORTED) + PNG_iCCP; +#endif +#if defined(PNG_READ_iTXt_SUPPORTED) + PNG_iTXt; +#endif +#if defined(PNG_READ_oFFs_SUPPORTED) + PNG_oFFs; +#endif +#if defined(PNG_READ_pCAL_SUPPORTED) + PNG_pCAL; +#endif +#if defined(PNG_READ_pHYs_SUPPORTED) + PNG_pHYs; +#endif +#if defined(PNG_READ_sBIT_SUPPORTED) + PNG_sBIT; +#endif +#if defined(PNG_READ_pCAL_SUPPORTED) + PNG_sCAL; +#endif +#if defined(PNG_READ_sPLT_SUPPORTED) + PNG_sPLT; +#endif +#if defined(PNG_READ_sRGB_SUPPORTED) + PNG_sRGB; +#endif +#if defined(PNG_READ_tEXt_SUPPORTED) + PNG_tEXt; +#endif +#if defined(PNG_READ_tIME_SUPPORTED) + PNG_tIME; +#endif +#if defined(PNG_READ_tRNS_SUPPORTED) + PNG_tRNS; +#endif +#if defined(PNG_READ_zTXt_SUPPORTED) + PNG_zTXt; +#endif +#endif /* PNG_GLOBAL_ARRAYS */ + png_read_data(png_ptr, chunk_length, 4); length = png_get_uint_32(chunk_length); @@ -678,6 +814,10 @@ png_read_end(png_structp png_ptr, png_infop info_ptr) else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4)) png_handle_pCAL(png_ptr, info_ptr, length); #endif +#if defined(PNG_READ_sCAL_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4)) + png_handle_sCAL(png_ptr, info_ptr, length); +#endif #if defined(PNG_READ_pHYs_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4)) png_handle_pHYs(png_ptr, info_ptr, length); @@ -690,6 +830,14 @@ png_read_end(png_structp png_ptr, png_infop info_ptr) else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4)) png_handle_sRGB(png_ptr, info_ptr, length); #endif +#if defined(PNG_READ_iCCP_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4)) + png_handle_iCCP(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_sPLT_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4)) + png_handle_sPLT(png_ptr, info_ptr, length); +#endif #if defined(PNG_READ_tEXt_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4)) png_handle_tEXt(png_ptr, info_ptr, length); @@ -705,6 +853,10 @@ png_read_end(png_structp png_ptr, png_infop info_ptr) #if defined(PNG_READ_zTXt_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4)) png_handle_zTXt(png_ptr, info_ptr, length); +#endif +#if defined(PNG_READ_iTXt_SUPPORTED) + else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4)) + png_handle_iTXt(png_ptr, info_ptr, length); #endif else png_handle_unknown(png_ptr, info_ptr, length); @@ -720,7 +872,7 @@ png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr, png_infop info_ptr = NULL, end_info_ptr = NULL; #ifdef PNG_USER_MEM_SUPPORTED png_free_ptr free_fn = NULL; -#endif /* PNG_USER_MEM_SUPPORTED */ +#endif png_debug(1, "in png_destroy_read_struct\n"); /* save jump buffer and error functions */ @@ -741,7 +893,7 @@ png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr, if (info_ptr != NULL) { -#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED) +#if defined(PNG_TEXT_SUPPORTED) png_free(png_ptr, info_ptr->text); #endif @@ -755,7 +907,7 @@ png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr, if (end_info_ptr != NULL) { -#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED) +#if defined(PNG_READ_TEXT_SUPPORTED) png_free(png_ptr, end_info_ptr->text); #endif #ifdef PNG_USER_MEM_SUPPORTED @@ -813,7 +965,7 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr #endif if (png_ptr->flags & PNG_FLAG_FREE_PALETTE) png_zfree(png_ptr, png_ptr->palette); -#if defined(PNG_READ_tRNS_SUPPORTED) || defined(PNG_WRITE_tRNS_SUPPORTED) || \ +#if defined(PNG_tRNS_SUPPORTED) || \ defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) if (png_ptr->flags & PNG_FLAG_FREE_TRANS) png_free(png_ptr, png_ptr->trans); @@ -858,7 +1010,7 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr #endif #if defined(PNG_TIME_RFC1123_SUPPORTED) png_free(png_ptr, png_ptr->time_buffer); -#endif /* PNG_TIME_RFC1123_SUPPORTED */ +#endif inflateEnd(&png_ptr->zstream); #ifdef PNG_PROGRESSIVE_READ_SUPPORTED diff --git a/pngrio.c b/pngrio.c index ba1c9963d..a8c1657af 100644 --- a/pngrio.c +++ b/pngrio.c @@ -1,7 +1,7 @@ /* pngrio.c - functions for data input * - * libpng 1.0.5a - October 23, 1999 + * libpng 1.0.5f - December 6, 1999 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. * Copyright (c) 1996, 1997 Andreas Dilger @@ -146,6 +146,6 @@ png_set_read_fn(png_structp png_ptr, png_voidp io_ptr, #if defined(PNG_WRITE_FLUSH_SUPPORTED) png_ptr->output_flush_fn = NULL; -#endif /* PNG_WRITE_FLUSH_SUPPORTED */ +#endif } diff --git a/pngrtran.c b/pngrtran.c index 693befcd5..9215bfac7 100644 --- a/pngrtran.c +++ b/pngrtran.c @@ -1,7 +1,7 @@ /* pngrtran.c - transforms the data in a row for PNG readers * - * libpng 1.0.5a - October 23, 1999 + * libpng 1.0.5f - December 6, 1999 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. * Copyright (c) 1996, 1997 Andreas Dilger @@ -92,13 +92,13 @@ png_set_background(png_structp png_ptr, /* Note: if need_expand is set and color_type is either RGB or RGB_ALPHA * (in which case need_expand is superfluous anyway), the background color * might actually be gray yet not be flagged as such. This is not a problem - * for the current code, which uses PNG_FLAG_BACKGROUND_IS_GRAY only to + * for the current code, which uses PNG_BACKGROUND_IS_GRAY only to * decide when to do the png_do_gray_to_rgb() transformation. */ if ((need_expand && !(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) || (!need_expand && background_color->red == background_color->green && background_color->red == background_color->blue)) - png_ptr->flags |= PNG_FLAG_BACKGROUND_IS_GRAY; + png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; } #endif @@ -1171,7 +1171,7 @@ From Andreas Dilger e-mail to png-implement, 26 March 1998: /* if gray -> RGB, do so now only if background is non-gray; else do later * for performance reasons */ if (png_ptr->transformations & PNG_GRAY_TO_RGB && - !(png_ptr->flags & PNG_FLAG_BACKGROUND_IS_GRAY)) + !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1); #endif @@ -1245,7 +1245,7 @@ From Andreas Dilger e-mail to png-implement, 26 March 1998: #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) /* if gray -> RGB, do so now only if we did not do so above */ if (png_ptr->transformations & PNG_GRAY_TO_RGB && - png_ptr->flags & PNG_FLAG_BACKGROUND_IS_GRAY) + png_ptr->mode & PNG_BACKGROUND_IS_GRAY) png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1); #endif diff --git a/pngrutil.c b/pngrutil.c index 7d103137a..4669b4ef8 100644 --- a/pngrutil.c +++ b/pngrutil.c @@ -1,7 +1,7 @@ /* pngrutil.c - utilities to read a PNG file * - * libpng 1.0.5a - October 23, 1999 + * libpng 1.0.5f - December 6, 1999 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. * Copyright (c) 1996, 1997 Andreas Dilger @@ -136,6 +136,125 @@ png_crc_error(png_structp png_ptr) return (0); } +#if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \ + defined(PNG_READ_iCCP_SUPPORTED) || defined(PNG_READ_sPLT_SUPPORTED) +/* + * Decompress trailing data in a chunk. The assumption is that chunkdata + * points at an allocated area holding the contents of a chunk with a + * trailing compressed part. What we get back is an allocated area + * holding the original prefix part and an uncompressed version of the + * trailing part (the malloc area passed in is freed). + */ +png_charp png_decompress_chunk(png_structp png_ptr, int comp_type, + png_charp chunkdata, png_size_t chunklength, + png_size_t prefix_size) +{ + static char msg[] = "Error decoding compressed text"; + png_charp text = NULL; + png_size_t text_size = (chunklength - prefix_size); + + if (comp_type == PNG_TEXT_COMPRESSION_zTXt) + { + png_ptr->zstream.next_in = (png_bytep)(chunkdata + prefix_size); + png_ptr->zstream.avail_in = (uInt)(chunklength - prefix_size); + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + + text_size = 0; + text = NULL; + + while (png_ptr->zstream.avail_in) + { + int ret; + + ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); + if (ret != Z_OK && ret != Z_STREAM_END) + { + if (png_ptr->zstream.msg != NULL) + png_warning(png_ptr, png_ptr->zstream.msg); + else + png_warning(png_ptr, msg); + inflateReset(&png_ptr->zstream); + png_ptr->zstream.avail_in = 0; + + if (text == NULL) + { + text_size = prefix_size + sizeof(msg) + 1; + text = (png_charp)png_malloc(png_ptr, text_size); + png_memcpy(text, chunkdata, prefix_size); + } + + text[text_size - 1] = 0x00; + + /* Copy what we can of the error message into the text chunk */ + text_size = (png_size_t)(chunklength - (text - chunkdata) - 1); + text_size = sizeof(msg) > text_size ? text_size : sizeof(msg); + png_memcpy(text + prefix_size, msg, text_size + 1); + break; + } + if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END) + { + if (text == NULL) + { + text_size = prefix_size + + png_ptr->zbuf_size - png_ptr->zstream.avail_out; + text = (png_charp)png_malloc(png_ptr, text_size + 1); + png_memcpy(text + prefix_size, png_ptr->zbuf, + text_size - prefix_size); + png_memcpy(text, chunkdata, prefix_size); + *(text + text_size) = 0x00; + } + else + { + png_charp tmp; + + tmp = text; + text = (png_charp)png_malloc(png_ptr, (png_uint_32)(text_size + + png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1)); + png_memcpy(text, tmp, text_size); + png_free(png_ptr, tmp); + png_memcpy(text + text_size, png_ptr->zbuf, + (png_ptr->zbuf_size - png_ptr->zstream.avail_out)); + text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out; + *(text + text_size) = 0x00; + } + if (ret == Z_STREAM_END) + break; + else + { + png_ptr->zstream.next_out = png_ptr->zbuf; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + } + } + } + + inflateReset(&png_ptr->zstream); + png_ptr->zstream.avail_in = 0; + + png_free(png_ptr, chunkdata); + chunkdata = text; + } + else /* if (comp_type >= PNG_TEXT_COMPRESSION_LAST) */ + { + png_size_t text_size; +#if !defined(PNG_NO_STDIO) + char umsg[50]; + + sprintf(umsg, "Unknown zTXt compression type %d", comp_type); + png_warning(png_ptr, umsg); +#else + png_warning(png_ptr, "Unknown zTXt compression type"); +#endif + + /* Copy what we can of the error message into the text chunk */ + text_size = (png_size_t)(chunklength - (text - chunkdata)); + text_size = sizeof(msg) > text_size ? text_size : sizeof(msg); + png_memcpy(text, msg, text_size); + } + + return chunkdata; +} +#endif /* read and check the IDHR chunk */ void @@ -726,6 +845,195 @@ png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } #endif /* PNG_READ_sRGB_SUPPORTED */ +#if defined(PNG_READ_iCCP_SUPPORTED) +void +png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +/* Note: this does not properly handle chunks that are > 64K under DOS */ +{ + png_charp chunkdata; + png_byte compression_type; + png_charp profile; + png_uint_32 skip = 0; + png_size_t slength, prefix_length; + + png_debug(1, "in png_handle_iCCP\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before iCCP"); + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid iCCP after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + else if (png_ptr->mode & PNG_HAVE_PLTE) + /* Should be an error, but we can cope with it */ + png_warning(png_ptr, "Out of place iCCP chunk"); + + else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_iCCP) + { + png_warning(png_ptr, "Duplicate iCCP chunk"); + png_crc_finish(png_ptr, length); + return; + } + +#ifdef PNG_MAX_MALLOC_64K + if (length > (png_uint_32)65535L) + { + png_warning(png_ptr, "iCCP chunk too large to fit in memory"); + skip = length - (png_uint_32)65535L; + length = (png_uint_32)65535L; + } +#endif + + chunkdata = (png_charp)png_malloc(png_ptr, length + 1); + slength = (png_size_t)length; + png_crc_read(png_ptr, (png_bytep)chunkdata, slength); + + if (png_crc_finish(png_ptr, skip)) + { + png_free(png_ptr, chunkdata); + return; + } + + chunkdata[slength] = 0x00; + + for (profile = chunkdata; *profile; profile++) + /* empty loop to find end of name */ ; + ++profile; + + /* there should be at least one NUL (the compression type byte) + following the separator, and we should be on it */ + if (profile >= chunkdata + slength) + { + png_free(png_ptr, chunkdata); + png_error(png_ptr, "malformed iCCP chunk"); + } + + /* compression should always be zero */ + compression_type = *profile++; + + prefix_length = profile - chunkdata; + chunkdata = png_decompress_chunk(png_ptr, compression_type, chunkdata, + slength, prefix_length); + + png_set_iCCP(png_ptr, info_ptr, chunkdata, compression_type, + chunkdata + prefix_length, png_strlen(chunkdata + prefix_length)); + png_free(png_ptr, chunkdata); +} +#endif /* PNG_READ_iCCP_SUPPORTED */ + +#if defined(PNG_READ_sPLT_SUPPORTED) +void +png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +/* Note: this does not properly handle chunks that are > 64K under DOS */ +{ + png_bytep chunkdata; + png_bytep entry_start; + png_spalette new_palette; + int data_length, entry_size, i; + png_uint_32 skip = 0; + png_size_t slength; + + png_debug(1, "in png_handle_sPLT\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before sPLT"); + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid sPLT after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + else if (png_ptr->mode & PNG_HAVE_PLTE) + /* Should be an error, but we can cope with it */ + png_warning(png_ptr, "Out of place sPLT chunk"); + + else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_sPLT) + { + png_warning(png_ptr, "Duplicate sPLT chunk"); + png_crc_finish(png_ptr, length); + return; + } + +#ifdef PNG_MAX_MALLOC_64K + if (length > (png_uint_32)65535L) + { + png_warning(png_ptr, "sPLT chunk too large to fit in memory"); + skip = length - (png_uint_32)65535L; + length = (png_uint_32)65535L; + } +#endif + + chunkdata = (png_bytep)png_malloc(png_ptr, length + 1); + slength = (png_size_t)length; + png_crc_read(png_ptr, chunkdata, slength); + + if (png_crc_finish(png_ptr, skip)) + { + png_free(png_ptr, chunkdata); + return; + } + + chunkdata[slength] = 0x00; + + for (entry_start = chunkdata; *entry_start; entry_start++) + /* empty loop to find end of name */ ; + ++entry_start; + + /* a sample depth should follow the separator, and we should be on it */ + if (entry_start > chunkdata + slength) + { + png_free(png_ptr, chunkdata); + png_error(png_ptr, "malformed sPLT chunk"); + } + + new_palette.depth = *entry_start++; + entry_size = (new_palette.depth == 8 ? 6 : 10); + data_length = (slength - (entry_start - chunkdata)); + + /* integrity-check the data length */ + if (data_length % entry_size) + { + png_free(png_ptr, chunkdata); + png_error(png_ptr, "sPLT chunk has bad length"); + } + + new_palette.nentries = data_length / entry_size; + new_palette.entries = (png_spalette_entryp)png_malloc( + png_ptr, new_palette.nentries * sizeof(png_spalette_entry)); + + for (i = 0; i < new_palette.nentries; i++) + { + png_spalette_entryp pp = new_palette.entries + i; + + if (new_palette.depth == 8) + { + pp->red = *entry_start++; + pp->green = *entry_start++; + pp->blue = *entry_start++; + pp->alpha = *entry_start++; + } + else + { + pp->red = png_get_uint_16(entry_start); entry_start += 2; + pp->green = png_get_uint_16(entry_start); entry_start += 2; + pp->blue = png_get_uint_16(entry_start); entry_start += 2; + pp->alpha = png_get_uint_16(entry_start); entry_start += 2; + } + pp->frequency = png_get_uint_16(entry_start); entry_start += 2; + } + + /* discard all chunk data except the name and stash that */ + new_palette.name = (png_charp)chunkdata; + + png_set_spalettes(png_ptr, info_ptr, &new_palette, 1); + + png_free(png_ptr, chunkdata); + png_free(png_ptr, new_palette.entries); +} +#endif /* PNG_READ_sPLT_SUPPORTED */ + #if defined(PNG_READ_tRNS_SUPPORTED) void png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) @@ -1012,7 +1320,7 @@ void png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { png_byte buf[9]; - png_uint_32 offset_x, offset_y; + png_int_32 offset_x, offset_y; int unit_type; png_debug(1, "in png_handle_oFFs\n"); @@ -1043,8 +1351,8 @@ png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) if (png_crc_finish(png_ptr, 0)) return; - offset_x = png_get_uint_32(buf); - offset_y = png_get_uint_32(buf + 4); + offset_x = png_get_int_32(buf); + offset_y = png_get_int_32(buf + 4); unit_type = buf[8]; png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type); } @@ -1167,6 +1475,77 @@ png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } #endif +#if defined(PNG_READ_sCAL_SUPPORTED) +/* read the sCAL chunk */ +void +png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_charp unit, ep, vp; + double width, height; + png_size_t slength; + + png_debug(1, "in png_handle_sCAL\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before sCAL"); + else if (png_ptr->mode & PNG_HAVE_IDAT) + { + png_warning(png_ptr, "Invalid sCAL after IDAT"); + png_crc_finish(png_ptr, length); + return; + } + else if (info_ptr != NULL && info_ptr->valid & PNG_INFO_sCAL) + { + png_warning(png_ptr, "Duplicate sCAL chunk"); + png_crc_finish(png_ptr, length); + return; + } + + png_debug1(2, "Allocating and reading sCAL chunk data (%d bytes)\n", + length + 1); + unit = (png_charp)png_malloc(png_ptr, length + 1); + slength = (png_size_t)length; + png_crc_read(png_ptr, (png_bytep)unit, slength); + + if (png_crc_finish(png_ptr, 0)) + { + png_free(png_ptr, unit); + return; + } + + unit[slength] = 0x00; /* null terminate the last string */ + + png_debug(3, "Finding end of sCAL unit string\n"); + for (ep = unit; *ep; ep++) + /* empty loop */ ; + ep++; + + width = strtod(ep, &vp); + if (*vp) + png_error(png_ptr, "malformed width string in sCAL chunk"); + + for (ep = unit; *ep; ep++) + /* empty loop */ ; + ep++; + + height = strtod(ep, &vp); + if (*vp) + png_error(png_ptr, "malformed height string in sCAL chunk"); + + if (unit + slength < ep || width <= 0. || height <= 0.) + { + png_warning(png_ptr, "Invalid sCAL data"); + png_free(png_ptr, unit); + return; + } + + + png_set_sCAL(png_ptr, info_ptr, unit, width, height); + + png_free(png_ptr, unit); +} +#endif + #if defined(PNG_READ_tIME_SUPPORTED) void png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) @@ -1258,6 +1637,7 @@ png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text)); text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; + text_ptr->lang = NULL; text_ptr->key = key; text_ptr->text = text; @@ -1273,12 +1653,11 @@ png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) void png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { - static char msg[] = "Error decoding zTXt chunk"; png_textp text_ptr; - png_charp key; + png_charp chunkdata; png_charp text; int comp_type = PNG_TEXT_COMPRESSION_NONE; - png_size_t slength; + png_size_t slength, prefix_len; png_debug(1, "in png_handle_zTXt\n"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) @@ -1298,142 +1677,128 @@ png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } #endif - key = (png_charp)png_malloc(png_ptr, length + 1); + chunkdata = (png_charp)png_malloc(png_ptr, length + 1); slength = (png_size_t)length; - png_crc_read(png_ptr, (png_bytep)key, slength); + png_crc_read(png_ptr, (png_bytep)chunkdata, slength); if (png_crc_finish(png_ptr, 0)) { - png_free(png_ptr, key); + png_free(png_ptr, chunkdata); return; } - key[slength] = 0x00; + chunkdata[slength] = 0x00; - for (text = key; *text; text++) + for (text = chunkdata; *text; text++) /* empty loop */ ; - /* zTXt must have some text after the keyword */ - if (text == key + slength) + /* zTXt must have some text after the chunkdataword */ + if (text == chunkdata + slength) { + comp_type = PNG_TEXT_COMPRESSION_NONE; png_warning(png_ptr, "Zero length zTXt chunk"); } - else if ((comp_type = *(++text)) == PNG_TEXT_COMPRESSION_zTXt) + else { - png_size_t text_size, key_size; - text++; - - png_ptr->zstream.next_in = (png_bytep)text; - png_ptr->zstream.avail_in = (uInt)(length - (text - key)); - png_ptr->zstream.next_out = png_ptr->zbuf; - png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; - - key_size = (png_size_t)(text - key); - text_size = 0; - text = NULL; - - while (png_ptr->zstream.avail_in) - { - int ret; - - ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); - if (ret != Z_OK && ret != Z_STREAM_END) - { - if (png_ptr->zstream.msg != NULL) - png_warning(png_ptr, png_ptr->zstream.msg); - else - png_warning(png_ptr, msg); - inflateReset(&png_ptr->zstream); - png_ptr->zstream.avail_in = 0; - - if (text == NULL) - { - text_size = key_size + sizeof(msg) + 1; - text = (png_charp)png_malloc(png_ptr, (png_uint_32)text_size); - png_memcpy(text, key, key_size); - } - - text[text_size - 1] = 0x00; - - /* Copy what we can of the error message into the text chunk */ - text_size = (png_size_t)(slength - (text - key) - 1); - text_size = sizeof(msg) > text_size ? text_size : sizeof(msg); - png_memcpy(text + key_size, msg, text_size + 1); - break; - } - if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END) - { - if (text == NULL) - { - text = (png_charp)png_malloc(png_ptr, - (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out - + key_size + 1)); - png_memcpy(text + key_size, png_ptr->zbuf, - png_ptr->zbuf_size - png_ptr->zstream.avail_out); - png_memcpy(text, key, key_size); - text_size = key_size + png_ptr->zbuf_size - - png_ptr->zstream.avail_out; - *(text + text_size) = 0x00; - } - else - { - png_charp tmp; - - tmp = text; - text = (png_charp)png_malloc(png_ptr, (png_uint_32)(text_size + - png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1)); - png_memcpy(text, tmp, text_size); - png_free(png_ptr, tmp); - png_memcpy(text + text_size, png_ptr->zbuf, - (png_ptr->zbuf_size - png_ptr->zstream.avail_out)); - text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out; - *(text + text_size) = 0x00; - } - if (ret != Z_STREAM_END) - { - png_ptr->zstream.next_out = png_ptr->zbuf; - png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; - } - else - { - break; - } - } - } - - inflateReset(&png_ptr->zstream); - png_ptr->zstream.avail_in = 0; - - png_free(png_ptr, key); - key = text; - text += key_size; + comp_type = *(++text); + text++; /* skip the compression byte */ } - else /* if (comp_type >= PNG_TEXT_COMPRESSION_LAST) */ - { - png_size_t text_size; -#if !defined(PNG_NO_STDIO) - char umsg[50]; + prefix_len = text - chunkdata; - sprintf(umsg, "Unknown zTXt compression type %d", comp_type); - png_warning(png_ptr, umsg); -#else - png_warning(png_ptr, "Unknown zTXt compression type"); -#endif - - /* Copy what we can of the error message into the text chunk */ - text_size = (png_size_t)(slength - (text - key) - 1); - text_size = sizeof(msg) > text_size ? text_size : sizeof(msg); - png_memcpy(text, msg, text_size + 1); - } + chunkdata = (png_charp)png_decompress_chunk(png_ptr, comp_type, chunkdata, + (png_size_t)length, prefix_len); text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text)); text_ptr->compression = comp_type; - text_ptr->key = key; - text_ptr->text = text; + text_ptr->lang = NULL; + text_ptr->key = chunkdata; + text_ptr->text = chunkdata + prefix_len; + + png_set_text(png_ptr, info_ptr, text_ptr, 1); + + png_free(png_ptr, text_ptr); + png_free(png_ptr, chunkdata); +} +#endif + +#if defined(PNG_READ_iTXt_SUPPORTED) +/* note: this does not correctly handle chunks that are > 64K under DOS */ +void +png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) +{ + png_textp text_ptr; + png_charp chunkdata; + png_charp lang, text; + int comp_type = PNG_TEXT_COMPRESSION_NONE; + int comp_flag = 0; + png_size_t slength, prefix_len; + + png_debug(1, "in png_handle_iTXt\n"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before iTXt"); + + if (png_ptr->mode & PNG_HAVE_IDAT) + png_ptr->mode |= PNG_AFTER_IDAT; + +#ifdef PNG_MAX_MALLOC_64K + /* We will no doubt have problems with chunks even half this size, but + there is no hard and fast rule to tell us where to stop. */ + if (length > (png_uint_32)65535L) + { + png_warning(png_ptr,"iTXt chunk too large to fit in memory"); + png_crc_finish(png_ptr, length); + return; + } +#endif + + chunkdata = (png_charp)png_malloc(png_ptr, length + 1); + slength = (png_size_t)length; + png_crc_read(png_ptr, (png_bytep)chunkdata, slength); + if (png_crc_finish(png_ptr, 0)) + { + png_free(png_ptr, chunkdata); + return; + } + + chunkdata[slength] = 0x00; + + for (lang = chunkdata; *lang; lang++) + /* empty loop */ ; + lang++; /* skip NUL separator */ + + /* iTXt must have a language tag and some text after the keyword */ + if (lang >= chunkdata + slength) + { + comp_type = PNG_TEXT_COMPRESSION_NONE; + png_warning(png_ptr, "Zero length iTXt chunk"); + } + else + { + comp_flag = *lang++; + comp_type = *lang++; + } + + for (text = lang; *text; text++) + /* empty loop */ ; + text++; /* skip NUL separator */ + + prefix_len = text - chunkdata; + + if (comp_flag) + chunkdata = png_decompress_chunk(png_ptr, comp_type, chunkdata, + (size_t)length, prefix_len); + + text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text)); + text_ptr->compression = (png_byte)comp_type; + text_ptr->lang = NULL; + text_ptr->key = chunkdata; + text_ptr->text = chunkdata + prefix_len; png_set_text(png_ptr, info_ptr, text_ptr, 1); png_free(png_ptr, text_ptr->key); png_free(png_ptr, text_ptr); + png_free(png_ptr, chunkdata); } #endif @@ -1713,6 +2078,13 @@ png_do_read_interlace (png_row_infop row_info, png_bytep row, int pass, png_uint_32 transformations) { +#ifdef PNG_USE_LOCAL_ARRAYS + /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* offset to next interlace block */ + const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; +#endif + png_debug(1,"in png_do_read_interlace\n"); if (row != NULL && row_info != NULL) { @@ -2051,6 +2423,22 @@ png_read_filter_row void png_read_finish_row(png_structp png_ptr) { +#ifdef PNG_USE_LOCAL_ARRAYS + /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* start of interlace block */ + const int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + + /* offset to next interlace block */ + const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + + /* start of interlace block in the y direction */ + const int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + + /* offset to next interlace block in the y direction */ + const int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; +#endif + png_debug(1, "in png_read_finish_row\n"); png_ptr->row_number++; if (png_ptr->row_number < png_ptr->num_rows) @@ -2091,6 +2479,9 @@ png_read_finish_row(png_structp png_ptr) if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) { +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_IDAT; +#endif char extra; int ret; @@ -2111,7 +2502,7 @@ png_read_finish_row(png_structp png_ptr) 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)) + if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4)) png_error(png_ptr, "Not enough image data"); } @@ -2154,6 +2545,22 @@ png_read_finish_row(png_structp png_ptr) void png_read_start_row(png_structp png_ptr) { +#ifdef PNG_USE_LOCAL_ARRAYS + /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* start of interlace block */ + const int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + + /* offset to next interlace block */ + const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + + /* start of interlace block in the y direction */ + const int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + + /* offset to next interlace block in the y direction */ + const int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; +#endif + int max_pixel_depth; png_uint_32 row_bytes; diff --git a/pngset.c b/pngset.c index d965d1fcd..8c7910968 100644 --- a/pngset.c +++ b/pngset.c @@ -1,7 +1,7 @@ /* pngset.c - storage of image information into info struct * - * libpng 1.0.5a - October 23, 1999 + * libpng 1.0.5f - December 6, 1999 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. * Copyright (c) 1996, 1997 Andreas Dilger @@ -16,7 +16,7 @@ #define PNG_INTERNAL #include "png.h" -#if defined(PNG_READ_bKGD_SUPPORTED) || defined(PNG_WRITE_bKGD_SUPPORTED) +#if defined(PNG_bKGD_SUPPORTED) void png_set_bKGD(png_structp png_ptr, png_infop info_ptr, png_color_16p background) { @@ -29,7 +29,7 @@ png_set_bKGD(png_structp png_ptr, png_infop info_ptr, png_color_16p background) } #endif -#if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED) +#if defined(PNG_cHRM_SUPPORTED) void png_set_cHRM(png_structp png_ptr, png_infop info_ptr, double white_x, double white_y, double red_x, double red_y, @@ -51,7 +51,7 @@ png_set_cHRM(png_structp png_ptr, png_infop info_ptr, } #endif -#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_WRITE_gAMA_SUPPORTED) +#if defined(PNG_gAMA_SUPPORTED) void png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma) { @@ -64,7 +64,7 @@ png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma) } #endif -#if defined(PNG_READ_hIST_SUPPORTED) || defined(PNG_WRITE_hIST_SUPPORTED) +#if defined(PNG_hIST_SUPPORTED) void png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p hist) { @@ -117,10 +117,10 @@ png_set_IHDR(png_structp png_ptr, png_infop info_ptr, info_ptr->rowbytes = (info_ptr->width * info_ptr->pixel_depth + 7) >> 3; } -#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED) +#if defined(PNG_oFFs_SUPPORTED) void png_set_oFFs(png_structp png_ptr, png_infop info_ptr, - png_uint_32 offset_x, png_uint_32 offset_y, int unit_type) + png_int_32 offset_x, png_int_32 offset_y, int unit_type) { png_debug1(1, "in %s storage function\n", "oFFs"); if (png_ptr == NULL || info_ptr == NULL) @@ -133,7 +133,7 @@ png_set_oFFs(png_structp png_ptr, png_infop info_ptr, } #endif -#if defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) +#if defined(PNG_pCAL_SUPPORTED) void png_set_pCAL(png_structp png_ptr, png_infop info_ptr, png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams, @@ -178,7 +178,29 @@ png_set_pCAL(png_structp png_ptr, png_infop info_ptr, } #endif -#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED) +#if defined(PNG_READ_sCAL_SUPPORTED) || defined(PNG_WRITE_sCAL_SUPPORTED) +void +png_set_sCAL(png_structp png_ptr, png_infop info_ptr, + png_charp unit, double width, double height) +{ + png_uint_32 length; + + png_debug1(1, "in %s storage function\n", "sCAL"); + if (png_ptr == NULL || info_ptr == NULL) + return; + + length = png_strlen(unit) + 1; + png_debug1(3, "allocating unit for info (%d bytes)\n", length); + info_ptr->scal_unit = (png_charp)png_malloc(png_ptr, length); + png_memcpy(info_ptr->scal_unit, unit, (png_size_t)length); + info_ptr->scal_pixel_width = width; + info_ptr->scal_pixel_height = height; + + info_ptr->valid |= PNG_INFO_sCAL; +} +#endif + +#if defined(PNG_pHYs_SUPPORTED) void png_set_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type) @@ -207,7 +229,7 @@ png_set_PLTE(png_structp png_ptr, png_infop info_ptr, info_ptr->valid |= PNG_INFO_PLTE; } -#if defined(PNG_READ_sBIT_SUPPORTED) || defined(PNG_WRITE_sBIT_SUPPORTED) +#if defined(PNG_sBIT_SUPPORTED) void png_set_sBIT(png_structp png_ptr, png_infop info_ptr, png_color_8p sig_bit) @@ -221,7 +243,7 @@ png_set_sBIT(png_structp png_ptr, png_infop info_ptr, } #endif -#if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED) +#if defined(PNG_sRGB_SUPPORTED) void png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int intent) { @@ -236,10 +258,10 @@ void png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr, int intent) { -#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_WRITE_gAMA_SUPPORTED) +#if defined(PNG_gAMA_SUPPORTED) float file_gamma; #endif -#if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED) +#if defined(PNG_cHRM_SUPPORTED) float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y; #endif png_debug1(1, "in %s storage function\n", "sRGB_gAMA_and_cHRM"); @@ -248,12 +270,12 @@ png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr, png_set_sRGB(png_ptr, info_ptr, intent); -#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_WRITE_gAMA_SUPPORTED) +#if defined(PNG_gAMA_SUPPORTED) file_gamma = (float).45455; png_set_gAMA(png_ptr, info_ptr, file_gamma); #endif -#if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED) +#if defined(PNG_cHRM_SUPPORTED) white_x = (float).3127; white_y = (float).3290; red_x = (float).64; @@ -270,8 +292,29 @@ png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr, } #endif -#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \ - defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED) +#if defined(PNG_iCCP_SUPPORTED) +void +png_set_iCCP(png_structp png_ptr, png_infop info_ptr, + png_charp name, int compression_type, + png_charp profile, int proflen) +{ + png_debug1(1, "in %s storage function\n", "iCCP"); + if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL) + return; + + info_ptr->iccp_name = png_malloc(png_ptr, png_strlen(name)+1); + strcpy(info_ptr->iccp_name, name); + info_ptr->iccp_profile = png_malloc(png_ptr, proflen); + memcpy(info_ptr->iccp_profile, profile, proflen); + info_ptr->iccp_proflen = (png_uint_32)proflen; + /* Compression is always zero but is here so the API and info structure + * does not have to change * if we introduce multiple compression types */ + info_ptr->iccp_compression = (png_byte)compression_type; + info_ptr->valid |= PNG_INFO_iCCP; +} +#endif + +#if defined(PNG_TEXT_SUPPORTED) void png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, int num_text) @@ -320,7 +363,13 @@ png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, png_charp key,text; if (text_ptr[i].key == (png_charp)NULL) - continue; + continue; + +#ifdef PNG_iTXt_SUPPORTED + textp->lang = text_ptr[i].lang; +#else + textp->lang = NULL; +#endif if (text_ptr[i].text[0] == '\0') { @@ -346,6 +395,7 @@ png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, png_memcpy(textp->key, text_ptr[i].key, (png_size_t)(text - key)); /* includes the zero-byte separator */ + textp->text = textp->key + (text-key); if(textp->text_length) { @@ -362,13 +412,13 @@ png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, } #endif -#if defined(PNG_READ_tIME_SUPPORTED) || defined(PNG_WRITE_tIME_SUPPORTED) +#if defined(PNG_tIME_SUPPORTED) void png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_timep mod_time) { png_debug1(1, "in %s storage function\n", "tIME"); if (png_ptr == NULL || info_ptr == NULL || - (png_ptr->flags & PNG_FLAG_WROTE_tIME)) + (png_ptr->mode & PNG_WROTE_tIME)) return; png_memcpy(&(info_ptr->mod_time), mod_time, sizeof (png_time)); @@ -376,7 +426,7 @@ png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_timep mod_time) } #endif -#if defined(PNG_READ_tRNS_SUPPORTED) || defined(PNG_WRITE_tRNS_SUPPORTED) +#if defined(PNG_tRNS_SUPPORTED) void png_set_tRNS(png_structp png_ptr, png_infop info_ptr, png_bytep trans, int num_trans, png_color_16p trans_values) @@ -402,6 +452,40 @@ png_set_tRNS(png_structp png_ptr, png_infop info_ptr, } #endif +#if defined(PNG_sPLT_SUPPORTED) +void +png_set_spalettes(png_structp png_ptr, + png_infop info_ptr, png_spalette_p entries, int nentries) +{ + png_spalette_p np; + int i; + + np = (png_spalette_p)png_malloc(png_ptr, + (info_ptr->splt_palettes_num + nentries) * sizeof(png_spalette)); + + memcpy(np, info_ptr->splt_palettes, + info_ptr->splt_palettes_num * sizeof(png_spalette)); + png_free(png_ptr, info_ptr->splt_palettes); + + for (i = 0; i < nentries; i++) + { + png_spalette_p to = np + i; + png_spalette_p from = entries + i; + + to->name = (png_charp)png_malloc(png_ptr, + png_strlen(from->name) + 1); + png_strcpy(to->name, from->name); + to->entries = (png_spalette_entryp)png_malloc(png_ptr, + from->nentries * sizeof(png_spalette)); + memcpy(to->entries, from->entries, + from->nentries * sizeof(png_spalette)); + } + + info_ptr->splt_palettes = np; + info_ptr->splt_palettes_num += nentries; +} +#endif /* PNG_sPLT_SUPPORTED */ + #if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) void png_permit_empty_plte (png_structp png_ptr, int empty_plte_permitted) @@ -412,3 +496,10 @@ png_permit_empty_plte (png_structp png_ptr, int empty_plte_permitted) png_ptr->empty_plte_permitted=(png_byte)empty_plte_permitted; } #endif + + + + + + + diff --git a/pngtrans.c b/pngtrans.c index 4ec7b383a..c0f29fced 100644 --- a/pngtrans.c +++ b/pngtrans.c @@ -1,7 +1,7 @@ /* pngtrans.c - transforms the data in a row (used by both readers and writers) * - * libpng 1.0.5a - October 23, 1999 + * libpng 1.0.5f - December 6, 1999 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. * Copyright (c) 1996, 1997 Andreas Dilger diff --git a/pngtypes.h b/pngtypes.h new file mode 100644 index 000000000..9b5049c6f --- /dev/null +++ b/pngtypes.h @@ -0,0 +1,31 @@ +/* pngtypes.h - array of chunk-types for libpng + * + * libpng 1.0.5d - November 28, 1999 + * For conditions of distribution and use, see copyright notice in png.h + * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. + * Copyright (c) 1996, 1997 Andreas Dilger + * Copyright (c) 1998, 1999 Glenn Randers-Pehrson + */ + +/* Constant strings for known chunk types. If you need to add a chunk, + * define the string in png.h and invoke it here. + */ + +PNG_IHDR; +PNG_IDAT; +PNG_IEND; +PNG_PLTE; +PNG_bKGD; +PNG_cHRM; +PNG_gAMA; +PNG_hIST; +PNG_oFFs; +PNG_pCAL; +PNG_pHYs; +PNG_sBIT; +PNG_sRGB; +PNG_tEXt; +PNG_tIME; +PNG_tRNS; +PNG_zTXt; + diff --git a/pngvcrd.c b/pngvcrd.c index 092037a7c..3398fffb7 100644 --- a/pngvcrd.c +++ b/pngvcrd.c @@ -2,7 +2,7 @@ * * For Intel x86 CPU and Microsoft Visual C++ compiler * - * libpng 1.0.5a - October 23, 1999 + * libpng 1.0.5f - December 6, 1999 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998, Intel Corporation * Copyright (c) 1998, 1999 Glenn Randers-Pehrson @@ -96,6 +96,9 @@ NOT_SUPPORTED: void png_combine_row(png_structp png_ptr, png_bytep row, int mask) { +#ifdef PNG_USE_LOCAL_ARRAYS + const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; +#endif #ifdef DISABLE_PNGVCRD_COMBINE int save_mmx_supported = mmx_supported; #endif @@ -966,6 +969,9 @@ void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, png_uint_32 transformations) { +#ifdef PNG_USE_LOCAL_ARRAYS + const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; +#endif #ifdef DISABLE_PNGVCRD_INTERLACE int save_mmx_supported = mmx_supported; #endif @@ -1496,8 +1502,8 @@ loop2_pass0: } } - sptr -= (width_mmx*2 - 2); // sign fixed - dp -= (width_mmx*16 - 2); // sign fixed + sptr -= (width_mmx*2 - 2); // sign fixed + dp -= (width_mmx*16 - 2); // sign fixed for (i = width; i; i--) { png_byte v[8]; @@ -1541,8 +1547,8 @@ loop2_pass2: } } - sptr -= (width_mmx*2 - 2); // sign fixed - dp -= (width_mmx*8 - 2); // sign fixed + sptr -= (width_mmx*2 - 2); // sign fixed + dp -= (width_mmx*8 - 2); // sign fixed for (i = width; i; i--) { png_byte v[8]; @@ -1581,8 +1587,8 @@ loop2_pass4: } } - sptr -= (width_mmx*2 - 2); // sign fixed - dp -= (width_mmx*4 - 2); // sign fixed + sptr -= (width_mmx*2 - 2); // sign fixed + dp -= (width_mmx*4 - 2); // sign fixed for (i = width; i; i--) { png_byte v[8]; @@ -1634,8 +1640,8 @@ loop4_pass0: } } - sptr -= (width_mmx*4 - 4); // sign fixed - dp -= (width_mmx*32 - 4); // sign fixed + sptr -= (width_mmx*4 - 4); // sign fixed + dp -= (width_mmx*32 - 4); // sign fixed for (i = width; i; i--) { png_byte v[8]; @@ -1679,8 +1685,8 @@ loop4_pass2: } } - sptr -= (width_mmx*4 - 4); // sign fixed - dp -= (width_mmx*16 - 4); // sign fixed + sptr -= (width_mmx*4 - 4); // sign fixed + dp -= (width_mmx*16 - 4); // sign fixed for (i = width; i; i--) { png_byte v[8]; @@ -1722,8 +1728,8 @@ loop4_pass4: } } - sptr -= (width_mmx*4 - 4); // sign fixed - dp -= (width_mmx*8 - 4); // sign fixed + sptr -= (width_mmx*4 - 4); // sign fixed + dp -= (width_mmx*8 - 4); // sign fixed for (i = width; i; i--) { png_byte v[8]; diff --git a/pngwio.c b/pngwio.c index 958e74ebc..91c3fbbac 100644 --- a/pngwio.c +++ b/pngwio.c @@ -1,7 +1,7 @@ /* pngwio.c - functions for data output * - * libpng 1.0.5a - October 23, 1999 + * libpng 1.0.5f - December 6, 1999 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. * Copyright (c) 1996, 1997 Andreas Dilger diff --git a/pngwrite.c b/pngwrite.c index e93ba476c..1f836ad1b 100644 --- a/pngwrite.c +++ b/pngwrite.c @@ -1,7 +1,7 @@ /* pngwrite.c - general routines to write a PNG file * - * libpng 1.0.5a - October 23, 1999 + * libpng 1.0.5f - December 6, 1999 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. * Copyright (c) 1996, 1997 Andreas Dilger @@ -22,13 +22,14 @@ * them in png_write_end(), and compressing them. */ void -png_write_info(png_structp png_ptr, png_infop info_ptr) +png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr) { -#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED) +#if defined(PNG_WRITE_sPLT_SUPPORTED) int i; #endif - - png_debug(1, "in png_write_info\n"); + png_debug(1, "in png_write_info_before_PLTE\n"); + if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE)) + { png_write_sig(png_ptr); /* write PNG signature */ /* write IHDR information. */ png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height, @@ -49,6 +50,16 @@ png_write_info(png_structp png_ptr, png_infop info_ptr) if (info_ptr->valid & PNG_INFO_sRGB) png_write_sRGB(png_ptr, (int)info_ptr->srgb_intent); #endif +#if defined(PNG_WRITE_iCCP_SUPPORTED) + if (info_ptr->valid & PNG_INFO_iCCP) + png_write_iCCP(png_ptr, info_ptr->iccp_name, PNG_TEXT_COMPRESSION_NONE, + info_ptr->iccp_profile, (int)info_ptr->iccp_proflen); +#endif +#if defined(PNG_WRITE_sPLT_SUPPORTED) + if (info_ptr->valid & PNG_INFO_sPLT) + for (i = 0; i < (int)info_ptr->splt_palettes_num; i++) + png_write_sPLT(png_ptr, info_ptr->splt_palettes + i); +#endif #if defined(PNG_WRITE_sBIT_SUPPORTED) if (info_ptr->valid & PNG_INFO_sBIT) png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type); @@ -61,6 +72,21 @@ png_write_info(png_structp png_ptr, png_infop info_ptr) info_ptr->x_green, info_ptr->y_green, info_ptr->x_blue, info_ptr->y_blue); #endif + png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE; + } +} + +void +png_write_info(png_structp png_ptr, png_infop info_ptr) +{ +#if defined(PNG_WRITE_TEXT_SUPPORTED) + int i; +#endif + + png_debug(1, "in png_write_info\n"); + + png_write_info_before_PLTE(png_ptr, info_ptr); + if (info_ptr->valid & PNG_INFO_PLTE) png_write_PLTE(png_ptr, info_ptr->palette, (png_uint_32)info_ptr->num_palette); @@ -103,6 +129,11 @@ png_write_info(png_structp png_ptr, png_infop info_ptr) info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams, info_ptr->pcal_units, info_ptr->pcal_params); #endif +#if defined(PNG_WRITE_sCAL_SUPPORTED) + if (info_ptr->valid & PNG_INFO_sCAL) + png_write_sCAL(png_ptr, info_ptr->scal_unit, + info_ptr->scal_pixel_width, info_ptr->scal_pixel_height); +#endif #if defined(PNG_WRITE_pHYs_SUPPORTED) if (info_ptr->valid & PNG_INFO_pHYs) png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit, @@ -112,17 +143,33 @@ png_write_info(png_structp png_ptr, png_infop info_ptr) if (info_ptr->valid & PNG_INFO_tIME) { png_write_tIME(png_ptr, &(info_ptr->mod_time)); - png_ptr->flags |= PNG_FLAG_WROTE_tIME; + png_ptr->mode |= PNG_WROTE_tIME; } #endif -#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED) +#if defined(PNG_WRITE_TEXT_SUPPORTED) /* Check to see if we need to write text chunks */ for (i = 0; i < info_ptr->num_text; i++) { png_debug2(2, "Writing header text chunk %d, type %d\n", i, info_ptr->text[i].compression); + /* an internationalized chunk? */ + if (info_ptr->text[i].lang) + { +#if defined(PNG_WRITE_iTXt_SUPPORTED) + /* write international chunk */ + png_write_iTXt(png_ptr, + info_ptr->text[i].compression, + info_ptr->text[i].lang, + info_ptr->text[i].key, + info_ptr->text[i].text); +#else + png_warning(png_ptr, "Unable to write international text\n"); +#endif + /* Mark this chunk as written */ + info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; + } /* If we want a compressed text chunk */ - if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt) + else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt) { #if defined(PNG_WRITE_zTXt_SUPPORTED) /* write compressed chunk */ @@ -140,7 +187,8 @@ png_write_info(png_structp png_ptr, png_infop info_ptr) #if defined(PNG_WRITE_tEXt_SUPPORTED) /* write uncompressed chunk */ png_write_tEXt(png_ptr, info_ptr->text[i].key, - info_ptr->text[i].text, info_ptr->text[i].text_length); + info_ptr->text[i].text, + info_ptr->text[i].text_length); #else png_warning(png_ptr, "Unable to write uncompressed text\n"); #endif @@ -166,16 +214,16 @@ png_write_end(png_structp png_ptr, png_infop info_ptr) /* see if user wants us to write information chunks */ if (info_ptr != NULL) { -#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED) +#if defined(PNG_WRITE_TEXT_SUPPORTED) int i; /* local index variable */ #endif #if defined(PNG_WRITE_tIME_SUPPORTED) /* check to see if user has supplied a time chunk */ if (info_ptr->valid & PNG_INFO_tIME && - !(png_ptr->flags & PNG_FLAG_WROTE_tIME)) + !(png_ptr->mode & PNG_WROTE_tIME)) png_write_tIME(png_ptr, &(info_ptr->mod_time)); #endif -#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED) +#if defined(PNG_WRITE_TEXT_SUPPORTED) /* loop through comment chunks */ for (i = 0; i < info_ptr->num_text; i++) { @@ -630,7 +678,7 @@ png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr) if (info_ptr != NULL) { -#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED) +#if defined(PNG_WRITE_TEXT_SUPPORTED) png_debug(1, "in png_info_destroy\n"); if (info_ptr->text != NULL) { @@ -642,6 +690,11 @@ png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr) png_free(png_ptr, info_ptr->text[i].key); info_ptr->text[i].key = NULL; } + if(info_ptr->text[i].lang != NULL) + { + png_free(png_ptr, info_ptr->text[i].lang); + info_ptr->text[i].lang = NULL; + } } png_free(png_ptr, info_ptr->text); info_ptr->text = NULL; @@ -705,16 +758,18 @@ png_write_destroy(png_structp png_ptr) png_free(png_ptr, png_ptr->up_row); png_free(png_ptr, png_ptr->avg_row); png_free(png_ptr, png_ptr->paeth_row); + #if defined(PNG_TIME_RFC1123_SUPPORTED) png_free(png_ptr, png_ptr->time_buffer); -#endif /* PNG_TIME_RFC1123_SUPPORTED */ +#endif + #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) png_free(png_ptr, png_ptr->prev_filters); png_free(png_ptr, png_ptr->filter_weights); png_free(png_ptr, png_ptr->inv_filter_weights); png_free(png_ptr, png_ptr->filter_costs); png_free(png_ptr, png_ptr->inv_filter_costs); -#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */ +#endif /* reset structure */ png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf)); diff --git a/pngwtran.c b/pngwtran.c index f6956319d..310064ea0 100644 --- a/pngwtran.c +++ b/pngwtran.c @@ -1,7 +1,7 @@ /* pngwtran.c - transforms the data in a row for PNG writers * - * libpng 1.0.5a - October 23, 1999 + * libpng 1.0.5f - December 6, 1999 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. * Copyright (c) 1996, 1997 Andreas Dilger @@ -19,6 +19,9 @@ png_do_write_transformations(png_structp png_ptr) { png_debug(1, "in png_do_write_transformations\n"); + if (png_ptr == NULL) + return; + #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) if (png_ptr->transformations & PNG_USER_TRANSFORM) if(png_ptr->write_user_transform_fn != NULL) diff --git a/pngwutil.c b/pngwutil.c index 459800d40..37a4f50c3 100644 --- a/pngwutil.c +++ b/pngwutil.c @@ -1,7 +1,7 @@ /* pngwutil.c - utilities to write a PNG file * - * libpng 1.0.5a - October 23, 1999 + * libpng 1.0.5f - December 6, 1999 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. * Copyright (c) 1996, 1997 Andreas Dilger @@ -127,11 +127,229 @@ png_write_chunk_end(png_structp png_ptr) void png_write_sig(png_structp png_ptr) { + png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; /* write the rest of the 8 byte signature */ - png_write_data(png_ptr, &png_sig[png_ptr->sig_bytes], + png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes], (png_size_t)8 - png_ptr->sig_bytes); } +#if defined(PNG_WRITE_TEXT_SUPPORTED) +/* + * This pair of functions encapsulates the operation of (a) compressing a + * text string, and (b) issuing it later as a series of chunk data writes. + * The compression_state structure is shared context for these functions + * set up by the caller in order to make the whole mess thread-safe. + */ + +typedef struct +{ + char *input; /* the uncompressed input data */ + int input_len; /* its length */ + int num_output_ptr; /* number of output pointers used */ + int max_output_ptr; /* size of output_ptr */ + png_charpp output_ptr; /* array of pointers to output */ +} compression_state; + +/* compress given text into storage in the png_ptr structure */ +static int +png_text_compress(png_structp png_ptr, + png_charp text, png_size_t text_len, int compression, + compression_state *comp) +{ + int ret; + + comp->num_output_ptr = comp->max_output_ptr = 0; + comp->output_ptr = NULL; + comp->input = NULL; + + /* we may just want to pass the text right through */ + if (compression == PNG_TEXT_COMPRESSION_NONE) + { + comp->input = text; + comp->input_len = text_len; + return(text_len); + } + + if (compression >= PNG_TEXT_COMPRESSION_LAST) + { +#if !defined(PNG_NO_STDIO) + char msg[50]; + sprintf(msg, "Unknown compression type %d", compression); + png_warning(png_ptr, msg); +#else + png_warning(png_ptr, "Unknown compression type"); +#endif + compression = PNG_TEXT_COMPRESSION_zTXt; + } + + /* We can't write the chunk until we find out how much data we have, + * which means we need to run the compressor first and save the + * output. This shouldn't be a problem, as the vast majority of + * comments should be reasonable, but we will set up an array of + * malloc'd pointers to be sure. + * + * If we knew the application was well behaved, we could simplify this + * greatly by assuming we can always malloc an output buffer large + * enough to hold the compressed text ((1001 * text_len / 1000) + 12) + * and malloc this directly. The only time this would be a bad idea is + * if we can't malloc more than 64K and we have 64K of random input + * data, or if the input string is incredibly large (although this + * wouldn't cause a failure, just a slowdown due to swapping). + */ + + /* set up the compression buffers */ + png_ptr->zstream.avail_in = (uInt)text_len; + png_ptr->zstream.next_in = (Bytef *)text; + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + png_ptr->zstream.next_out = (Bytef *)png_ptr->zbuf; + + /* this is the same compression loop as in png_write_row() */ + do + { + /* compress the data */ + ret = deflate(&png_ptr->zstream, Z_NO_FLUSH); + if (ret != Z_OK) + { + /* error */ + if (png_ptr->zstream.msg != NULL) + png_error(png_ptr, png_ptr->zstream.msg); + else + png_error(png_ptr, "zlib error"); + } + /* check to see if we need more room */ + if (!png_ptr->zstream.avail_out && png_ptr->zstream.avail_in) + { + /* make sure the output array has room */ + if (comp->num_output_ptr >= comp->max_output_ptr) + { + int old_max; + + old_max = comp->max_output_ptr; + comp->max_output_ptr = comp->num_output_ptr + 4; + if (comp->output_ptr != NULL) + { + png_charpp old_ptr; + + old_ptr = comp->output_ptr; + comp->output_ptr = (png_charpp)png_malloc(png_ptr, + (png_uint_32)(comp->max_output_ptr * sizeof (png_charpp))); + png_memcpy(comp->output_ptr, old_ptr, + old_max * sizeof (png_charp)); + png_free(png_ptr, old_ptr); + } + else + comp->output_ptr = (png_charpp)png_malloc(png_ptr, + (png_uint_32)(comp->max_output_ptr * sizeof (png_charp))); + } + + /* save the data */ + comp->output_ptr[comp->num_output_ptr] = (png_charp)png_malloc(png_ptr, + (png_uint_32)png_ptr->zbuf_size); + png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf, + png_ptr->zbuf_size); + comp->num_output_ptr++; + + /* and reset the buffer */ + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + png_ptr->zstream.next_out = png_ptr->zbuf; + } + /* continue until we don't have any more to compress */ + } while (png_ptr->zstream.avail_in); + + /* finish the compression */ + do + { + /* tell zlib we are finished */ + ret = deflate(&png_ptr->zstream, Z_FINISH); + if (ret != Z_OK && ret != Z_STREAM_END) + { + /* we got an error */ + if (png_ptr->zstream.msg != NULL) + png_error(png_ptr, png_ptr->zstream.msg); + else + png_error(png_ptr, "zlib error"); + } + + /* check to see if we need more room */ + if (!(png_ptr->zstream.avail_out) && ret == Z_OK) + { + /* check to make sure our output array has room */ + if (comp->num_output_ptr >= comp->max_output_ptr) + { + int old_max; + + old_max = comp->max_output_ptr; + comp->max_output_ptr = comp->num_output_ptr + 4; + if (comp->output_ptr != NULL) + { + png_charpp old_ptr; + + old_ptr = comp->output_ptr; + /* This could be optimized to realloc() */ + comp->output_ptr = (png_charpp)png_malloc(png_ptr, + (png_uint_32)(comp->max_output_ptr * sizeof (png_charpp))); + png_memcpy(comp->output_ptr, old_ptr, + old_max * sizeof (png_charp)); + png_free(png_ptr, old_ptr); + } + else + comp->output_ptr = (png_charpp)png_malloc(png_ptr, + (png_uint_32)(comp->max_output_ptr * sizeof (png_charp))); + } + + /* save off the data */ + comp->output_ptr[comp->num_output_ptr] = (png_charp)png_malloc(png_ptr, + (png_uint_32)png_ptr->zbuf_size); + png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf, + png_ptr->zbuf_size); + comp->num_output_ptr++; + + /* and reset the buffer pointers */ + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + png_ptr->zstream.next_out = png_ptr->zbuf; + } + } while (ret != Z_STREAM_END); + + /* text length is number of buffers plus last buffer */ + text_len = png_ptr->zbuf_size * comp->num_output_ptr; + if (png_ptr->zstream.avail_out < png_ptr->zbuf_size) + text_len += png_ptr->zbuf_size - (png_size_t)png_ptr->zstream.avail_out; + + return(text_len); +} + +/* ship the compressed text out via chunk writes */ +static void +png_write_compressed_data_out(png_structp png_ptr, compression_state *comp) +{ + int i; + + /* handle the no-compression case */ + if (comp->input) + { + png_write_chunk_data(png_ptr, (png_bytep)comp->input, comp->input_len); + return; + } + + /* write saved output buffers, if any */ + for (i = 0; i < comp->num_output_ptr; i++) + { + png_write_chunk_data(png_ptr,(png_bytep)comp->output_ptr[i],png_ptr->zbuf_size); + png_free(png_ptr, comp->output_ptr[i]); + } + if (comp->max_output_ptr != 0) + png_free(png_ptr, comp->output_ptr); + /* write anything left in zbuf */ + if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size) + png_write_chunk_data(png_ptr, png_ptr->zbuf, + png_ptr->zbuf_size - png_ptr->zstream.avail_out); + + /* reset zlib for another zTXt/iTXt or the image data */ + deflateReset(&png_ptr->zstream); + +} +#endif + /* Write the IHDR chunk, and update the png_struct with the necessary * information. Note that the rest of this code depends upon this * information being correct. @@ -141,6 +359,9 @@ png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height, int bit_depth, int color_type, int compression_type, int filter_type, int interlace_type) { +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_IHDR; +#endif png_byte buf[13]; /* buffer to store the IHDR info */ png_debug(1, "in png_write_IHDR\n"); @@ -234,7 +455,7 @@ png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height, buf[12] = (png_byte)interlace_type; /* write the chunk */ - png_write_chunk(png_ptr, png_IHDR, buf, (png_size_t)13); + png_write_chunk(png_ptr, (png_bytep)png_IHDR, buf, (png_size_t)13); /* initialize zlib with PNG info */ png_ptr->zstream.zalloc = png_zalloc; @@ -279,6 +500,9 @@ png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height, void png_write_PLTE(png_structp png_ptr, png_colorp palette, png_uint_32 num_pal) { +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_PLTE; +#endif png_uint_32 i; png_colorp pal_ptr; png_byte buf[3]; @@ -304,7 +528,7 @@ png_write_PLTE(png_structp png_ptr, png_colorp palette, png_uint_32 num_pal) png_ptr->num_palette = (png_uint_16)num_pal; png_debug1(3, "num_palette = %d\n", png_ptr->num_palette); - png_write_chunk_start(png_ptr, png_PLTE, num_pal * 3); + png_write_chunk_start(png_ptr, (png_bytep)png_PLTE, num_pal * 3); for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++) { buf[0] = pal_ptr->red; @@ -320,8 +544,11 @@ png_write_PLTE(png_structp png_ptr, png_colorp palette, png_uint_32 num_pal) void png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length) { +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_IDAT; +#endif png_debug(1, "in png_write_IDAT\n"); - png_write_chunk(png_ptr, png_IDAT, data, length); + png_write_chunk(png_ptr, (png_bytep)png_IDAT, data, length); png_ptr->mode |= PNG_HAVE_IDAT; } @@ -329,8 +556,11 @@ png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length) void png_write_IEND(png_structp png_ptr) { +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_IEND; +#endif png_debug(1, "in png_write_IEND\n"); - png_write_chunk(png_ptr, png_IEND, NULL, (png_size_t)0); + png_write_chunk(png_ptr, (png_bytep)png_IEND, NULL, (png_size_t)0); png_ptr->mode |= PNG_HAVE_IEND; } @@ -339,6 +569,9 @@ png_write_IEND(png_structp png_ptr) void png_write_gAMA(png_structp png_ptr, double file_gamma) { +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_gAMA; +#endif png_uint_32 igamma; png_byte buf[4]; @@ -346,7 +579,7 @@ png_write_gAMA(png_structp png_ptr, double file_gamma) /* file_gamma is saved in 1/1000000ths */ igamma = (png_uint_32)(file_gamma * 100000.0 + 0.5); png_save_uint_32(buf, igamma); - png_write_chunk(png_ptr, png_gAMA, buf, (png_size_t)4); + png_write_chunk(png_ptr, (png_bytep)png_gAMA, buf, (png_size_t)4); } #endif @@ -355,6 +588,9 @@ png_write_gAMA(png_structp png_ptr, double file_gamma) void png_write_sRGB(png_structp png_ptr, int srgb_intent) { +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_sRGB; +#endif png_byte buf[1]; png_debug(1, "in png_write_sRGB\n"); @@ -362,7 +598,105 @@ png_write_sRGB(png_structp png_ptr, int srgb_intent) png_warning(png_ptr, "Invalid sRGB rendering intent specified"); buf[0]=(png_byte)srgb_intent; - png_write_chunk(png_ptr, png_sRGB, buf, (png_size_t)1); + png_write_chunk(png_ptr, (png_bytep)png_sRGB, buf, (png_size_t)1); +} +#endif + +#if defined(PNG_WRITE_iCCP_SUPPORTED) +/* write an iCCP chunk */ +void +png_write_iCCP(png_structp png_ptr, png_charp name, int compression_type, + png_charp profile, int profile_len) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_iCCP; +#endif + png_size_t name_len; + png_charp new_name; + compression_state comp; + + png_debug(1, "in png_write_iCCP\n"); + if (name == NULL || (name_len = png_check_keyword(png_ptr, name, + &new_name)) == 0) + { + png_warning(png_ptr, "Empty keyword in iCCP chunk"); + return; + } + + if (compression_type) + /* ignore */ ; + + if (profile == NULL || *profile == '\0') + profile_len = 0; + + if (profile_len) + profile_len = png_text_compress(png_ptr, profile, profile_len, + PNG_TEXT_COMPRESSION_zTXt, &comp); + + /* make sure we include the NULL after the name and the compression type */ + png_write_chunk_start(png_ptr, (png_bytep)png_iCCP, + (png_uint_32)name_len+profile_len+2); + png_write_chunk_data(png_ptr, (png_bytep)new_name, name_len + 2); + + if (profile_len) + png_write_compressed_data_out(png_ptr, &comp); + + png_write_chunk_end(png_ptr); + png_free(png_ptr, new_name); +} +#endif + +#if defined(PNG_WRITE_sPLT_SUPPORTED) +/* write a sPLT chunk */ +void +png_write_sPLT(png_structp png_ptr, png_spalette_p spalette) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_sPLT; +#endif + png_size_t name_len; + png_charp new_name; + png_byte entrybuf[10]; + int entry_size = (spalette->depth == 8 ? 6 : 10); + int palette_size = entry_size * spalette->nentries; + png_spalette_entryp ep; + + png_debug(1, "in png_write_sPLT\n"); + if (spalette->name == NULL || (name_len = png_check_keyword(png_ptr, spalette->name, &new_name))==0) + { + png_warning(png_ptr, "Empty keyword in sPLT chunk"); + return; + } + + /* make sure we include the NULL after the name */ + png_write_chunk_start(png_ptr, (png_bytep) png_sPLT, + (png_uint_32)(name_len + 1 + palette_size)); + png_write_chunk_data(png_ptr, (png_bytep)new_name, name_len + 1); + + /* loop through each palette entry, writing appropriately */ + for (ep = spalette->entries; epentries+spalette->nentries; ep++) + { + if (spalette->depth == 8) + { + entrybuf[0] = (png_byte)ep->red; + entrybuf[1] = (png_byte)ep->green; + entrybuf[2] = (png_byte)ep->blue; + entrybuf[3] = (png_byte)ep->alpha; + png_save_uint_16(entrybuf + 4, ep->frequency); + } + else + { + png_save_uint_16(entrybuf + 0, ep->red); + png_save_uint_16(entrybuf + 2, ep->green); + png_save_uint_16(entrybuf + 4, ep->blue); + png_save_uint_16(entrybuf + 6, ep->alpha); + png_save_uint_16(entrybuf + 8, ep->frequency); + } + png_write_chunk_data(png_ptr, entrybuf, entry_size); + } + + png_write_chunk_end(png_ptr); + png_free(png_ptr, new_name); } #endif @@ -371,6 +705,9 @@ png_write_sRGB(png_structp png_ptr, int srgb_intent) void png_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type) { +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_sBIT; +#endif png_byte buf[4]; png_size_t size; @@ -415,7 +752,7 @@ png_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type) buf[size++] = sbit->alpha; } - png_write_chunk(png_ptr, png_sBIT, buf, size); + png_write_chunk(png_ptr, (png_bytep)png_sBIT, buf, size); } #endif @@ -426,6 +763,9 @@ png_write_cHRM(png_structp png_ptr, double white_x, double white_y, double red_x, double red_y, double green_x, double green_y, double blue_x, double blue_y) { +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_cHRM; +#endif png_uint_32 itemp; png_byte buf[32]; @@ -475,7 +815,7 @@ png_write_cHRM(png_structp png_ptr, double white_x, double white_y, itemp = (png_uint_32)(blue_y * 100000.0 + 0.5); png_save_uint_32(buf + 28, itemp); - png_write_chunk(png_ptr, png_cHRM, buf, (png_size_t)32); + png_write_chunk(png_ptr, (png_bytep)png_cHRM, buf, (png_size_t)32); } #endif @@ -485,6 +825,9 @@ void png_write_tRNS(png_structp png_ptr, png_bytep trans, png_color_16p tran, int num_trans, int color_type) { +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_tRNS; +#endif png_byte buf[6]; png_debug(1, "in png_write_tRNS\n"); @@ -496,13 +839,13 @@ png_write_tRNS(png_structp png_ptr, png_bytep trans, png_color_16p tran, return; } /* write the chunk out as it is */ - png_write_chunk(png_ptr, png_tRNS, trans, (png_size_t)num_trans); + png_write_chunk(png_ptr, (png_bytep)png_tRNS, trans, (png_size_t)num_trans); } else if (color_type == PNG_COLOR_TYPE_GRAY) { /* one 16 bit value */ png_save_uint_16(buf, tran->gray); - png_write_chunk(png_ptr, png_tRNS, buf, (png_size_t)2); + png_write_chunk(png_ptr, (png_bytep)png_tRNS, buf, (png_size_t)2); } else if (color_type == PNG_COLOR_TYPE_RGB) { @@ -510,7 +853,7 @@ png_write_tRNS(png_structp png_ptr, png_bytep trans, png_color_16p tran, png_save_uint_16(buf, tran->red); png_save_uint_16(buf + 2, tran->green); png_save_uint_16(buf + 4, tran->blue); - png_write_chunk(png_ptr, png_tRNS, buf, (png_size_t)6); + png_write_chunk(png_ptr, (png_bytep)png_tRNS, buf, (png_size_t)6); } else { @@ -524,6 +867,9 @@ png_write_tRNS(png_structp png_ptr, png_bytep trans, png_color_16p tran, void png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type) { +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_bKGD; +#endif png_byte buf[6]; png_debug(1, "in png_write_bKGD\n"); @@ -540,19 +886,19 @@ png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type) return; } buf[0] = back->index; - png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)1); + png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)1); } else if (color_type & PNG_COLOR_MASK_COLOR) { png_save_uint_16(buf, back->red); png_save_uint_16(buf + 2, back->green); png_save_uint_16(buf + 4, back->blue); - png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)6); + png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)6); } else { png_save_uint_16(buf, back->gray); - png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)2); + png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)2); } } #endif @@ -562,6 +908,9 @@ png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type) void png_write_hIST(png_structp png_ptr, png_uint_16p hist, int num_hist) { +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_hIST; +#endif int i; png_byte buf[3]; @@ -574,7 +923,7 @@ png_write_hIST(png_structp png_ptr, png_uint_16p hist, int num_hist) return; } - png_write_chunk_start(png_ptr, png_hIST, (png_uint_32)(num_hist * 2)); + png_write_chunk_start(png_ptr, (png_bytep)png_hIST, (png_uint_32)(num_hist * 2)); for (i = 0; i < num_hist; i++) { png_save_uint_16(buf, hist[i]); @@ -584,8 +933,8 @@ png_write_hIST(png_structp png_ptr, png_uint_16p hist, int num_hist) } #endif -#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED) || \ - defined(PNG_WRITE_pCAL_SUPPORTED) +#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \ + defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED) /* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification, * and if invalid, correct the keyword rather than discarding the entire * chunk. The PNG 1.0 specification requires keywords 1-79 characters in @@ -710,6 +1059,9 @@ void png_write_tEXt(png_structp png_ptr, png_charp key, png_charp text, png_size_t text_len) { +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_tEXt; +#endif png_size_t key_len; png_charp new_key; @@ -724,11 +1076,12 @@ png_write_tEXt(png_structp png_ptr, png_charp key, png_charp text, text_len = 0; /* make sure we include the 0 after the key */ - png_write_chunk_start(png_ptr, png_tEXt, (png_uint_32)key_len+text_len+1); + png_write_chunk_start(png_ptr, (png_bytep)png_tEXt, (png_uint_32)key_len+text_len+1); /* * We leave it to the application to meet PNG-1.0 requirements on the * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them. + * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. */ png_write_chunk_data(png_ptr, (png_bytep)new_key, key_len + 1); if (text_len) @@ -745,13 +1098,13 @@ void png_write_zTXt(png_structp png_ptr, png_charp key, png_charp text, png_size_t text_len, int compression) { +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_zTXt; +#endif png_size_t key_len; char buf[1]; png_charp new_key; - int i, ret; - png_charpp output_ptr = NULL; /* array of pointers to output */ - int num_output_ptr = 0; /* number of output pointers used */ - int max_output_ptr = 0; /* size of output_ptr */ + compression_state comp; png_debug(1, "in png_write_zTXt\n"); @@ -770,177 +1123,92 @@ png_write_zTXt(png_structp png_ptr, png_charp key, png_charp text, png_free(png_ptr, new_key); - if (compression >= PNG_TEXT_COMPRESSION_LAST) - { -#if !defined(PNG_NO_STDIO) - char msg[50]; - sprintf(msg, "Unknown zTXt compression type %d", compression); - png_warning(png_ptr, msg); -#else - png_warning(png_ptr, "Unknown zTXt compression type"); -#endif - compression = PNG_TEXT_COMPRESSION_zTXt; - } - - /* We can't write the chunk until we find out how much data we have, - * which means we need to run the compressor first and save the - * output. This shouldn't be a problem, as the vast majority of - * comments should be reasonable, but we will set up an array of - * malloc'd pointers to be sure. - * - * If we knew the application was well behaved, we could simplify this - * greatly by assuming we can always malloc an output buffer large - * enough to hold the compressed text ((1001 * text_len / 1000) + 12) - * and malloc this directly. The only time this would be a bad idea is - * if we can't malloc more than 64K and we have 64K of random input - * data, or if the input string is incredibly large (although this - * wouldn't cause a failure, just a slowdown due to swapping). - */ - - /* set up the compression buffers */ - png_ptr->zstream.avail_in = (uInt)text_len; - png_ptr->zstream.next_in = (Bytef *)text; - png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; - png_ptr->zstream.next_out = (Bytef *)png_ptr->zbuf; - - /* this is the same compression loop as in png_write_row() */ - do - { - /* compress the data */ - ret = deflate(&png_ptr->zstream, Z_NO_FLUSH); - if (ret != Z_OK) - { - /* error */ - if (png_ptr->zstream.msg != NULL) - png_error(png_ptr, png_ptr->zstream.msg); - else - png_error(png_ptr, "zlib error"); - } - /* check to see if we need more room */ - if (!png_ptr->zstream.avail_out && png_ptr->zstream.avail_in) - { - /* make sure the output array has room */ - if (num_output_ptr >= max_output_ptr) - { - int old_max; - - old_max = max_output_ptr; - max_output_ptr = num_output_ptr + 4; - if (output_ptr != NULL) - { - png_charpp old_ptr; - - old_ptr = output_ptr; - output_ptr = (png_charpp)png_malloc(png_ptr, - (png_uint_32)(max_output_ptr * sizeof (png_charpp))); - png_memcpy(output_ptr, old_ptr, old_max * sizeof (png_charp)); - png_free(png_ptr, old_ptr); - } - else - output_ptr = (png_charpp)png_malloc(png_ptr, - (png_uint_32)(max_output_ptr * sizeof (png_charp))); - } - - /* save the data */ - output_ptr[num_output_ptr] = (png_charp)png_malloc(png_ptr, - (png_uint_32)png_ptr->zbuf_size); - png_memcpy(output_ptr[num_output_ptr], png_ptr->zbuf, - png_ptr->zbuf_size); - num_output_ptr++; - - /* and reset the buffer */ - png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; - png_ptr->zstream.next_out = png_ptr->zbuf; - } - /* continue until we don't have any more to compress */ - } while (png_ptr->zstream.avail_in); - - /* finish the compression */ - do - { - /* tell zlib we are finished */ - ret = deflate(&png_ptr->zstream, Z_FINISH); - if (ret != Z_OK && ret != Z_STREAM_END) - { - /* we got an error */ - if (png_ptr->zstream.msg != NULL) - png_error(png_ptr, png_ptr->zstream.msg); - else - png_error(png_ptr, "zlib error"); - } - - /* check to see if we need more room */ - if (!(png_ptr->zstream.avail_out) && ret == Z_OK) - { - /* check to make sure our output array has room */ - if (num_output_ptr >= max_output_ptr) - { - int old_max; - - old_max = max_output_ptr; - max_output_ptr = num_output_ptr + 4; - if (output_ptr != NULL) - { - png_charpp old_ptr; - - old_ptr = output_ptr; - /* This could be optimized to realloc() */ - output_ptr = (png_charpp)png_malloc(png_ptr, - (png_uint_32)(max_output_ptr * sizeof (png_charpp))); - png_memcpy(output_ptr, old_ptr, old_max * sizeof (png_charp)); - png_free(png_ptr, old_ptr); - } - else - output_ptr = (png_charpp)png_malloc(png_ptr, - (png_uint_32)(max_output_ptr * sizeof (png_charp))); - } - - /* save off the data */ - output_ptr[num_output_ptr] = (png_charp)png_malloc(png_ptr, - (png_uint_32)png_ptr->zbuf_size); - png_memcpy(output_ptr[num_output_ptr], png_ptr->zbuf, - png_ptr->zbuf_size); - num_output_ptr++; - - /* and reset the buffer pointers */ - png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; - png_ptr->zstream.next_out = png_ptr->zbuf; - } - } while (ret != Z_STREAM_END); - - /* text length is number of buffers plus last buffer */ - text_len = png_ptr->zbuf_size * num_output_ptr; - if (png_ptr->zstream.avail_out < png_ptr->zbuf_size) - text_len += png_ptr->zbuf_size - (png_size_t)png_ptr->zstream.avail_out; + /* compute the compressed data; do it now for the length */ + text_len = png_text_compress(png_ptr, text, text_len, compression, &comp); /* write start of chunk */ - png_write_chunk_start(png_ptr, png_zTXt, (png_uint_32)(key_len+text_len+2)); + png_write_chunk_start(png_ptr, (png_bytep)png_zTXt, (png_uint_32) + (key_len+text_len+2)); /* write key */ png_write_chunk_data(png_ptr, (png_bytep)key, key_len + 1); buf[0] = (png_byte)compression; /* write compression */ png_write_chunk_data(png_ptr, (png_bytep)buf, (png_size_t)1); + /* write the compressed data */ + png_write_compressed_data_out(png_ptr, &comp); - /* write saved output buffers, if any */ - for (i = 0; i < num_output_ptr; i++) - { - png_write_chunk_data(png_ptr,(png_bytep)output_ptr[i],png_ptr->zbuf_size); - png_free(png_ptr, output_ptr[i]); - } - if (max_output_ptr != 0) - png_free(png_ptr, output_ptr); - /* write anything left in zbuf */ - if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size) - png_write_chunk_data(png_ptr, png_ptr->zbuf, - png_ptr->zbuf_size - png_ptr->zstream.avail_out); /* close the chunk */ png_write_chunk_end(png_ptr); - - /* reset zlib for another zTXt or the image data */ - deflateReset(&png_ptr->zstream); } #endif +#if defined(PNG_WRITE_iTXt_SUPPORTED) +/* write an iTXt chunk */ +void +png_write_iTXt(png_structp png_ptr, int compression, + png_charp key, png_charp lang, png_charp text) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_iTXt; +#endif + png_size_t lang_len, key_len, text_len = png_strlen(text); + png_charp new_lang, new_key; + png_byte cbuf[2]; + compression_state comp; + + png_debug(1, "in png_write_iTXt\n"); + 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; + } + if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0) + { + png_warning(png_ptr, "Empty keyword in iTXt chunk"); + return; + } + + if (text == NULL || *text == '\0') + text_len = 0; + + /* compute the compressed data; do it now for the length */ + text_len = png_text_compress(png_ptr, text, text_len, compression, &comp); + + /* make sure we include the compression flag, the compression byte, + * and the NULs after the lang and key parts */ + png_write_chunk_start(png_ptr, (png_bytep)png_iTXt, + (png_uint_32)(2 + lang_len+1 + key_len+1 + text_len)); + + /* set the compression bits */ + if (compression == PNG_TEXT_COMPRESSION_NONE) + { + cbuf[0] = 0; + cbuf[1] = 0; + } + else /* compression == PNG_TEXT_COMPRESSION_zTXt */ + { + cbuf[0] = 1; + cbuf[1] = 0; + } + png_write_chunk_data(png_ptr, cbuf, 2); + + /* + * We leave it to the application to meet PNG-1.0 requirements on the + * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of + * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them. + * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. + */ + png_write_chunk_data(png_ptr, (png_bytep)new_lang, lang_len + 1); + png_write_chunk_data(png_ptr, (png_bytep)new_key, 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); +} +#endif #if defined(PNG_WRITE_oFFs_SUPPORTED) /* write the oFFs chunk */ @@ -949,6 +1217,9 @@ png_write_oFFs(png_structp png_ptr, png_uint_32 x_offset, png_uint_32 y_offset, int unit_type) { +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_oFFs; +#endif png_byte buf[9]; png_debug(1, "in png_write_oFFs\n"); @@ -959,7 +1230,7 @@ png_write_oFFs(png_structp png_ptr, png_uint_32 x_offset, png_save_uint_32(buf + 4, y_offset); buf[8] = (png_byte)unit_type; - png_write_chunk(png_ptr, png_oFFs, buf, (png_size_t)9); + png_write_chunk(png_ptr, (png_bytep)png_oFFs, buf, (png_size_t)9); } #endif @@ -969,6 +1240,9 @@ void png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams, png_charp units, png_charpp params) { +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_pCAL; +#endif png_size_t purpose_len, units_len, total_len; png_uint_32p params_len; png_byte buf[10]; @@ -998,7 +1272,7 @@ png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0, } png_debug1(3, "pCAL total length = %d\n", total_len); - png_write_chunk_start(png_ptr, png_pCAL, (png_uint_32)total_len); + png_write_chunk_start(png_ptr, (png_bytep)png_pCAL, (png_uint_32)total_len); png_write_chunk_data(png_ptr, (png_bytep)new_purpose, purpose_len); png_save_int_32(buf, X0); png_save_int_32(buf + 4, X1); @@ -1020,6 +1294,33 @@ png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0, } #endif +#if defined(PNG_WRITE_sCAL_SUPPORTED) +/* write the sCAL chunk */ +void +png_write_sCAL(png_structp png_ptr, png_charp unit, double width,double height) +{ +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_sCAL; +#endif + png_size_t total_len; + char wbuf[32], hbuf[32]; + + png_debug(1, "in png_write_sCAL\n"); + + sprintf(wbuf, "%12.12e", width); + sprintf(hbuf, "%12.12e", height); + total_len = png_strlen(unit)+1 + png_strlen(wbuf)+1 + png_strlen(hbuf); + + png_debug1(3, "sCAL total length = %d\n", total_len); + png_write_chunk_start(png_ptr, (png_bytep)png_sCAL, (png_uint_32)total_len); + png_write_chunk_data(png_ptr, (png_bytep)unit, png_strlen(unit)+1); + png_write_chunk_data(png_ptr, (png_bytep)wbuf, strlen(wbuf)+1); + png_write_chunk_data(png_ptr, (png_bytep)hbuf, strlen(hbuf)); + + png_write_chunk_end(png_ptr); +} +#endif + #if defined(PNG_WRITE_pHYs_SUPPORTED) /* write the pHYs chunk */ void @@ -1027,6 +1328,9 @@ png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit, int unit_type) { +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_pHYs; +#endif png_byte buf[9]; png_debug(1, "in png_write_pHYs\n"); @@ -1037,7 +1341,7 @@ png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit, png_save_uint_32(buf + 4, y_pixels_per_unit); buf[8] = (png_byte)unit_type; - png_write_chunk(png_ptr, png_pHYs, buf, (png_size_t)9); + png_write_chunk(png_ptr, (png_bytep)png_pHYs, buf, (png_size_t)9); } #endif @@ -1048,6 +1352,9 @@ png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit, void png_write_tIME(png_structp png_ptr, png_timep mod_time) { +#ifdef PNG_USE_LOCAL_ARRAYS + PNG_tIME; +#endif png_byte buf[7]; png_debug(1, "in png_write_tIME\n"); @@ -1066,7 +1373,7 @@ png_write_tIME(png_structp png_ptr, png_timep mod_time) buf[5] = mod_time->minute; buf[6] = mod_time->second; - png_write_chunk(png_ptr, png_tIME, buf, (png_size_t)7); + png_write_chunk(png_ptr, (png_bytep)png_tIME, buf, (png_size_t)7); } #endif @@ -1074,6 +1381,22 @@ png_write_tIME(png_structp png_ptr, png_timep mod_time) void png_write_start_row(png_structp png_ptr) { +#ifdef PNG_USE_LOCAL_ARRAYS + /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* start of interlace block */ + int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + + /* offset to next interlace block */ + int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + + /* start of interlace block in the y direction */ + int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + + /* offset to next interlace block in the y direction */ + int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; +#endif + png_size_t buf_size; png_debug(1, "in png_write_start_row\n"); @@ -1152,6 +1475,22 @@ png_write_start_row(png_structp png_ptr) void png_write_finish_row(png_structp png_ptr) { +#ifdef PNG_USE_LOCAL_ARRAYS + /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* start of interlace block */ + int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + + /* offset to next interlace block */ + int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + + /* start of interlace block in the y direction */ + int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + + /* offset to next interlace block in the y direction */ + int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; +#endif + int ret; png_debug(1, "in png_write_finish_row\n"); @@ -1250,6 +1589,16 @@ png_write_finish_row(png_structp png_ptr) void png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) { +#ifdef PNG_USE_LOCAL_ARRAYS + /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + + /* start of interlace block */ + int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + + /* offset to next interlace block */ + int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; +#endif + png_debug(1, "in png_do_write_interlace\n"); /* we don't have to do anything on the last pass (6) */ #if defined(PNG_USELESS_TESTS_SUPPORTED) @@ -2076,5 +2425,5 @@ png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row) { png_write_flush(png_ptr); } -#endif /* PNG_WRITE_FLUSH_SUPPORTED */ +#endif }