diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 6700037edb..45574c39c0 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -16,6 +16,30 @@ The license applies to all entries newer than 2009-04-28. */ +2011-01-08 12:07 UTC+0100 Viktor Szakats (harbour.01 syenar.hu) + * src/3rd/png/pngerror.c + * src/3rd/png/pngrio.c + * src/3rd/png/pngwrite.c + * src/3rd/png/pngconf.h + * src/3rd/png/pngwtran.c + * src/3rd/png/pngpread.c + * src/3rd/png/pngset.c + * src/3rd/png/LICENSE + * src/3rd/png/pngwio.c + * src/3rd/png/pngrutil.c + * src/3rd/png/pngwutil.c + * src/3rd/png/pngread.c + * src/3rd/png/pngmem.c + * src/3rd/png/png.c + * src/3rd/png/pngget.c + * src/3rd/png/png.h + * src/3rd/png/pngpriv.h + * src/3rd/png/pngrtran.c + * src/3rd/png/pngtrans.c + * src/3rd/png/Makefile + * libpng update to 1.5 (from 1.4) + ; Patch by Tamas Tevesz. Thanks very much! + 2011-01-08 12:04 UTC+0100 Viktor Szakats (harbour.01 syenar.hu) * contrib/hbide/hbide.hbp + Added hbformat.hbc as dependency for hbide. diff --git a/harbour/src/3rd/png/LICENSE b/harbour/src/3rd/png/LICENSE index 734398fc5d..f9fa45f10e 100644 --- a/harbour/src/3rd/png/LICENSE +++ b/harbour/src/3rd/png/LICENSE @@ -10,7 +10,7 @@ this sentence. This code is released under the libpng license. -libpng versions 1.2.6, August 15, 2004, through 1.4.5, December 9, 2010, are +libpng versions 1.2.6, August 15, 2004, through 1.5.0, January 6, 2011, are Copyright (c) 2004, 2006-2010 Glenn Randers-Pehrson, and are distributed according to the same disclaimer and license as libpng-1.2.5 with the following individual added to the list of Contributing Authors @@ -108,4 +108,4 @@ certification mark of the Open Source Initiative. Glenn Randers-Pehrson glennrp at users.sourceforge.net -December 9, 2010 +January 6, 2011 diff --git a/harbour/src/3rd/png/Makefile b/harbour/src/3rd/png/Makefile index 6fd6bafdd8..3492b642e1 100644 --- a/harbour/src/3rd/png/Makefile +++ b/harbour/src/3rd/png/Makefile @@ -72,13 +72,14 @@ else endif # ORIGIN http://www.libpng.org/pub/png/libpng.html -# VER 1.4.5 -# URL http://sourceforge.net/projects/libpng/files/libpng14/1.4.5/lpng145.zip/download +# VER 1.5.0 +# URL http://prdownloads.sourceforge.net/libpng/libpng-1.5.0.tar.gz?download # DIFF # # MAP LICENSE # MAP png.c # MAP pngconf.h +# MAP scripts/pnglibconf.h.prebuilt pnglconf.h # MAP pngerror.c # MAP pngget.c # MAP png.h @@ -95,3 +96,6 @@ endif # MAP pngwrite.c # MAP pngwtran.c # MAP pngwutil.c +# MAP pnginfo.h +# MAP pngstruct.h pngstru.h +# MAP pngdebug.h diff --git a/harbour/src/3rd/png/png.c b/harbour/src/3rd/png/png.c index 00d258dffa..e0ef11ab86 100644 --- a/harbour/src/3rd/png/png.c +++ b/harbour/src/3rd/png/png.c @@ -1,8 +1,8 @@ /* png.c - location for general purpose libpng functions * - * Last changed in libpng 1.4.2 [May 6, 2010] - * Copyright (c) 1998-2010 Glenn Randers-Pehrson + * Last changed in libpng 1.5.0 [January 6, 2011] + * Copyright (c) 1998-2011 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -11,13 +11,10 @@ * and license in png.h */ -#define PNG_NO_EXTERN -#define PNG_NO_PEDANTIC_WARNINGS -#include "png.h" #include "pngpriv.h" /* Generate a compiler error if there is an old png.h in the search path. */ -typedef version_1_4_5 Your_png_h_is_not_version_1_4_5; +typedef png_libpng_version_1_5_0 Your_png_h_is_not_version_1_5_0; /* 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 @@ -49,11 +46,13 @@ png_set_sig_bytes(png_structp png_ptr, int num_bytes) * PNG signature (this is the same behaviour as strcmp, memcmp, etc). */ int PNGAPI -png_sig_cmp(png_bytep sig, png_size_t start, png_size_t num_to_check) +png_sig_cmp(png_const_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) return (-1); @@ -69,9 +68,9 @@ png_sig_cmp(png_bytep sig, png_size_t start, png_size_t num_to_check) #endif /* PNG_READ_SUPPORTED */ #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) -/* Function to allocate memory for zlib and clear it to 0. */ -voidpf /* PRIVATE */ -png_zalloc(voidpf png_ptr, uInt items, uInt size) +/* Function to allocate memory for zlib */ +PNG_FUNCTION(voidpf /* PRIVATE */, +png_zalloc,(voidpf png_ptr, uInt items, uInt size),PNG_ALLOCATED) { png_voidp ptr; png_structp p=(png_structp)png_ptr; @@ -80,6 +79,7 @@ png_zalloc(voidpf png_ptr, uInt items, uInt size) if (png_ptr == NULL) return (NULL); + if (items > PNG_UINT_32_MAX/size) { png_warning (p, "Potential overflow in png_zalloc()"); @@ -116,7 +116,7 @@ png_reset_crc(png_structp png_ptr) * trouble of calculating it. */ void /* PRIVATE */ -png_calculate_crc(png_structp png_ptr, png_bytep ptr, png_size_t length) +png_calculate_crc(png_structp png_ptr, png_const_bytep ptr, png_size_t length) { int need_crc = 1; @@ -126,6 +126,7 @@ png_calculate_crc(png_structp png_ptr, png_bytep ptr, png_size_t length) (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) need_crc = 0; } + else /* critical */ { if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) @@ -142,8 +143,8 @@ png_calculate_crc(png_structp png_ptr, png_bytep ptr, png_size_t length) * and png_info_init() so that applications that want to use a shared * libpng don't have to be recompiled if png_info changes size. */ -png_infop PNGAPI -png_create_info_struct(png_structp png_ptr) +PNG_FUNCTION(png_infop,PNGAPI +png_create_info_struct,(png_structp png_ptr),PNG_ALLOCATED) { png_infop info_ptr; @@ -233,8 +234,10 @@ png_data_freer(png_structp png_ptr, png_infop info_ptr, if (freer == PNG_DESTROY_WILL_FREE_DATA) info_ptr->free_me |= mask; + else if (freer == PNG_USER_WILL_FREE_DATA) info_ptr->free_me &= ~mask; + else png_warning(png_ptr, "Unknown freer parameter in png_data_freer"); @@ -261,6 +264,7 @@ png_free_data(png_structp png_ptr, png_infop info_ptr, png_uint_32 mask, info_ptr->text[num].key = NULL; } } + else { int i; @@ -346,6 +350,7 @@ png_free_data(png_structp png_ptr, png_infop info_ptr, png_uint_32 mask, info_ptr->splt_palettes[num].entries = NULL; } } + else { if (info_ptr->splt_palettes_num) @@ -380,13 +385,14 @@ png_free_data(png_structp png_ptr, png_infop info_ptr, png_uint_32 mask, info_ptr->unknown_chunks[num].data = NULL; } } + else { int i; if (info_ptr->unknown_chunks_num) { - for (i = 0; i < (int)info_ptr->unknown_chunks_num; i++) + for (i = 0; i < info_ptr->unknown_chunks_num; i++) png_free_data(png_ptr, info_ptr, PNG_FREE_UNKN, i); png_free(png_ptr, info_ptr->unknown_chunks); @@ -435,10 +441,10 @@ png_free_data(png_structp png_ptr, png_infop info_ptr, png_uint_32 mask, } #endif - if (num == -1) - info_ptr->free_me &= ~mask; - else - info_ptr->free_me &= ~(mask & ~PNG_FREE_MUL); + if (num != -1) + mask &= ~PNG_FREE_MUL; + + info_ptr->free_me &= ~mask; } /* This is an internal routine to free any memory that the info struct is @@ -474,11 +480,12 @@ png_get_io_ptr(png_structp png_ptr) { if (png_ptr == NULL) return (NULL); + return (png_ptr->io_ptr); } #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) -#ifdef PNG_STDIO_SUPPORTED +# ifdef PNG_STDIO_SUPPORTED /* Initialize the default input/output functions for the PNG file. If you * use your own read or write routines, you can call either png_set_read_fn() * or png_set_write_fn() instead of png_init_io(). If you have defined @@ -495,14 +502,14 @@ png_init_io(png_structp png_ptr, png_FILE_p fp) png_ptr->io_ptr = (png_voidp)fp; } -#endif +# endif -#ifdef PNG_TIME_RFC1123_SUPPORTED +# ifdef PNG_TIME_RFC1123_SUPPORTED /* Convert the supplied time into an RFC 1123 string suitable for use in * a "Creation Time" or other text-based time string. */ -png_charp PNGAPI -png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime) +png_const_charp PNGAPI +png_convert_to_rfc1123(png_structp png_ptr, png_const_timep ptime) { static PNG_CONST char short_months[12][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", @@ -510,13 +517,14 @@ png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime) if (png_ptr == NULL) return (NULL); + if (png_ptr->time_buffer == NULL) { png_ptr->time_buffer = (png_charp)png_malloc(png_ptr, (png_uint_32)(29* png_sizeof(char))); } -#ifdef USE_FAR_KEYWORD +# ifdef USE_FAR_KEYWORD { char near_time_buf[29]; png_snprintf6(near_time_buf, 29, "%d %s %d %02d:%02d:%02d +0000", @@ -526,38 +534,38 @@ png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime) png_memcpy(png_ptr->time_buffer, near_time_buf, 29*png_sizeof(char)); } -#else +# else png_snprintf6(png_ptr->time_buffer, 29, "%d %s %d %02d:%02d:%02d +0000", ptime->day % 32, short_months[(ptime->month - 1) % 12], ptime->year, ptime->hour % 24, ptime->minute % 60, ptime->second % 61); -#endif - return ((png_charp)png_ptr->time_buffer); +# endif + return png_ptr->time_buffer; } -#endif /* PNG_TIME_RFC1123_SUPPORTED */ +# endif /* PNG_TIME_RFC1123_SUPPORTED */ #endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ -png_charp PNGAPI +png_const_charp PNGAPI png_get_copyright(png_structp png_ptr) { - png_ptr = png_ptr; /* Silence compiler warning about unused png_ptr */ + PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ #ifdef PNG_STRING_COPYRIGHT - return PNG_STRING_COPYRIGHT + return PNG_STRING_COPYRIGHT #else -#ifdef __STDC__ - return ((png_charp) PNG_STRING_NEWLINE \ - "libpng version 1.4.5 - December 9, 2010" PNG_STRING_NEWLINE \ - "Copyright (c) 1998-2010 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \ +# ifdef __STDC__ + return PNG_STRING_NEWLINE \ + "libpng version 1.5.0 - January 6, 2011" PNG_STRING_NEWLINE \ + "Copyright (c) 1998-2011 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \ "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \ "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \ - PNG_STRING_NEWLINE); -#else - return ((png_charp) "libpng version 1.4.5 - December 9, 2010\ - Copyright (c) 1998-2010 Glenn Randers-Pehrson\ + PNG_STRING_NEWLINE; +# else + return "libpng version 1.5.0 - January 6, 2011\ + Copyright (c) 1998-2011 Glenn Randers-Pehrson\ Copyright (c) 1996-1997 Andreas Dilger\ - Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc."); -#endif + Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc."; +# endif #endif } @@ -569,55 +577,55 @@ png_get_copyright(png_structp png_ptr) * png_get_header_ver(). Due to the version_nn_nn_nn typedef guard, * it is guaranteed that png.c uses the correct version of png.h. */ -png_charp PNGAPI +png_const_charp PNGAPI png_get_libpng_ver(png_structp png_ptr) { /* Version of *.c files used when building libpng */ - png_ptr = png_ptr; /* Silence compiler warning about unused png_ptr */ - return ((png_charp) PNG_LIBPNG_VER_STRING); + return png_get_header_ver(png_ptr); } -png_charp PNGAPI +png_const_charp PNGAPI png_get_header_ver(png_structp png_ptr) { /* Version of *.h files used when building libpng */ - png_ptr = png_ptr; /* Silence compiler warning about unused png_ptr */ - return ((png_charp) PNG_LIBPNG_VER_STRING); + PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ + return PNG_LIBPNG_VER_STRING; } -png_charp PNGAPI +png_const_charp PNGAPI png_get_header_version(png_structp png_ptr) { /* Returns longer string containing both version and date */ - png_ptr = png_ptr; /* Silence compiler warning about unused png_ptr */ + PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ #ifdef __STDC__ - return ((png_charp) PNG_HEADER_VERSION_STRING -#ifndef PNG_READ_SUPPORTED + return PNG_HEADER_VERSION_STRING +# ifndef PNG_READ_SUPPORTED " (NO READ SUPPORT)" -#endif - PNG_STRING_NEWLINE); +# endif + PNG_STRING_NEWLINE; #else - return ((png_charp) PNG_HEADER_VERSION_STRING); + return PNG_HEADER_VERSION_STRING; #endif } #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +# ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED int PNGAPI -png_handle_as_unknown(png_structp png_ptr, png_bytep chunk_name) +png_handle_as_unknown(png_structp png_ptr, png_const_bytep chunk_name) { /* Check chunk_name and return "keep" value if it's on the list, else 0 */ int i; png_bytep p; if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list<=0) return 0; + p = png_ptr->chunk_list + png_ptr->num_chunk_list*5 - 5; for (i = png_ptr->num_chunk_list; i; i--, p -= 5) if (!png_memcmp(chunk_name, p, 4)) return ((int)*(p + 4)); return 0; } -#endif +# endif #endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ #ifdef PNG_READ_SUPPORTED @@ -627,6 +635,7 @@ png_reset_zstream(png_structp png_ptr) { if (png_ptr == NULL) return Z_STREAM_ERROR; + return (inflateReset(&png_ptr->zstream)); } #endif /* PNG_READ_SUPPORTED */ @@ -636,13 +645,13 @@ png_uint_32 PNGAPI png_access_version_number(void) { /* Version of *.c files used when building libpng */ - return((png_uint_32) PNG_LIBPNG_VER); + return((png_uint_32)PNG_LIBPNG_VER); } #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) -#ifdef PNG_SIZE_T +# ifdef PNG_SIZE_T /* Added at libpng version 1.2.6 */ PNG_EXTERN png_size_t PNGAPI png_convert_size PNGARG((size_t size)); png_size_t PNGAPI @@ -650,53 +659,13 @@ png_convert_size(size_t size) { if (size > (png_size_t)-1) PNG_ABORT(); /* We haven't got access to png_ptr, so no png_error() */ + return ((png_size_t)size); } -#endif /* PNG_SIZE_T */ +# endif /* PNG_SIZE_T */ /* Added at libpng version 1.2.34 and 1.4.0 (moved from pngset.c) */ -#ifdef PNG_cHRM_SUPPORTED -#ifdef PNG_CHECK_cHRM_SUPPORTED - -/* - * Multiply two 32-bit numbers, V1 and V2, using 32-bit - * arithmetic, to produce a 64 bit result in the HI/LO words. - * - * A B - * x C D - * ------ - * AD || BD - * AC || CB || 0 - * - * where A and B are the high and low 16-bit words of V1, - * C and D are the 16-bit words of V2, AD is the product of - * A and D, and X || Y is (X << 16) + Y. -*/ - -void /* PRIVATE */ -png_64bit_product(long v1, long v2, unsigned long *hi_product, - unsigned long *lo_product) -{ - int a, b, c, d; - long lo, hi, x, y; - - a = (v1 >> 16) & 0xffff; - b = v1 & 0xffff; - c = (v2 >> 16) & 0xffff; - d = v2 & 0xffff; - - lo = b * d; /* BD */ - x = a * d + c * b; /* AD + CB */ - y = ((lo >> 16) & 0xffff) + x; - - lo = (lo & 0xffff) | ((y & 0xffff) << 16); - hi = (y >> 16) & 0xffff; - - hi += a * c; /* AC */ - - *hi_product = (unsigned long)hi; - *lo_product = (unsigned long)lo; -} +# ifdef PNG_CHECK_cHRM_SUPPORTED int /* PRIVATE */ png_check_cHRM_fixed(png_structp png_ptr, @@ -721,14 +690,14 @@ png_check_cHRM_fixed(png_structp png_ptr, "Ignoring attempt to set negative chromaticity value"); ret = 0; } - if (white_x > (png_fixed_point) PNG_UINT_31_MAX || - white_y > (png_fixed_point) PNG_UINT_31_MAX || - red_x > (png_fixed_point) PNG_UINT_31_MAX || - red_y > (png_fixed_point) PNG_UINT_31_MAX || - green_x > (png_fixed_point) PNG_UINT_31_MAX || - green_y > (png_fixed_point) PNG_UINT_31_MAX || - blue_x > (png_fixed_point) PNG_UINT_31_MAX || - blue_y > (png_fixed_point) PNG_UINT_31_MAX ) + if (white_x > (png_fixed_point)PNG_UINT_31_MAX || + white_y > (png_fixed_point)PNG_UINT_31_MAX || + red_x > (png_fixed_point)PNG_UINT_31_MAX || + red_y > (png_fixed_point)PNG_UINT_31_MAX || + green_x > (png_fixed_point)PNG_UINT_31_MAX || + green_y > (png_fixed_point)PNG_UINT_31_MAX || + blue_x > (png_fixed_point)PNG_UINT_31_MAX || + blue_y > (png_fixed_point)PNG_UINT_31_MAX ) { png_warning(png_ptr, "Ignoring attempt to set chromaticity value exceeding 21474.83"); @@ -739,16 +708,19 @@ png_check_cHRM_fixed(png_structp png_ptr, png_warning(png_ptr, "Invalid cHRM white point"); ret = 0; } + if (red_x > 100000L - red_y) { png_warning(png_ptr, "Invalid cHRM red point"); ret = 0; } + if (green_x > 100000L - green_y) { png_warning(png_ptr, "Invalid cHRM green point"); ret = 0; } + if (blue_x > 100000L - blue_y) { png_warning(png_ptr, "Invalid cHRM blue point"); @@ -767,8 +739,7 @@ png_check_cHRM_fixed(png_structp png_ptr, return ret; } -#endif /* PNG_CHECK_cHRM_SUPPORTED */ -#endif /* PNG_cHRM_SUPPORTED */ +# endif /* PNG_CHECK_cHRM_SUPPORTED */ void /* PRIVATE */ png_check_IHDR(png_structp png_ptr, @@ -791,21 +762,22 @@ png_check_IHDR(png_structp png_ptr, error = 1; } -#ifdef PNG_SET_USER_LIMITS_SUPPORTED +# ifdef PNG_SET_USER_LIMITS_SUPPORTED if (width > png_ptr->user_width_max || width > PNG_USER_WIDTH_MAX) -#else + +# else if (width > PNG_USER_WIDTH_MAX) -#endif +# endif { png_warning(png_ptr, "Image width exceeds user limit in IHDR"); error = 1; } -#ifdef PNG_SET_USER_LIMITS_SUPPORTED +# ifdef PNG_SET_USER_LIMITS_SUPPORTED if (height > png_ptr->user_height_max || height > PNG_USER_HEIGHT_MAX) -#else +# else if (height > PNG_USER_HEIGHT_MAX) -#endif +# endif { png_warning(png_ptr, "Image height exceeds user limit in IHDR"); error = 1; @@ -817,15 +789,15 @@ png_check_IHDR(png_structp png_ptr, error = 1; } - if ( height > PNG_UINT_31_MAX) + if (height > PNG_UINT_31_MAX) { png_warning(png_ptr, "Invalid image height in IHDR"); error = 1; } - if ( width > (PNG_UINT_32_MAX + if (width > (PNG_UINT_32_MAX >> 3) /* 8-byte RGBA pixels */ - - 64 /* bigrowbuf hack */ + - 48 /* bigrowbuf hack */ - 1 /* filter byte */ - 7*8 /* rounding of width to multiple of 8 pixels */ - 8) /* extra max_pixel_depth pad */ @@ -867,7 +839,7 @@ png_check_IHDR(png_structp png_ptr, error = 1; } -#ifdef PNG_MNG_FEATURES_SUPPORTED +# ifdef PNG_MNG_FEATURES_SUPPORTED /* Accept filter_method 64 (intrapixel differencing) only if * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and * 2. Libpng did not read a PNG signature (this filter_method is only @@ -884,10 +856,10 @@ png_check_IHDR(png_structp png_ptr, if (filter_type != PNG_FILTER_TYPE_BASE) { if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && - (filter_type == PNG_INTRAPIXEL_DIFFERENCING) && - ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) && - (color_type == PNG_COLOR_TYPE_RGB || - color_type == PNG_COLOR_TYPE_RGB_ALPHA))) + (filter_type == PNG_INTRAPIXEL_DIFFERENCING) && + ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) && + (color_type == PNG_COLOR_TYPE_RGB || + color_type == PNG_COLOR_TYPE_RGB_ALPHA))) { png_warning(png_ptr, "Unknown filter method in IHDR"); error = 1; @@ -900,15 +872,1491 @@ png_check_IHDR(png_structp png_ptr, } } -#else +# else if (filter_type != PNG_FILTER_TYPE_BASE) { png_warning(png_ptr, "Unknown filter method in IHDR"); error = 1; } -#endif +# endif if (error == 1) png_error(png_ptr, "Invalid IHDR data"); } + +#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) +/* ASCII to fp functions */ +/* Check an ASCII formated floating point value, see the more detailed + * comments in pngpriv.h + */ +/* The following is used internally to preserve the 'valid' flag */ +#define png_fp_add(state, flags) ((state) |= (flags)) +#define png_fp_set(state, value)\ + ((state) = (value) | ((state) & PNG_FP_WAS_VALID)) + +/* Internal type codes: bits above the base state! */ +#define PNG_FP_SIGN 0 /* [+-] */ +#define PNG_FP_DOT 4 /* . */ +#define PNG_FP_DIGIT 8 /* [0123456789] */ +#define PNG_FP_E 12 /* [Ee] */ + +int /* PRIVATE */ +png_check_fp_number(png_const_charp string, png_size_t size, int *statep, + png_size_tp whereami) +{ + int state = *statep; + png_size_t i = *whereami; + + while (i < size) + { + int type; + /* First find the type of the next character */ + { + char ch = string[i]; + + if (ch >= 48 && ch <= 57) + type = PNG_FP_DIGIT; + + else switch (ch) + { + case 43: case 45: type = PNG_FP_SIGN; break; + case 46: type = PNG_FP_DOT; break; + case 69: case 101: type = PNG_FP_E; break; + default: goto PNG_FP_End; + } + } + + /* Now deal with this type according to the current + * state, the type is arranged to not overlap the + * bits of the PNG_FP_STATE. + */ + switch ((state & PNG_FP_STATE) + type) + { + case PNG_FP_INTEGER + PNG_FP_SIGN: + if (state & PNG_FP_SAW_ANY) + goto PNG_FP_End; /* not a part of the number */ + + png_fp_add(state, PNG_FP_SAW_SIGN); + break; + + case PNG_FP_INTEGER + PNG_FP_DOT: + /* Ok as trailer, ok as lead of fraction. */ + if (state & PNG_FP_SAW_DOT) /* two dots */ + goto PNG_FP_End; + + else if (state & PNG_FP_SAW_DIGIT) /* trailing dot? */ + png_fp_add(state, PNG_FP_SAW_DOT); + + else + png_fp_set(state, PNG_FP_FRACTION | PNG_FP_SAW_DOT); + + break; + + case PNG_FP_INTEGER + PNG_FP_DIGIT: + if (state & PNG_FP_SAW_DOT) /* delayed fraction */ + png_fp_set(state, PNG_FP_FRACTION | PNG_FP_SAW_DOT); + + png_fp_add(state, PNG_FP_SAW_DIGIT + PNG_FP_WAS_VALID); + + break; + case PNG_FP_INTEGER + PNG_FP_E: + if ((state & PNG_FP_SAW_DIGIT) == 0) + goto PNG_FP_End; + + png_fp_set(state, PNG_FP_EXPONENT); + + break; + + /* case PNG_FP_FRACTION + PNG_FP_SIGN: + goto PNG_FP_End; ** no sign in exponent */ + + /* case PNG_FP_FRACTION + PNG_FP_DOT: + goto PNG_FP_End; ** Because SAW_DOT is always set */ + + case PNG_FP_FRACTION + PNG_FP_DIGIT: + png_fp_add(state, PNG_FP_SAW_DIGIT + PNG_FP_WAS_VALID); + break; + + case PNG_FP_FRACTION + PNG_FP_E: + /* This is correct because the trailing '.' on an + * integer is handled above - so we can only get here + * with the sequence ".E" (with no preceding digits). + */ + if ((state & PNG_FP_SAW_DIGIT) == 0) + goto PNG_FP_End; + + png_fp_set(state, PNG_FP_EXPONENT); + + break; + + case PNG_FP_EXPONENT + PNG_FP_SIGN: + if (state & PNG_FP_SAW_ANY) + goto PNG_FP_End; /* not a part of the number */ + + png_fp_add(state, PNG_FP_SAW_SIGN); + + break; + + /* case PNG_FP_EXPONENT + PNG_FP_DOT: + goto PNG_FP_End; */ + + case PNG_FP_EXPONENT + PNG_FP_DIGIT: + png_fp_add(state, PNG_FP_SAW_DIGIT + PNG_FP_WAS_VALID); + + break; + + /* case PNG_FP_EXPONEXT + PNG_FP_E: + goto PNG_FP_End; */ + + default: goto PNG_FP_End; /* I.e. break 2 */ + } + + /* The character seems ok, continue. */ + ++i; + } + +PNG_FP_End: + /* Here at the end, update the state and return the correct + * return code. + */ + *statep = state; + *whereami = i; + + return (state & PNG_FP_SAW_DIGIT) != 0; +} + + +/* The same but for a complete string. */ +int +png_check_fp_string(png_const_charp string, png_size_t size) +{ + int state=0; + png_size_t index=0; + + return png_check_fp_number(string, size, &state, &index) && + (index == size || string[index] == 0); +} +#endif /* pCAL or sCAL */ + +#ifdef PNG_READ_sCAL_SUPPORTED +# ifdef PNG_FLOATING_POINT_SUPPORTED +/* Utility used below - a simple accurate power of ten from an integral + * exponent. + */ +static double +png_pow10(int power) +{ + int recip = 0; + double d = 1; + + /* Handle negative exponent with a reciprocal at the end because + * 10 is exact whereas .1 is inexact in base 2 + */ + if (power < 0) + { + if (power < DBL_MIN_10_EXP) return 0; + recip = 1, power = -power; + } + + if (power > 0) + { + /* Decompose power bitwise. */ + double mult = 10; + do + { + if (power & 1) d *= mult; + mult *= mult; + power >>= 1; + } + while (power > 0); + + if (recip) d = 1/d; + } + /* else power is 0 and d is 1 */ + + return d; +} + +/* Function to format a floating point value in ASCII with a given + * precision. + */ +void /* PRIVATE */ +png_ascii_from_fp(png_structp png_ptr, png_charp ascii, png_size_t size, + double fp, unsigned int precision) +{ + /* We use standard functions from math.h, but not printf because + * that would require stdio. The caller must supply a buffer of + * sufficient size or we will png_error. The tests on size and + * the space in ascii[] consumed are indicated below. + */ + if (precision < 1) + precision = DBL_DIG; + + /* Enforce the limit of the implementation precision too. */ + if (precision > DBL_DIG+1) + precision = DBL_DIG+1; + + /* Basic sanity checks */ + if (size >= precision+5) /* See the requirements below. */ + { + if (fp < 0) + { + fp = -fp; + *ascii++ = 45; /* '-' PLUS 1 TOTAL 1*/ + --size; + } + + if (fp >= DBL_MIN && fp <= DBL_MAX) + { + int exp; /* A base 10 exponent */ + double base; /* 10^exp */ + + /* First extract a base 10 exponent of the number, + * the calculation below rounds down when converting + * from base 2 to base 10 (multiply by log10(2) - + * 0.3010, but 77/256 is 0.3008, so exp needs to + * be increased. Note that the arithmetic shift + * performs a floor() unlike C arithmetic - using a + * C multiply would break the following for negative + * exponents. + */ + (void)frexp(fp, &exp); /* exponent to base 2 */ + + exp = (exp * 77) >> 8; /* <= exponent to base 10 */ + + /* Avoid underflow here. */ + base = png_pow10(exp); /* May underflow */ + + while (base < DBL_MIN || base < fp) + { + /* And this may overflow. */ + double test = png_pow10(exp+1); + + if (test <= DBL_MAX) + ++exp, base = test; + + else + break; + } + + /* Normalize fp and correct exp, after this fp is in the + * range [.1,1) and exp is both the exponent and the digit + * *before* which the decimal point should be inserted + * (starting with 0 for the first digit). Note that this + * works even if 10^exp is out of range because of the + * test on DBL_MAX above. + */ + fp /= base; + while (fp >= 1) fp /= 10, ++exp; + + /* Because of the code above fp may, at this point, be + * less than .1, this is ok because the code below can + * handle the leading zeros this generates, so no attempt + * is made to correct that here. + */ + + { + int czero, clead, cdigits; + char exponent[10]; + + /* Allow up to two leading zeros - this will not lengthen + * the number compared to using E-n. + */ + if (exp < 0 && exp > -3) /* PLUS 3 TOTAL 4 */ + { + czero = -exp; /* PLUS 2 digits: TOTAL 3 */ + exp = 0; /* Dot added below before first output. */ + } + else + czero = 0; /* No zeros to add */ + + /* Generate the digit list, stripping trailing zeros and + * inserting a '.' before a digit if the exponent is 0. + */ + clead = czero; /* Count of leading zeros */ + cdigits = 0; /* Count of digits in list. */ + + do + { + double d; + + fp *= 10; + /* Use modf here, not floor and subtract, so that + * the separation is done in one step. At the end + * of the loop don't break the number into parts so + * that the final digit is rounded. + */ + if (cdigits+czero-clead+1 < (int)precision) + fp = modf(fp, &d); + + else + { + d = floor(fp + .5); + + if (d > 9) + { + /* Rounding up to 10, handle that here. */ + if (czero > 0) + { + --czero, d = 1; + if (cdigits == 0) --clead; + } + else + { + while (cdigits > 0 && d > 9) + { + int ch = *--ascii; + + if (exp != (-1)) + ++exp; + + else if (ch == 46) + { + ch = *--ascii, ++size; + /* Advance exp to '1', so that the + * decimal point happens after the + * previous digit. + */ + exp = 1; + } + + --cdigits; + d = ch - 47; /* I.e. 1+(ch-48) */ + } + + /* Did we reach the beginning? If so adjust the + * exponent but take into account the leading + * decimal point. + */ + if (d > 9) /* cdigits == 0 */ + { + if (exp == (-1)) + { + /* Leading decimal point (plus zeros?), if + * we lose the decimal point here it must + * be reentered below. + */ + int ch = *--ascii; + + if (ch == 46) + ++size, exp = 1; + + /* Else lost a leading zero, so 'exp' is + * still ok at (-1) + */ + } + else + ++exp; + + /* In all cases we output a '1' */ + d = 1; + } + } + } + fp = 0; /* Guarantees termination below. */ + } + + if (d == 0) + { + ++czero; + if (cdigits == 0) ++clead; + } + else + { + /* Included embedded zeros in the digit count. */ + cdigits += czero - clead; + clead = 0; + + while (czero > 0) + { + /* exp == (-1) means we just output the decimal + * place - after the DP don't adjust 'exp' any + * more! + */ + if (exp != (-1)) + { + if (exp == 0) *ascii++ = 46, --size; + /* PLUS 1: TOTAL 4 */ + --exp; + } + *ascii++ = 48, --czero; + } + + if (exp != (-1)) + { + if (exp == 0) *ascii++ = 46, --size; /* counted above */ + --exp; + } + *ascii++ = (char)(48 + (int)d), ++cdigits; + } + } + while (cdigits+czero-clead < (int)precision && fp > DBL_MIN); + + /* The total output count (max) is now 4+precision */ + + /* Check for an exponent, if we don't need one we are + * done and just need to terminate the string. At + * this point exp==(-1) is effectively if flag - it got + * to '-1' because of the decrement after outputing + * the decimal point above (the exponent required is + * *not* -1!) + */ + if (exp >= (-1) && exp <= 2) + { + /* The following only happens if we didn't output the + * leading zeros above for negative exponent, so this + * doest add to the digit requirement. Note that the + * two zeros here can only be output if the two leading + * zeros were *not* output, so this doesn't increase + * the output count. + */ + while (--exp >= 0) *ascii++ = 48; + + *ascii = 0; + + /* Total buffer requirement (including the '\0') is + * 5+precision - see check at the start. + */ + return; + } + + /* Here if an exponent is required, adjust size for + * the digits we output but did not count. The total + * digit output here so far is at most 1+precision - no + * decimal point and no leading or trailing zeros have + * been output. + */ + size -= cdigits; + + *ascii++ = 69, --size; /* 'E': PLUS 1 TOTAL 2+precision*/ + if (exp < 0) + { + *ascii++ = 45, --size; /* '-': PLUS 1 TOTAL 3+precision */ + exp = -exp; + } + + cdigits = 0; + + while (exp > 0) + { + exponent[cdigits++] = (char)(48 + exp % 10); + exp /= 10; + } + + /* Need another size check here for the exponent digits, so + * this need not be considered above. + */ + if ((int)size > cdigits) + { + while (cdigits > 0) *ascii++ = exponent[--cdigits]; + + *ascii = 0; + + return; + } + } + } + else if (!(fp >= DBL_MIN)) + { + *ascii++ = 48; /* '0' */ + *ascii = 0; + return; + } + else + { + *ascii++ = 105; /* 'i' */ + *ascii++ = 110; /* 'n' */ + *ascii++ = 102; /* 'f' */ + *ascii = 0; + return; + } + } + + /* Here on buffer too small. */ + png_error(png_ptr, "ASCII conversion buffer too small"); +} + +# endif /* FLOATING_POINT */ + +# ifdef PNG_FIXED_POINT_SUPPORTED +/* Function to format a fixed point value in ASCII. + */ +void /* PRIVATE */ +png_ascii_from_fixed(png_structp png_ptr, png_charp ascii, png_size_t size, + png_fixed_point fp) +{ + /* Require space for 10 decimal digits, a decimal point, a minus sign and a + * trailing \0, 13 characters: + */ + if (size > 12) + { + png_uint_32 num; + + /* Avoid overflow here on the minimum integer. */ + if (fp < 0) + *ascii++ = 45, --size, num = -fp; + else + num = fp; + + if (num <= 0x80000000U) /* else overflowed */ + { + unsigned int ndigits = 0, first = 16/*flag value*/; + char digits[10]; + + while (num) + { + /* Split the low digit off num: */ + unsigned int tmp = num/10; + num -= tmp*10; + digits[ndigits++] = (char)(48 + num); + /* Record the first non-zero digit, note that this is a number + * starting at 1, it's not actually the array index. + */ + if (first == 16 && num > 0) + first = ndigits; + num = tmp; + } + + if (ndigits > 0) + { + while (ndigits > 5) *ascii++ = digits[--ndigits]; + /* The remaining digits are fractional digits, ndigits is '5' or + * smaller at this point. It is certainly not zero. Check for a + * non-zero fractional digit: + */ + if (first <= 5) + { + unsigned int i; + *ascii++ = 46; /* decimal point */ + /* ndigits may be <5 for small numbers, output leading zeros + * then ndigits digits to first: + */ + i = 5; + while (ndigits < i) *ascii++ = 48, --i; + while (ndigits >= first) *ascii++ = digits[--ndigits]; + /* Don't output the trailing zeros! */ + } + } + else + *ascii++ = 48; + + /* And null terminate the string: */ + *ascii = 0; + return; + } + } + + /* Here on buffer too small. */ + png_error(png_ptr, "ASCII conversion buffer too small"); +} +# endif /* FIXED_POINT */ +#endif /* READ_SCAL */ + +#if defined(PNG_FLOATING_POINT_SUPPORTED) && \ + !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) +png_fixed_point +png_fixed(png_structp png_ptr, double fp, png_const_charp text) +{ + double r = floor(100000 * fp + .5); + + if (r <= 2147483647. && r >= -2147483648.) + return (png_fixed_point)r; + + png_fixed_error(png_ptr, text); + /*NOT REACHED*/ +} +#endif + +#if defined(PNG_READ_GAMMA_SUPPORTED) || \ + defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG__READ_pHYs_SUPPORTED) +/* muldiv functions */ +/* This API takes signed arguments and rounds the result to the nearest + * integer (or, for a fixed point number - the standard argument - to + * the nearest .00001). Overflow and divide by zero are signalled in + * the result, a boolean - true on success, false on overflow. + */ +int +png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times, + png_int_32 div) +{ + /* Return a * times / div, rounded. */ + if (div != 0) + { + if (a == 0 || times == 0) + { + *res = 0; + return 1; + } + else + { +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + double r = a; + r *= times; + r /= div; + r = floor(r+.5); + + /* A png_fixed_point is a 32 bit integer. */ + if (r <= 2147483647. && r >= -2147483648.) + { + *res = (png_fixed_point)r; + return 1; + } +#else + int negative = 0; + png_uint_32 A, T, D; + png_uint_32 s16, s32, s00; + + if (a < 0) + negative = 1, A = -a; + else + A = a; + + if (times < 0) + negative = !negative, T = -times; + else + T = times; + + if (div < 0) + negative = !negative, D = -div; + else + D = div; + + /* Following can't overflow because the arguments only + * have 31 bits each, however the result may be 32 bits. + */ + s16 = (A >> 16) * (T & 0xffff) + + (A & 0xffff) * (T >> 16); + /* Can't overflow because the a*times bit is only 30 + * bits at most. + */ + s32 = (A >> 16) * (T >> 16) + (s16 >> 16); + s00 = (A & 0xffff) * (T & 0xffff); + + s16 = (s16 & 0xffff) << 16; + s00 += s16; + + if (s00 < s16) + ++s32; /* carry */ + + if (s32 < D) /* else overflow */ + { + /* s32.s00 is now the 64 bit product, do a standard + * division, we know that s32 < D, so the maximum + * required shift is 31. + */ + int bitshift = 32; + png_fixed_point result = 0; /* NOTE: signed */ + + while (--bitshift >= 0) + { + png_uint_32 d32, d00; + + if (bitshift > 0) + d32 = D >> (32-bitshift), d00 = D << bitshift; + + else + d32 = 0, d00 = D; + + if (s32 > d32) + { + if (s00 < d00) --s32; /* carry */ + s32 -= d32, s00 -= d00, result += 1<= d00) + s32 = 0, s00 -= d00, result += 1<= (D >> 1)) + ++result; + + if (negative) + result = -result; + + /* Check for overflow. */ + if ((negative && result <= 0) || (!negative && result >= 0)) + { + *res = result; + return 1; + } + } +#endif + } + } + + return 0; +} +#endif /* READ_GAMMA || INCH_CONVERSIONS */ + +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED) +/* The following is for when the caller doesn't much care about the + * result. + */ +png_fixed_point +png_muldiv_warn(png_structp png_ptr, png_fixed_point a, png_int_32 times, + png_int_32 div) +{ + png_fixed_point result; + + if (png_muldiv(&result, a, times, div)) + return result; + + png_warning(png_ptr, "fixed point overflow ignored"); + return 0; +} +#endif + +#ifdef PNG_READ_GAMMA_SUPPORTED /* more fixed point functions for gammma */ +/* Calculate a reciprocal, return 0 on div-by-zero or overflow. */ +png_fixed_point +png_reciprocal(png_fixed_point a) +{ +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + double r = floor(1E10/a+.5); + + if (r <= 2147483647. && r >= -2147483648.) + return (png_fixed_point)r; +#else + png_fixed_point res; + + if (png_muldiv(&res, 100000, 100000, a)) + return res; +#endif + + return 0; /* error/overflow */ +} + +/* A local convenience routine. */ +static png_fixed_point +png_product2(png_fixed_point a, png_fixed_point b) +{ + /* The required result is 1/a * 1/b; the following preserves accuracy. */ +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + double r = a * 1E-5; + r *= b; + r = floor(r+.5); + + if (r <= 2147483647. && r >= -2147483648.) + return (png_fixed_point)r; +#else + png_fixed_point res; + + if (png_muldiv(&res, a, b, 100000)) + return res; +#endif + + return 0; /* overflow */ +} + +/* The inverse of the above. */ +png_fixed_point +png_reciprocal2(png_fixed_point a, png_fixed_point b) +{ + /* The required result is 1/a * 1/b; the following preserves accuracy. */ +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + double r = 1E15/a; + r /= b; + r = floor(r+.5); + + if (r <= 2147483647. && r >= -2147483648.) + return (png_fixed_point)r; +#else + /* This may overflow because the range of png_fixed_point isn't symmetric, + * but this API is only used for the product of file and screen gamma so it + * doesn't matter that the smallest number it can produce is 1/21474, not + * 1/100000 + */ + png_fixed_point res = png_product2(a, b); + + if (res != 0) + return png_reciprocal(res); +#endif + + return 0; /* overflow */ +} +#endif /* READ_GAMMA */ + +#ifdef PNG_CHECK_cHRM_SUPPORTED +/* Added at libpng version 1.2.34 (Dec 8, 2008) and 1.4.0 (Jan 2, + * 2010: moved from pngset.c) */ +/* + * Multiply two 32-bit numbers, V1 and V2, using 32-bit + * arithmetic, to produce a 64 bit result in the HI/LO words. + * + * A B + * x C D + * ------ + * AD || BD + * AC || CB || 0 + * + * where A and B are the high and low 16-bit words of V1, + * C and D are the 16-bit words of V2, AD is the product of + * A and D, and X || Y is (X << 16) + Y. +*/ + +void /* PRIVATE */ +png_64bit_product (long v1, long v2, unsigned long *hi_product, + unsigned long *lo_product) +{ + int a, b, c, d; + long lo, hi, x, y; + + a = (v1 >> 16) & 0xffff; + b = v1 & 0xffff; + c = (v2 >> 16) & 0xffff; + d = v2 & 0xffff; + + lo = b * d; /* BD */ + x = a * d + c * b; /* AD + CB */ + y = ((lo >> 16) & 0xffff) + x; + + lo = (lo & 0xffff) | ((y & 0xffff) << 16); + hi = (y >> 16) & 0xffff; + + hi += a * c; /* AC */ + + *hi_product = (unsigned long)hi; + *lo_product = (unsigned long)lo; +} +#endif /* CHECK_cHRM */ + +#ifdef PNG_READ_GAMMA_SUPPORTED /* gamma table code */ +#ifndef PNG_FLOATING_ARITHMETIC_SUPPORTED +/* Fixed point gamma. + * + * To calculate gamma this code implements fast log() and exp() calls using only + * fixed point arithmetic. This code has sufficient precision for either 8 or + * 16 bit sample values. + * + * The tables used here were calculated using simple 'bc' programs, but C double + * precision floating point arithmetic would work fine. The programs are given + * at the head of each table. + * + * 8 bit log table + * This is a table of -log(value/255)/log(2) for 'value' in the range 128 to + * 255, so it's the base 2 logarithm of a normalized 8 bit floating point + * mantissa. The numbers are 32 bit fractions. + */ +static png_uint_32 +png_8bit_l2[128] = +{ +# if PNG_DO_BC + for (i=128;i<256;++i) { .5 - l(i/255)/l(2)*65536*65536; } +# endif + 4270715492U, 4222494797U, 4174646467U, 4127164793U, 4080044201U, 4033279239U, + 3986864580U, 3940795015U, 3895065449U, 3849670902U, 3804606499U, 3759867474U, + 3715449162U, 3671346997U, 3627556511U, 3584073329U, 3540893168U, 3498011834U, + 3455425220U, 3413129301U, 3371120137U, 3329393864U, 3287946700U, 3246774933U, + 3205874930U, 3165243125U, 3124876025U, 3084770202U, 3044922296U, 3005329011U, + 2965987113U, 2926893432U, 2888044853U, 2849438323U, 2811070844U, 2772939474U, + 2735041326U, 2697373562U, 2659933400U, 2622718104U, 2585724991U, 2548951424U, + 2512394810U, 2476052606U, 2439922311U, 2404001468U, 2368287663U, 2332778523U, + 2297471715U, 2262364947U, 2227455964U, 2192742551U, 2158222529U, 2123893754U, + 2089754119U, 2055801552U, 2022034013U, 1988449497U, 1955046031U, 1921821672U, + 1888774511U, 1855902668U, 1823204291U, 1790677560U, 1758320682U, 1726131893U, + 1694109454U, 1662251657U, 1630556815U, 1599023271U, 1567649391U, 1536433567U, + 1505374214U, 1474469770U, 1443718700U, 1413119487U, 1382670639U, 1352370686U, + 1322218179U, 1292211689U, 1262349810U, 1232631153U, 1203054352U, 1173618059U, + 1144320946U, 1115161701U, 1086139034U, 1057251672U, 1028498358U, 999877854U, + 971388940U, 943030410U, 914801076U, 886699767U, 858725327U, 830876614U, + 803152505U, 775551890U, 748073672U, 720716771U, 693480120U, 666362667U, + 639363374U, 612481215U, 585715177U, 559064263U, 532527486U, 506103872U, + 479792461U, 453592303U, 427502463U, 401522014U, 375650043U, 349885648U, + 324227938U, 298676034U, 273229066U, 247886176U, 222646516U, 197509248U, + 172473545U, 147538590U, 122703574U, 97967701U, 73330182U, 48790236U, + 24347096U, 0U +#if 0 + /* The following are the values for 16 bit tables - these work fine for the 8 + * bit conversions but produce very slightly larger errors in the 16 bit log + * (about 1.2 as opposed to 0.7 absolute error in the final value). To use + * these all the shifts below must be adjusted appropriately. + */ + 65166, 64430, 63700, 62976, 62257, 61543, 60835, 60132, 59434, 58741, 58054, + 57371, 56693, 56020, 55352, 54689, 54030, 53375, 52726, 52080, 51439, 50803, + 50170, 49542, 48918, 48298, 47682, 47070, 46462, 45858, 45257, 44661, 44068, + 43479, 42894, 42312, 41733, 41159, 40587, 40020, 39455, 38894, 38336, 37782, + 37230, 36682, 36137, 35595, 35057, 34521, 33988, 33459, 32932, 32408, 31887, + 31369, 30854, 30341, 29832, 29325, 28820, 28319, 27820, 27324, 26830, 26339, + 25850, 25364, 24880, 24399, 23920, 23444, 22970, 22499, 22029, 21562, 21098, + 20636, 20175, 19718, 19262, 18808, 18357, 17908, 17461, 17016, 16573, 16132, + 15694, 15257, 14822, 14390, 13959, 13530, 13103, 12678, 12255, 11834, 11415, + 10997, 10582, 10168, 9756, 9346, 8937, 8531, 8126, 7723, 7321, 6921, 6523, + 6127, 5732, 5339, 4947, 4557, 4169, 3782, 3397, 3014, 2632, 2251, 1872, 1495, + 1119, 744, 372 +#endif +}; + +static png_int_32 +png_log8bit(unsigned int x) +{ + unsigned int log = 0; + /* Each time 'x' is multiplied by 2, 1 must be subtracted off the final log, + * because the log is actually negate that means adding 1. The final + * returned value thus has the range 0 (for 255 input) to 7.994 (for 1 + * input), return 7.99998 for the overflow (log 0) case - so the result is + * always at most 19 bits. + */ + if ((x &= 0xff) == 0) + return 0xffffffff; + + if ((x & 0xf0) == 0) + log = 4, x <<= 4; + + if ((x & 0xc0) == 0) + log += 2, x <<= 2; + + if ((x & 0x80) == 0) + log += 1, x <<= 1; + + /* result is at most 19 bits, so this cast is safe: */ + return (png_int_32)((log << 16) + ((png_8bit_l2[x-128]+32768)>>16)); +} + +/* The above gives exact (to 16 binary places) log2 values for 8 bit images, + * for 16 bit images we use the most significant 8 bits of the 16 bit value to + * get an approximation then multiply the approximation by a correction factor + * determined by the remaining up to 8 bits. This requires an additional step + * in the 16 bit case. + * + * We want log2(value/65535), we have log2(v'/255), where: + * + * value = v' * 256 + v'' + * = v' * f + * + * So f is value/v', which is equal to (256+v''/v') since v' is in the range 128 + * to 255 and v'' is in the range 0 to 255 f will be in the range 256 to less + * than 258. The final factor also needs to correct for the fact that our 8 bit + * value is scaled by 255, whereas the 16 bit values must be scaled by 65535. + * + * This gives a final formula using a calculated value 'x' which is value/v' and + * scaling by 65536 to match the above table: + * + * log2(x/257) * 65536 + * + * Since these numbers are so close to '1' we can use simple linear + * interpolation between the two end values 256/257 (result -368.61) and 258/257 + * (result 367.179). The values used below are scaled by a further 64 to give + * 16 bit precision in the interpolation: + * + * Start (256): -23591 + * Zero (257): 0 + * End (258): 23499 + */ +static png_int_32 +png_log16bit(png_uint_32 x) +{ + unsigned int log = 0; + + /* As above, but now the input has 16 bits. */ + if ((x &= 0xffff) == 0) + return 0xffffffff; + + if ((x & 0xff00) == 0) + log = 8, x <<= 8; + + if ((x & 0xf000) == 0) + log += 4, x <<= 4; + + if ((x & 0xc000) == 0) + log += 2, x <<= 2; + + if ((x & 0x8000) == 0) + log += 1, x <<= 1; + + /* Calculate the base logarithm from the top 8 bits as a 28 bit fractional + * value. + */ + log <<= 28; + log += (png_8bit_l2[(x>>8)-128]+8) >> 4; + + /* Now we need to interpolate the factor, this requires a division by the top + * 8 bits. Do this with maximum precision. + */ + x = ((x << 16) + (x >> 9)) / (x >> 8); + + /* Since we divided by the top 8 bits of 'x' there will be a '1' at 1<<24, + * the value at 1<<16 (ignoring this) will be 0 or 1; this gives us exactly + * 16 bits to interpolate to get the low bits of the result. Round the + * answer. Note that the end point values are scaled by 64 to retain overall + * precision and that 'log' is current scaled by an extra 12 bits, so adjust + * the overall scaling by 6-12. Round at every step. + */ + x -= 1U << 24; + + if (x <= 65536U) /* <= '257' */ + log += ((23591U * (65536U-x)) + (1U << (16+6-12-1))) >> (16+6-12); + + else + log -= ((23499U * (x-65536U)) + (1U << (16+6-12-1))) >> (16+6-12); + + /* Safe, because the result can't have more than 20 bits: */ + return (png_int_32)((log + 2048) >> 12); +} + +/* The 'exp()' case must invert the above, taking a 20 bit fixed point + * logarithmic value and returning a 16 or 8 bit number as appropriate. In + * each case only the low 16 bits are relevant - the fraction - since the + * integer bits (the top 4) simply determine a shift. + * + * The worst case is the 16 bit distinction between 65535 and 65534, this + * requires perhaps spurious accuracty in the decoding of the logarithm to + * distinguish log2(65535/65534.5) - 10^-5 or 17 bits. There is little chance + * of getting this accuracy in practice. + * + * To deal with this the following exp() function works out the exponent of the + * frational part of the logarithm by using an accurate 32 bit value from the + * top four fractional bits then multiplying in the remaining bits. + */ +static png_uint_32 +png_32bit_exp[16] = +{ +# if PNG_DO_BC + for (i=0;i<16;++i) { .5 + e(-i/16*l(2))*2^32; } +# endif + /* NOTE: the first entry is deliberately set to the maximum 32 bit value. */ + 4294967295U, 4112874773U, 3938502376U, 3771522796U, 3611622603U, 3458501653U, + 3311872529U, 3171459999U, 3037000500U, 2908241642U, 2784941738U, 2666869345U, + 2553802834U, 2445529972U, 2341847524U, 2242560872U +}; + +/* Adjustment table; provided to explain the numbers in the code below. */ +#if PNG_DO_BC +for (i=11;i>=0;--i){ print i, " ", (1 - e(-(2^i)/65536*l(2))) * 2^(32-i), "\n"} + 11 44937.64284865548751208448 + 10 45180.98734845585101160448 + 9 45303.31936980687359311872 + 8 45364.65110595323018870784 + 7 45395.35850361789624614912 + 6 45410.72259715102037508096 + 5 45418.40724413220722311168 + 4 45422.25021786898173001728 + 3 45424.17186732298419044352 + 2 45425.13273269940811464704 + 1 45425.61317555035558641664 + 0 45425.85339951654943850496 +#endif + +static png_uint_32 +png_exp(png_fixed_point x) +{ + if (x > 0 && x <= 0xfffff) /* Else overflow or zero (underflow) */ + { + /* Obtain a 4 bit approximation */ + png_uint_32 e = png_32bit_exp[(x >> 12) & 0xf]; + + /* Incorporate the low 12 bits - these decrease the returned value by + * multiplying by a number less than 1 if the bit is set. The multiplier + * is determined by the above table and the shift. Notice that the values + * converge on 45426 and this is used to allow linear interpolation of the + * low bits. + */ + if (x & 0x800) + e -= (((e >> 16) * 44938U) + 16U) >> 5; + + if (x & 0x400) + e -= (((e >> 16) * 45181U) + 32U) >> 6; + + if (x & 0x200) + e -= (((e >> 16) * 45303U) + 64U) >> 7; + + if (x & 0x100) + e -= (((e >> 16) * 45365U) + 128U) >> 8; + + if (x & 0x080) + e -= (((e >> 16) * 45395U) + 256U) >> 9; + + if (x & 0x040) + e -= (((e >> 16) * 45410U) + 512U) >> 10; + + /* And handle the low 6 bits in a single block. */ + e -= (((e >> 16) * 355U * (x & 0x3fU)) + 256U) >> 9; + + /* Handle the upper bits of x. */ + e >>= x >> 16; + return e; + } + + /* Check for overflow */ + if (x <= 0) + return png_32bit_exp[0]; + + /* Else underflow */ + return 0; +} + +static png_byte +png_exp8bit(png_fixed_point log) +{ + /* Get a 32 bit value: */ + png_uint_32 x = png_exp(log); + + /* Convert the 32 bit value to 0..255 by multiplying by 256-1, note that the + * second, rounding, step can't overflow because of the first, subtraction, + * step. + */ + x -= x >> 8; + return (png_byte)((x + 0x7fffffU) >> 24); +} + +static png_uint_16 +png_exp16bit(png_fixed_point log) +{ + /* Get a 32 bit value: */ + png_uint_32 x = png_exp(log); + + /* Convert the 32 bit value to 0..65535 by multiplying by 65536-1: */ + x -= x >> 16; + return (png_uint_16)((x + 32767U) >> 16); +} +#endif /* FLOATING_ARITHMETIC */ + +png_byte +png_gamma_8bit_correct(unsigned int value, png_fixed_point gamma) +{ + if (value > 0 && value < 255) + { +# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + double r = floor(255*pow(value/255.,gamma*.00001)+.5); + return (png_byte)r; +# else + png_int_32 log = png_log8bit(value); + png_fixed_point res; + + if (png_muldiv(&res, gamma, log, PNG_FP_1)) + return png_exp8bit(res); + + /* Overflow. */ + value = 0; +# endif + } + + return (png_byte)value; +} + +png_uint_16 +png_gamma_16bit_correct(unsigned int value, png_fixed_point gamma) +{ + if (value > 0 && value < 65535) + { +# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + double r = floor(65535*pow(value/65535.,gamma*.00001)+.5); + return (png_uint_16)r; +# else + png_int_32 log = png_log16bit(value); + png_fixed_point res; + + if (png_muldiv(&res, gamma, log, PNG_FP_1)) + return png_exp16bit(res); + + /* Overflow. */ + value = 0; +# endif + } + + return (png_uint_16)value; +} + +/* This does the right thing based on the bit_depth field of the + * png_struct, interpreting values as 8 or 16 bit. While the result + * is nominally a 16 bit value if bit depth is 8 then the result is + * 8 bit (as are the arguments.) + */ +png_uint_16 /* PRIVATE */ +png_gamma_correct(png_structp png_ptr, unsigned int value, + png_fixed_point gamma) +{ + if (png_ptr->bit_depth == 8) + return png_gamma_8bit_correct(value, gamma); + + else + return png_gamma_16bit_correct(value, gamma); +} + +/* This is the shared test on whether a gamma value is 'significant' - whether + * it is worth doing gamma correction. + */ +int /* PRIVATE */ +png_gamma_significant(png_fixed_point gamma) +{ + return gamma < PNG_FP_1 - PNG_GAMMA_THRESHOLD_FIXED || + gamma > PNG_FP_1 + PNG_GAMMA_THRESHOLD_FIXED; +} + +/* Internal function to build a single 16 bit table - the table consists of + * 'num' 256 entry subtables, where 'num' is determined by 'shift' - the amount + * to shift the input values right (or 16-number_of_signifiant_bits). + * + * The caller is responsible for ensuring that the table gets cleaned up on + * png_error (i.e. if one of the mallocs below fails) - i.e. the *table argument + * should be somewhere that will be cleaned. + */ +static void +png_build_16bit_table(png_structp png_ptr, png_uint_16pp *ptable, + PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma) +{ + /* Various values derived from 'shift': */ + PNG_CONST unsigned int num = 1U << (8U - shift); + PNG_CONST unsigned int max = (1U << (16U - shift))-1U; + PNG_CONST unsigned int max_by_2 = 1U << (15U-shift); + unsigned int i; + + png_uint_16pp table = *ptable = + (png_uint_16pp)png_calloc(png_ptr, num * png_sizeof(png_uint_16p)); + + for (i = 0; i < num; i++) + { + png_uint_16p sub_table = table[i] = + (png_uint_16p)png_malloc(png_ptr, 256 * png_sizeof(png_uint_16)); + + /* The 'threshold' test is repeated here because it can arise for one of + * the 16 bit tables even if the others don't hit it. + */ + if (png_gamma_significant(gamma)) + { + /* The old code would overflow at the end and this would cause the + * 'pow' function to return a result >1, resulting in an + * arithmetic error. This code follows the spec exactly; ig is + * the recovered input sample, it always has 8-16 bits. + * + * We want input * 65535/max, rounded, the arithmetic fits in 32 + * bits (unsigned) so long as max <= 32767. + */ + unsigned int j; + for (j = 0; j < 256; j++) + { + png_uint_32 ig = (j << (8-shift)) + i; +# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED + /* Inline the 'max' scaling operation: */ + double d = floor(65535*pow(ig/(double)max, gamma*.00001)+.5); + sub_table[j] = (png_uint_16)d; +# else + if (shift) + ig = (ig * 65535U + max_by_2)/max; + + sub_table[j] = png_gamma_16bit_correct(ig, gamma); +# endif + } + } + else + { + /* We must still build a table, but do it the fast way. */ + unsigned int j; + + for (j = 0; j < 256; j++) + { + png_uint_32 ig = (j << (8-shift)) + i; + + if (shift) + ig = (ig * 65535U + max_by_2)/max; + + sub_table[j] = (png_uint_16)ig; + } + } + } +} + +/* NOTE: this function expects the *inverse* of the overall gamma transformation + * required. + */ +static void +png_build_16to8_table(png_structp png_ptr, png_uint_16pp *ptable, + PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma) +{ + PNG_CONST unsigned int num = 1U << (8U - shift); + PNG_CONST unsigned int max = (1U << (16U - shift))-1U; + unsigned int i; + png_uint_32 last; + + png_uint_16pp table = *ptable = + (png_uint_16pp)png_calloc(png_ptr, num * png_sizeof(png_uint_16p)); + + /* 'num' is the number of tables and also the number of low bits of low + * bits of the input 16 bit value used to select a table. Each table is + * itself index by the high 8 bits of the value. + */ + for (i = 0; i < num; i++) + table[i] = (png_uint_16p)png_malloc(png_ptr, + 256 * png_sizeof(png_uint_16)); + + /* 'gamma' is set to the reciprocal of the value calculated above, so + * pow(out,g) is an *input* value. 'last' is the last input value set. + * + * In the loop 'i' is used to find output values. Since the output is 8 + * bit there are only 256 possible values. The tables are set up to + * select the closest possible output value for each input by finding + * the input value at the boundary between each pair of output values + * and filling the table up to that boundary with the lower output + * value. + * + * The boundary values are 0.5,1.5..253.5,254.5. Since these are 9 bit + * values the code below uses a 16 bit value in i; the values start at + * 128.5 (for 0.5) and step by 257, for a total of 254 values (the last + * entries are filled with 255). Start i at 128 and fill all 'last' + * table entries <= 'max' + */ + last = 0; + for (i = 0; i < 255; ++i) /* 8 bit output value */ + { + /* Find the corresponding maximum input value */ + png_uint_16 out = (png_uint_16)(i * 257U); /* 16 bit output value */ + + /* Find the boundary value in 16 bits: */ + png_uint_32 bound = png_gamma_16bit_correct(out+128U, gamma); + + /* Adjust (round) to (16-shift) bits: */ + bound = (bound * max + 32768U)/65535U + 1U; + + while (last < bound) + { + table[last & (0xffU >> shift)][last >> (8U - shift)] = out; + last++; + } + } + + /* And fill in the final entries. */ + while (last < (num << 8)) + { + table[last & (0xff >> shift)][last >> (8U - shift)] = 65535U; + last++; + } +} + +/* Build a single 8 bit table: same as the 16 bit case but much simpler (and + * typically much faster). Note that libpng currently does no sBIT processing + * (apparently contrary to the spec) so a 256 entry table is always generated. + */ +static void +png_build_8bit_table(png_structp png_ptr, png_bytepp ptable, + PNG_CONST png_fixed_point gamma) +{ + unsigned int i; + png_bytep table = *ptable = (png_bytep)png_malloc(png_ptr, 256); + + if (png_gamma_significant(gamma)) for (i=0; i<256; i++) + table[i] = png_gamma_8bit_correct(i, gamma); + + else for (i=0; i<256; ++i) + table[i] = (png_byte)i; +} + +/* We build the 8- or 16-bit gamma tables here. Note that for 16-bit + * tables, we don't make a full table if we are reducing to 8-bit in + * the future. Note also how the gamma_16 tables are segmented so that + * we don't need to allocate > 64K chunks for a full 16-bit table. + */ +void /* PRIVATE */ +png_build_gamma_table(png_structp png_ptr, int bit_depth) +{ + png_debug(1, "in png_build_gamma_table"); + + if (bit_depth <= 8) + { + png_build_8bit_table(png_ptr, &png_ptr->gamma_table, + png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->gamma, + png_ptr->screen_gamma) : PNG_FP_1); + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ + defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) + if (png_ptr->transformations & ((PNG_BACKGROUND) | PNG_RGB_TO_GRAY)) + { + png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1, + png_reciprocal(png_ptr->gamma)); + + png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1, + png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) : + png_ptr->gamma/* Probably doing rgb_to_gray */); + } +#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */ + } + else + { + png_byte shift, sig_bit; + + if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) + { + sig_bit = png_ptr->sig_bit.red; + + if (png_ptr->sig_bit.green > sig_bit) + sig_bit = png_ptr->sig_bit.green; + + if (png_ptr->sig_bit.blue > sig_bit) + sig_bit = png_ptr->sig_bit.blue; + } + else + sig_bit = png_ptr->sig_bit.gray; + + /* 16 bit gamma code uses this equation: + * + * ov = table[(iv & 0xff) >> gamma_shift][iv >> 8] + * + * Where 'iv' is the input color value and 'ov' is the output value - + * pow(iv, gamma). + * + * Thus the gamma table consists of up to 256 256 entry tables. The table + * is selected by the (8-gamma_shift) most significant of the low 8 bits of + * the color value then indexed by the upper 8 bits: + * + * table[low bits][high 8 bits] + * + * So the table 'n' corresponds to all those 'iv' of: + * + * ..<(n+1 << gamma_shift)-1> + * + */ + if (sig_bit > 0 && sig_bit < 16U) + shift = (png_byte)(16U - sig_bit); /* shift == insignificant bits */ + + else + shift = 0; /* keep all 16 bits */ + + if (png_ptr->transformations & PNG_16_TO_8) + { + /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively + * the significant bits in the *input* when the output will + * eventually be 8 bits. By default it is 11. + */ + if (shift < (16U - PNG_MAX_GAMMA_8)) + shift = (16U - PNG_MAX_GAMMA_8); + } + + if (shift > 8U) + shift = 8U; /* Guarantees at least one table! */ + + png_ptr->gamma_shift = shift; + +#ifdef PNG_16BIT_SUPPORTED + if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND)) +#endif + png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift, + png_ptr->screen_gamma > 0 ? png_product2(png_ptr->gamma, + png_ptr->screen_gamma) : PNG_FP_1); + +#ifdef PNG_16BIT_SUPPORTED + else + png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift, + png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->gamma, + png_ptr->screen_gamma) : PNG_FP_1); +#endif + +#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ + defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) + if (png_ptr->transformations & (PNG_BACKGROUND | PNG_RGB_TO_GRAY)) + { + png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift, + png_reciprocal(png_ptr->gamma)); + + /* Notice that the '16 from 1' table should be full precision, however + * the lookup on this table still uses gamma_shift, so it can't be. + * TODO: fix this. + */ + png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift, + png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) : + png_ptr->gamma/* Probably doing rgb_to_gray */); + } +#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */ + } +} +#endif /* READ_GAMMA */ #endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ diff --git a/harbour/src/3rd/png/png.h b/harbour/src/3rd/png/png.h index b1f1bc364e..470ae68d31 100644 --- a/harbour/src/3rd/png/png.h +++ b/harbour/src/3rd/png/png.h @@ -1,26 +1,26 @@ /* png.h - header file for PNG reference library * - * libpng version 1.4.5 - December 9, 2010 - * Copyright (c) 1998-2010 Glenn Randers-Pehrson + * libpng version 1.5.0 - January 6, 2011 + * Copyright (c) 1998-2011 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * * This code is released under the libpng license (See LICENSE, below) * * Authors and maintainers: - * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat - * libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger - * libpng versions 0.97, January 1998, through 1.4.5 - December 9, 2010: Glenn - * See also "Contributing Authors", below. + * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat + * libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger + * libpng versions 0.97, January 1998, through 1.5.0 - January 6, 2011: Glenn + * See also "Contributing Authors", below. * * Note about libpng version numbers: * - * Due to various miscommunications, unforeseen code incompatibilities - * and occasional factors outside the authors' control, version numbering - * on the library has not always been consistent and straightforward. - * The following table summarizes matters since version 0.89c, which was - * the first widely used release: + * Due to various miscommunications, unforeseen code incompatibilities + * and occasional factors outside the authors' control, version numbering + * on the library has not always been consistent and straightforward. + * The following table summarizes matters since version 0.89c, which was + * the first widely used release: * * source png.h png.h shared-lib * version string int version @@ -137,43 +137,34 @@ * 1.4.1beta01-03 14 10401 14.so.14.1[.0] * 1.4.1rc01 14 10401 14.so.14.1[.0] * 1.4.1beta04-12 14 10401 14.so.14.1[.0] - * 1.4.1rc02-04 14 10401 14.so.14.1[.0] * 1.4.1 14 10401 14.so.14.1[.0] - * 1.4.2beta01 14 10402 14.so.14.2[.0] - * 1.4.2rc02-06 14 10402 14.so.14.2[.0] * 1.4.2 14 10402 14.so.14.2[.0] - * 1.4.3beta01-05 14 10403 14.so.14.3[.0] - * 1.4.3rc01-03 14 10403 14.so.14.3[.0] * 1.4.3 14 10403 14.so.14.3[.0] - * 1.4.4beta01-08 14 10404 14.so.14.4[.0] - * 1.4.4rc01-05 14 10404 14.so.14.4[.0] * 1.4.4 14 10404 14.so.14.4[.0] - * 1.4.5beta01-04 14 10405 14.so.14.5[.0] - * 1.4.5rc01 14 10405 14.so.14.5[.0] - * 1.4.5beta05-07 14 10405 14.so.14.5[.0] - * 1.4.5rc02-03 14 10405 14.so.14.5[.0] - * 1.4.5 14 10405 14.so.14.5[.0] + * 1.5.0beta01-58 15 10500 15.so.15.0[.0] + * 1.5.0rc01-07 15 10500 15.so.15.0[.0] + * 1.5.0 15 10500 15.so.15.0[.0] * - * Henceforth the source version will match the shared-library major - * and minor numbers; the shared-library major version number will be - * used for changes in backward compatibility, as it is intended. The - * PNG_LIBPNG_VER macro, which is not used within libpng but is available - * for applications, is an unsigned integer of the form xyyzz corresponding - * to the source version x.y.z (leading zeros in y and z). Beta versions - * were given the previous public release number plus a letter, until - * version 1.0.6j; from then on they were given the upcoming public - * release number plus "betaNN" or "rcN". + * Henceforth the source version will match the shared-library major + * and minor numbers; the shared-library major version number will be + * used for changes in backward compatibility, as it is intended. The + * PNG_LIBPNG_VER macro, which is not used within libpng but is available + * for applications, is an unsigned integer of the form xyyzz corresponding + * to the source version x.y.z (leading zeros in y and z). Beta versions + * were given the previous public release number plus a letter, until + * version 1.0.6j; from then on they were given the upcoming public + * release number plus "betaNN" or "rcN". * - * Binary incompatibility exists only when applications make direct access - * to the info_ptr or png_ptr members through png.h, and the compiled - * application is loaded with a different version of the library. + * Binary incompatibility exists only when applications make direct access + * to the info_ptr or png_ptr members through png.h, and the compiled + * application is loaded with a different version of the library. * - * DLLNUM will change each time there are forward or backward changes - * in binary compatibility (e.g., when a new feature is added). + * DLLNUM will change each time there are forward or backward changes + * in binary compatibility (e.g., when a new feature is added). * - * See libpng.txt or libpng.3 for more information. The PNG specification - * is available as a W3C Recommendation and as an ISO Specification, - * +# endif + +/* Need the time information for converting tIME chunks, it + * defines struct tm: + */ +#ifdef PNG_CONVERT_tIME_SUPPORTED + /* "time.h" functions are not supported on all operating systems */ +# include +#endif + +/* Machine specific configuration. */ +# include "pngconf.h" +#endif /* * Added at libpng-1.2.8 @@ -422,13 +433,13 @@ * StringFileInfo block must contain a SpecialBuild string. */ -#ifdef PNG_USER_PRIVATEBUILD +#ifdef PNG_USER_PRIVATEBUILD /* From pnglibconf.h */ # define PNG_LIBPNG_BUILD_TYPE \ - (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_PRIVATE) + (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_PRIVATE) #else # ifdef PNG_LIBPNG_SPECIALBUILD # define PNG_LIBPNG_BUILD_TYPE \ - (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_SPECIAL) + (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_SPECIAL) # else # define PNG_LIBPNG_BUILD_TYPE (PNG_LIBPNG_BUILD_BASE_TYPE) # endif @@ -441,20 +452,61 @@ extern "C" { #endif /* __cplusplus */ -/* This file is arranged in several sections. The first section contains - * structure and type definitions. The second section contains the external - * library functions, while the third has the internal library functions, - * which applications aren't expected to use directly. - */ - -/* Variables declared in png.c - only it needs to define PNG_NO_EXTERN */ -#if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN) /* Version information for C files, stored in png.c. This had better match * the version above. */ #define png_libpng_ver png_get_header_ver(NULL) -#endif /* PNG_NO_EXTERN */ +/* This file is arranged in several sections: + * + * 1. Any configuration options that can be specified by for the application + * code when it is built. (Build time configuration is in pnglibconf.h) + * 2. Type definitions (base types are defined in pngconf.h), structure + * definitions. + * 3. Exported library functions. + * + * The library source code has additional files (principally pngpriv.h) that + * allow configuration of the library. + */ +/* Section 1: run time configuration + * See pnglibconf.h for build time configuration + * + * Run time configuration allows the application to choose between + * implementations of certain arithmetic APIs. The default is set + * at build time and recorded in pnglibconf.h, but it is safe to + * override these (and only these) settings. Note that this won't + * change what the library does, only application code, and the + * settings can (and probably should) be made on a per-file basis + * by setting the #defines before including png.h + * + * Use macros to read integers from PNG data or use the exported + * functions? + * PNG_USE_READ_MACROS: use the macros (see below) Note that + * the macros evaluate their argument multiple times. + * PNG_NO_USE_READ_MACROS: call the relevant library function. + * + * Use the alternative algorithm for compositing alpha samples that + * does not use division? + * PNG_READ_COMPOSITE_NODIV_SUPPORTED: use the 'no division' + * algorithm. + * PNG_NO_READ_COMPOSITE_NODIV: use the 'division' algorithm. + * + * How to handle benign errors if PNG_ALLOW_BENIGN_ERRORS is + * false? + * PNG_ALLOW_BENIGN_ERRORS: map calls to the benign error + * APIs to png_warning. + * Otherwise the calls are mapped to png_error. + */ + +/* Section 2: type definitions, including structures and compile time + * constants. + * See pngconf.h for base types that vary by machine/system + */ + +/* This triggers a compiler error in png.c, if png.c and png.h + * do not agree upon the version number. + */ +typedef char* png_libpng_version_1_5_0; /* Three color definitions. The order of the red, green, and blue, (and the * exact size) is not important, although the size of the fields need to @@ -467,6 +519,7 @@ typedef struct png_color_struct png_byte blue; } png_color; typedef png_color FAR * png_colorp; +typedef PNG_CONST png_color FAR * png_const_colorp; typedef png_color FAR * FAR * png_colorpp; typedef struct png_color_16_struct @@ -478,6 +531,7 @@ typedef struct png_color_16_struct png_uint_16 gray; /* for use in grayscale files */ } png_color_16; typedef png_color_16 FAR * png_color_16p; +typedef PNG_CONST png_color_16 FAR * png_const_color_16p; typedef png_color_16 FAR * FAR * png_color_16pp; typedef struct png_color_8_struct @@ -489,6 +543,7 @@ typedef struct png_color_8_struct png_byte alpha; /* for alpha channel files */ } png_color_8; typedef png_color_8 FAR * png_color_8p; +typedef PNG_CONST png_color_8 FAR * png_const_color_8p; typedef png_color_8 FAR * FAR * png_color_8pp; /* @@ -504,6 +559,7 @@ typedef struct png_sPLT_entry_struct png_uint_16 frequency; } png_sPLT_entry; typedef png_sPLT_entry FAR * png_sPLT_entryp; +typedef PNG_CONST png_sPLT_entry FAR * png_const_sPLT_entryp; typedef png_sPLT_entry FAR * FAR * png_sPLT_entrypp; /* When the depth of the sPLT palette is 8 bits, the color and alpha samples @@ -519,15 +575,16 @@ typedef struct png_sPLT_struct png_int_32 nentries; /* number of palette entries */ } png_sPLT_t; typedef png_sPLT_t FAR * png_sPLT_tp; +typedef PNG_CONST png_sPLT_t FAR * png_const_sPLT_tp; typedef png_sPLT_t FAR * FAR * png_sPLT_tpp; #ifdef PNG_TEXT_SUPPORTED -/* png_text holds the contents of a text/ztxt/itxt chunk in a PNG file, +/* png_text holds the contents of a text/ztxt/itxt chunk in a PNG file, * and whether that contents is compressed or not. The "key" field * points to a regular zero-terminated C string. The "text", "lang", and * "lang_key" fields can be regular C strings, empty strings, or NULL pointers. * However, the * structure returned by png_get_text() will always contain - * regular zero-terminated C strings (possibly empty), never NULL pointers, + * regular zero-terminated C strings (possibly empty), never NULL pointers, * so they can be safely used in printf() and other string-handling functions. */ typedef struct png_text_struct @@ -541,15 +598,14 @@ typedef struct png_text_struct png_charp text; /* comment, may be an empty string (ie "") or a NULL pointer */ png_size_t text_length; /* length of the text string */ -#ifdef PNG_iTXt_SUPPORTED png_size_t itxt_length; /* length of the itxt string */ png_charp lang; /* language code, 0-79 characters or a NULL pointer */ png_charp lang_key; /* keyword translated UTF-8 string, 0 or more chars or a NULL pointer */ -#endif } png_text; typedef png_text FAR * png_textp; +typedef PNG_CONST png_text FAR * png_const_textp; typedef png_text FAR * FAR * png_textpp; #endif @@ -579,10 +635,11 @@ typedef struct png_time_struct png_byte second; /* second of minute, 0 - 60 (for leap seconds) */ } png_time; typedef png_time FAR * png_timep; +typedef PNG_CONST png_time FAR * png_const_timep; typedef png_time FAR * FAR * png_timepp; #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) || \ - defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED) + defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED) /* png_unknown_chunk is a structure to hold queued chunks for which there is * no specific support. The idea is that we can use this to queue * up private chunks for output even though the library doesn't actually @@ -599,311 +656,11 @@ typedef struct png_unknown_chunk_t } png_unknown_chunk; typedef png_unknown_chunk FAR * png_unknown_chunkp; +typedef PNG_CONST png_unknown_chunk FAR * png_const_unknown_chunkp; typedef png_unknown_chunk FAR * FAR * png_unknown_chunkpp; #endif -/* png_info is a structure that holds the information in a PNG file so - * that the application can find out the characteristics of the image. - * If you are reading the file, this structure will tell you what is - * in the PNG file. If you are writing the file, fill in the information - * you want to put into the PNG file, then call png_write_info(). - * The names chosen should be very close to the PNG specification, so - * consult that document for information about the meaning of each field. - * - * With libpng < 0.95, it was only possible to directly set and read the - * the values in the png_info_struct, which meant that the contents and - * order of the values had to remain fixed. With libpng 0.95 and later, - * however, there are now functions that abstract the contents of - * png_info_struct from the application, so this makes it easier to use - * libpng with dynamic libraries, and even makes it possible to use - * libraries that don't have all of the libpng ancillary chunk-handing - * functionality. - * - * 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, trans, text, - * pcal_purpose, pcal_units, pcal_params, hist, iccp_name, iccp_profile, - * splt_palettes, scal_unit, row_pointers, and unknowns. By default, these - * are automatically freed when the info structure is deallocated, if they were - * allocated internally by libpng. This behavior can be changed by means - * of the png_data_freer() function. - * - * More allocation details: all the chunk-reading functions that - * change these members go through the corresponding png_set_* - * functions. A function to clear these members is available: see - * png_free_data(). 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 - * functions use the same storage passed to them in the text_ptr or - * itxt_ptr structure argument, and the png_set_rows and png_set_unknowns - * functions do not make their own copies. - */ -typedef struct png_info_struct -{ - /* the following are necessary for every PNG file */ - png_uint_32 width PNG_DEPSTRUCT; /* width of image in pixels (from IHDR) */ - png_uint_32 height PNG_DEPSTRUCT; /* height of image in pixels (from IHDR) */ - png_uint_32 valid PNG_DEPSTRUCT; /* valid chunk data (see PNG_INFO_ - below) */ - png_size_t rowbytes PNG_DEPSTRUCT; /* bytes needed to hold an untransformed - row */ - png_colorp palette PNG_DEPSTRUCT; /* array of color values - (valid & PNG_INFO_PLTE) */ - png_uint_16 num_palette PNG_DEPSTRUCT; /* number of color entries in - "palette" (PLTE) */ - png_uint_16 num_trans PNG_DEPSTRUCT; /* number of transparent palette - color (tRNS) */ - png_byte bit_depth PNG_DEPSTRUCT; /* 1, 2, 4, 8, or 16 bits/channel - (from IHDR) */ - png_byte color_type PNG_DEPSTRUCT; /* see PNG_COLOR_TYPE_ below - (from IHDR) */ - /* The following three should have been named *_method not *_type */ - png_byte compression_type PNG_DEPSTRUCT; /* must be - PNG_COMPRESSION_TYPE_BASE (IHDR) */ - png_byte filter_type PNG_DEPSTRUCT; /* must be PNG_FILTER_TYPE_BASE - (from IHDR) */ - png_byte interlace_type PNG_DEPSTRUCT; /* One of PNG_INTERLACE_NONE, - PNG_INTERLACE_ADAM7 */ - - /* The following is informational only on read, and not used on writes. */ - png_byte channels PNG_DEPSTRUCT; /* number of data channels per - pixel (1, 2, 3, 4) */ - png_byte pixel_depth PNG_DEPSTRUCT; /* number of bits per pixel */ - png_byte spare_byte PNG_DEPSTRUCT; /* to align the data, and for - future use */ - png_byte signature[8] PNG_DEPSTRUCT; /* magic bytes read by libpng - from start of file */ - - /* The rest of the data is optional. If you are reading, check the - * valid field to see if the information in these are valid. If you - * are writing, set the valid field to those chunks you want written, - * and initialize the appropriate fields below. - */ - -#if defined(PNG_gAMA_SUPPORTED) && defined(PNG_FLOATING_POINT_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 PNG_DEPSTRUCT; /* gamma value of image, - if (valid & PNG_INFO_gAMA) */ -#endif - -#ifdef PNG_sRGB_SUPPORTED - /* GR-P, 0.96a */ - /* Data valid if (valid & PNG_INFO_sRGB) non-zero. */ - png_byte srgb_intent PNG_DEPSTRUCT; /* sRGB rendering intent - [0, 1, 2, or 3] */ -#endif - -#ifdef 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 PNG_DEPSTRUCT; /* number of comments read/to write */ - int max_text PNG_DEPSTRUCT; /* current size of text array */ - png_textp text PNG_DEPSTRUCT; /* array of comments read/to write */ -#endif /* PNG_TEXT_SUPPORTED */ - -#ifdef 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 PNG_DEPSTRUCT; -#endif - -#ifdef 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 - * the low-order bits is not specified. Data is valid if - * (valid & PNG_INFO_sBIT) is non-zero. - */ - png_color_8 sig_bit PNG_DEPSTRUCT; /* significant bits in color channels */ -#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 - * same order as the palette colors, starting from index 0. Values - * for the data are in the range [0, 255], ranging from fully transparent - * to fully opaque, respectively. For non-paletted images, there is a - * single color specified that should be treated as fully transparent. - * Data is valid if (valid & PNG_INFO_tRNS) is non-zero. - */ - png_bytep trans_alpha PNG_DEPSTRUCT; /* alpha values for paletted - image */ - png_color_16 trans_color PNG_DEPSTRUCT; /* transparent color for - non-palette image */ -#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 - * in "background" are normally in the same color space/depth as the - * pixel data. Data is valid if (valid & PNG_INFO_bKGD) is non-zero. - */ - png_color_16 background PNG_DEPSTRUCT; -#endif - -#ifdef 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_int_32 x_offset PNG_DEPSTRUCT; /* x offset on page */ - png_int_32 y_offset PNG_DEPSTRUCT; /* y offset on page */ - png_byte offset_unit_type PNG_DEPSTRUCT; /* offset units type */ -#endif - -#ifdef 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. - */ - png_uint_32 x_pixels_per_unit PNG_DEPSTRUCT; /* horizontal pixel density */ - png_uint_32 y_pixels_per_unit PNG_DEPSTRUCT; /* vertical pixel density */ - png_byte phys_unit_type PNG_DEPSTRUCT; /* resolution type (see - PNG_RESOLUTION_ below) */ -#endif - -#ifdef 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" - * values in the range [0,65535]. Data valid if (valid & PNG_INFO_hIST) - * is non-zero. - */ - png_uint_16p hist PNG_DEPSTRUCT; -#endif - -#ifdef 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 - * colors in the image as the creator. Values are in the range - * [0.0, 0.8]. Data valid if (valid & PNG_INFO_cHRM) non-zero. - */ -#ifdef PNG_FLOATING_POINT_SUPPORTED - float x_white PNG_DEPSTRUCT; - float y_white PNG_DEPSTRUCT; - float x_red PNG_DEPSTRUCT; - float y_red PNG_DEPSTRUCT; - float x_green PNG_DEPSTRUCT; - float y_green PNG_DEPSTRUCT; - float x_blue PNG_DEPSTRUCT; - float y_blue PNG_DEPSTRUCT; -#endif -#endif - -#ifdef PNG_pCAL_SUPPORTED - /* The pCAL chunk describes a transformation between the stored pixel - * 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" - * and "pcal_params" into "pcal_units". Please see the PNG_EQUATION_ - * defines below, and the PNG-Group's PNG extensions document for a - * complete description of the transformations and how they should be - * implemented, and for a description of the ASCII parameter strings. - * Data values are valid if (valid & PNG_INFO_pCAL) non-zero. - */ - png_charp pcal_purpose PNG_DEPSTRUCT; /* pCAL chunk description string */ - png_int_32 pcal_X0 PNG_DEPSTRUCT; /* minimum value */ - png_int_32 pcal_X1 PNG_DEPSTRUCT; /* maximum value */ - png_charp pcal_units PNG_DEPSTRUCT; /* Latin-1 string giving physical - units */ - png_charpp pcal_params PNG_DEPSTRUCT; /* ASCII strings containing - parameter values */ - png_byte pcal_type PNG_DEPSTRUCT; /* equation type - (see PNG_EQUATION_ below) */ - png_byte pcal_nparams PNG_DEPSTRUCT; /* number of parameters given - in pcal_params */ -#endif - -/* New members added in libpng-1.0.6 */ - png_uint_32 free_me PNG_DEPSTRUCT; /* flags items libpng is - responsible for freeing */ - -#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) || \ - defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED) - /* Storage for unknown chunks that the library doesn't recognize. */ - png_unknown_chunkp unknown_chunks PNG_DEPSTRUCT; - png_size_t unknown_chunks_num PNG_DEPSTRUCT; -#endif - -#ifdef PNG_iCCP_SUPPORTED - /* iCCP chunk data. */ - png_charp iccp_name PNG_DEPSTRUCT; /* profile name */ - png_charp iccp_profile PNG_DEPSTRUCT; /* International Color Consortium - profile data */ - /* Note to maintainer: should be png_bytep */ - png_uint_32 iccp_proflen PNG_DEPSTRUCT; /* ICC profile data length */ - png_byte iccp_compression PNG_DEPSTRUCT; /* Always zero */ -#endif - -#ifdef PNG_sPLT_SUPPORTED - /* Data on sPLT chunks (there may be more than one). */ - png_sPLT_tp splt_palettes PNG_DEPSTRUCT; - png_uint_32 splt_palettes_num PNG_DEPSTRUCT; -#endif - -#ifdef PNG_sCAL_SUPPORTED - /* The sCAL chunk describes the actual physical dimensions of the - * subject matter of the graphic. The chunk contains a unit specification - * a byte value, 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_byte scal_unit PNG_DEPSTRUCT; /* unit of physical scale */ -#ifdef PNG_FLOATING_POINT_SUPPORTED - double scal_pixel_width PNG_DEPSTRUCT; /* width of one pixel */ - double scal_pixel_height PNG_DEPSTRUCT; /* height of one pixel */ -#endif -#ifdef PNG_FIXED_POINT_SUPPORTED - png_charp scal_s_width PNG_DEPSTRUCT; /* string containing height */ - png_charp scal_s_height PNG_DEPSTRUCT; /* string containing width */ -#endif -#endif - -#ifdef PNG_INFO_IMAGE_SUPPORTED - /* Memory has been allocated if (valid & PNG_ALLOCATED_INFO_ROWS) - non-zero */ - /* Data valid if (valid & PNG_INFO_IDAT) non-zero */ - png_bytepp row_pointers PNG_DEPSTRUCT; /* the image bits */ -#endif - -#if defined(PNG_FIXED_POINT_SUPPORTED) && defined(PNG_gAMA_SUPPORTED) - png_fixed_point int_gamma PNG_DEPSTRUCT; /* gamma of image, - if (valid & PNG_INFO_gAMA) */ -#endif - -#if defined(PNG_cHRM_SUPPORTED) && defined(PNG_FIXED_POINT_SUPPORTED) - png_fixed_point int_x_white PNG_DEPSTRUCT; - png_fixed_point int_y_white PNG_DEPSTRUCT; - png_fixed_point int_x_red PNG_DEPSTRUCT; - png_fixed_point int_y_red PNG_DEPSTRUCT; - png_fixed_point int_x_green PNG_DEPSTRUCT; - png_fixed_point int_y_green PNG_DEPSTRUCT; - png_fixed_point int_x_blue PNG_DEPSTRUCT; - png_fixed_point int_y_blue PNG_DEPSTRUCT; -#endif - -} png_info; - +typedef struct png_info_def png_info; typedef png_info FAR * png_infop; typedef png_info FAR * FAR * png_infopp; @@ -912,6 +669,12 @@ typedef png_info FAR * FAR * png_infopp; #define PNG_UINT_32_MAX ((png_uint_32)(-1)) #define PNG_SIZE_MAX ((png_size_t)(-1)) +/* These are constants for fixed point values encoded in the + * PNG specification manner (x100000) + */ +#define PNG_FP_1 100000 +#define PNG_FP_HALF 50000 + /* These describe the color_type field in png_info. */ /* color type masks */ #define PNG_COLOR_MASK_PALETTE 1 @@ -1006,11 +769,11 @@ typedef png_info FAR * FAR * png_infopp; */ typedef struct png_row_info_struct { - png_uint_32 width; /* width of row */ - png_size_t rowbytes; /* number of bytes in row */ - png_byte color_type; /* color type of row */ - png_byte bit_depth; /* bit depth of row */ - png_byte channels; /* number of channels (1, 2, 3, or 4) */ + png_uint_32 width; /* width of row */ + png_size_t rowbytes; /* number of bytes in row */ + png_byte color_type; /* color type of row */ + png_byte bit_depth; /* bit depth of row */ + png_byte channels; /* number of channels (1, 2, 3, or 4) */ png_byte pixel_depth; /* bits per pixel (depth * channels) */ } png_row_info; @@ -1021,46 +784,64 @@ typedef png_row_info FAR * FAR * png_row_infopp; * that allow the user to override the default I/O functions with his or her * own. The png_error_ptr type should match that of user-supplied warning * and error functions, while the png_rw_ptr type should match that of the - * user read/write data functions. + * user read/write data functions. Note that the 'write' function must not + * modify the buffer it is passed. The 'read' function, on the other hand, is + * expected to return the read data in the buffer. */ typedef struct png_struct_def png_struct; typedef png_struct FAR * png_structp; -typedef void (PNGAPI *png_error_ptr) PNGARG((png_structp, png_const_charp)); -typedef void (PNGAPI *png_rw_ptr) PNGARG((png_structp, png_bytep, png_size_t)); -typedef void (PNGAPI *png_flush_ptr) PNGARG((png_structp)); -typedef void (PNGAPI *png_read_status_ptr) PNGARG((png_structp, png_uint_32, - int)); -typedef void (PNGAPI *png_write_status_ptr) PNGARG((png_structp, png_uint_32, - int)); +typedef PNG_CALLBACK(void, *png_error_ptr, (png_structp, png_const_charp), ); +typedef PNG_CALLBACK(void, *png_rw_ptr, (png_structp, png_bytep, png_size_t), ); +typedef PNG_CALLBACK(void, *png_flush_ptr, (png_structp), ); +typedef PNG_CALLBACK(void, *png_read_status_ptr, (png_structp, png_uint_32, + int), ); +typedef PNG_CALLBACK(void, *png_write_status_ptr, (png_structp, png_uint_32, + int), ); #ifdef PNG_PROGRESSIVE_READ_SUPPORTED -typedef void (PNGAPI *png_progressive_info_ptr) PNGARG((png_structp, - png_infop)); -typedef void (PNGAPI *png_progressive_end_ptr) PNGARG((png_structp, png_infop)); -typedef void (PNGAPI *png_progressive_row_ptr) PNGARG((png_structp, png_bytep, - png_uint_32, int)); +typedef PNG_CALLBACK(void, *png_progressive_info_ptr, + (png_structp, png_infop), ); +typedef PNG_CALLBACK(void, *png_progressive_end_ptr, + (png_structp, png_infop), ); +typedef PNG_CALLBACK(void, *png_progressive_row_ptr, + (png_structp, png_bytep, png_uint_32, int), ); #endif #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) -typedef void (PNGAPI *png_user_transform_ptr) PNGARG((png_structp, - png_row_infop, png_bytep)); +typedef PNG_CALLBACK(void, *png_user_transform_ptr, + (png_structp, png_row_infop, png_bytep), ); #endif #ifdef PNG_USER_CHUNKS_SUPPORTED -typedef int (PNGAPI *png_user_chunk_ptr) PNGARG((png_structp, - png_unknown_chunkp)); +typedef PNG_CALLBACK(int, *png_user_chunk_ptr, (png_structp, + png_unknown_chunkp), ); #endif #ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED -typedef void (PNGAPI *png_unknown_chunk_ptr) PNGARG((png_structp)); +typedef PNG_CALLBACK(void, *png_unknown_chunk_ptr, (png_structp), ); #endif + #ifdef PNG_SETJMP_SUPPORTED /* This must match the function definition in , and the * application must include this before png.h to obtain the definition - * of jmp_buf. + * of jmp_buf. The function is required to be PNG_NORETURN. (Note that + * PNG_PTR_NORETURN is used here because current versions of the Microsoft + * C compiler do not support the PNG_NORETURN attribute on a pointer.) + * + * If you get a type warning from the compiler when linking against this line + * then your compiler has 'longjmp' that does not match the requirements of the + * compiler that built libpng. You will have to write a wrapper function for + * your compiler's longjmp and call png_set_longjmp_fn directly (not via the + * png_jmpbuf macro.) + * + * If you get a warning here while building the library you will need to make + * changes to ensure that pnglibconf.h records the calling convention used by + * your compiler. This may be very difficult - try using a different compiler + * to build the library! */ -typedef void (PNGAPI *png_longjmp_ptr) PNGARG((jmp_buf, int)); +typedef PNG_FUNCTION(void, (PNGCAPI *png_longjmp_ptr), PNGARG((jmp_buf, int)), + PNG_PTR_NORETURN); #endif /* Transform masks for the high-level interface */ @@ -1088,447 +869,85 @@ typedef void (PNGAPI *png_longjmp_ptr) PNGARG((jmp_buf, int)); #define PNG_FLAG_MNG_FILTER_64 0x04 #define PNG_ALL_MNG_FEATURES 0x05 -typedef png_voidp (*png_malloc_ptr) PNGARG((png_structp, png_alloc_size_t)); -typedef void (*png_free_ptr) PNGARG((png_structp, png_voidp)); - -/* The structure that holds the information to read and write PNG files. - * The only people who need to care about what is inside of this are the - * people who will be modifying the library for their own special needs. - * It should NOT be accessed directly by an application, except to store - * the jmp_buf. +/* NOTE: prior to 1.5 these functions had no 'API' style declaration, + * this allowed the zlib default functions to be used on Windows + * platforms. In 1.5 the zlib default malloc (which just calls malloc and + * ignores the first argument) should be completely compatible with the + * following. */ - -struct png_struct_def -{ -#ifdef PNG_SETJMP_SUPPORTED - jmp_buf jmpbuf PNG_DEPSTRUCT; /* used in png_error */ - png_longjmp_ptr longjmp_fn PNG_DEPSTRUCT;/* setjmp non-local goto - function. */ -#endif - png_error_ptr error_fn PNG_DEPSTRUCT; /* function for printing - errors and aborting */ - png_error_ptr warning_fn PNG_DEPSTRUCT; /* function for printing - warnings */ - png_voidp error_ptr PNG_DEPSTRUCT; /* user supplied struct for - error functions */ - png_rw_ptr write_data_fn PNG_DEPSTRUCT; /* function for writing - output data */ - png_rw_ptr read_data_fn PNG_DEPSTRUCT; /* function for reading - input data */ - png_voidp io_ptr PNG_DEPSTRUCT; /* ptr to application struct - for I/O functions */ - -#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED - png_user_transform_ptr read_user_transform_fn PNG_DEPSTRUCT; /* user read - transform */ -#endif - -#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED - png_user_transform_ptr write_user_transform_fn PNG_DEPSTRUCT; /* user write - transform */ -#endif - -/* These were added in libpng-1.0.2 */ -#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED -#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ - defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) - png_voidp user_transform_ptr PNG_DEPSTRUCT; /* user supplied struct - for user transform */ - png_byte user_transform_depth PNG_DEPSTRUCT; /* bit depth of user - transformed pixels */ - png_byte user_transform_channels PNG_DEPSTRUCT; /* channels in user - transformed pixels */ -#endif -#endif - - png_uint_32 mode PNG_DEPSTRUCT; /* tells us where we are in - the PNG file */ - png_uint_32 flags PNG_DEPSTRUCT; /* flags indicating various - things to libpng */ - png_uint_32 transformations PNG_DEPSTRUCT; /* which transformations - to perform */ - - z_stream zstream PNG_DEPSTRUCT; /* pointer to decompression - structure (below) */ - png_bytep zbuf PNG_DEPSTRUCT; /* buffer for zlib */ - png_size_t zbuf_size PNG_DEPSTRUCT; /* size of zbuf */ - int zlib_level PNG_DEPSTRUCT; /* holds zlib compression level */ - int zlib_method PNG_DEPSTRUCT; /* holds zlib compression method */ - int zlib_window_bits PNG_DEPSTRUCT; /* holds zlib compression window - bits */ - int zlib_mem_level PNG_DEPSTRUCT; /* holds zlib compression memory - level */ - int zlib_strategy PNG_DEPSTRUCT; /* holds zlib compression - strategy */ - - png_uint_32 width PNG_DEPSTRUCT; /* width of image in pixels */ - png_uint_32 height PNG_DEPSTRUCT; /* height of image in pixels */ - png_uint_32 num_rows PNG_DEPSTRUCT; /* number of rows in current pass */ - png_uint_32 usr_width PNG_DEPSTRUCT; /* width of row at start of write */ - png_size_t rowbytes PNG_DEPSTRUCT; /* size of row in bytes */ -#if 0 /* Replaced with the following in libpng-1.4.1 */ - png_size_t irowbytes PNG_DEPSTRUCT; -#endif -/* Added in libpng-1.4.1 */ -#ifdef PNG_USER_LIMITS_SUPPORTED - /* Total memory that a zTXt, sPLT, iTXt, iCCP, or unknown chunk - * can occupy when decompressed. 0 means unlimited. - * We will change the typedef from png_size_t to png_alloc_size_t - * in libpng-1.6.0 - */ - png_alloc_size_t user_chunk_malloc_max PNG_DEPSTRUCT; -#endif - png_uint_32 iwidth PNG_DEPSTRUCT; /* width of current interlaced - row in pixels */ - png_uint_32 row_number PNG_DEPSTRUCT; /* current row in interlace pass */ - png_bytep prev_row PNG_DEPSTRUCT; /* buffer to save previous - (unfiltered) row */ - png_bytep row_buf PNG_DEPSTRUCT; /* buffer to save current - (unfiltered) row */ - png_bytep sub_row PNG_DEPSTRUCT; /* buffer to save "sub" row - when filtering */ - png_bytep up_row PNG_DEPSTRUCT; /* buffer to save "up" row - when filtering */ - png_bytep avg_row PNG_DEPSTRUCT; /* buffer to save "avg" row - when filtering */ - png_bytep paeth_row PNG_DEPSTRUCT; /* buffer to save "Paeth" row - when filtering */ - png_row_info row_info PNG_DEPSTRUCT; /* used for transformation - routines */ - - png_uint_32 idat_size PNG_DEPSTRUCT; /* current IDAT size for read */ - png_uint_32 crc PNG_DEPSTRUCT; /* current chunk CRC value */ - png_colorp palette PNG_DEPSTRUCT; /* palette from the input file */ - png_uint_16 num_palette PNG_DEPSTRUCT; /* number of color entries in - palette */ - png_uint_16 num_trans PNG_DEPSTRUCT; /* number of transparency values */ - png_byte chunk_name[5] PNG_DEPSTRUCT; /* null-terminated name of current - chunk */ - png_byte compression PNG_DEPSTRUCT; /* file compression type - (always 0) */ - png_byte filter PNG_DEPSTRUCT; /* file filter type (always 0) */ - png_byte interlaced PNG_DEPSTRUCT; /* PNG_INTERLACE_NONE, - PNG_INTERLACE_ADAM7 */ - png_byte pass PNG_DEPSTRUCT; /* current interlace pass (0 - 6) */ - png_byte do_filter PNG_DEPSTRUCT; /* row filter flags (see - PNG_FILTER_ below ) */ - png_byte color_type PNG_DEPSTRUCT; /* color type of file */ - png_byte bit_depth PNG_DEPSTRUCT; /* bit depth of file */ - png_byte usr_bit_depth PNG_DEPSTRUCT; /* bit depth of users row */ - png_byte pixel_depth PNG_DEPSTRUCT; /* number of bits per pixel */ - png_byte channels PNG_DEPSTRUCT; /* number of channels in file */ - png_byte usr_channels PNG_DEPSTRUCT; /* channels at start of write */ - png_byte sig_bytes PNG_DEPSTRUCT; /* magic bytes read/written from - start of file */ - -#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) - png_uint_16 filler PNG_DEPSTRUCT; /* filler bytes for pixel - expansion */ -#endif - -#ifdef PNG_bKGD_SUPPORTED - png_byte background_gamma_type PNG_DEPSTRUCT; -# ifdef PNG_FLOATING_POINT_SUPPORTED - float background_gamma PNG_DEPSTRUCT; -# endif - png_color_16 background PNG_DEPSTRUCT; /* background color in - screen gamma space */ -#ifdef PNG_READ_GAMMA_SUPPORTED - png_color_16 background_1 PNG_DEPSTRUCT; /* background normalized - to gamma 1.0 */ -#endif -#endif /* PNG_bKGD_SUPPORTED */ - -#ifdef PNG_WRITE_FLUSH_SUPPORTED - png_flush_ptr output_flush_fn PNG_DEPSTRUCT; /* Function for flushing - output */ - png_uint_32 flush_dist PNG_DEPSTRUCT; /* how many rows apart to flush, - 0 - no flush */ - png_uint_32 flush_rows PNG_DEPSTRUCT; /* number of rows written since - last flush */ -#endif - -#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) - int gamma_shift PNG_DEPSTRUCT; /* number of "insignificant" bits - 16-bit gamma */ -#ifdef PNG_FLOATING_POINT_SUPPORTED - float gamma PNG_DEPSTRUCT; /* file gamma value */ - float screen_gamma PNG_DEPSTRUCT; /* screen gamma value - (display_exponent) */ -#endif -#endif - -#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) - png_bytep gamma_table PNG_DEPSTRUCT; /* gamma table for 8-bit - depth files */ - png_bytep gamma_from_1 PNG_DEPSTRUCT; /* converts from 1.0 to screen */ - png_bytep gamma_to_1 PNG_DEPSTRUCT; /* converts from file to 1.0 */ - png_uint_16pp gamma_16_table PNG_DEPSTRUCT; /* gamma table for 16-bit - depth files */ - png_uint_16pp gamma_16_from_1 PNG_DEPSTRUCT; /* converts from 1.0 to - screen */ - png_uint_16pp gamma_16_to_1 PNG_DEPSTRUCT; /* converts from file to 1.0 */ -#endif - -#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED) - png_color_8 sig_bit PNG_DEPSTRUCT; /* significant bits in each - available channel */ -#endif - -#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) - png_color_8 shift PNG_DEPSTRUCT; /* shift for significant bit - tranformation */ -#endif - -#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \ - || defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) - png_bytep trans_alpha PNG_DEPSTRUCT; /* alpha values for - paletted files */ - png_color_16 trans_color PNG_DEPSTRUCT; /* transparent color for - non-paletted files */ -#endif - - png_read_status_ptr read_row_fn PNG_DEPSTRUCT; /* called after each - row is decoded */ - png_write_status_ptr write_row_fn PNG_DEPSTRUCT; /* called after each - row is encoded */ -#ifdef PNG_PROGRESSIVE_READ_SUPPORTED - png_progressive_info_ptr info_fn PNG_DEPSTRUCT; /* called after header - data fully read */ - png_progressive_row_ptr row_fn PNG_DEPSTRUCT; /* called after each - prog. row is decoded */ - png_progressive_end_ptr end_fn PNG_DEPSTRUCT; /* called after image - is complete */ - png_bytep save_buffer_ptr PNG_DEPSTRUCT; /* current location in - save_buffer */ - png_bytep save_buffer PNG_DEPSTRUCT; /* buffer for previously - read data */ - png_bytep current_buffer_ptr PNG_DEPSTRUCT; /* current location in - current_buffer */ - png_bytep current_buffer PNG_DEPSTRUCT; /* buffer for recently - used data */ - png_uint_32 push_length PNG_DEPSTRUCT; /* size of current input - chunk */ - png_uint_32 skip_length PNG_DEPSTRUCT; /* bytes to skip in - input data */ - png_size_t save_buffer_size PNG_DEPSTRUCT; /* amount of data now - in save_buffer */ - png_size_t save_buffer_max PNG_DEPSTRUCT; /* total size of - save_buffer */ - png_size_t buffer_size PNG_DEPSTRUCT; /* total amount of - available input data */ - png_size_t current_buffer_size PNG_DEPSTRUCT; /* amount of data now - in current_buffer */ - int process_mode PNG_DEPSTRUCT; /* what push library - is currently doing */ - int cur_palette PNG_DEPSTRUCT; /* current push library - palette index */ - -# ifdef PNG_TEXT_SUPPORTED - png_size_t current_text_size PNG_DEPSTRUCT; /* current size of - text input data */ - png_size_t current_text_left PNG_DEPSTRUCT; /* how much text left - to read in input */ - png_charp current_text PNG_DEPSTRUCT; /* current text chunk - buffer */ - png_charp current_text_ptr PNG_DEPSTRUCT; /* current location - in current_text */ -# endif /* PNG_PROGRESSIVE_READ_SUPPORTED && PNG_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 PNG_DEPSTRUCT; - png_bytep offset_table PNG_DEPSTRUCT; - png_uint_16 offset_table_number PNG_DEPSTRUCT; - png_uint_16 offset_table_count PNG_DEPSTRUCT; - png_uint_16 offset_table_count_free PNG_DEPSTRUCT; -#endif - -#ifdef PNG_READ_QUANTIZE_SUPPORTED - png_bytep palette_lookup PNG_DEPSTRUCT; /* lookup table for quantizing */ - png_bytep quantize_index PNG_DEPSTRUCT; /* index translation for palette - files */ -#endif - -#if defined(PNG_READ_QUANTIZE_SUPPORTED) || defined(PNG_hIST_SUPPORTED) - png_uint_16p hist PNG_DEPSTRUCT; /* histogram */ -#endif - -#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - png_byte heuristic_method PNG_DEPSTRUCT; /* heuristic for row - filter selection */ - png_byte num_prev_filters PNG_DEPSTRUCT; /* number of weights - for previous rows */ - png_bytep prev_filters PNG_DEPSTRUCT; /* filter type(s) of - previous row(s) */ - png_uint_16p filter_weights PNG_DEPSTRUCT; /* weight(s) for previous - line(s) */ - png_uint_16p inv_filter_weights PNG_DEPSTRUCT; /* 1/weight(s) for - previous line(s) */ - png_uint_16p filter_costs PNG_DEPSTRUCT; /* relative filter - calculation cost */ - png_uint_16p inv_filter_costs PNG_DEPSTRUCT; /* 1/relative filter - calculation cost */ -#endif - -#ifdef PNG_TIME_RFC1123_SUPPORTED - png_charp time_buffer PNG_DEPSTRUCT; /* String to hold RFC 1123 time text */ -#endif - -/* New members added in libpng-1.0.6 */ - - png_uint_32 free_me PNG_DEPSTRUCT; /* flags items libpng is - responsible for freeing */ - -#ifdef PNG_USER_CHUNKS_SUPPORTED - png_voidp user_chunk_ptr PNG_DEPSTRUCT; - png_user_chunk_ptr read_user_chunk_fn PNG_DEPSTRUCT; /* user read - chunk handler */ -#endif - -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - int num_chunk_list PNG_DEPSTRUCT; - png_bytep chunk_list PNG_DEPSTRUCT; -#endif - -/* New members added in libpng-1.0.3 */ -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED - png_byte rgb_to_gray_status PNG_DEPSTRUCT; - /* These were changed from png_byte in libpng-1.0.6 */ - png_uint_16 rgb_to_gray_red_coeff PNG_DEPSTRUCT; - png_uint_16 rgb_to_gray_green_coeff PNG_DEPSTRUCT; - png_uint_16 rgb_to_gray_blue_coeff PNG_DEPSTRUCT; -#endif - -/* New member added in libpng-1.0.4 (renamed in 1.0.9) */ -#if defined(PNG_MNG_FEATURES_SUPPORTED) || \ - defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \ - defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) -/* Changed from png_byte to png_uint_32 at version 1.2.0 */ - png_uint_32 mng_features_permitted PNG_DEPSTRUCT; -#endif - -/* New member added in libpng-1.0.7 */ -#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) - png_fixed_point int_gamma PNG_DEPSTRUCT; -#endif - -/* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */ -#ifdef PNG_MNG_FEATURES_SUPPORTED - png_byte filter_type PNG_DEPSTRUCT; -#endif - -/* New members added in libpng-1.2.0 */ - -/* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */ -#ifdef PNG_USER_MEM_SUPPORTED - png_voidp mem_ptr PNG_DEPSTRUCT; /* user supplied struct for - mem functions */ - png_malloc_ptr malloc_fn PNG_DEPSTRUCT; /* function for - allocating memory */ - png_free_ptr free_fn PNG_DEPSTRUCT; /* function for - freeing memory */ -#endif - -/* New member added in libpng-1.0.13 and 1.2.0 */ - png_bytep big_row_buf PNG_DEPSTRUCT; /* buffer to save current - (unfiltered) row */ - -#ifdef PNG_READ_QUANTIZE_SUPPORTED -/* The following three members were added at version 1.0.14 and 1.2.4 */ - png_bytep quantize_sort PNG_DEPSTRUCT; /* working sort array */ - png_bytep index_to_palette PNG_DEPSTRUCT; /* where the original - index currently is - in the palette */ - png_bytep palette_to_index PNG_DEPSTRUCT; /* which original index - points to this - palette color */ -#endif - -/* New members added in libpng-1.0.16 and 1.2.6 */ - png_byte compression_type PNG_DEPSTRUCT; - -#ifdef PNG_USER_LIMITS_SUPPORTED - png_uint_32 user_width_max PNG_DEPSTRUCT; - png_uint_32 user_height_max PNG_DEPSTRUCT; - /* Added in libpng-1.4.0: Total number of sPLT, text, and unknown - * chunks that can be stored (0 means unlimited). - */ - png_uint_32 user_chunk_cache_max PNG_DEPSTRUCT; -#endif - -/* New member added in libpng-1.0.25 and 1.2.17 */ -#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED - /* Storage for unknown chunk that the library doesn't recognize. */ - png_unknown_chunk unknown_chunk PNG_DEPSTRUCT; -#endif - -/* New members added in libpng-1.2.26 */ - png_uint_32 old_big_row_buf_size PNG_DEPSTRUCT; - png_uint_32 old_prev_row_size PNG_DEPSTRUCT; - -/* New member added in libpng-1.2.30 */ - png_charp chunkdata PNG_DEPSTRUCT; /* buffer for reading chunk data */ - -#ifdef PNG_IO_STATE_SUPPORTED -/* New member added in libpng-1.4.0 */ - png_uint_32 io_state PNG_DEPSTRUCT; -#endif -}; - - -/* This triggers a compiler error in png.c, if png.c and png.h - * do not agree upon the version number. - */ -typedef png_structp version_1_4_5; +typedef PNG_CALLBACK(png_voidp, *png_malloc_ptr, (png_structp, + png_alloc_size_t), ); +typedef PNG_CALLBACK(void, *png_free_ptr, (png_structp, png_voidp), ); typedef png_struct FAR * FAR * png_structpp; -/* Here are the function definitions most commonly used. This is not - * the place to find out how to use libpng. See libpng.txt for the +/* Section 3: exported functions + * Here are the function definitions most commonly used. This is not + * the place to find out how to use libpng. See libpng-manual.txt for the * full explanation, see example.c for the summary. This just provides * a simple one line description of the use of each function. + * + * The PNG_EXPORT() and PNG_EXPORTA() macros used below are defined in + * pngconf.h and in the *.dfn files in the scripts directory. + * + * PNG_EXPORT(ordinal, type, name, (args)); + * + * ordinal: ordinal that is used while building + * *.def files. The ordinal value is only + * relevant when preprocessing png.h with + * the *.dfn files for building symbol table + * entries, and are removed by pngconf.h. + * type: return type of the function + * name: function name + * args: function arguments, with types + * + * When we wish to append attributes to a function prototype we use + * the PNG_EXPORTA() macro instead. + * + * PNG_EXPORTA(ordinal, type, name, (args), attributes); + * + * ordinal, type, name, and args: same as in PNG_EXPORT(). + * attributes: function attributes */ /* Returns the version number of the library */ -PNG_EXPORT(png_uint_32,png_access_version_number) PNGARG((void)); +PNG_EXPORT(1, png_uint_32, png_access_version_number, (void)); /* Tell lib we have already handled the first magic bytes. * Handling more than 8 bytes from the beginning of the file is an error. */ -PNG_EXPORT(void,png_set_sig_bytes) PNGARG((png_structp png_ptr, - int num_bytes)); +PNG_EXPORT(2, void, png_set_sig_bytes, (png_structp png_ptr, int num_bytes)); /* Check sig[start] through sig[start + num_to_check - 1] to see if it's a * PNG file. Returns zero if the supplied bytes match the 8-byte PNG * signature, and non-zero otherwise. Having num_to_check == 0 or * start > 7 will always fail (ie return non-zero). */ -PNG_EXPORT(int,png_sig_cmp) PNGARG((png_bytep sig, png_size_t start, - png_size_t num_to_check)); +PNG_EXPORT(3, int, png_sig_cmp, (png_const_bytep sig, png_size_t start, + png_size_t num_to_check)); /* Simple signature checking function. This is the same as calling * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n). */ -#define png_check_sig(sig,n) !png_sig_cmp((sig), 0, (n)) +#define png_check_sig(sig, n) !png_sig_cmp((sig), 0, (n)) /* Allocate and initialize png_ptr struct for reading, and any other memory. */ -PNG_EXPORT(png_structp,png_create_read_struct) - PNGARG((png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn)) PNG_ALLOCATED; +PNG_EXPORTA(4, png_structp, png_create_read_struct, + (png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn), + PNG_ALLOCATED); /* Allocate and initialize png_ptr struct for writing, and any other memory */ -PNG_EXPORT(png_structp,png_create_write_struct) - PNGARG((png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn)) PNG_ALLOCATED; +PNG_EXPORTA(5, png_structp, png_create_write_struct, + (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, + png_error_ptr warn_fn), + PNG_ALLOCATED); -PNG_EXPORT(png_size_t,png_get_compression_buffer_size) - PNGARG((png_structp png_ptr)); +PNG_EXPORT(6, png_size_t, png_get_compression_buffer_size, + (png_structp png_ptr)); -PNG_EXPORT(void,png_set_compression_buffer_size) - PNGARG((png_structp png_ptr, png_size_t size)); +PNG_EXPORT(7, void, png_set_compression_buffer_size, (png_structp png_ptr, + png_size_t size)); /* Moved from pngconf.h in 1.4.0 and modified to ensure setjmp/longjmp * match up. @@ -1541,291 +960,309 @@ PNG_EXPORT(void,png_set_compression_buffer_size) * allocated by the library - the call will return NULL on a mismatch * indicating an ABI mismatch. */ -PNG_EXPORT(jmp_buf*, png_set_longjmp_fn) - PNGARG((png_structp png_ptr, png_longjmp_ptr longjmp_fn, size_t - jmp_buf_size)); +PNG_EXPORT(8, jmp_buf*, png_set_longjmp_fn, (png_structp png_ptr, + png_longjmp_ptr longjmp_fn, size_t jmp_buf_size)); # define png_jmpbuf(png_ptr) \ - (*png_set_longjmp_fn((png_ptr), longjmp, sizeof (jmp_buf))) + (*png_set_longjmp_fn((png_ptr), longjmp, sizeof (jmp_buf))) #else # define png_jmpbuf(png_ptr) \ - (LIBPNG_WAS_COMPILED_WITH__PNG_NO_SETJMP) + (LIBPNG_WAS_COMPILED_WITH__PNG_NO_SETJMP) #endif +/* This function should be used by libpng applications in place of + * longjmp(png_ptr->jmpbuf, val). If longjmp_fn() has been set, it + * will use it; otherwise it will call PNG_ABORT(). This function was + * added in libpng-1.5.0. + */ +PNG_EXPORTA(9, void, png_longjmp, (png_structp png_ptr, int val), + PNG_NORETURN); #ifdef PNG_READ_SUPPORTED /* Reset the compression stream */ -PNG_EXPORT(int,png_reset_zstream) PNGARG((png_structp png_ptr)); +PNG_EXPORT(10, int, png_reset_zstream, (png_structp png_ptr)); #endif /* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */ #ifdef PNG_USER_MEM_SUPPORTED -PNG_EXPORT(png_structp,png_create_read_struct_2) - PNGARG((png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, - png_malloc_ptr malloc_fn, png_free_ptr free_fn)) PNG_ALLOCATED; -PNG_EXPORT(png_structp,png_create_write_struct_2) - PNGARG((png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, - png_malloc_ptr malloc_fn, png_free_ptr free_fn)) PNG_ALLOCATED; +PNG_EXPORTA(11, png_structp, png_create_read_struct_2, + (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, + png_error_ptr warn_fn, + png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn), + PNG_ALLOCATED); +PNG_EXPORTA(12, png_structp, png_create_write_struct_2, + (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn, + png_error_ptr warn_fn, + png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn), + PNG_ALLOCATED); #endif /* Write the PNG file signature. */ -PNG_EXPORT(void,png_write_sig) PNGARG((png_structp png_ptr)); +PNG_EXPORT(13, void, png_write_sig, (png_structp png_ptr)); /* Write a PNG chunk - size, type, (optional) data, CRC. */ -PNG_EXPORT(void,png_write_chunk) PNGARG((png_structp png_ptr, - png_bytep chunk_name, png_bytep data, png_size_t length)); +PNG_EXPORT(14, void, png_write_chunk, (png_structp png_ptr, png_const_bytep + chunk_name, png_const_bytep data, png_size_t length)); /* Write the start of a PNG chunk - length and chunk name. */ -PNG_EXPORT(void,png_write_chunk_start) PNGARG((png_structp png_ptr, - png_bytep chunk_name, png_uint_32 length)); +PNG_EXPORT(15, void, png_write_chunk_start, (png_structp png_ptr, + png_const_bytep chunk_name, png_uint_32 length)); /* Write the data of a PNG chunk started with png_write_chunk_start(). */ -PNG_EXPORT(void,png_write_chunk_data) PNGARG((png_structp png_ptr, - png_bytep data, png_size_t length)); +PNG_EXPORT(16, void, png_write_chunk_data, (png_structp png_ptr, + png_const_bytep data, png_size_t length)); /* Finish a chunk started with png_write_chunk_start() (includes CRC). */ -PNG_EXPORT(void,png_write_chunk_end) PNGARG((png_structp png_ptr)); +PNG_EXPORT(17, void, png_write_chunk_end, (png_structp png_ptr)); /* Allocate and initialize the info structure */ -PNG_EXPORT(png_infop,png_create_info_struct) - PNGARG((png_structp png_ptr)) PNG_ALLOCATED; +PNG_EXPORTA(18, png_infop, png_create_info_struct, (png_structp png_ptr), + PNG_ALLOCATED); -PNG_EXPORT(void,png_info_init_3) PNGARG((png_infopp info_ptr, +PNG_EXPORT(19, void, png_info_init_3, (png_infopp info_ptr, png_size_t png_info_struct_size)); /* Writes all the PNG information before the image. */ -PNG_EXPORT(void,png_write_info_before_PLTE) PNGARG((png_structp png_ptr, - png_infop info_ptr)); -PNG_EXPORT(void,png_write_info) PNGARG((png_structp png_ptr, - png_infop info_ptr)); +PNG_EXPORT(20, void, png_write_info_before_PLTE, + (png_structp png_ptr, png_infop info_ptr)); +PNG_EXPORT(21, void, png_write_info, + (png_structp png_ptr, png_infop info_ptr)); #ifdef PNG_SEQUENTIAL_READ_SUPPORTED /* Read the information before the actual image data. */ -PNG_EXPORT(void,png_read_info) PNGARG((png_structp png_ptr, - png_infop info_ptr)); +PNG_EXPORT(22, void, png_read_info, + (png_structp png_ptr, png_infop info_ptr)); #endif #ifdef PNG_TIME_RFC1123_SUPPORTED -PNG_EXPORT(png_charp,png_convert_to_rfc1123) - PNGARG((png_structp png_ptr, png_timep ptime)); +PNG_EXPORT(23, png_const_charp, png_convert_to_rfc1123, + (png_structp png_ptr, + png_const_timep ptime)); #endif #ifdef PNG_CONVERT_tIME_SUPPORTED /* Convert from a struct tm to png_time */ -PNG_EXPORT(void,png_convert_from_struct_tm) PNGARG((png_timep ptime, - struct tm FAR * ttime)); +PNG_EXPORT(24, void, png_convert_from_struct_tm, (png_timep ptime, + PNG_CONST struct tm FAR * ttime)); /* Convert from time_t to png_time. Uses gmtime() */ -PNG_EXPORT(void,png_convert_from_time_t) PNGARG((png_timep ptime, - time_t ttime)); +PNG_EXPORT(25, void, png_convert_from_time_t, + (png_timep ptime, time_t ttime)); #endif /* PNG_CONVERT_tIME_SUPPORTED */ #ifdef PNG_READ_EXPAND_SUPPORTED /* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */ -PNG_EXPORT(void,png_set_expand) PNGARG((png_structp png_ptr)); -PNG_EXPORT(void,png_set_expand_gray_1_2_4_to_8) PNGARG((png_structp - png_ptr)); -PNG_EXPORT(void,png_set_palette_to_rgb) PNGARG((png_structp png_ptr)); -PNG_EXPORT(void,png_set_tRNS_to_alpha) PNGARG((png_structp png_ptr)); +PNG_EXPORT(26, void, png_set_expand, (png_structp png_ptr)); +PNG_EXPORT(27, void, png_set_expand_gray_1_2_4_to_8, (png_structp png_ptr)); +PNG_EXPORT(28, void, png_set_palette_to_rgb, (png_structp png_ptr)); +PNG_EXPORT(29, void, png_set_tRNS_to_alpha, (png_structp png_ptr)); #endif #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) /* Use blue, green, red order for pixels. */ -PNG_EXPORT(void,png_set_bgr) PNGARG((png_structp png_ptr)); +PNG_EXPORT(30, void, png_set_bgr, (png_structp png_ptr)); #endif #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED /* Expand the grayscale to 24-bit RGB if necessary. */ -PNG_EXPORT(void,png_set_gray_to_rgb) PNGARG((png_structp png_ptr)); -#endif +PNG_EXPORT(31, void, png_set_gray_to_rgb, (png_structp png_ptr)); -#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED /* Reduce RGB to grayscale. */ -#ifdef PNG_FLOATING_POINT_SUPPORTED -PNG_EXPORT(void,png_set_rgb_to_gray) PNGARG((png_structp png_ptr, - int error_action, double red, double green )); -#endif -PNG_EXPORT(void,png_set_rgb_to_gray_fixed) PNGARG((png_structp png_ptr, - int error_action, png_fixed_point red, png_fixed_point green )); -PNG_EXPORT(png_byte,png_get_rgb_to_gray_status) PNGARG((png_structp - png_ptr)); +PNG_FP_EXPORT(32, void, png_set_rgb_to_gray, (png_structp png_ptr, + int error_action, double red, double green)); +PNG_FIXED_EXPORT(33, void, png_set_rgb_to_gray_fixed, (png_structp png_ptr, + int error_action, png_fixed_point red, png_fixed_point green)); + +PNG_EXPORT(34, png_byte, png_get_rgb_to_gray_status, (png_structp png_ptr)); #endif -PNG_EXPORT(void,png_build_grayscale_palette) PNGARG((int bit_depth, - png_colorp palette)); +PNG_EXPORT(35, void, png_build_grayscale_palette, (int bit_depth, + png_colorp palette)); #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED -PNG_EXPORT(void,png_set_strip_alpha) PNGARG((png_structp png_ptr)); +PNG_EXPORT(36, void, png_set_strip_alpha, (png_structp png_ptr)); #endif #if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \ defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) -PNG_EXPORT(void,png_set_swap_alpha) PNGARG((png_structp png_ptr)); +PNG_EXPORT(37, void, png_set_swap_alpha, (png_structp png_ptr)); #endif #if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \ defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED) -PNG_EXPORT(void,png_set_invert_alpha) PNGARG((png_structp png_ptr)); +PNG_EXPORT(38, void, png_set_invert_alpha, (png_structp png_ptr)); #endif #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) /* Add a filler byte to 8-bit Gray or 24-bit RGB images. */ -PNG_EXPORT(void,png_set_filler) PNGARG((png_structp png_ptr, - png_uint_32 filler, int flags)); +PNG_EXPORT(39, void, png_set_filler, (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 +# define PNG_FILLER_BEFORE 0 +# define PNG_FILLER_AFTER 1 /* Add an alpha byte to 8-bit Gray or 24-bit RGB images. */ -PNG_EXPORT(void,png_set_add_alpha) PNGARG((png_structp png_ptr, - png_uint_32 filler, int flags)); +PNG_EXPORT(40, void, png_set_add_alpha, + (png_structp png_ptr, png_uint_32 filler, + int flags)); #endif /* PNG_READ_FILLER_SUPPORTED || PNG_WRITE_FILLER_SUPPORTED */ #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) /* Swap bytes in 16-bit depth files. */ -PNG_EXPORT(void,png_set_swap) PNGARG((png_structp png_ptr)); +PNG_EXPORT(41, void, png_set_swap, (png_structp png_ptr)); #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. */ -PNG_EXPORT(void,png_set_packing) PNGARG((png_structp png_ptr)); +PNG_EXPORT(42, void, png_set_packing, (png_structp png_ptr)); #endif #if defined(PNG_READ_PACKSWAP_SUPPORTED) || \ defined(PNG_WRITE_PACKSWAP_SUPPORTED) /* Swap packing order of pixels in bytes. */ -PNG_EXPORT(void,png_set_packswap) PNGARG((png_structp png_ptr)); +PNG_EXPORT(43, void, png_set_packswap, (png_structp png_ptr)); #endif #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) /* Converts files to legal bit depths. */ -PNG_EXPORT(void,png_set_shift) PNGARG((png_structp png_ptr, - png_color_8p true_bits)); +PNG_EXPORT(44, void, png_set_shift, (png_structp png_ptr, png_const_color_8p + true_bits)); #endif #if defined(PNG_READ_INTERLACING_SUPPORTED) || \ defined(PNG_WRITE_INTERLACING_SUPPORTED) -/* Have the code handle the interlacing. Returns the number of passes. */ -PNG_EXPORT(int,png_set_interlace_handling) PNGARG((png_structp png_ptr)); +/* Have the code handle the interlacing. Returns the number of passes. + * MUST be called before png_read_update_info or png_start_read_image, + * otherwise it will not have the desired effect. Note that it is still + * necessary to call png_read_row or png_read_rows png_get_image_height + * times for each pass. +*/ +PNG_EXPORT(45, int, png_set_interlace_handling, (png_structp png_ptr)); #endif #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) /* Invert monochrome files */ -PNG_EXPORT(void,png_set_invert_mono) PNGARG((png_structp png_ptr)); +PNG_EXPORT(46, void, png_set_invert_mono, (png_structp png_ptr)); #endif #ifdef PNG_READ_BACKGROUND_SUPPORTED /* Handle alpha and tRNS by replacing with a background color. */ -#ifdef PNG_FLOATING_POINT_SUPPORTED -PNG_EXPORT(void,png_set_background) PNGARG((png_structp png_ptr, - png_color_16p background_color, int background_gamma_code, - int need_expand, double background_gamma)); +PNG_FP_EXPORT(47, void, png_set_background, (png_structp png_ptr, + png_const_color_16p background_color, int background_gamma_code, + int need_expand, double background_gamma)); +PNG_FIXED_EXPORT(215, void, png_set_background_fixed, (png_structp png_ptr, + png_const_color_16p background_color, int background_gamma_code, + int need_expand, png_fixed_point background_gamma)); #endif -#define PNG_BACKGROUND_GAMMA_UNKNOWN 0 -#define PNG_BACKGROUND_GAMMA_SCREEN 1 -#define PNG_BACKGROUND_GAMMA_FILE 2 -#define PNG_BACKGROUND_GAMMA_UNIQUE 3 +#ifdef PNG_READ_BACKGROUND_SUPPORTED +# define PNG_BACKGROUND_GAMMA_UNKNOWN 0 +# define PNG_BACKGROUND_GAMMA_SCREEN 1 +# define PNG_BACKGROUND_GAMMA_FILE 2 +# define PNG_BACKGROUND_GAMMA_UNIQUE 3 #endif #ifdef PNG_READ_16_TO_8_SUPPORTED /* Strip the second byte of information from a 16-bit depth file. */ -PNG_EXPORT(void,png_set_strip_16) PNGARG((png_structp png_ptr)); +PNG_EXPORT(48, void, png_set_strip_16, (png_structp png_ptr)); #endif #ifdef PNG_READ_QUANTIZE_SUPPORTED /* Turn on quantizing, and reduce the palette to the number of colors - * available. Prior to libpng-1.4.2, this was png_set_dither(). + * available. */ -PNG_EXPORT(void,png_set_quantize) PNGARG((png_structp png_ptr, - png_colorp palette, int num_palette, int maximum_colors, - png_uint_16p histogram, int full_quantize)); +PNG_EXPORT(49, void, png_set_quantize, + (png_structp png_ptr, png_colorp palette, + int num_palette, int maximum_colors, png_const_uint_16p histogram, + int full_quantize)); #endif -/* This migration aid will be removed from libpng-1.5.0 */ -#define png_set_dither png_set_quantize #ifdef PNG_READ_GAMMA_SUPPORTED -/* Handle gamma correction. Screen_gamma=(display_exponent) */ -#ifdef PNG_FLOATING_POINT_SUPPORTED -PNG_EXPORT(void,png_set_gamma) PNGARG((png_structp png_ptr, - double screen_gamma, double default_file_gamma)); -#endif -#endif +/* The threshold on gamma processing is configurable but hard-wired into the + * library. The following is the floating point variant. + */ +#define PNG_GAMMA_THRESHOLD (PNG_GAMMA_THRESHOLD_FIXED*.00001) +/* Handle gamma correction. Screen_gamma=(display_exponent) */ +PNG_FP_EXPORT(50, void, png_set_gamma, + (png_structp png_ptr, double screen_gamma, + double default_file_gamma)); +PNG_FIXED_EXPORT(208, void, png_set_gamma_fixed, (png_structp png_ptr, + png_fixed_point screen_gamma, png_fixed_point default_file_gamma)); +#endif #ifdef PNG_WRITE_FLUSH_SUPPORTED /* Set how many lines between output flushes - 0 for no flushing */ -PNG_EXPORT(void,png_set_flush) PNGARG((png_structp png_ptr, int nrows)); +PNG_EXPORT(51, void, png_set_flush, (png_structp png_ptr, int nrows)); /* Flush the current PNG output buffer */ -PNG_EXPORT(void,png_write_flush) PNGARG((png_structp png_ptr)); +PNG_EXPORT(52, void, png_write_flush, (png_structp png_ptr)); #endif /* Optional update palette with requested transformations */ -PNG_EXPORT(void,png_start_read_image) PNGARG((png_structp png_ptr)); +PNG_EXPORT(53, void, png_start_read_image, (png_structp png_ptr)); /* Optional call to update the users info structure */ -PNG_EXPORT(void,png_read_update_info) PNGARG((png_structp png_ptr, - png_infop info_ptr)); +PNG_EXPORT(54, void, png_read_update_info, + (png_structp png_ptr, png_infop info_ptr)); #ifdef PNG_SEQUENTIAL_READ_SUPPORTED /* Read one or more rows of image data. */ -PNG_EXPORT(void,png_read_rows) PNGARG((png_structp png_ptr, - png_bytepp row, png_bytepp display_row, png_uint_32 num_rows)); +PNG_EXPORT(55, void, png_read_rows, (png_structp png_ptr, png_bytepp row, + png_bytepp display_row, png_uint_32 num_rows)); #endif #ifdef PNG_SEQUENTIAL_READ_SUPPORTED /* Read a row of data. */ -PNG_EXPORT(void,png_read_row) PNGARG((png_structp png_ptr, - png_bytep row, - png_bytep display_row)); +PNG_EXPORT(56, void, png_read_row, (png_structp png_ptr, png_bytep row, + png_bytep display_row)); #endif #ifdef PNG_SEQUENTIAL_READ_SUPPORTED /* Read the whole image into memory at once. */ -PNG_EXPORT(void,png_read_image) PNGARG((png_structp png_ptr, - png_bytepp image)); +PNG_EXPORT(57, void, png_read_image, (png_structp png_ptr, png_bytepp image)); #endif /* Write a row of image data */ -PNG_EXPORT(void,png_write_row) PNGARG((png_structp png_ptr, - png_bytep row)); +PNG_EXPORT(58, void, png_write_row, + (png_structp png_ptr, png_const_bytep row)); -/* Write a few rows of image data */ -PNG_EXPORT(void,png_write_rows) PNGARG((png_structp png_ptr, - png_bytepp row, png_uint_32 num_rows)); +/* Write a few rows of image data: (*row) is not written; however, the type + * is declared as writeable to maintain compatibility with previous versions + * of libpng and to allow the 'display_row' array from read_rows to be passed + * unchanged to write_rows. + */ +PNG_EXPORT(59, void, png_write_rows, (png_structp png_ptr, png_bytepp row, + png_uint_32 num_rows)); /* Write the image data */ -PNG_EXPORT(void,png_write_image) PNGARG((png_structp png_ptr, - png_bytepp image)); +PNG_EXPORT(60, void, png_write_image, + (png_structp png_ptr, png_bytepp image)); /* Write the end of the PNG file. */ -PNG_EXPORT(void,png_write_end) PNGARG((png_structp png_ptr, - png_infop info_ptr)); +PNG_EXPORT(61, void, png_write_end, + (png_structp png_ptr, png_infop info_ptr)); #ifdef PNG_SEQUENTIAL_READ_SUPPORTED /* Read the end of the PNG file. */ -PNG_EXPORT(void,png_read_end) PNGARG((png_structp png_ptr, - png_infop info_ptr)); +PNG_EXPORT(62, void, png_read_end, (png_structp png_ptr, png_infop info_ptr)); #endif /* Free any memory associated with the png_info_struct */ -PNG_EXPORT(void,png_destroy_info_struct) PNGARG((png_structp png_ptr, - png_infopp info_ptr_ptr)); +PNG_EXPORT(63, void, png_destroy_info_struct, (png_structp png_ptr, + png_infopp info_ptr_ptr)); /* Free any memory associated with the png_struct and the png_info_structs */ -PNG_EXPORT(void,png_destroy_read_struct) PNGARG((png_structpp - png_ptr_ptr, png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr)); +PNG_EXPORT(64, void, png_destroy_read_struct, (png_structpp png_ptr_ptr, + png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr)); /* Free any memory associated with the png_struct and the png_info_structs */ -PNG_EXPORT(void,png_destroy_write_struct) - PNGARG((png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)); +PNG_EXPORT(65, void, png_destroy_write_struct, (png_structpp png_ptr_ptr, + png_infopp info_ptr_ptr)); /* Set the libpng method of handling chunk CRC errors */ -PNG_EXPORT(void,png_set_crc_action) PNGARG((png_structp png_ptr, - int crit_action, int ancil_action)); +PNG_EXPORT(66, void, png_set_crc_action, + (png_structp png_ptr, int crit_action, int ancil_action)); -/* Values for png_set_crc_action() to say how to handle CRC errors in +/* Values for png_set_crc_action() say how to handle CRC errors in * ancillary and critical chunks, and whether to use the data contained * therein. Note that it is impossible to "discard" data in a critical - * chunk. For versions prior to 0.90, the action was always error/quit, + * chunk. For versions prior to 0.90, the action was always error/quit, * whereas in version 0.90 and later, the action for CRC errors in ancillary * chunks is warn/discard. These values should NOT be changed. * @@ -1849,8 +1286,8 @@ PNG_EXPORT(void,png_set_crc_action) PNGARG((png_structp png_ptr, /* Set the filtering method(s) used by libpng. Currently, the only valid * value for "method" is 0. */ -PNG_EXPORT(void,png_set_filter) PNGARG((png_structp png_ptr, int method, - int filters)); +PNG_EXPORT(67, void, png_set_filter, + (png_structp png_ptr, int method, int filters)); /* Flags for png_set_filter() to say which filters to use. The flags * are chosen so that they don't conflict with real filter types @@ -1905,11 +1342,13 @@ PNG_EXPORT(void,png_set_filter) PNGARG((png_structp png_ptr, int method, * the weights and costs are set to 1.0, this degenerates the WEIGHTED method * to the UNWEIGHTED method, but with added encoding time/computation. */ -#ifdef PNG_FLOATING_POINT_SUPPORTED -PNG_EXPORT(void,png_set_filter_heuristics) PNGARG((png_structp png_ptr, - int heuristic_method, int num_weights, png_doublep filter_weights, - png_doublep filter_costs)); -#endif +PNG_FP_EXPORT(68, void, png_set_filter_heuristics, (png_structp png_ptr, + int heuristic_method, int num_weights, png_const_doublep filter_weights, + png_const_doublep filter_costs)); +PNG_FIXED_EXPORT(209, void, png_set_filter_heuristics_fixed, + (png_structp png_ptr, + int heuristic_method, int num_weights, png_const_fixed_point_p + filter_weights, png_const_fixed_point_p filter_costs)); #endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */ /* Heuristic used for row filter selection. These defines should NOT be @@ -1924,37 +1363,36 @@ PNG_EXPORT(void,png_set_filter_heuristics) PNGARG((png_structp png_ptr, * 0 - 9, corresponding directly to the zlib compression levels 0 - 9 * (0 - no compression, 9 - "maximal" compression). Note that tests have * shown that zlib compression levels 3-6 usually perform as well as level 9 - * for PNG images, and do considerably fewer caclulations. In the future, + * for PNG images, and do considerably fewer caclulations. In the future, * these values may not correspond directly to the zlib compression levels. */ -PNG_EXPORT(void,png_set_compression_level) PNGARG((png_structp png_ptr, - int level)); +PNG_EXPORT(69, void, png_set_compression_level, + (png_structp png_ptr, int level)); -PNG_EXPORT(void,png_set_compression_mem_level) - PNGARG((png_structp png_ptr, int mem_level)); +PNG_EXPORT(70, void, png_set_compression_mem_level, (png_structp png_ptr, + int mem_level)); -PNG_EXPORT(void,png_set_compression_strategy) - PNGARG((png_structp png_ptr, int strategy)); +PNG_EXPORT(71, void, png_set_compression_strategy, (png_structp png_ptr, + int strategy)); -PNG_EXPORT(void,png_set_compression_window_bits) - PNGARG((png_structp png_ptr, int window_bits)); +PNG_EXPORT(72, void, png_set_compression_window_bits, (png_structp png_ptr, + int window_bits)); -PNG_EXPORT(void,png_set_compression_method) PNGARG((png_structp png_ptr, - int method)); +PNG_EXPORT(73, void, png_set_compression_method, (png_structp png_ptr, + int method)); /* These next functions are called for input/output, memory, and error - * handling. They are in the file pngrio.c, pngwio.c, and pngerror.c, + * handling. They are in the file pngrio.c, pngwio.c, and pngerror.c, * and call standard C I/O routines such as fread(), fwrite(), and * fprintf(). These functions can be made to use other I/O routines * at run time for those applications that need to handle I/O in a - * different manner by calling png_set_???_fn(). See libpng.txt for + * different manner by calling png_set_???_fn(). See libpng-manual.txt for * more information. */ #ifdef PNG_STDIO_SUPPORTED /* Initialize the input/output for the PNG file to the default functions. */ -PNG_EXPORT(void,png_init_io) PNGARG((png_structp png_ptr, - png_FILE_p fp)); +PNG_EXPORT(74, void, png_init_io, (png_structp png_ptr, png_FILE_p fp)); #endif /* Replace the (error and abort), and warning functions with user @@ -1965,11 +1403,12 @@ PNG_EXPORT(void,png_init_io) PNGARG((png_structp png_ptr, * default function will be used. */ -PNG_EXPORT(void,png_set_error_fn) PNGARG((png_structp png_ptr, - png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn)); +PNG_EXPORT(75, void, png_set_error_fn, + (png_structp png_ptr, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warning_fn)); /* Return the user pointer associated with the error functions */ -PNG_EXPORT(png_voidp,png_get_error_ptr) PNGARG((png_structp png_ptr)); +PNG_EXPORT(76, png_voidp, png_get_error_ptr, (png_structp png_ptr)); /* Replace the default data output functions with a user supplied one(s). * If buffered output is not used, then output_flush_fn can be set to NULL. @@ -1981,101 +1420,104 @@ PNG_EXPORT(png_voidp,png_get_error_ptr) PNGARG((png_structp png_ptr)); * default flush function, which uses the standard *FILE structure, will * be used. */ -PNG_EXPORT(void,png_set_write_fn) PNGARG((png_structp png_ptr, - png_voidp io_ptr, png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)); +PNG_EXPORT(77, void, png_set_write_fn, (png_structp png_ptr, png_voidp io_ptr, + png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)); /* Replace the default data input function with a user supplied one. */ -PNG_EXPORT(void,png_set_read_fn) PNGARG((png_structp png_ptr, - png_voidp io_ptr, png_rw_ptr read_data_fn)); +PNG_EXPORT(78, void, png_set_read_fn, (png_structp png_ptr, png_voidp io_ptr, + png_rw_ptr read_data_fn)); /* Return the user pointer associated with the I/O functions */ -PNG_EXPORT(png_voidp,png_get_io_ptr) PNGARG((png_structp png_ptr)); +PNG_EXPORT(79, png_voidp, png_get_io_ptr, (png_structp png_ptr)); -PNG_EXPORT(void,png_set_read_status_fn) PNGARG((png_structp png_ptr, - png_read_status_ptr read_row_fn)); +PNG_EXPORT(80, void, png_set_read_status_fn, (png_structp png_ptr, + png_read_status_ptr read_row_fn)); -PNG_EXPORT(void,png_set_write_status_fn) PNGARG((png_structp png_ptr, - png_write_status_ptr write_row_fn)); +PNG_EXPORT(81, void, png_set_write_status_fn, (png_structp png_ptr, + png_write_status_ptr write_row_fn)); #ifdef PNG_USER_MEM_SUPPORTED /* Replace the default memory allocation functions with user supplied one(s). */ -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)); +PNG_EXPORT(82, void, png_set_mem_fn, (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 */ -PNG_EXPORT(png_voidp,png_get_mem_ptr) PNGARG((png_structp png_ptr)); +PNG_EXPORT(83, png_voidp, png_get_mem_ptr, (png_structp png_ptr)); #endif #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED -PNG_EXPORT(void,png_set_read_user_transform_fn) PNGARG((png_structp - png_ptr, png_user_transform_ptr read_user_transform_fn)); +PNG_EXPORT(84, void, png_set_read_user_transform_fn, (png_structp png_ptr, + png_user_transform_ptr read_user_transform_fn)); #endif #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED -PNG_EXPORT(void,png_set_write_user_transform_fn) PNGARG((png_structp - png_ptr, png_user_transform_ptr write_user_transform_fn)); +PNG_EXPORT(85, void, png_set_write_user_transform_fn, (png_structp png_ptr, + png_user_transform_ptr write_user_transform_fn)); #endif #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) -PNG_EXPORT(void,png_set_user_transform_info) PNGARG((png_structp - png_ptr, png_voidp user_transform_ptr, int user_transform_depth, - int user_transform_channels)); +PNG_EXPORT(86, void, png_set_user_transform_info, (png_structp png_ptr, + png_voidp user_transform_ptr, int user_transform_depth, + int user_transform_channels)); /* Return the user pointer associated with the user transform functions */ -PNG_EXPORT(png_voidp,png_get_user_transform_ptr) - PNGARG((png_structp png_ptr)); +PNG_EXPORT(87, png_voidp, png_get_user_transform_ptr, (png_structp png_ptr)); #endif #ifdef PNG_USER_CHUNKS_SUPPORTED -PNG_EXPORT(void,png_set_read_user_chunk_fn) PNGARG((png_structp png_ptr, - png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn)); -PNG_EXPORT(png_voidp,png_get_user_chunk_ptr) PNGARG((png_structp - png_ptr)); +PNG_EXPORT(88, void, png_set_read_user_chunk_fn, (png_structp png_ptr, + png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn)); +PNG_EXPORT(89, png_voidp, png_get_user_chunk_ptr, (png_structp png_ptr)); #endif #ifdef PNG_PROGRESSIVE_READ_SUPPORTED /* Sets the function callbacks for the push reader, and a pointer to a * user-defined structure available to the callback functions. */ -PNG_EXPORT(void,png_set_progressive_read_fn) PNGARG((png_structp png_ptr, - png_voidp progressive_ptr, - png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn, - png_progressive_end_ptr end_fn)); +PNG_EXPORT(90, void, png_set_progressive_read_fn, (png_structp png_ptr, + png_voidp progressive_ptr, png_progressive_info_ptr info_fn, + png_progressive_row_ptr row_fn, png_progressive_end_ptr end_fn)); /* Returns the user pointer associated with the push read functions */ -PNG_EXPORT(png_voidp,png_get_progressive_ptr) - PNGARG((png_structp png_ptr)); +PNG_EXPORT(91, png_voidp, png_get_progressive_ptr, (png_structp png_ptr)); /* Function to be called when data becomes available */ -PNG_EXPORT(void,png_process_data) PNGARG((png_structp png_ptr, - png_infop info_ptr, png_bytep buffer, png_size_t buffer_size)); +PNG_EXPORT(92, void, png_process_data, + (png_structp png_ptr, png_infop info_ptr, + png_bytep buffer, png_size_t buffer_size)); -/* Function that combines rows. Not very much different than the - * png_combine_row() call. Is this even used????? +/* Function that combines rows. 'new_row' is a flag that should come from + * the callback and be non-NULL if anything needs to be done; the library + * stores its own version of the new data internally and ignores the passed + * in value. */ -PNG_EXPORT(void,png_progressive_combine_row) PNGARG((png_structp png_ptr, - png_bytep old_row, png_bytep new_row)); +PNG_EXPORT(93, void, png_progressive_combine_row, (png_structp png_ptr, + png_bytep old_row, png_const_bytep new_row)); #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ -PNG_EXPORT(png_voidp,png_malloc) PNGARG((png_structp png_ptr, - png_alloc_size_t size)) PNG_ALLOCATED; +PNG_EXPORTA(94, png_voidp, png_malloc, + (png_structp png_ptr, png_alloc_size_t size), + PNG_ALLOCATED); /* Added at libpng version 1.4.0 */ -PNG_EXPORT(png_voidp,png_calloc) PNGARG((png_structp png_ptr, - png_alloc_size_t size)) PNG_ALLOCATED; +PNG_EXPORTA(95, png_voidp, png_calloc, + (png_structp png_ptr, png_alloc_size_t size), + PNG_ALLOCATED); /* Added at libpng version 1.2.4 */ -PNG_EXPORT(png_voidp,png_malloc_warn) PNGARG((png_structp png_ptr, - png_alloc_size_t size)) PNG_ALLOCATED; +PNG_EXPORTA(96, png_voidp, png_malloc_warn, (png_structp png_ptr, + png_alloc_size_t size), PNG_ALLOCATED); /* Frees a pointer allocated by png_malloc() */ -PNG_EXPORT(void,png_free) PNGARG((png_structp png_ptr, png_voidp ptr)); +PNG_EXPORT(97, void, png_free, (png_structp png_ptr, png_voidp ptr)); /* Free data that was allocated internally */ -PNG_EXPORT(void,png_free_data) PNGARG((png_structp png_ptr, - png_infop info_ptr, png_uint_32 free_me, int num)); +PNG_EXPORT(98, void, png_free_data, + (png_structp png_ptr, png_infop info_ptr, png_uint_32 free_me, int num)); + /* Reassign responsibility for freeing existing data, whether allocated * by libpng or by the application */ -PNG_EXPORT(void,png_data_freer) PNGARG((png_structp png_ptr, - png_infop info_ptr, int freer, png_uint_32 mask)); +PNG_EXPORT(99, void, png_data_freer, + (png_structp png_ptr, png_infop info_ptr, int freer, png_uint_32 mask)); + /* Assignments for png_data_freer */ #define PNG_DESTROY_WILL_FREE_DATA 1 #define PNG_SET_WILL_FREE_DATA 1 @@ -2096,46 +1538,56 @@ PNG_EXPORT(void,png_data_freer) PNGARG((png_structp png_ptr, #define PNG_FREE_MUL 0x4220 /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */ #ifdef PNG_USER_MEM_SUPPORTED -PNG_EXPORT(png_voidp,png_malloc_default) PNGARG((png_structp png_ptr, - png_alloc_size_t size)) PNG_ALLOCATED; -PNG_EXPORT(void,png_free_default) PNGARG((png_structp png_ptr, - png_voidp ptr)); +PNG_EXPORTA(100, png_voidp, png_malloc_default, (png_structp png_ptr, + png_alloc_size_t size), PNG_ALLOCATED); +PNG_EXPORT(101, void, png_free_default, (png_structp png_ptr, png_voidp ptr)); #endif -#ifndef PNG_NO_ERROR_TEXT +#ifdef PNG_ERROR_TEXT_SUPPORTED /* Fatal error in PNG image of libpng - can't continue */ -PNG_EXPORT(void,png_error) PNGARG((png_structp png_ptr, - png_const_charp error_message)) PNG_NORETURN; +PNG_EXPORTA(102, void, png_error, + (png_structp png_ptr, png_const_charp error_message), + PNG_NORETURN); /* The same, but the chunk name is prepended to the error string. */ -PNG_EXPORT(void,png_chunk_error) PNGARG((png_structp png_ptr, - png_const_charp error_message)) PNG_NORETURN; +PNG_EXPORTA(103, void, png_chunk_error, (png_structp png_ptr, + png_const_charp error_message), PNG_NORETURN); #else /* Fatal error in PNG image of libpng - can't continue */ -PNG_EXPORT(void,png_err) PNGARG((png_structp png_ptr)) PNG_NORETURN; +PNG_EXPORTA(104, void, png_err, (png_structp png_ptr), PNG_NORETURN); #endif /* Non-fatal error in libpng. Can continue, but may have a problem. */ -PNG_EXPORT(void,png_warning) PNGARG((png_structp png_ptr, - png_const_charp warning_message)); +PNG_EXPORT(105, void, png_warning, (png_structp png_ptr, + png_const_charp warning_message)); /* Non-fatal error in libpng, chunk name is prepended to message. */ -PNG_EXPORT(void,png_chunk_warning) PNGARG((png_structp png_ptr, - png_const_charp warning_message)); +PNG_EXPORT(106, void, png_chunk_warning, (png_structp png_ptr, + png_const_charp warning_message)); #ifdef PNG_BENIGN_ERRORS_SUPPORTED /* Benign error in libpng. Can continue, but may have a problem. * User can choose whether to handle as a fatal error or as a warning. */ -PNG_EXPORT(void,png_benign_error) PNGARG((png_structp png_ptr, - png_const_charp warning_message)); +# undef png_benign_error +PNG_EXPORT(107, void, png_benign_error, (png_structp png_ptr, + png_const_charp warning_message)); /* Same, chunk name is prepended to message. */ -PNG_EXPORT(void,png_chunk_benign_error) PNGARG((png_structp png_ptr, - png_const_charp warning_message)); +# undef png_chunk_benign_error +PNG_EXPORT(108, void, png_chunk_benign_error, (png_structp png_ptr, + png_const_charp warning_message)); -PNG_EXPORT(void,png_set_benign_errors) PNGARG((png_structp - png_ptr, int allowed)); +PNG_EXPORT(109, void, png_set_benign_errors, + (png_structp png_ptr, int allowed)); +#else +# ifdef PNG_ALLOW_BENIGN_ERRORS +# define png_benign_error png_warning +# define png_chunk_benign_error png_chunk_warning +# else +# define png_benign_error png_error +# define png_chunk_benign_error png_chunk_error +# endif #endif /* The png_set_ functions are for storing values in the png_info_struct. @@ -2151,261 +1603,268 @@ PNG_EXPORT(void,png_set_benign_errors) PNGARG((png_structp * png_info_struct. */ /* Returns "flag" if chunk data is valid in info_ptr. */ -PNG_EXPORT(png_uint_32,png_get_valid) PNGARG((png_structp png_ptr, -png_infop info_ptr, png_uint_32 flag)); +PNG_EXPORT(110, png_uint_32, png_get_valid, + (png_structp png_ptr, png_infop info_ptr, + png_uint_32 flag)); /* Returns number of bytes needed to hold a transformed row. */ -PNG_EXPORT(png_size_t,png_get_rowbytes) PNGARG((png_structp png_ptr, -png_infop info_ptr)); +PNG_EXPORT(111, png_size_t, png_get_rowbytes, (png_structp png_ptr, + png_infop info_ptr)); #ifdef PNG_INFO_IMAGE_SUPPORTED /* Returns row_pointers, which is an array of pointers to scanlines that was * returned from png_read_png(). */ -PNG_EXPORT(png_bytepp,png_get_rows) PNGARG((png_structp png_ptr, -png_infop info_ptr)); +PNG_EXPORT(112, png_bytepp, png_get_rows, + (png_structp png_ptr, png_infop info_ptr)); /* Set row_pointers, which is an array of pointers to scanlines for use * by png_write_png(). */ -PNG_EXPORT(void,png_set_rows) PNGARG((png_structp png_ptr, - png_infop info_ptr, png_bytepp row_pointers)); +PNG_EXPORT(113, void, png_set_rows, (png_structp png_ptr, png_infop info_ptr, + png_bytepp row_pointers)); #endif /* Returns number of color channels in image. */ -PNG_EXPORT(png_byte,png_get_channels) PNGARG((png_structp png_ptr, -png_infop info_ptr)); +PNG_EXPORT(114, png_byte, png_get_channels, + (png_structp png_ptr, png_infop info_ptr)); #ifdef PNG_EASY_ACCESS_SUPPORTED /* Returns image width in pixels. */ -PNG_EXPORT(png_uint_32, png_get_image_width) PNGARG((png_structp -png_ptr, png_infop info_ptr)); +PNG_EXPORT(115, png_uint_32, png_get_image_width, (png_structp png_ptr, + png_infop info_ptr)); /* Returns image height in pixels. */ -PNG_EXPORT(png_uint_32, png_get_image_height) PNGARG((png_structp -png_ptr, png_infop info_ptr)); +PNG_EXPORT(116, png_uint_32, png_get_image_height, (png_structp png_ptr, + png_infop info_ptr)); /* Returns image bit_depth. */ -PNG_EXPORT(png_byte, png_get_bit_depth) PNGARG((png_structp -png_ptr, png_infop info_ptr)); +PNG_EXPORT(117, png_byte, png_get_bit_depth, + (png_structp png_ptr, png_infop info_ptr)); /* Returns image color_type. */ -PNG_EXPORT(png_byte, png_get_color_type) PNGARG((png_structp -png_ptr, png_infop info_ptr)); +PNG_EXPORT(118, png_byte, png_get_color_type, (png_structp png_ptr, + png_infop info_ptr)); /* Returns image filter_type. */ -PNG_EXPORT(png_byte, png_get_filter_type) PNGARG((png_structp -png_ptr, png_infop info_ptr)); +PNG_EXPORT(119, png_byte, png_get_filter_type, (png_structp png_ptr, + png_infop info_ptr)); /* Returns image interlace_type. */ -PNG_EXPORT(png_byte, png_get_interlace_type) PNGARG((png_structp -png_ptr, png_infop info_ptr)); +PNG_EXPORT(120, png_byte, png_get_interlace_type, (png_structp png_ptr, + png_infop info_ptr)); /* Returns image compression_type. */ -PNG_EXPORT(png_byte, png_get_compression_type) PNGARG((png_structp -png_ptr, png_infop info_ptr)); +PNG_EXPORT(121, png_byte, png_get_compression_type, (png_structp png_ptr, + png_infop info_ptr)); /* Returns image resolution in pixels per meter, from pHYs chunk data. */ -PNG_EXPORT(png_uint_32, png_get_pixels_per_meter) PNGARG((png_structp -png_ptr, png_infop info_ptr)); -PNG_EXPORT(png_uint_32, png_get_x_pixels_per_meter) PNGARG((png_structp -png_ptr, png_infop info_ptr)); -PNG_EXPORT(png_uint_32, png_get_y_pixels_per_meter) PNGARG((png_structp -png_ptr, png_infop info_ptr)); +PNG_EXPORT(122, png_uint_32, png_get_pixels_per_meter, (png_structp png_ptr, + png_infop info_ptr)); +PNG_EXPORT(123, png_uint_32, png_get_x_pixels_per_meter, (png_structp png_ptr, + png_infop info_ptr)); +PNG_EXPORT(124, png_uint_32, png_get_y_pixels_per_meter, (png_structp png_ptr, + png_infop info_ptr)); /* Returns pixel aspect ratio, computed from pHYs chunk data. */ -#ifdef PNG_FLOATING_POINT_SUPPORTED -PNG_EXPORT(float, png_get_pixel_aspect_ratio) PNGARG((png_structp -png_ptr, png_infop info_ptr)); -#endif +PNG_FP_EXPORT(125, float, png_get_pixel_aspect_ratio, (png_structp png_ptr, + png_infop info_ptr)); +PNG_FIXED_EXPORT(210, png_fixed_point, png_get_pixel_aspect_ratio_fixed, + (png_structp png_ptr, png_infop info_ptr)); /* Returns image x, y offset in pixels or microns, from oFFs chunk data. */ -PNG_EXPORT(png_int_32, png_get_x_offset_pixels) PNGARG((png_structp -png_ptr, png_infop info_ptr)); -PNG_EXPORT(png_int_32, png_get_y_offset_pixels) PNGARG((png_structp -png_ptr, png_infop info_ptr)); -PNG_EXPORT(png_int_32, png_get_x_offset_microns) PNGARG((png_structp -png_ptr, png_infop info_ptr)); -PNG_EXPORT(png_int_32, png_get_y_offset_microns) PNGARG((png_structp -png_ptr, png_infop info_ptr)); +PNG_EXPORT(126, png_int_32, png_get_x_offset_pixels, (png_structp png_ptr, + png_infop info_ptr)); +PNG_EXPORT(127, png_int_32, png_get_y_offset_pixels, (png_structp png_ptr, + png_infop info_ptr)); +PNG_EXPORT(128, png_int_32, png_get_x_offset_microns, (png_structp png_ptr, + png_infop info_ptr)); +PNG_EXPORT(129, png_int_32, png_get_y_offset_microns, (png_structp png_ptr, + png_infop info_ptr)); #endif /* PNG_EASY_ACCESS_SUPPORTED */ /* Returns pointer to signature string read from PNG header */ -PNG_EXPORT(png_bytep,png_get_signature) PNGARG((png_structp png_ptr, -png_infop info_ptr)); +PNG_EXPORT(130, png_const_bytep, png_get_signature, (png_structp png_ptr, + png_infop info_ptr)); #ifdef PNG_bKGD_SUPPORTED -PNG_EXPORT(png_uint_32,png_get_bKGD) PNGARG((png_structp png_ptr, - png_infop info_ptr, png_color_16p *background)); +PNG_EXPORT(131, png_uint_32, png_get_bKGD, + (png_structp png_ptr, png_infop info_ptr, + png_color_16p *background)); #endif #ifdef PNG_bKGD_SUPPORTED -PNG_EXPORT(void,png_set_bKGD) PNGARG((png_structp png_ptr, - png_infop info_ptr, png_color_16p background)); +PNG_EXPORT(132, void, png_set_bKGD, (png_structp png_ptr, png_infop info_ptr, + png_const_color_16p background)); #endif #ifdef PNG_cHRM_SUPPORTED -#ifdef PNG_FLOATING_POINT_SUPPORTED -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 -#ifdef PNG_FIXED_POINT_SUPPORTED -PNG_EXPORT(png_uint_32,png_get_cHRM_fixed) PNGARG((png_structp png_ptr, - png_infop info_ptr, png_fixed_point *int_white_x, png_fixed_point - *int_white_y, png_fixed_point *int_red_x, png_fixed_point *int_red_y, - png_fixed_point *int_green_x, png_fixed_point *int_green_y, png_fixed_point - *int_blue_x, png_fixed_point *int_blue_y)); +PNG_FP_EXPORT(133, png_uint_32, png_get_cHRM, (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)); +#ifdef PNG_FIXED_POINT_SUPPORTED /* Otherwise not implemented */ +PNG_FIXED_EXPORT(134, png_uint_32, png_get_cHRM_fixed, (png_structp png_ptr, + png_infop info_ptr, png_fixed_point *int_white_x, + png_fixed_point *int_white_y, png_fixed_point *int_red_x, + png_fixed_point *int_red_y, png_fixed_point *int_green_x, + png_fixed_point *int_green_y, png_fixed_point *int_blue_x, + png_fixed_point *int_blue_y)); #endif #endif #ifdef PNG_cHRM_SUPPORTED -#ifdef PNG_FLOATING_POINT_SUPPORTED -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 -#ifdef PNG_FIXED_POINT_SUPPORTED -PNG_EXPORT(void,png_set_cHRM_fixed) PNGARG((png_structp png_ptr, - png_infop info_ptr, png_fixed_point int_white_x, png_fixed_point int_white_y, - png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point - int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x, - png_fixed_point int_blue_y)); -#endif +PNG_FP_EXPORT(135, void, png_set_cHRM, + (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)); +PNG_FIXED_EXPORT(136, void, png_set_cHRM_fixed, (png_structp png_ptr, + png_infop info_ptr, png_fixed_point int_white_x, + png_fixed_point int_white_y, png_fixed_point int_red_x, + png_fixed_point int_red_y, png_fixed_point int_green_x, + png_fixed_point int_green_y, png_fixed_point int_blue_x, + png_fixed_point int_blue_y)); #endif #ifdef PNG_gAMA_SUPPORTED -#ifdef PNG_FLOATING_POINT_SUPPORTED -PNG_EXPORT(png_uint_32,png_get_gAMA) PNGARG((png_structp png_ptr, - png_infop info_ptr, double *file_gamma)); -#endif -PNG_EXPORT(png_uint_32,png_get_gAMA_fixed) PNGARG((png_structp png_ptr, - png_infop info_ptr, png_fixed_point *int_file_gamma)); +PNG_FP_EXPORT(137, png_uint_32, png_get_gAMA, + (png_structp png_ptr, png_infop info_ptr, + double *file_gamma)); +PNG_FIXED_EXPORT(138, png_uint_32, png_get_gAMA_fixed, (png_structp png_ptr, + png_infop info_ptr, png_fixed_point *int_file_gamma)); #endif #ifdef PNG_gAMA_SUPPORTED -#ifdef PNG_FLOATING_POINT_SUPPORTED -PNG_EXPORT(void,png_set_gAMA) PNGARG((png_structp png_ptr, - png_infop info_ptr, double file_gamma)); -#endif -PNG_EXPORT(void,png_set_gAMA_fixed) PNGARG((png_structp png_ptr, - png_infop info_ptr, png_fixed_point int_file_gamma)); +PNG_FP_EXPORT(139, void, png_set_gAMA, (png_structp png_ptr, png_infop info_ptr, + double file_gamma)); +PNG_FIXED_EXPORT(140, void, png_set_gAMA_fixed, (png_structp png_ptr, + png_infop info_ptr, png_fixed_point int_file_gamma)); #endif #ifdef PNG_hIST_SUPPORTED -PNG_EXPORT(png_uint_32,png_get_hIST) PNGARG((png_structp png_ptr, - png_infop info_ptr, png_uint_16p *hist)); +PNG_EXPORT(141, png_uint_32, png_get_hIST, + (png_structp png_ptr, png_infop info_ptr, + png_uint_16p *hist)); #endif #ifdef PNG_hIST_SUPPORTED -PNG_EXPORT(void,png_set_hIST) PNGARG((png_structp png_ptr, - png_infop info_ptr, png_uint_16p hist)); +PNG_EXPORT(142, void, png_set_hIST, (png_structp png_ptr, png_infop info_ptr, + png_const_uint_16p hist)); #endif -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, - int *bit_depth, int *color_type, int *interlace_method, - int *compression_method, int *filter_method)); +PNG_EXPORT(143, png_uint_32, png_get_IHDR, + (png_structp png_ptr, png_infop info_ptr, + png_uint_32 *width, png_uint_32 *height, int *bit_depth, int *color_type, + int *interlace_method, int *compression_method, int *filter_method)); -PNG_EXPORT(void,png_set_IHDR) PNGARG((png_structp png_ptr, - png_infop info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth, - int color_type, int interlace_method, int compression_method, - int filter_method)); +PNG_EXPORT(144, void, png_set_IHDR, + (png_structp png_ptr, png_infop info_ptr, + png_uint_32 width, png_uint_32 height, int bit_depth, int color_type, + int interlace_method, int compression_method, int filter_method)); #ifdef PNG_oFFs_SUPPORTED -PNG_EXPORT(png_uint_32,png_get_oFFs) PNGARG((png_structp png_ptr, - png_infop info_ptr, png_int_32 *offset_x, png_int_32 *offset_y, - int *unit_type)); +PNG_EXPORT(145, png_uint_32, png_get_oFFs, + (png_structp png_ptr, png_infop info_ptr, + png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type)); #endif #ifdef PNG_oFFs_SUPPORTED -PNG_EXPORT(void,png_set_oFFs) PNGARG((png_structp png_ptr, - png_infop info_ptr, png_int_32 offset_x, png_int_32 offset_y, - int unit_type)); +PNG_EXPORT(146, void, png_set_oFFs, + (png_structp png_ptr, png_infop info_ptr, + png_int_32 offset_x, png_int_32 offset_y, int unit_type)); #endif #ifdef PNG_pCAL_SUPPORTED -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)); +PNG_EXPORT(147, png_uint_32, png_get_pCAL, + (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 #ifdef PNG_pCAL_SUPPORTED -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)); +PNG_EXPORT(148, void, png_set_pCAL, (png_structp png_ptr, png_infop info_ptr, + png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type, + int nparams, png_const_charp units, png_charpp params)); #endif #ifdef PNG_pHYs_SUPPORTED -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)); +PNG_EXPORT(149, png_uint_32, png_get_pHYs, + (png_structp png_ptr, png_infop info_ptr, + png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)); #endif #ifdef PNG_pHYs_SUPPORTED -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)); +PNG_EXPORT(150, 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)); #endif -PNG_EXPORT(png_uint_32,png_get_PLTE) PNGARG((png_structp png_ptr, - png_infop info_ptr, png_colorp *palette, int *num_palette)); +PNG_EXPORT(151, png_uint_32, png_get_PLTE, + (png_structp png_ptr, png_infop info_ptr, + png_colorp *palette, int *num_palette)); -PNG_EXPORT(void,png_set_PLTE) PNGARG((png_structp png_ptr, - png_infop info_ptr, png_colorp palette, int num_palette)); +PNG_EXPORT(152, void, png_set_PLTE, + (png_structp png_ptr, png_infop info_ptr, + png_const_colorp palette, int num_palette)); #ifdef PNG_sBIT_SUPPORTED -PNG_EXPORT(png_uint_32,png_get_sBIT) PNGARG((png_structp png_ptr, - png_infop info_ptr, png_color_8p *sig_bit)); +PNG_EXPORT(153, png_uint_32, png_get_sBIT, + (png_structp png_ptr, png_infop info_ptr, + png_color_8p *sig_bit)); #endif #ifdef PNG_sBIT_SUPPORTED -PNG_EXPORT(void,png_set_sBIT) PNGARG((png_structp png_ptr, - png_infop info_ptr, png_color_8p sig_bit)); +PNG_EXPORT(154, void, png_set_sBIT, + (png_structp png_ptr, png_infop info_ptr, png_const_color_8p sig_bit)); #endif #ifdef PNG_sRGB_SUPPORTED -PNG_EXPORT(png_uint_32,png_get_sRGB) PNGARG((png_structp png_ptr, - png_infop info_ptr, int *intent)); +PNG_EXPORT(155, png_uint_32, png_get_sRGB, + (png_structp png_ptr, png_infop info_ptr, int *intent)); #endif #ifdef PNG_sRGB_SUPPORTED -PNG_EXPORT(void,png_set_sRGB) PNGARG((png_structp png_ptr, - png_infop info_ptr, int intent)); -PNG_EXPORT(void,png_set_sRGB_gAMA_and_cHRM) PNGARG((png_structp png_ptr, - png_infop info_ptr, int intent)); +PNG_EXPORT(156, void, png_set_sRGB, + (png_structp png_ptr, png_infop info_ptr, int intent)); +PNG_EXPORT(157, void, png_set_sRGB_gAMA_and_cHRM, (png_structp png_ptr, + png_infop info_ptr, int intent)); #endif #ifdef PNG_iCCP_SUPPORTED -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_uint_32 *proflen)); - /* Note to maintainer: profile should be png_bytepp */ +PNG_EXPORT(158, png_uint_32, png_get_iCCP, + (png_structp png_ptr, png_infop info_ptr, + png_charpp name, int *compression_type, png_bytepp profile, + png_uint_32 *proflen)); #endif #ifdef PNG_iCCP_SUPPORTED -PNG_EXPORT(void,png_set_iCCP) PNGARG((png_structp png_ptr, - png_infop info_ptr, png_charp name, int compression_type, - png_charp profile, png_uint_32 proflen)); - /* Note to maintainer: profile should be png_bytep */ +PNG_EXPORT(159, void, png_set_iCCP, + (png_structp png_ptr, png_infop info_ptr, + png_const_charp name, int compression_type, png_const_bytep profile, + png_uint_32 proflen)); #endif #ifdef PNG_sPLT_SUPPORTED -PNG_EXPORT(png_uint_32,png_get_sPLT) PNGARG((png_structp png_ptr, - png_infop info_ptr, png_sPLT_tpp entries)); +PNG_EXPORT(160, png_uint_32, png_get_sPLT, + (png_structp png_ptr, png_infop info_ptr, + png_sPLT_tpp entries)); #endif #ifdef PNG_sPLT_SUPPORTED -PNG_EXPORT(void,png_set_sPLT) PNGARG((png_structp png_ptr, - png_infop info_ptr, png_sPLT_tp entries, int nentries)); +PNG_EXPORT(161, void, png_set_sPLT, + (png_structp png_ptr, png_infop info_ptr, + png_const_sPLT_tp entries, int nentries)); #endif #ifdef PNG_TEXT_SUPPORTED /* png_get_text also returns the number of text chunks in *num_text */ -PNG_EXPORT(png_uint_32,png_get_text) PNGARG((png_structp png_ptr, - png_infop info_ptr, png_textp *text_ptr, int *num_text)); +PNG_EXPORT(162, png_uint_32, png_get_text, + (png_structp png_ptr, png_infop info_ptr, + png_textp *text_ptr, int *num_text)); #endif -/* Note while png_set_text() will accept a structure whose text, +/* Note while png_set_text() will accept a structure whose text, * language, and translated keywords are NULL pointers, the structure * returned by png_get_text will always contain regular * zero-terminated C strings. They might be empty strings but @@ -2413,59 +1872,63 @@ PNG_EXPORT(png_uint_32,png_get_text) PNGARG((png_structp png_ptr, */ #ifdef PNG_TEXT_SUPPORTED -PNG_EXPORT(void,png_set_text) PNGARG((png_structp png_ptr, - png_infop info_ptr, png_textp text_ptr, int num_text)); +PNG_EXPORT(163, void, png_set_text, + (png_structp png_ptr, png_infop info_ptr, + png_const_textp text_ptr, int num_text)); #endif #ifdef PNG_tIME_SUPPORTED -PNG_EXPORT(png_uint_32,png_get_tIME) PNGARG((png_structp png_ptr, - png_infop info_ptr, png_timep *mod_time)); +PNG_EXPORT(164, png_uint_32, png_get_tIME, + (png_structp png_ptr, png_infop info_ptr, png_timep *mod_time)); #endif #ifdef PNG_tIME_SUPPORTED -PNG_EXPORT(void,png_set_tIME) PNGARG((png_structp png_ptr, - png_infop info_ptr, png_timep mod_time)); +PNG_EXPORT(165, void, png_set_tIME, + (png_structp png_ptr, png_infop info_ptr, png_const_timep mod_time)); #endif #ifdef PNG_tRNS_SUPPORTED -PNG_EXPORT(png_uint_32,png_get_tRNS) PNGARG((png_structp png_ptr, - png_infop info_ptr, png_bytep *trans_alpha, int *num_trans, - png_color_16p *trans_color)); -#endif - -#ifdef PNG_tRNS_SUPPORTED -PNG_EXPORT(void,png_set_tRNS) PNGARG((png_structp png_ptr, - png_infop info_ptr, png_bytep trans_alpha, int num_trans, - png_color_16p trans_color)); +PNG_EXPORT(166, png_uint_32, png_get_tRNS, + (png_structp png_ptr, png_infop info_ptr, + png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color)); #endif #ifdef PNG_tRNS_SUPPORTED +PNG_EXPORT(167, void, png_set_tRNS, + (png_structp png_ptr, png_infop info_ptr, + png_const_bytep trans_alpha, int num_trans, + png_const_color_16p trans_color)); #endif #ifdef PNG_sCAL_SUPPORTED -#ifdef PNG_FLOATING_POINT_SUPPORTED -PNG_EXPORT(png_uint_32,png_get_sCAL) PNGARG((png_structp png_ptr, - png_infop info_ptr, int *unit, double *width, double *height)); -#else -#ifdef PNG_FIXED_POINT_SUPPORTED -PNG_EXPORT(png_uint_32,png_get_sCAL_s) PNGARG((png_structp png_ptr, - png_infop info_ptr, int *unit, png_charpp swidth, png_charpp sheight)); -#endif +PNG_FP_EXPORT(168, png_uint_32, png_get_sCAL, + (png_structp png_ptr, png_infop info_ptr, + int *unit, double *width, double *height)); +#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED +/* NOTE: this API is currently implemented using floating point arithmetic, + * consequently it can only be used on systems with floating point support. + * In any case the range of values supported by png_fixed_point is small and it + * is highly recommended that png_get_sCAL_s be used instead. + */ +PNG_FIXED_EXPORT(214, png_uint_32, png_get_sCAL_fixed, (png_structp png_ptr, + png_infop info_ptr, int *unit, png_fixed_point *width, + png_fixed_point *height)); #endif +PNG_EXPORT(169, png_uint_32, png_get_sCAL_s, + (png_structp png_ptr, + png_infop info_ptr, int *unit, png_charpp swidth, png_charpp sheight)); + +PNG_FP_EXPORT(170, void, png_set_sCAL, + (png_structp png_ptr, png_infop info_ptr, + int unit, double width, double height)); +PNG_FIXED_EXPORT(213, void, png_set_sCAL_fixed, (png_structp png_ptr, + png_infop info_ptr, int unit, png_fixed_point width, + png_fixed_point height)); +PNG_EXPORT(171, void, png_set_sCAL_s, + (png_structp png_ptr, png_infop info_ptr, + int unit, png_const_charp swidth, png_const_charp sheight)); #endif /* PNG_sCAL_SUPPORTED */ -#ifdef PNG_sCAL_SUPPORTED -#ifdef PNG_FLOATING_POINT_SUPPORTED -PNG_EXPORT(void,png_set_sCAL) PNGARG((png_structp png_ptr, - png_infop info_ptr, int unit, double width, double height)); -#else -#ifdef PNG_FIXED_POINT_SUPPORTED -PNG_EXPORT(void,png_set_sCAL_s) PNGARG((png_structp png_ptr, - png_infop info_ptr, int unit, png_charp swidth, png_charp sheight)); -#endif -#endif -#endif /* PNG_sCAL_SUPPORTED || PNG_WRITE_sCAL_SUPPORTED */ - #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED /* Provide a list of chunks and how they are to be handled, if the built-in handling or default unknown chunk handling is not desired. Any chunks not @@ -2476,48 +1939,44 @@ PNG_EXPORT(void,png_set_sCAL_s) PNGARG((png_structp png_ptr, = 2: keep only if safe-to-copy = 3: keep even if unsafe-to-copy */ -PNG_EXPORT(void, png_set_keep_unknown_chunks) PNGARG((png_structp - png_ptr, int keep, png_bytep chunk_list, int num_chunks)); -PNG_EXPORT(int,png_handle_as_unknown) PNGARG((png_structp png_ptr, png_bytep - chunk_name)); +PNG_EXPORT(172, void, png_set_keep_unknown_chunks, + (png_structp png_ptr, int keep, + png_const_bytep chunk_list, int num_chunks)); +PNG_EXPORT(173, int, png_handle_as_unknown, (png_structp png_ptr, + png_const_bytep chunk_name)); #endif #ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED -PNG_EXPORT(void, png_set_unknown_chunks) PNGARG((png_structp png_ptr, - png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns)); -PNG_EXPORT(void, png_set_unknown_chunk_location) - PNGARG((png_structp png_ptr, png_infop info_ptr, int chunk, int location)); -PNG_EXPORT(png_uint_32,png_get_unknown_chunks) PNGARG((png_structp - png_ptr, png_infop info_ptr, png_unknown_chunkpp entries)); +PNG_EXPORT(174, void, png_set_unknown_chunks, (png_structp png_ptr, + png_infop info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns)); +PNG_EXPORT(175, void, png_set_unknown_chunk_location, (png_structp png_ptr, + png_infop info_ptr, int chunk, int location)); +PNG_EXPORT(176, int, png_get_unknown_chunks, (png_structp png_ptr, + png_infop info_ptr, png_unknown_chunkpp entries)); #endif /* Png_free_data() will turn off the "valid" flag for anything it frees. - * If you need to turn it off for a chunk that your application has freed, + * If you need to turn it off for a chunk that your application has freed, * you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK); */ -PNG_EXPORT(void, png_set_invalid) PNGARG((png_structp png_ptr, - png_infop info_ptr, int mask)); +PNG_EXPORT(177, void, png_set_invalid, + (png_structp png_ptr, png_infop info_ptr, int mask)); #ifdef PNG_INFO_IMAGE_SUPPORTED /* The "params" pointer is currently not used and is for future expansion. */ -PNG_EXPORT(void, png_read_png) PNGARG((png_structp png_ptr, - png_infop info_ptr, - int transforms, - png_voidp params)); -PNG_EXPORT(void, png_write_png) PNGARG((png_structp png_ptr, - png_infop info_ptr, - int transforms, - png_voidp params)); +PNG_EXPORT(178, void, png_read_png, (png_structp png_ptr, png_infop info_ptr, + int transforms, png_voidp params)); +PNG_EXPORT(179, void, png_write_png, (png_structp png_ptr, png_infop info_ptr, + int transforms, png_voidp params)); #endif -PNG_EXPORT(png_charp,png_get_copyright) PNGARG((png_structp png_ptr)); -PNG_EXPORT(png_charp,png_get_header_ver) PNGARG((png_structp png_ptr)); -PNG_EXPORT(png_charp,png_get_header_version) PNGARG((png_structp - png_ptr)); -PNG_EXPORT(png_charp,png_get_libpng_ver) PNGARG((png_structp png_ptr)); +PNG_EXPORT(180, png_const_charp, png_get_copyright, (png_structp png_ptr)); +PNG_EXPORT(181, png_const_charp, png_get_header_ver, (png_structp png_ptr)); +PNG_EXPORT(182, png_const_charp, png_get_header_version, (png_structp png_ptr)); +PNG_EXPORT(183, png_const_charp, png_get_libpng_ver, (png_structp png_ptr)); #ifdef PNG_MNG_FEATURES_SUPPORTED -PNG_EXPORT(png_uint_32,png_permit_mng_features) PNGARG((png_structp - png_ptr, png_uint_32 mng_features_permitted)); +PNG_EXPORT(184, png_uint_32, png_permit_mng_features, (png_structp png_ptr, + png_uint_32 mng_features_permitted)); #endif /* For use in png_set_keep_unknown, added to version 1.2.6 */ @@ -2530,74 +1989,129 @@ PNG_EXPORT(png_uint_32,png_permit_mng_features) PNGARG((png_structp * messages before passing them to the error or warning handler. */ #ifdef PNG_ERROR_NUMBERS_SUPPORTED -PNG_EXPORT(void,png_set_strip_error_numbers) PNGARG((png_structp - png_ptr, png_uint_32 strip_mode)); +PNG_EXPORT(185, void, png_set_strip_error_numbers, + (png_structp png_ptr, + png_uint_32 strip_mode)); #endif /* Added in libpng-1.2.6 */ #ifdef PNG_SET_USER_LIMITS_SUPPORTED -PNG_EXPORT(void,png_set_user_limits) PNGARG((png_structp - png_ptr, png_uint_32 user_width_max, png_uint_32 user_height_max)); -PNG_EXPORT(png_uint_32,png_get_user_width_max) PNGARG((png_structp - png_ptr)); -PNG_EXPORT(png_uint_32,png_get_user_height_max) PNGARG((png_structp - png_ptr)); +PNG_EXPORT(186, void, png_set_user_limits, (png_structp png_ptr, + png_uint_32 user_width_max, png_uint_32 user_height_max)); +PNG_EXPORT(187, png_uint_32, png_get_user_width_max, (png_structp png_ptr)); +PNG_EXPORT(188, png_uint_32, png_get_user_height_max, (png_structp png_ptr)); /* Added in libpng-1.4.0 */ -PNG_EXPORT(void,png_set_chunk_cache_max) PNGARG((png_structp - png_ptr, png_uint_32 user_chunk_cache_max)); -PNG_EXPORT(png_uint_32,png_get_chunk_cache_max) - PNGARG((png_structp png_ptr)); +PNG_EXPORT(189, void, png_set_chunk_cache_max, (png_structp png_ptr, + png_uint_32 user_chunk_cache_max)); +PNG_EXPORT(190, png_uint_32, png_get_chunk_cache_max, (png_structp png_ptr)); /* Added in libpng-1.4.1 */ -PNG_EXPORT(void,png_set_chunk_malloc_max) PNGARG((png_structp - png_ptr, png_alloc_size_t user_chunk_cache_max)); -PNG_EXPORT(png_alloc_size_t,png_get_chunk_malloc_max) - PNGARG((png_structp png_ptr)); +PNG_EXPORT(191, void, png_set_chunk_malloc_max, (png_structp png_ptr, + png_alloc_size_t user_chunk_cache_max)); +PNG_EXPORT(192, png_alloc_size_t, png_get_chunk_malloc_max, + (png_structp png_ptr)); #endif -#if defined(PNG_INCH_CONVERSIONS) && defined(PNG_FLOATING_POINT_SUPPORTED) -PNG_EXPORT(png_uint_32,png_get_pixels_per_inch) PNGARG((png_structp png_ptr, -png_infop info_ptr)); +#if defined(PNG_INCH_CONVERSIONS_SUPPORTED) +PNG_EXPORT(193, png_uint_32, png_get_pixels_per_inch, (png_structp png_ptr, + png_infop info_ptr)); -PNG_EXPORT(png_uint_32,png_get_x_pixels_per_inch) PNGARG((png_structp png_ptr, -png_infop info_ptr)); +PNG_EXPORT(194, png_uint_32, png_get_x_pixels_per_inch, (png_structp png_ptr, + png_infop info_ptr)); -PNG_EXPORT(png_uint_32,png_get_y_pixels_per_inch) PNGARG((png_structp png_ptr, -png_infop info_ptr)); +PNG_EXPORT(195, png_uint_32, png_get_y_pixels_per_inch, (png_structp png_ptr, + png_infop info_ptr)); -PNG_EXPORT(float,png_get_x_offset_inches) PNGARG((png_structp png_ptr, -png_infop info_ptr)); +PNG_FP_EXPORT(196, float, png_get_x_offset_inches, (png_structp png_ptr, + png_infop info_ptr)); +#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */ +PNG_FIXED_EXPORT(211, png_fixed_point, png_get_x_offset_inches_fixed, + (png_structp png_ptr, png_infop info_ptr)); +#endif -PNG_EXPORT(float,png_get_y_offset_inches) PNGARG((png_structp png_ptr, -png_infop info_ptr)); +PNG_FP_EXPORT(197, float, png_get_y_offset_inches, (png_structp png_ptr, + png_infop info_ptr)); +#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */ +PNG_FIXED_EXPORT(212, png_fixed_point, png_get_y_offset_inches_fixed, + (png_structp png_ptr, png_infop info_ptr)); +#endif -#ifdef PNG_pHYs_SUPPORTED -PNG_EXPORT(png_uint_32,png_get_pHYs_dpi) PNGARG((png_structp png_ptr, -png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)); -#endif /* PNG_pHYs_SUPPORTED */ -#endif /* PNG_INCH_CONVERSIONS && PNG_FLOATING_POINT_SUPPORTED */ +# ifdef PNG_pHYs_SUPPORTED +PNG_EXPORT(198, png_uint_32, png_get_pHYs_dpi, (png_structp png_ptr, + png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, + int *unit_type)); +# endif /* PNG_pHYs_SUPPORTED */ +#endif /* PNG_INCH_CONVERSIONS_SUPPORTED */ /* Added in libpng-1.4.0 */ #ifdef PNG_IO_STATE_SUPPORTED -PNG_EXPORT(png_uint_32,png_get_io_state) PNGARG((png_structp png_ptr)); +PNG_EXPORT(199, png_uint_32, png_get_io_state, (png_structp png_ptr)); -PNG_EXPORT(png_bytep,png_get_io_chunk_name) - PNGARG((png_structp png_ptr)); +PNG_EXPORT(200, png_const_bytep, png_get_io_chunk_name, (png_structp png_ptr)); /* The flags returned by png_get_io_state() are the following: */ -#define PNG_IO_NONE 0x0000 /* no I/O at this moment */ -#define PNG_IO_READING 0x0001 /* currently reading */ -#define PNG_IO_WRITING 0x0002 /* currently writing */ -#define PNG_IO_SIGNATURE 0x0010 /* currently at the file signature */ -#define PNG_IO_CHUNK_HDR 0x0020 /* currently at the chunk header */ -#define PNG_IO_CHUNK_DATA 0x0040 /* currently at the chunk data */ -#define PNG_IO_CHUNK_CRC 0x0080 /* currently at the chunk crc */ -#define PNG_IO_MASK_OP 0x000f /* current operation: reading/writing */ -#define PNG_IO_MASK_LOC 0x00f0 /* current location: sig/hdr/data/crc */ +# define PNG_IO_NONE 0x0000 /* no I/O at this moment */ +# define PNG_IO_READING 0x0001 /* currently reading */ +# define PNG_IO_WRITING 0x0002 /* currently writing */ +# define PNG_IO_SIGNATURE 0x0010 /* currently at the file signature */ +# define PNG_IO_CHUNK_HDR 0x0020 /* currently at the chunk header */ +# define PNG_IO_CHUNK_DATA 0x0040 /* currently at the chunk data */ +# define PNG_IO_CHUNK_CRC 0x0080 /* currently at the chunk crc */ +# define PNG_IO_MASK_OP 0x000f /* current operation: reading/writing */ +# define PNG_IO_MASK_LOC 0x00f0 /* current location: sig/hdr/data/crc */ #endif /* ?PNG_IO_STATE_SUPPORTED */ -/* Maintainer: Put new public prototypes here ^, in libpng.3, and project - * defs +/* Interlace support. The following macros are always defined so that if + * libpng interlace handling is turned off the macros may be used to handle + * interlaced images within the application. */ +#define PNG_INTERLACE_ADAM7_PASSES 7 + +/* Two macros to return the first row and first column of the original, + * full, image which appears in a given pass. 'pass' is in the range 0 + * to 6 and the result is in the range 0 to 7. + */ +#define PNG_PASS_START_ROW(pass) (((1U&~(pass))<<(3-((pass)>>1)))&7) +#define PNG_PASS_START_COL(pass) (((1U& (pass))<<(3-(((pass)+1)>>1)))&7) + +/* Two macros to help evaluate the number of rows or columns in each + * pass. This is expressed as a shift - effectively log2 of the number or + * rows or columns in each 8x8 tile of the original image. + */ +#define PNG_PASS_ROW_SHIFT(pass) ((pass)>2?(8-(pass))>>1:3) +#define PNG_PASS_COL_SHIFT(pass) ((pass)>1?(7-(pass))>>1:3) + +/* Hence two macros to determine the number of rows or columns in a given + * pass of an image given its height or width. In fact these macros may + * return non-zero even though the sub-image is empty, because the other + * dimension may be empty for a small image. + */ +#define PNG_PASS_ROWS(height, pass) (((height)+(((1<>PNG_PASS_ROW_SHIFT(pass)) +#define PNG_PASS_COLS(width, pass) (((width)+(((1<>PNG_PASS_COL_SHIFT(pass)) + +/* For the progressive reader it is necessary to find the row in the output + * image given a row in an interlaced image, so two more macros: + */ +#define PNG_ROW_FROM_PASS_ROW(yIn, pass) \ + (((yIn)<>(((7-(off))-(pass))<<2)) & 0xFU) | \ + ((0x01145AF0U>>(((7-(off))-(pass))<<2)) & 0xF0U)) + +#define PNG_ROW_IN_INTERLACE_PASS(y, pass) \ + ((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1) +#define PNG_COL_IN_INTERLACE_PASS(x, pass) \ + ((PNG_PASS_MASK(pass,1) >> ((x)&7)) & 1) #ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED /* With these routines we avoid an integer divide, which will be slower on @@ -2612,7 +2126,7 @@ PNG_EXPORT(png_bytep,png_get_io_chunk_name) * [Optimized code by Greg Roelofs and Mark Adler...blame us for bugs. :-) ] */ - /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */ + /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */ # define png_composite(composite, fg, alpha, bg) \ { png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) \ @@ -2630,15 +2144,15 @@ PNG_EXPORT(png_bytep,png_get_io_chunk_name) #else /* Standard method using integer division */ -# define png_composite(composite, fg, alpha, bg) \ - (composite) = (png_byte)(((png_uint_16)(fg) * (png_uint_16)(alpha) + \ - (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \ - (png_uint_16)127) / 255) +# define png_composite(composite, fg, alpha, bg) \ + (composite) = (png_byte)(((png_uint_16)(fg) * (png_uint_16)(alpha) + \ + (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \ + (png_uint_16)127) / 255) # define png_composite_16(composite, fg, alpha, bg) \ (composite) = (png_uint_16)(((png_uint_32)(fg) * (png_uint_32)(alpha) + \ - (png_uint_32)(bg)*(png_uint_32)(65535L - (png_uint_32)(alpha)) + \ - (png_uint_32)32767) / (png_uint_32)65535L) + (png_uint_32)(bg)*(png_uint_32)(65535L - (png_uint_32)(alpha)) + \ + (png_uint_32)32767) / (png_uint_32)65535L) #endif /* PNG_READ_COMPOSITE_NODIV_SUPPORTED */ #ifdef PNG_USE_READ_MACROS @@ -2652,61 +2166,57 @@ PNG_EXPORT(png_bytep,png_get_io_chunk_name) ((png_uint_32)(*((buf) + 2)) << 8) + \ ((png_uint_32)(*((buf) + 3)))) - /* The following definition introduces an API incompatibility (but not - * an ABI incompatibility) with libpng-1.4.0 through 1.4.4. Prior to - * libpng-1.4.5 the macro, which is used by default, returned (incorrectly) - * a (png_uint_32), while the function, if used instead, correctly returned - * a (png_uint_16). - * - * Libpng versions 1.0.x and 1.2.x only used a function so are not affected - * by this potential API incompatibility between macros. - */ + /* From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the + * function) incorrectly returned a value of type png_uint_32. + */ # define png_get_uint_16(buf) \ ((png_uint_16) \ - (((unsigned int)(*(buf)) << 8) + \ - ((unsigned int)(*((buf) + 1))))) + (((unsigned int)(*(buf)) << 8) + \ + ((unsigned int)(*((buf) + 1))))) # define png_get_int_32(buf) \ ((png_int_32)((*(buf) & 0x80) \ ? -((png_int_32)((png_get_uint_32(buf) ^ 0xffffffffL) + 1)) \ : (png_int_32)png_get_uint_32(buf))) -#else -PNG_EXPORT(png_uint_32,png_get_uint_32) PNGARG((png_bytep buf)); -PNG_EXPORT(png_uint_16,png_get_uint_16) PNGARG((png_bytep buf)); -#ifdef PNG_GET_INT_32_SUPPORTED -PNG_EXPORT(png_int_32,png_get_int_32) PNGARG((png_bytep buf)); #endif + +#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED +PNG_EXPORT(201, png_uint_32, png_get_uint_32, (png_const_bytep buf)); +PNG_EXPORT(202, png_uint_16, png_get_uint_16, (png_const_bytep buf)); +PNG_EXPORT(203, png_int_32, png_get_int_32, (png_const_bytep buf)); #endif -PNG_EXPORT(png_uint_32,png_get_uint_31) - PNGARG((png_structp png_ptr, png_bytep buf)); + +PNG_EXPORT(204, png_uint_32, png_get_uint_31, (png_structp png_ptr, + png_const_bytep buf)); /* No png_get_int_16 -- may be added if there's a real need for it. */ /* Place a 32-bit number into a buffer in PNG byte order (big-endian). */ -PNG_EXPORT(void,png_save_uint_32) - PNGARG((png_bytep buf, png_uint_32 i)); -PNG_EXPORT(void,png_save_int_32) - PNGARG((png_bytep buf, png_int_32 i)); +#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED +PNG_EXPORT(205, void, png_save_uint_32, (png_bytep buf, png_uint_32 i)); +#endif +#ifdef PNG_SAVE_INT_32_SUPPORTED +PNG_EXPORT(206, void, png_save_int_32, (png_bytep buf, png_int_32 i)); +#endif /* Place a 16-bit number into a buffer in PNG byte order. - * The parameter is declared unsigned int, not png_uint_16, + * The parameter is declared unsigned int, not png_uint_16, * just to avoid potential problems on pre-ANSI C compilers. */ -PNG_EXPORT(void,png_save_uint_16) - PNGARG((png_bytep buf, unsigned int i)); +#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED +PNG_EXPORT(207, void, png_save_uint_16, (png_bytep buf, unsigned int i)); /* No png_save_int_16 -- may be added if there's a real need for it. */ +#endif -/* ************************************************************************* */ - -/* Various modes of operation. Note that after an init, mode is set to - * zero automatically when the structure is created. +/* Maintainer: Put new public prototypes here ^, in libpng.3, and project + * defs */ -#define PNG_HAVE_IHDR 0x01 -#define PNG_HAVE_PLTE 0x02 -#define PNG_HAVE_IDAT 0x04 -#define PNG_AFTER_IDAT 0x08 /* Have complete zlib datastream */ -#define PNG_HAVE_IEND 0x10 -#define PNG_HAVE_gAMA 0x20 -#define PNG_HAVE_cHRM 0x40 + +/* The last ordinal number (this is the *last* one already used; the next + * one to use is one more than this.) + */ +#ifdef PNG_EXPORT_LAST_ORDINAL + PNG_EXPORT_LAST_ORDINAL(215); +#endif #ifdef __cplusplus } diff --git a/harbour/src/3rd/png/pngconf.h b/harbour/src/3rd/png/pngconf.h index 8a6d83698b..455cef3d83 100644 --- a/harbour/src/3rd/png/pngconf.h +++ b/harbour/src/3rd/png/pngconf.h @@ -1,9 +1,9 @@ /* pngconf.h - machine configurable file for libpng * - * libpng version 1.4.5 - December 9, 2010 - * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2010 Glenn Randers-Pehrson + * libpng version 1.5.0 - January 6, 2011 + * + * Copyright (c) 1998-2011 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -22,290 +22,55 @@ #ifndef PNGCONF_H #define PNGCONF_H +/* PNG_NO_LIMITS_H may be used to turn off the use of the standard C + * definition file for machine specific limits, this may impact the + * correctness of the definitons below (see uses of INT_MAX). + */ #ifndef PNG_NO_LIMITS_H # include #endif -/* Added at libpng-1.2.9 */ - -/* config.h is created by and PNG_CONFIGURE_LIBPNG is set by the "configure" - * script. +/* For the memory copy APIs (i.e. the standard definitions of these), + * because this file defines png_memcpy and so on the base APIs must + * be defined here. */ -#ifdef PNG_CONFIGURE_LIBPNG -# ifdef HAVE_CONFIG_H -# include "config.h" -# endif -#endif - -/* - * Added at libpng-1.2.8 - * - * PNG_USER_CONFIG has to be defined on the compiler command line. This - * includes the resource compiler for Windows DLL configurations. - */ -#ifdef PNG_USER_CONFIG -# include "pngusr.h" -# ifndef PNG_USER_PRIVATEBUILD -# define PNG_USER_PRIVATEBUILD -# endif -#endif - -/* - * If you create a private DLL you should define in "pngusr.h" the following: - * #define PNG_USER_PRIVATEBUILD - * e.g. #define PNG_USER_PRIVATEBUILD "Build by MyCompany for xyz reasons." - * #define PNG_USER_DLLFNAME_POSTFIX - * e.g. // private DLL "libpng14gx.dll" - * #define PNG_USER_DLLFNAME_POSTFIX "gx" - * - * The following macros are also at your disposal if you want to complete the - * DLL VERSIONINFO structure. - * - PNG_USER_VERSIONINFO_COMMENTS - * - PNG_USER_VERSIONINFO_COMPANYNAME - * - PNG_USER_VERSIONINFO_LEGALTRADEMARKS - */ - -#ifdef __STDC__ -# ifdef SPECIALBUILD -# pragma message("PNG_LIBPNG_SPECIALBUILD (and deprecated SPECIALBUILD)\ - are now LIBPNG reserved macros. Use PNG_USER_PRIVATEBUILD instead.") -# endif - -# ifdef PRIVATEBUILD -# pragma message("PRIVATEBUILD is deprecated.\ - Use PNG_USER_PRIVATEBUILD instead.") -# define PNG_USER_PRIVATEBUILD PRIVATEBUILD -# endif -#endif /* __STDC__ */ - -/* End of material added to libpng-1.2.8 */ - -#ifndef PNG_VERSION_INFO_ONLY - -/* 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 - * machine. One of these will be allocated per png_struct. When this - * is full, it writes the data to the disk, and does some other - * calculations. Making this an extremely small size will slow - * the library down, but you may want to experiment to determine - * where it becomes significant, if you are concerned with memory - * usage. Note that zlib allocates at least 32Kb also. For readers, - * this describes the size of the buffer available to read the data in. - * Unless this gets smaller than the size of a row (compressed), - * it should not make much difference how big this is. - */ - -#ifndef PNG_ZBUF_SIZE -# define PNG_ZBUF_SIZE 8192 -#endif - -/* Enable if you want a write-only libpng */ - -#ifndef PNG_NO_READ_SUPPORTED -# define PNG_READ_SUPPORTED -#endif - -/* Enable if you want a read-only libpng */ - -#ifndef PNG_NO_WRITE_SUPPORTED -# define PNG_WRITE_SUPPORTED -#endif - -/* Enabled in 1.4.0. */ -#ifdef PNG_ALLOW_BENIGN_ERRORS -# define png_benign_error png_warning -# define png_chunk_benign_error png_chunk_warning +#ifdef BSD +# include #else -# ifndef PNG_BENIGN_ERRORS_SUPPORTED -# define png_benign_error png_error -# define png_chunk_benign_error png_chunk_error -# endif +# include #endif -/* Added at libpng version 1.4.0 */ -#if !defined(PNG_NO_WARNINGS) && !defined(PNG_WARNINGS_SUPPORTED) -# define PNG_WARNINGS_SUPPORTED -#endif - -/* Added at libpng version 1.4.0 */ -#if !defined(PNG_NO_ERROR_TEXT) && !defined(PNG_ERROR_TEXT_SUPPORTED) -# define PNG_ERROR_TEXT_SUPPORTED -#endif - -/* Added at libpng version 1.4.0 */ -#if !defined(PNG_NO_CHECK_cHRM) && !defined(PNG_CHECK_cHRM_SUPPORTED) -# define PNG_CHECK_cHRM_SUPPORTED -#endif - -/* Added at libpng version 1.4.0 */ -#if !defined(PNG_NO_ALIGNED_MEMORY) && !defined(PNG_ALIGNED_MEMORY_SUPPORTED) -# define PNG_ALIGNED_MEMORY_SUPPORTED -#endif - -/* Enabled by default in 1.2.0. You can disable this if you don't need to - support PNGs that are embedded in MNG datastreams */ -#ifndef PNG_NO_MNG_FEATURES -# ifndef PNG_MNG_FEATURES_SUPPORTED -# define PNG_MNG_FEATURES_SUPPORTED -# endif -#endif - -/* Added at libpng version 1.4.0 */ -#ifndef PNG_NO_FLOATING_POINT_SUPPORTED -# ifndef PNG_FLOATING_POINT_SUPPORTED -# define PNG_FLOATING_POINT_SUPPORTED -# endif -#endif - -/* Added at libpng-1.4.0beta49 for testing (this test is no longer used - in libpng and png_calloc() is always present) +/* For png_FILE_p - this provides the standard definition of a + * FILE */ -#define PNG_CALLOC_SUPPORTED - -/* If you are running on a machine where you cannot allocate more - * than 64K of memory at once, uncomment this. While libpng will not - * normally need that much memory in a chunk (unless you load up a very - * large file), zlib needs to know how big of a chunk it can use, and - * libpng thus makes sure to check any memory allocation to verify it - * will fit into memory. -#define PNG_MAX_MALLOC_64K - */ -#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K) -# define PNG_MAX_MALLOC_64K +#ifdef PNG_STDIO_SUPPORTED +# include #endif -/* Special munging to support doing things the 'cygwin' way: - * 'Normal' png-on-win32 defines/defaults: - * PNG_BUILD_DLL -- building dll - * PNG_USE_DLL -- building an application, linking to dll - * (no define) -- building static library, or building an - * application and linking to the static lib - * 'Cygwin' defines/defaults: - * PNG_BUILD_DLL -- (ignored) building the dll - * (no define) -- (ignored) building an application, linking to the dll - * PNG_STATIC -- (ignored) building the static lib, or building an - * application that links to the static lib. - * ALL_STATIC -- (ignored) building various static libs, or building an - * application that links to the static libs. - * Thus, - * a cygwin user should define either PNG_BUILD_DLL or PNG_STATIC, and - * this bit of #ifdefs will define the 'correct' config variables based on - * that. If a cygwin user *wants* to define 'PNG_USE_DLL' that's okay, but - * unnecessary. +/* This controls optimization of the reading of 16 and 32 bit values + * from PNG files. It can be set on a per-app-file basis - it + * just changes whether a macro is used to the function is called. + * The library builder sets the default, if read functions are not + * built into the library the macro implementation is forced on. + */ +#ifndef PNG_READ_INT_FUNCTIONS_SUPPORTED +# define PNG_USE_READ_MACROS +#endif +#if !defined(PNG_NO_USE_READ_MACROS) && !defined(PNG_USE_READ_MACROS) +# if PNG_DEFAULT_READ_MACROS +# define PNG_USE_READ_MACROS +# endif +#endif + +/* COMPILER SPECIFIC OPTIONS. * - * Also, the precedence order is: - * ALL_STATIC (since we can't #undef something outside our namespace) - * PNG_BUILD_DLL - * PNG_STATIC - * (nothing) == PNG_USE_DLL - * - * CYGWIN (2002-01-20): The preceding is now obsolete. With the advent - * of auto-import in binutils, we no longer need to worry about - * __declspec(dllexport) / __declspec(dllimport) and friends. Therefore, - * we don't need to worry about PNG_STATIC or ALL_STATIC when it comes - * to __declspec() stuff. However, we DO need to worry about - * PNG_BUILD_DLL and PNG_STATIC because those change some defaults - * such as CONSOLE_IO. - */ -#ifdef __CYGWIN__ -# ifdef ALL_STATIC -# ifdef PNG_BUILD_DLL -# undef PNG_BUILD_DLL -# endif -# ifdef PNG_USE_DLL -# undef PNG_USE_DLL -# endif -# ifdef PNG_DLL -# undef PNG_DLL -# endif -# ifndef PNG_STATIC -# define PNG_STATIC -# endif -# else -# ifdef PNG_BUILD_DLL -# ifdef PNG_STATIC -# undef PNG_STATIC -# endif -# ifdef PNG_USE_DLL -# undef PNG_USE_DLL -# endif -# ifndef PNG_DLL -# define PNG_DLL -# endif -# else -# ifdef PNG_STATIC -# ifdef PNG_USE_DLL -# undef PNG_USE_DLL -# endif -# ifdef PNG_DLL -# undef PNG_DLL -# endif -# else -# ifndef PNG_USE_DLL -# define PNG_USE_DLL -# endif -# ifndef PNG_DLL -# define PNG_DLL -# endif -# endif -# endif -# endif -#endif - -/* This protects us against compilers that run on a windowing system - * and thus don't have or would rather us not use the stdio types: - * stdin, stdout, and stderr. The only one currently used is stderr - * in png_error() and png_warning(). #defining PNG_NO_CONSOLE_IO will - * prevent these from being compiled and used. #defining PNG_NO_STDIO - * will also prevent these, plus will prevent the entire set of stdio - * macros and functions (FILE *, printf, etc.) from being compiled and used, - * unless (PNG_DEBUG > 0) has been #defined. - * - * #define PNG_NO_CONSOLE_IO - * #define PNG_NO_STDIO + * These options are provided so that a variety of difficult compilers + * can be used. Some are fixed at build time (e.g. PNG_API_RULE + * below) but still have compiler specific implementations, others + * may be changed on a per-file basis when compiling against libpng. */ -#ifdef _WIN32_WCE -# define PNG_NO_CONSOLE_IO -# define PNG_NO_STDIO -# define PNG_NO_TIME_RFC1123 -# ifdef PNG_DEBUG -# undef PNG_DEBUG -# endif -#endif - -#if !defined(PNG_NO_STDIO) && !defined(PNG_STDIO_SUPPORTED) -# define PNG_STDIO_SUPPORTED -#endif - -#ifdef PNG_BUILD_DLL -# if !defined(PNG_CONSOLE_IO_SUPPORTED) && !defined(PNG_NO_CONSOLE_IO) -# define PNG_NO_CONSOLE_IO -# endif -#endif - -# ifdef PNG_NO_STDIO -# ifndef PNG_NO_CONSOLE_IO -# define PNG_NO_CONSOLE_IO -# endif -# ifdef PNG_DEBUG -# if (PNG_DEBUG > 0) -# include -# endif -# endif -# else -# include -# endif - -#if !(defined PNG_NO_CONSOLE_IO) && !defined(PNG_CONSOLE_IO_SUPPORTED) -# define PNG_CONSOLE_IO_SUPPORTED -#endif - -/* This macro protects us against machines that don't have function +/* The PNGARG macro protects us against machines that don't have function * prototypes (ie K&R style headers). If your compiler does not handle * function prototypes, define this macro and use the included ansi2knr. * I've always been able to use _NO_PROTO as the indicator, but you may @@ -314,142 +79,384 @@ */ #ifndef PNGARG -#ifdef OF /* zlib prototype munger */ -# define PNGARG(arglist) OF(arglist) -#else +# ifdef OF /* zlib prototype munger */ +# define PNGARG(arglist) OF(arglist) +# else -#ifdef _NO_PROTO -# define PNGARG(arglist) () -#else -# define PNGARG(arglist) arglist -#endif /* _NO_PROTO */ +# ifdef _NO_PROTO +# define PNGARG(arglist) () +# else +# define PNGARG(arglist) arglist +# endif /* _NO_PROTO */ -#endif /* OF */ +# endif /* OF */ #endif /* PNGARG */ -/* Try to determine if we are compiling on a Mac. Note that testing for - * just __MWERKS__ is not good enough, because the Codewarrior is now used - * on non-Mac platforms. +/* Function calling conventions. + * ============================= + * Normally it is not necessary to specify to the compiler how to call + * a function - it just does it - however on x86 systems derived from + * Microsoft and Borland C compilers ('IBM PC', 'DOS', 'Windows' systems + * and some others) there are multiple ways to call a function and the + * default can be changed on the compiler command line. For this reason + * libpng specifies the calling convention of every exported function and + * every function called via a user supplied function pointer. This is + * done in this file by defining the following macros: + * + * PNGAPI Calling convention for exported functions. + * PNGCBAPI Calling convention for user provided (callback) functions. + * PNGCAPI Calling convention used by the ANSI-C library (required + * for longjmp callbacks and sometimes used internally to + * specify the calling convention for zlib). + * + * These macros should never be overridden. If it is necessary to + * change calling convention in a private build this can be done + * by setting PNG_API_RULE (which defaults to 0) to one of the values + * below to select the correct 'API' variants. + * + * PNG_API_RULE=0 Use PNGCAPI - the 'C' calling convention - throughout. + * This is correct in every known environment. + * PNG_API_RULE=1 Use the operating system convention for PNGAPI and + * the 'C' calling convention (from PNGCAPI) for + * callbacks (PNGCBAPI). This is no longer required + * in any known environment - if it has to be used + * please post an explanation of the problem to the + * libpng mailing list. + * + * These cases only differ if the operating system does not use the C + * calling convention, at present this just means the above cases + * (x86 DOS/Windows sytems) and, even then, this does not apply to + * Cygwin running on those systems. + * + * Note that the value must be defined in pnglibconf.h so that what + * the application uses to call the library matches the conventions + * set when building the library. */ -#ifndef MACOS -# if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \ - defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC) -# define MACOS + +/* Symbol export + * ============= + * When building a shared library it is almost always necessary to tell + * the compiler which symbols to export. The png.h macro 'PNG_EXPORT' + * is used to mark the symbols. On some systems these symbols can be + * extracted at link time and need no special processing by the compiler, + * on other systems the symbols are flagged by the compiler and just + * the declaration requires a special tag applied (unfortunately) in a + * compiler dependent way. Some systems can do either. + * + * A small number of older systems also require a symbol from a DLL to + * be flagged to the program that calls it. This is a problem because + * we do not know in the header file included by application code that + * the symbol will come from a shared library, as opposed to a statically + * linked one. For this reason the application must tell us by setting + * the magic flag PNG_USE_DLL to turn on the special processing before + * it includes png.h. + * + * Four additional macros are used to make this happen: + * + * PNG_IMPEXP The magic (if any) to cause a symbol to be exported from + * the build or imported if PNG_USE_DLL is set - compiler + * and system specific. + * + * PNG_EXPORT_TYPE(type) A macro that pre or appends PNG_IMPEXP to + * 'type', compiler specific. + * + * PNG_DLL_EXPORT Set to the magic to use during a libpng build to + * make a symbol exported from the DLL. + * + * PNG_DLL_IMPORT Set to the magic to force the libpng symbols to come + * from a DLL - used to define PNG_IMPEXP when + * PNG_USE_DLL is set. + */ + +/* System specific discovery. + * ========================== + * This code is used at build time to find PNG_IMPEXP, the API settings + * and PNG_EXPORT_TYPE(), it may also set a macro to indicate the DLL + * import processing is possible. On Windows/x86 systems it also sets + * compiler-specific macros to the values required to change the calling + * conventions of the various functions. + */ +#if ( defined(_Windows) || defined(_WINDOWS) || defined(WIN32) ||\ + defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) ) &&\ + ( defined(_X86_) || defined(_X64_) || defined(_M_IX86) ||\ + defined(_M_X64) || defined(_M_IA64) ) + /* Windows system (DOS doesn't support DLLs) running on x86/x64. Includes + * builds under Cygwin or MinGW. Also includes Watcom builds but these need + * special treatment because they are not compatible with GCC or Visual C + * because of different calling conventions. + */ +# if PNG_API_RULE == 2 + /* If this line results in an error, either because __watcall is not + * understood or because of a redefine just below you cannot use *this* + * build of the library with the compiler you are using. *This* build was + * build using Watcom and applications must also be built using Watcom! + */ +# define PNGCAPI __watcall +# endif + +# if defined(__GNUC__) || (defined (_MSC_VER) && (_MSC_VER >= 800)) +# define PNGCAPI __cdecl +# if PNG_API_RULE == 1 +# define PNGAPI __stdcall +# endif +# else + /* An older compiler, or one not detected (erroneously) above, + * if necessary override on the command line to get the correct + * variants for the compiler. + */ +# ifndef PNGCAPI +# define PNGCAPI _cdecl +# endif +# if PNG_API_RULE == 1 && !defined(PNGAPI) +# define PNGAPI _stdcall +# endif +# endif /* compiler/api */ + /* NOTE: PNGCBAPI always defaults to PNGCAPI. */ + +# if defined(PNGAPI) && !defined(PNG_USER_PRIVATEBUILD) + ERROR: PNG_USER_PRIVATEBUILD must be defined if PNGAPI is changed +# endif + +# if (defined(_MSC_VER) && _MSC_VER < 800) ||\ + (defined(__BORLANDC__) && __BORLANDC__ < 0x500) + /* older Borland and MSC + * compilers used '__export' and required this to be after + * the type. + */ +# ifndef PNG_EXPORT_TYPE +# define PNG_EXPORT_TYPE(type) type PNG_IMPEXP +# endif +# define PNG_DLL_EXPORT __export +# else /* newer compiler */ +# define PNG_DLL_EXPORT __declspec(dllexport) +# ifndef PNG_DLL_IMPORT +# define PNG_DLL_IMPORT __declspec(dllimport) +# endif +# endif /* compiler */ + +#else /* !Windows/x86 */ +# if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__) +# define PNGAPI _System +# else /* !Windows/x86 && !OS/2 */ + /* Use the defaults, or define PNG*API on the command line (but + * this will have to be done for every compile!) + */ +# endif /* other system, !OS/2 */ +#endif /* !Windows/x86 */ + +/* Now do all the defaulting . */ +#ifndef PNGCAPI +# define PNGCAPI +#endif +#ifndef PNGCBAPI +# define PNGCBAPI PNGCAPI +#endif +#ifndef PNGAPI +# define PNGAPI PNGCAPI +#endif + +/* The default for PNG_IMPEXP depends on whether the library is + * being built or used. + */ +#ifndef PNG_IMPEXP +# ifdef PNGLIB_BUILD + /* Building the library */ +# if (defined(DLL_EXPORT)/*from libtool*/ ||\ + defined(_WINDLL) || defined(_DLL) || defined(__DLL__) ||\ + defined(_USRDLL) ||\ + defined(PNG_BUILD_DLL)) && defined(PNG_DLL_EXPORT) + /* Building a DLL. */ +# define PNG_IMPEXP PNG_DLL_EXPORT +# endif /* DLL */ +# else + /* Using the library */ +# if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT) + /* This forces use of a DLL, disallowing static linking */ +# define PNG_IMPEXP PNG_DLL_IMPORT +# endif +# endif + +# ifndef PNG_IMPEXP +# define PNG_IMPEXP # endif #endif -/* Enough people need this for various reasons to include it here */ -#if !defined(MACOS) && !defined(RISCOS) -# include +/* THe following complexity is concerned with getting the 'attributes' of the + * declared function in the correct place. This potentially requires a separate + * PNG_EXPORT function for every compiler. + */ +#ifndef PNG_FUNCTION +# ifdef __GNUC__ +# define PNG_FUNCTION(type, name, args, attributes)\ + attributes type name args +# else /* !GNUC */ +# ifdef _MSC_VER +# define PNG_FUNCTION(type, name, args, attributes)\ + attributes type name args +# else /* !MSC */ +# define PNG_FUNCTION(type, name, args, attributes)\ + type name args +# endif +# endif #endif -/* PNG_SETJMP_NOT_SUPPORTED and PNG_NO_SETJMP_SUPPORTED are deprecated. */ -#if !defined(PNG_NO_SETJMP) && \ - !defined(PNG_SETJMP_NOT_SUPPORTED) && !defined(PNG_NO_SETJMP_SUPPORTED) -# define PNG_SETJMP_SUPPORTED +#ifndef PNG_EXPORT_TYPE +# define PNG_EXPORT_TYPE(type) PNG_IMPEXP type #endif -#ifdef PNG_SETJMP_SUPPORTED -/* This is an attempt to force a single setjmp behaviour on Linux. If - * the X config stuff didn't define _BSD_SOURCE we wouldn't need this. + /* The ordinal value is only relevant when preprocessing png.h for symbol + * table entries, so we discard it here. See the .dfn files in the + * scripts directory. + */ +#ifndef PNG_EXPORTA +# define PNG_EXPORTA(ordinal, type, name, args, attributes)\ + extern PNG_FUNCTION(PNG_EXPORT_TYPE(type),(PNGAPI name),PNGARG(args),\ + attributes) +#endif + +#define PNG_EXPORT(ordinal, type, name, args)\ + PNG_EXPORTA(ordinal, type, name, args, ) + +/* Use PNG_REMOVED to comment out a removed interface. */ +#ifndef PNG_REMOVED +# define PNG_REMOVED(ordinal, type, name, args, attributes) +#endif + +#ifndef PNG_CALLBACK +# define PNG_CALLBACK(type, name, args, attributes)\ + type (PNGCBAPI name) PNGARG(args) attributes +#endif + +/* Support for compiler specific function attributes. These are used + * so that where compiler support is available incorrect use of API + * functions in png.h will generate compiler warnings. * - * You can bypass this test if you know that your application uses exactly - * the same setjmp.h that was included when libpng was built. Only define - * PNG_SKIP_SETJMP_CHECK while building your application, prior to the - * application's '#include "png.h"'. Don't define PNG_SKIP_SETJMP_CHECK - * while building a separate libpng library for general use. + * Added at libpng-1.2.41. */ -# ifndef PNG_SKIP_SETJMP_CHECK -# ifdef __linux__ -# ifdef _BSD_SOURCE -# define PNG_SAVE_BSD_SOURCE -# undef _BSD_SOURCE -# endif -# ifdef _SETJMP_H - /* If you encounter a compiler error here, see the explanation - * near the end of INSTALL. - */ - __pngconf.h__ in libpng already includes setjmp.h; - __dont__ include it again.; -# endif -# endif /* __linux__ */ -# endif /* PNG_SKIP_SETJMP_CHECK */ +#ifndef PNG_NO_PEDANTIC_WARNINGS +# ifndef PNG_PEDANTIC_WARNINGS_SUPPORTED +# define PNG_PEDANTIC_WARNINGS_SUPPORTED +# endif +#endif - /* Include setjmp.h for error handling */ -# include - -# ifdef __linux__ -# ifdef PNG_SAVE_BSD_SOURCE -# ifdef _BSD_SOURCE -# undef _BSD_SOURCE -# endif -# define _BSD_SOURCE -# undef PNG_SAVE_BSD_SOURCE +#ifdef PNG_PEDANTIC_WARNINGS_SUPPORTED + /* Support for compiler specific function attributes. These are used + * so that where compiler support is available incorrect use of API + * functions in png.h will generate compiler warnings. Added at libpng + * version 1.2.41. + */ +# ifdef __GNUC__ +# ifndef PNG_USE_RESULT +# define PNG_USE_RESULT __attribute__((__warn_unused_result__)) +# endif +# ifndef PNG_NORETURN +# define PNG_NORETURN __attribute__((__noreturn__)) +# endif +# ifndef PNG_PTR_NORETURN +# define PNG_PTR_NORETURN __attribute__((__noreturn__)) +# endif +# ifndef PNG_ALLOCATED +# define PNG_ALLOCATED __attribute__((__malloc__)) # endif -# endif /* __linux__ */ -#endif /* PNG_SETJMP_SUPPORTED */ -#ifdef BSD -# include -#else -# include -#endif + /* This specifically protects structure members that should only be + * accessed from within the library, therefore should be empty during + * a library build. + */ +# ifndef PNGLIB_BUILD +# ifndef PNG_DEPRECATED +# define PNG_DEPRECATED __attribute__((__deprecated__)) +# endif +# ifndef PNG_DEPSTRUCT +# define PNG_DEPSTRUCT __attribute__((__deprecated__)) +# endif +# ifndef PNG_PRIVATE +# if 0 /* Doesn't work so we use deprecated instead*/ +# define PNG_PRIVATE \ + __attribute__((warning("This function is not exported by libpng."))) +# else +# define PNG_PRIVATE \ + __attribute__((__deprecated__)) +# endif +# endif /* PNG_PRIVATE */ +# endif /* PNGLIB_BUILD */ +# endif /* __GNUC__ */ +# ifdef _MSC_VER /* may need to check value */ +# ifndef PNG_USE_RESULT +# define PNG_USE_RESULT /*not supported*/ +# endif +# ifndef PNG_NORETURN +# define PNG_NORETURN __declspec(noreturn) +# endif +# ifndef PNG_PTR_NORETURN +# define PNG_PTR_NORETURN /*not supported*/ +# endif +# ifndef PNG_ALLOCATED +# define PNG_ALLOCATED __declspec(restrict) +# endif -/* Other defines for things like memory and the like can go here. */ + /* This specifically protects structure members that should only be + * accessed from within the library, therefore should be empty during + * a library build. + */ +# ifndef PNGLIB_BUILD +# ifndef PNG_DEPRECATED +# define PNG_DEPRECATED __declspec(deprecated) +# endif +# ifndef PNG_DEPSTRUCT +# define PNG_DEPSTRUCT __declspec(deprecated) +# endif +# ifndef PNG_PRIVATE +# define PNG_PRIVATE __declspec(deprecated) +# endif /* PNG_PRIVATE */ +# endif /* PNGLIB_BUILD */ +# endif /* __GNUC__ */ +#endif /* PNG_PEDANTIC_WARNINGS */ -/* This controls how fine the quantizing gets. As this allocates - * a largish chunk of memory (32K), those who are not as concerned - * with quantizing quality can decrease some or all of these. - */ - -/* Prior to libpng-1.4.2, these were PNG_DITHER_*_BITS - * These migration aids will be removed from libpng-1.5.0. - */ -#ifdef PNG_DITHER_RED_BITS -# define PNG_QUANTIZE_RED_BITS PNG_DITHER_RED_BITS +#ifndef PNG_DEPRECATED +# define PNG_DEPRECATED /* Use of this function is deprecated */ #endif -#ifdef PNG_DITHER_GREEN_BITS -# define PNG_QUANTIZE_GREEN_BITS PNG_DITHER_GREEN_BITS +#ifndef PNG_USE_RESULT +# define PNG_USE_RESULT /* The result of this function must be checked */ #endif -#ifdef PNG_DITHER_BLUE_BITS -# define PNG_QUANTIZE_BLUE_BITS PNG_DITHER_BLUE_BITS +#ifndef PNG_NORETURN +# define PNG_NORETURN /* This function does not return */ #endif - -#ifndef PNG_QUANTIZE_RED_BITS -# define PNG_QUANTIZE_RED_BITS 5 +#ifndef PNG_ALLOCATED +# define PNG_ALLOCATED /* The result of the function is new memory */ #endif -#ifndef PNG_QUANTIZE_GREEN_BITS -# define PNG_QUANTIZE_GREEN_BITS 5 +#ifndef PNG_DEPSTRUCT +# define PNG_DEPSTRUCT /* Access to this struct member is deprecated */ #endif -#ifndef PNG_QUANTIZE_BLUE_BITS -# define PNG_QUANTIZE_BLUE_BITS 5 +#ifndef PNG_PRIVATE +# define PNG_PRIVATE /* This is a private libpng function */ #endif - -/* This controls how fine the gamma correction becomes when you - * are only interested in 8 bits anyway. Increasing this value - * results in more memory being used, and more pow() functions - * being called to fill in the gamma tables. Don't set this value - * less then 8, and even that may not work (I haven't tested it). - */ - -#ifndef PNG_MAX_GAMMA_8 -# define PNG_MAX_GAMMA_8 11 +#ifndef PNG_FP_EXPORT /* A floating point API. */ +# ifdef PNG_FLOATING_POINT_SUPPORTED +# define PNG_FP_EXPORT(ordinal, type, name, args)\ + PNG_EXPORT(ordinal, type, name, args) +# else /* No floating point APIs */ +# define PNG_FP_EXPORT(ordinal, type, name, args) +# endif #endif - -/* This controls how much a difference in gamma we can tolerate before - * we actually start doing gamma conversion. - */ -#ifndef PNG_GAMMA_THRESHOLD -# define PNG_GAMMA_THRESHOLD 0.05 +#ifndef PNG_FIXED_EXPORT /* A fixed point API. */ +# ifdef PNG_FIXED_POINT_SUPPORTED +# define PNG_FIXED_EXPORT(ordinal, type, name, args)\ + PNG_EXPORT(ordinal, type, name, args) +# else /* No fixed point APIs */ +# define PNG_FIXED_EXPORT(ordinal, type, name, args) +# endif #endif /* The following uses const char * instead of char * for error * and warning message functions, so some compilers won't complain. - * If you do not want to use const, define PNG_NO_CONST. + * If you do not want to use const, define PNG_NO_CONST here. + * + * This should not change how the APIs are called, so it can be done + * on a per-file basis in the application. */ - #ifndef PNG_CONST # ifndef PNG_NO_CONST # define PNG_CONST const @@ -458,648 +465,6 @@ # endif #endif -/* The following defines give you the ability to remove code from the - * library that you will not be using. I wish I could figure out how to - * automate this, but I can't do that without making it seriously hard - * on the users. So if you are not using an ability, change the #define - * to an #undef, or pass in PNG_NO_feature and that part of the library - * will not be compiled. - - * If your linker can't find a function, you may want to make sure the - * ability is defined here. Some of these depend upon some others being - * defined. I haven't figured out all the interactions here, so you may - * have to experiment awhile to get everything to compile. If you are - * creating or using a shared library, you probably shouldn't touch this, - * as it will affect the size of the structures, and this will cause bad - * things to happen if the library and/or application ever change. - */ - -/* Any features you will not be using can be undef'ed here */ - -/* GR-P, 0.96a: Set "*TRANSFORMS_SUPPORTED as default but allow user - * to turn it off with PNG_NO_READ|WRITE_TRANSFORMS on the compile line, - * then pick and choose which ones to define without having to edit this - * file. It is safe to use the PNG_NO_READ|WRITE_TRANSFORMS - * if you only want to have a png-compliant reader/writer but don't need - * any of the extra transformations. This saves about 80 kbytes in a - * typical installation of the library. (PNG_NO_* form added in version - * 1.0.1c, for consistency; PNG_*_TRANSFORMS_NOT_SUPPORTED deprecated in - * 1.4.0) - */ - -/* Ignore attempt to turn off both floating and fixed point support */ -#if !defined(PNG_FLOATING_POINT_SUPPORTED) || \ - !defined(PNG_NO_FIXED_POINT_SUPPORTED) -# define PNG_FIXED_POINT_SUPPORTED -#endif - -#ifdef PNG_READ_SUPPORTED - -/* PNG_READ_TRANSFORMS_NOT_SUPPORTED is deprecated. */ -#if !defined(PNG_READ_TRANSFORMS_NOT_SUPPORTED) && \ - !defined(PNG_NO_READ_TRANSFORMS) -# define PNG_READ_TRANSFORMS_SUPPORTED -#endif - -#ifdef PNG_READ_TRANSFORMS_SUPPORTED -# ifndef PNG_NO_READ_EXPAND -# define PNG_READ_EXPAND_SUPPORTED -# endif -# ifndef PNG_NO_READ_SHIFT -# define PNG_READ_SHIFT_SUPPORTED -# endif -# ifndef PNG_NO_READ_PACK -# define PNG_READ_PACK_SUPPORTED -# endif -# ifndef PNG_NO_READ_BGR -# define PNG_READ_BGR_SUPPORTED -# endif -# ifndef PNG_NO_READ_SWAP -# define PNG_READ_SWAP_SUPPORTED -# endif -# ifndef PNG_NO_READ_PACKSWAP -# define PNG_READ_PACKSWAP_SUPPORTED -# endif -# ifndef PNG_NO_READ_INVERT -# define PNG_READ_INVERT_SUPPORTED -# endif -# ifndef PNG_NO_READ_QUANTIZE - /* Prior to libpng-1.4.0 this was PNG_READ_DITHER_SUPPORTED */ -# ifndef PNG_NO_READ_DITHER /* This migration aid will be removed */ -# define PNG_READ_QUANTIZE_SUPPORTED -# endif -# endif -# ifndef PNG_NO_READ_BACKGROUND -# define PNG_READ_BACKGROUND_SUPPORTED -# endif -# ifndef PNG_NO_READ_16_TO_8 -# define PNG_READ_16_TO_8_SUPPORTED -# endif -# ifndef PNG_NO_READ_FILLER -# define PNG_READ_FILLER_SUPPORTED -# endif -# ifndef PNG_NO_READ_GAMMA -# define PNG_READ_GAMMA_SUPPORTED -# endif -# ifndef PNG_NO_READ_GRAY_TO_RGB -# define PNG_READ_GRAY_TO_RGB_SUPPORTED -# endif -# ifndef PNG_NO_READ_SWAP_ALPHA -# define PNG_READ_SWAP_ALPHA_SUPPORTED -# endif -# ifndef PNG_NO_READ_INVERT_ALPHA -# define PNG_READ_INVERT_ALPHA_SUPPORTED -# endif -# ifndef PNG_NO_READ_STRIP_ALPHA -# define PNG_READ_STRIP_ALPHA_SUPPORTED -# endif -# ifndef PNG_NO_READ_USER_TRANSFORM -# define PNG_READ_USER_TRANSFORM_SUPPORTED -# endif -# ifndef PNG_NO_READ_RGB_TO_GRAY -# define PNG_READ_RGB_TO_GRAY_SUPPORTED -# endif -#endif /* PNG_READ_TRANSFORMS_SUPPORTED */ - -/* PNG_PROGRESSIVE_READ_NOT_SUPPORTED is deprecated. */ -#if !defined(PNG_NO_PROGRESSIVE_READ) && \ - !defined(PNG_PROGRESSIVE_READ_NOT_SUPPORTED) /* if you don't do progressive */ -# define PNG_PROGRESSIVE_READ_SUPPORTED /* reading. This is not talking */ -#endif /* about interlacing capability! You'll */ - /* still have interlacing unless you change the following define: */ - -#define PNG_READ_INTERLACING_SUPPORTED /* required for PNG-compliant decoders */ - -/* PNG_NO_SEQUENTIAL_READ_SUPPORTED is deprecated. */ -#if !defined(PNG_NO_SEQUENTIAL_READ) && \ - !defined(PNG_SEQUENTIAL_READ_SUPPORTED) && \ - !defined(PNG_NO_SEQUENTIAL_READ_SUPPORTED) -# define PNG_SEQUENTIAL_READ_SUPPORTED -#endif - -#ifndef PNG_NO_READ_COMPOSITE_NODIV -# ifndef PNG_NO_READ_COMPOSITED_NODIV /* libpng-1.0.x misspelling */ -# define PNG_READ_COMPOSITE_NODIV_SUPPORTED /* well tested on Intel, SGI */ -# endif -#endif - -#if !defined(PNG_NO_GET_INT_32) || defined(PNG_READ_oFFS_SUPPORTED) || \ - defined(PNG_READ_pCAL_SUPPORTED) -# ifndef PNG_GET_INT_32_SUPPORTED -# define PNG_GET_INT_32_SUPPORTED -# endif -#endif - -#endif /* PNG_READ_SUPPORTED */ - -#ifdef PNG_WRITE_SUPPORTED - -/* PNG_WRITE_TRANSFORMS_NOT_SUPPORTED is deprecated. */ -#if !defined(PNG_WRITE_TRANSFORMS_NOT_SUPPORTED) && \ - !defined(PNG_NO_WRITE_TRANSFORMS) -# define PNG_WRITE_TRANSFORMS_SUPPORTED -#endif - -#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED -# ifndef PNG_NO_WRITE_SHIFT -# define PNG_WRITE_SHIFT_SUPPORTED -# endif -# ifndef PNG_NO_WRITE_PACK -# define PNG_WRITE_PACK_SUPPORTED -# endif -# ifndef PNG_NO_WRITE_BGR -# define PNG_WRITE_BGR_SUPPORTED -# endif -# ifndef PNG_NO_WRITE_SWAP -# define PNG_WRITE_SWAP_SUPPORTED -# endif -# ifndef PNG_NO_WRITE_PACKSWAP -# define PNG_WRITE_PACKSWAP_SUPPORTED -# endif -# ifndef PNG_NO_WRITE_INVERT -# define PNG_WRITE_INVERT_SUPPORTED -# endif -# ifndef PNG_NO_WRITE_FILLER -# define PNG_WRITE_FILLER_SUPPORTED /* same as WRITE_STRIP_ALPHA */ -# endif -# ifndef PNG_NO_WRITE_SWAP_ALPHA -# define PNG_WRITE_SWAP_ALPHA_SUPPORTED -# endif -# ifndef PNG_NO_WRITE_INVERT_ALPHA -# define PNG_WRITE_INVERT_ALPHA_SUPPORTED -# endif -# ifndef PNG_NO_WRITE_USER_TRANSFORM -# define PNG_WRITE_USER_TRANSFORM_SUPPORTED -# endif -#endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */ - -#if !defined(PNG_NO_WRITE_INTERLACING_SUPPORTED) && \ - !defined(PNG_WRITE_INTERLACING_SUPPORTED) - /* This is not required for PNG-compliant encoders, but can cause - * trouble if left undefined - */ -# define PNG_WRITE_INTERLACING_SUPPORTED -#endif - -#if !defined(PNG_NO_WRITE_WEIGHTED_FILTER) && \ - !defined(PNG_WRITE_WEIGHTED_FILTER) && \ - defined(PNG_FLOATING_POINT_SUPPORTED) -# define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED -#endif - -#ifndef PNG_NO_WRITE_FLUSH -# define PNG_WRITE_FLUSH_SUPPORTED -#endif - -#if !defined(PNG_NO_SAVE_INT_32) || defined(PNG_WRITE_oFFS_SUPPORTED) || \ - defined(PNG_WRITE_pCAL_SUPPORTED) -# ifndef PNG_SAVE_INT_32_SUPPORTED -# define PNG_SAVE_INT_32_SUPPORTED -# endif -#endif - -#endif /* PNG_WRITE_SUPPORTED */ - -#define PNG_NO_ERROR_NUMBERS - -#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ - defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) -# ifndef PNG_NO_USER_TRANSFORM_PTR -# define PNG_USER_TRANSFORM_PTR_SUPPORTED -# endif -#endif - -#if defined(PNG_STDIO_SUPPORTED) && !defined(PNG_TIME_RFC1123_SUPPORTED) -# define PNG_TIME_RFC1123_SUPPORTED -#endif - -/* This adds extra functions in pngget.c for accessing data from the - * info pointer (added in version 0.99) - * png_get_image_width() - * png_get_image_height() - * png_get_bit_depth() - * png_get_color_type() - * png_get_compression_type() - * png_get_filter_type() - * png_get_interlace_type() - * png_get_pixel_aspect_ratio() - * png_get_pixels_per_meter() - * png_get_x_offset_pixels() - * png_get_y_offset_pixels() - * png_get_x_offset_microns() - * png_get_y_offset_microns() - */ -#if !defined(PNG_NO_EASY_ACCESS) && !defined(PNG_EASY_ACCESS_SUPPORTED) -# define PNG_EASY_ACCESS_SUPPORTED -#endif - -/* Added at libpng-1.2.0 */ -#if !defined(PNG_NO_USER_MEM) && !defined(PNG_USER_MEM_SUPPORTED) -# define PNG_USER_MEM_SUPPORTED -#endif - -/* Added at libpng-1.2.6 */ -#ifndef PNG_NO_SET_USER_LIMITS -# ifndef PNG_SET_USER_LIMITS_SUPPORTED -# define PNG_SET_USER_LIMITS_SUPPORTED -# endif - /* Feature added at libpng-1.4.0, this flag added at 1.4.1 */ -# ifndef PNG_SET_CHUNK_CACHE_LIMIT_SUPPORTED -# define PNG_SET_CHUNK_CACHE_LIMIT_SUPPORTED -# endif - /* Feature added at libpng-1.4.1, this flag added at 1.4.1 */ -# ifndef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED -# define PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED -# endif -#endif - -/* Added at libpng-1.2.43 */ -#ifndef PNG_USER_LIMITS_SUPPORTED -# ifndef PNG_NO_USER_LIMITS -# define PNG_USER_LIMITS_SUPPORTED -# endif -#endif - -/* Added at libpng-1.0.16 and 1.2.6. To accept all valid PNGs no matter - * how large, set these two limits to 0x7fffffffL - */ -#ifndef PNG_USER_WIDTH_MAX -# define PNG_USER_WIDTH_MAX 1000000L -#endif -#ifndef PNG_USER_HEIGHT_MAX -# define PNG_USER_HEIGHT_MAX 1000000L -#endif - -/* Added at libpng-1.2.43. To accept all valid PNGs no matter - * how large, set these two limits to 0. - */ -#ifndef PNG_USER_CHUNK_CACHE_MAX -# define PNG_USER_CHUNK_CACHE_MAX 0 -#endif - -/* Added at libpng-1.2.43 */ -#ifndef PNG_USER_CHUNK_MALLOC_MAX -# define PNG_USER_CHUNK_MALLOC_MAX 0 -#endif - -/* Added at libpng-1.4.0 */ -#if !defined(PNG_NO_IO_STATE) && !defined(PNG_IO_STATE_SUPPORTED) -# define PNG_IO_STATE_SUPPORTED -#endif - -#ifndef PNG_LITERAL_SHARP -# define PNG_LITERAL_SHARP 0x23 -#endif -#ifndef PNG_LITERAL_LEFT_SQUARE_BRACKET -# define PNG_LITERAL_LEFT_SQUARE_BRACKET 0x5b -#endif -#ifndef PNG_LITERAL_RIGHT_SQUARE_BRACKET -# define PNG_LITERAL_RIGHT_SQUARE_BRACKET 0x5d -#endif -#ifndef PNG_STRING_NEWLINE -#define PNG_STRING_NEWLINE "\n" -#endif - -/* These are currently experimental features, define them if you want */ - -/* Very little testing */ -/* -#ifdef PNG_READ_SUPPORTED -# ifndef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED -# define PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED -# endif -#endif -*/ - -/* This is only for PowerPC big-endian and 680x0 systems */ -/* some testing */ -/* -#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED -# define PNG_READ_BIG_ENDIAN_SUPPORTED -#endif -*/ - -#if !defined(PNG_NO_USE_READ_MACROS) && !defined(PNG_USE_READ_MACROS) -# define PNG_USE_READ_MACROS -#endif - -/* Buggy compilers (e.g., gcc 2.7.2.2) need PNG_NO_POINTER_INDEXING */ - -#if !defined(PNG_NO_POINTER_INDEXING) && \ - !defined(PNG_POINTER_INDEXING_SUPPORTED) -# define PNG_POINTER_INDEXING_SUPPORTED -#endif - - -/* Any chunks you are not interested in, you can undef here. The - * ones that allocate memory may be expecially important (hIST, - * tEXt, zTXt, tRNS, pCAL). Others will just save time and make png_info - * a bit smaller. - */ - -/* The size of the png_text structure changed in libpng-1.0.6 when - * iTXt support was added. iTXt support was turned off by default through - * libpng-1.2.x, to support old apps that malloc the png_text structure - * instead of calling png_set_text() and letting libpng malloc it. It - * was turned on by default in libpng-1.4.0. - */ - -/* PNG_READ_ANCILLARY_CHUNKS_NOT_SUPPORTED is deprecated. */ -#if defined(PNG_READ_SUPPORTED) && \ - !defined(PNG_READ_ANCILLARY_CHUNKS_NOT_SUPPORTED) && \ - !defined(PNG_NO_READ_ANCILLARY_CHUNKS) -# define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED -#endif - -/* PNG_WRITE_ANCILLARY_CHUNKS_NOT_SUPPORTED is deprecated. */ -#if defined(PNG_WRITE_SUPPORTED) && \ - !defined(PNG_WRITE_ANCILLARY_CHUNKS_NOT_SUPPORTED) && \ - !defined(PNG_NO_WRITE_ANCILLARY_CHUNKS) -# define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED -#endif - -#ifdef PNG_READ_ANCILLARY_CHUNKS_SUPPORTED - -#ifdef PNG_NO_READ_TEXT -# define PNG_NO_READ_iTXt -# define PNG_NO_READ_tEXt -# define PNG_NO_READ_zTXt -#endif - -#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 -# ifndef PNG_READ_iTXt_SUPPORTED -# define PNG_READ_iTXt_SUPPORTED -# endif -# ifndef PNG_iTXt_SUPPORTED -# define PNG_iTXt_SUPPORTED -# endif -#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 */ -#endif /* optional 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 */ - -#ifndef PNG_NO_READ_UNKNOWN_CHUNKS -# ifndef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED -# define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED -# endif -# ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED -# define PNG_UNKNOWN_CHUNKS_SUPPORTED -# endif -# ifndef PNG_READ_USER_CHUNKS_SUPPORTED -# define PNG_READ_USER_CHUNKS_SUPPORTED -# endif -#endif -#ifndef PNG_NO_READ_USER_CHUNKS -# ifndef PNG_READ_USER_CHUNKS_SUPPORTED -# define PNG_READ_USER_CHUNKS_SUPPORTED -# endif -# ifndef PNG_USER_CHUNKS_SUPPORTED -# define PNG_USER_CHUNKS_SUPPORTED -# endif -#endif -#ifndef PNG_NO_HANDLE_AS_UNKNOWN -# ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -# define PNG_HANDLE_AS_UNKNOWN_SUPPORTED -# endif -#endif - -#ifdef PNG_WRITE_SUPPORTED -#ifdef PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED - -#ifdef PNG_NO_WRITE_TEXT -# define PNG_NO_WRITE_iTXt -# define PNG_NO_WRITE_tEXt -# define PNG_NO_WRITE_zTXt -#endif -#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 -# ifndef PNG_WRITE_iTXt_SUPPORTED -# define PNG_WRITE_iTXt_SUPPORTED -# endif -# 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 - -#ifdef PNG_WRITE_tIME_SUPPORTED -# ifndef PNG_NO_CONVERT_tIME -# ifndef _WIN32_WCE -/* The "tm" structure is not supported on WindowsCE */ -# ifndef PNG_CONVERT_tIME_SUPPORTED -# define PNG_CONVERT_tIME_SUPPORTED -# endif -# endif -# endif -#endif - -#endif /* PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED */ - -#ifndef PNG_NO_WRITE_FILTER -# ifndef PNG_WRITE_FILTER_SUPPORTED -# define PNG_WRITE_FILTER_SUPPORTED -# endif -#endif - -#ifndef PNG_NO_WRITE_UNKNOWN_CHUNKS -# define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED -# ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED -# define PNG_UNKNOWN_CHUNKS_SUPPORTED -# endif -#endif -#ifndef PNG_NO_HANDLE_AS_UNKNOWN -# ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -# define PNG_HANDLE_AS_UNKNOWN_SUPPORTED -# endif -#endif -#endif /* PNG_WRITE_SUPPORTED */ - -/* Turn this off to disable png_read_png() and - * png_write_png() and leave the row_pointers member - * out of the info structure. - */ -#ifndef PNG_NO_INFO_IMAGE -# define PNG_INFO_IMAGE_SUPPORTED -#endif - -/* Need the time information for converting tIME chunks */ -#ifdef PNG_CONVERT_tIME_SUPPORTED - /* "time.h" functions are not supported on WindowsCE */ -# include -#endif - /* Some typedefs to get us started. These should be safe on most of the * common platforms. The typedefs should be at least as large as the * numbers suggest (a png_uint_32 must be at least 32 bits long), but they @@ -1120,9 +485,9 @@ typedef short png_int_16; typedef unsigned char png_byte; #ifdef PNG_NO_SIZE_T - typedef unsigned int png_size_t; +typedef unsigned int png_size_t; #else - typedef size_t png_size_t; +typedef size_t png_size_t; #endif #define png_sizeof(x) (sizeof (x)) @@ -1144,20 +509,20 @@ typedef unsigned char png_byte; # else # define LDATA 0 # endif - /* GRR: why is Cygwin in here? Cygwin is not Borland C... */ + /* GRR: why is Cygwin in here? Cygwin is not Borland C... */ # if !defined(__WIN32__) && !defined(__FLAT__) && !defined(__CYGWIN__) -# define PNG_MAX_MALLOC_64K +# define PNG_MAX_MALLOC_64K /* only used in build */ # if (LDATA != 1) # ifndef FAR # define FAR __far # endif # define USE_FAR_KEYWORD # endif /* LDATA != 1 */ - /* Possibly useful for moving data out of default segment. - * Uncomment it if you want. Could also define FARDATA as - * const if your compiler supports it. (SJT) -# define FARDATA FAR - */ + /* Possibly useful for moving data out of default segment. + * Uncomment it if you want. Could also define FARDATA as + * const if your compiler supports it. (SJT) +# define FARDATA FAR + */ # endif /* __WIN32__, __FLAT__, __CYGWIN__ */ #endif /* __BORLANDC__ */ @@ -1187,26 +552,37 @@ typedef unsigned char png_byte; #endif /* Typedef for floating-point numbers that are converted - to fixed-point with a multiple of 100,000, e.g., int_gamma */ + * to fixed-point with a multiple of 100,000, e.g., gamma + */ typedef png_int_32 png_fixed_point; /* Add typedefs for pointers */ -typedef void FAR * png_voidp; -typedef png_byte FAR * png_bytep; -typedef png_uint_32 FAR * png_uint_32p; -typedef png_int_32 FAR * png_int_32p; -typedef png_uint_16 FAR * png_uint_16p; -typedef png_int_16 FAR * png_int_16p; -typedef PNG_CONST char FAR * png_const_charp; -typedef char FAR * png_charp; -typedef png_fixed_point FAR * png_fixed_point_p; +typedef void FAR * png_voidp; +typedef PNG_CONST void FAR * png_const_voidp; +typedef png_byte FAR * png_bytep; +typedef PNG_CONST png_byte FAR * png_const_bytep; +typedef png_uint_32 FAR * png_uint_32p; +typedef PNG_CONST png_uint_32 FAR * png_const_uint_32p; +typedef png_int_32 FAR * png_int_32p; +typedef PNG_CONST png_int_32 FAR * png_const_int_32p; +typedef png_uint_16 FAR * png_uint_16p; +typedef PNG_CONST png_uint_16 FAR * png_const_uint_16p; +typedef png_int_16 FAR * png_int_16p; +typedef PNG_CONST png_int_16 FAR * png_const_int_16p; +typedef char FAR * png_charp; +typedef PNG_CONST char FAR * png_const_charp; +typedef png_fixed_point FAR * png_fixed_point_p; +typedef PNG_CONST png_fixed_point FAR * png_const_fixed_point_p; +typedef png_size_t FAR * png_size_tp; +typedef PNG_CONST png_size_t FAR * png_const_size_tp; -#ifndef PNG_NO_STDIO -typedef FILE * png_FILE_p; +#ifdef PNG_STDIO_SUPPORTED +typedef FILE * png_FILE_p; #endif #ifdef PNG_FLOATING_POINT_SUPPORTED -typedef double FAR * png_doublep; +typedef double FAR * png_doublep; +typedef PNG_CONST double FAR * png_const_doublep; #endif /* Pointers to pointers; i.e. arrays */ @@ -1225,277 +601,6 @@ typedef double FAR * FAR * png_doublepp; /* Pointers to pointers to pointers; i.e., pointer to array */ typedef char FAR * FAR * FAR * png_charppp; -/* Define PNG_BUILD_DLL if the module being built is a Windows - * LIBPNG DLL. - * - * Define PNG_USE_DLL if you want to *link* to the Windows LIBPNG DLL. - * It is equivalent to Microsoft predefined macro _DLL that is - * automatically defined when you compile using the share - * version of the CRT (C Run-Time library) - * - * The cygwin mods make this behavior a little different: - * Define PNG_BUILD_DLL if you are building a dll for use with cygwin - * Define PNG_STATIC if you are building a static library for use with cygwin, - * -or- if you are building an application that you want to link to the - * static library. - * PNG_USE_DLL is defined by default (no user action needed) unless one of - * the other flags is defined. - */ - -#if !defined(PNG_DLL) && (defined(PNG_BUILD_DLL) || defined(PNG_USE_DLL)) -# define PNG_DLL -#endif - -/* If you define PNGAPI, e.g., with compiler option "-DPNGAPI=__stdcall", - * you may get warnings regarding the linkage of png_zalloc and png_zfree. - * Don't ignore those warnings; you must also reset the default calling - * convention in your compiler to match your PNGAPI, and you must build - * zlib and your applications the same way you build libpng. - */ - -#ifdef __CYGWIN__ -# undef PNGAPI -# define PNGAPI __cdecl -# undef PNG_IMPEXP -# define PNG_IMPEXP -#endif - -#ifdef __WATCOMC__ -# ifndef PNGAPI -# define PNGAPI -# endif -#endif - -#if defined(__MINGW32__) && !defined(PNG_MODULEDEF) -# ifndef PNG_NO_MODULEDEF -# define PNG_NO_MODULEDEF -# endif -#endif - -#if !defined(PNG_IMPEXP) && defined(PNG_BUILD_DLL) && !defined(PNG_NO_MODULEDEF) -# define PNG_IMPEXP -#endif - -#if defined(PNG_DLL) || defined(_DLL) || defined(__DLL__ ) || \ - (( defined(_Windows) || defined(_WINDOWS) || \ - defined(WIN32) || defined(_WIN32) || defined(__WIN32__) )) - -# ifndef PNGAPI -# if defined(__GNUC__) || (defined (_MSC_VER) && (_MSC_VER >= 800)) -# define PNGAPI __cdecl -# else -# define PNGAPI _cdecl -# endif -# endif - -# if !defined(PNG_IMPEXP) && (!defined(PNG_DLL) || \ - 0 /* WINCOMPILER_WITH_NO_SUPPORT_FOR_DECLIMPEXP */) -# define PNG_IMPEXP -# endif - -# ifndef PNG_IMPEXP - -# define PNG_EXPORT_TYPE1(type,symbol) PNG_IMPEXP type PNGAPI symbol -# define PNG_EXPORT_TYPE2(type,symbol) type PNG_IMPEXP PNGAPI symbol - - /* Borland/Microsoft */ -# if defined(_MSC_VER) || defined(__BORLANDC__) -# if (_MSC_VER >= 800) || (__BORLANDC__ >= 0x500) -# define PNG_EXPORT PNG_EXPORT_TYPE1 -# else -# define PNG_EXPORT PNG_EXPORT_TYPE2 -# ifdef PNG_BUILD_DLL -# define PNG_IMPEXP __export -# else -# define PNG_IMPEXP /*__import */ /* doesn't exist AFAIK in VC++ */ -# endif /* Exists in Borland C++ for - C++ classes (== huge) */ -# endif -# endif - -# ifndef PNG_IMPEXP -# ifdef PNG_BUILD_DLL -# define PNG_IMPEXP __declspec(dllexport) -# else -# define PNG_IMPEXP __declspec(dllimport) -# endif -# endif -# endif /* PNG_IMPEXP */ -#else /* !(DLL || non-cygwin WINDOWS) */ -# if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__) -# ifndef PNGAPI -# define PNGAPI _System -# endif -# else -# if 0 /* ... other platforms, with other meanings */ -# endif -# endif -#endif - -#ifndef PNGAPI -# define PNGAPI -#endif -#ifndef PNG_IMPEXP -# define PNG_IMPEXP -#endif - -#ifdef PNG_BUILDSYMS -# ifndef PNG_EXPORT -# define PNG_EXPORT(type,symbol) PNG_FUNCTION_EXPORT symbol END -# endif -#endif - -#ifndef PNG_EXPORT -# define PNG_EXPORT(type,symbol) PNG_IMPEXP type PNGAPI symbol -#endif - -#define PNG_USE_LOCAL_ARRAYS /* Not used in libpng, defined for legacy apps */ - -/* Support for compiler specific function attributes. These are used - * so that where compiler support is available incorrect use of API - * functions in png.h will generate compiler warnings. - * - * Added at libpng-1.2.41. - */ - -#ifndef PNG_NO_PEDANTIC_WARNINGS -# ifndef PNG_PEDANTIC_WARNINGS_SUPPORTED -# define PNG_PEDANTIC_WARNINGS_SUPPORTED -# endif -#endif - -#ifdef PNG_PEDANTIC_WARNINGS_SUPPORTED -/* Support for compiler specific function attributes. These are used - * so that where compiler support is available incorrect use of API - * functions in png.h will generate compiler warnings. Added at libpng - * version 1.2.41. - */ -# ifdef __GNUC__ -# ifndef PNG_USE_RESULT -# define PNG_USE_RESULT __attribute__((__warn_unused_result__)) -# endif -# ifndef PNG_NORETURN -# define PNG_NORETURN __attribute__((__noreturn__)) -# endif -# ifndef PNG_ALLOCATED -# define PNG_ALLOCATED __attribute__((__malloc__)) -# endif - - /* This specifically protects structure members that should only be - * accessed from within the library, therefore should be empty during - * a library build. - */ -# ifndef PNG_DEPRECATED -# define PNG_DEPRECATED __attribute__((__deprecated__)) -# endif -# ifndef PNG_DEPSTRUCT -# define PNG_DEPSTRUCT __attribute__((__deprecated__)) -# endif -# ifndef PNG_PRIVATE -# if 0 /* Doesn't work so we use deprecated instead*/ -# define PNG_PRIVATE \ - __attribute__((warning("This function is not exported by libpng."))) -# else -# define PNG_PRIVATE \ - __attribute__((__deprecated__)) -# endif -# endif /* PNG_PRIVATE */ -# endif /* __GNUC__ */ -#endif /* PNG_PEDANTIC_WARNINGS */ - -#ifndef PNG_DEPRECATED -# define PNG_DEPRECATED /* Use of this function is deprecated */ -#endif -#ifndef PNG_USE_RESULT -# define PNG_USE_RESULT /* The result of this function must be checked */ -#endif -#ifndef PNG_NORETURN -# define PNG_NORETURN /* This function does not return */ -#endif -#ifndef PNG_ALLOCATED -# define PNG_ALLOCATED /* The result of the function is new memory */ -#endif -#ifndef PNG_DEPSTRUCT -# define PNG_DEPSTRUCT /* Access to this struct member is deprecated */ -#endif -#ifndef PNG_PRIVATE -# define PNG_PRIVATE /* This is a private libpng function */ -#endif - -/* Users may want to use these so they are not private. Any library - * functions that are passed far data must be model-independent. - */ - -/* memory model/platform independent fns */ -#ifndef PNG_ABORT -# if (defined(_Windows) || defined(_WINDOWS) || defined(_WINDOWS_)) -# define PNG_ABORT() ExitProcess(0) -# else -# define PNG_ABORT() abort() -# endif -#endif - -#ifdef USE_FAR_KEYWORD -/* Use this to make far-to-near assignments */ -# define CHECK 1 -# define NOCHECK 0 -# define CVT_PTR(ptr) (png_far_to_near(png_ptr,ptr,CHECK)) -# define CVT_PTR_NOCHECK(ptr) (png_far_to_near(png_ptr,ptr,NOCHECK)) -# define png_strcpy _fstrcpy -# define png_strncpy _fstrncpy /* Added to v 1.2.6 */ -# define png_strlen _fstrlen -# define png_memcmp _fmemcmp /* SJT: added */ -# define png_memcpy _fmemcpy -# define png_memset _fmemset -# define png_sprintf sprintf -#else -# if (defined(_Windows) || defined(_WINDOWS) || defined(_WINDOWS_)) -# /* Favor Windows over C runtime fns */ -# define CVT_PTR(ptr) (ptr) -# define CVT_PTR_NOCHECK(ptr) (ptr) -# define png_strcpy lstrcpyA -# define png_strncpy lstrcpynA -# define png_strlen lstrlenA -# define png_memcmp memcmp -# define png_memcpy CopyMemory -# define png_memset memset -# define png_sprintf wsprintfA -# else -# define CVT_PTR(ptr) (ptr) -# define CVT_PTR_NOCHECK(ptr) (ptr) -# define png_strcpy strcpy -# define png_strncpy strncpy /* Added to v 1.2.6 */ -# define png_strlen strlen -# define png_memcmp memcmp /* SJT: added */ -# define png_memcpy memcpy -# define png_memset memset -# define png_sprintf sprintf -# endif -#endif - -#ifndef PNG_NO_SNPRINTF -# ifdef _MSC_VER -# define png_snprintf _snprintf /* Added to v 1.2.19 */ -# define png_snprintf2 _snprintf -# define png_snprintf6 _snprintf -# else -# define png_snprintf snprintf /* Added to v 1.2.19 */ -# define png_snprintf2 snprintf -# define png_snprintf6 snprintf -# endif -#else - /* You don't have or don't want to use snprintf(). Caution: Using - * sprintf instead of snprintf exposes your application to accidental - * or malevolent buffer overflows. If you don't have snprintf() - * as a general rule you should provide one (you can get one from - * Portable OpenSSH). - */ -# define png_snprintf(s1,n,fmt,x1) png_sprintf(s1,fmt,x1) -# define png_snprintf2(s1,n,fmt,x1,x2) png_sprintf(s1,fmt,x1,x2) -# define png_snprintf6(s1,n,fmt,x1,x2,x3,x4,x5,x6) \ - png_sprintf(s1,fmt,x1,x2,x3,x4,x5,x6) -#endif - /* png_alloc_size_t is guaranteed to be no smaller than png_size_t, * and no smaller than png_uint_32. Casts from png_size_t or png_uint_32 * to png_alloc_size_t are not necessary; in fact, it is recommended @@ -1523,18 +628,5 @@ typedef char FAR * FAR * FAR * png_charppp; # endif # endif #endif -/* End of memory model/platform independent support */ - -/* Just a little check that someone hasn't tried to define something - * contradictory. - */ -#if (PNG_ZBUF_SIZE > 65536L) && defined(PNG_MAX_MALLOC_64K) -# undef PNG_ZBUF_SIZE -# define PNG_ZBUF_SIZE 65536L -#endif - - -/* Added at libpng-1.2.8 */ -#endif /* PNG_VERSION_INFO_ONLY */ #endif /* PNGCONF_H */ diff --git a/harbour/src/3rd/png/pngerror.c b/harbour/src/3rd/png/pngerror.c index 633eae29f9..f209f46592 100644 --- a/harbour/src/3rd/png/pngerror.c +++ b/harbour/src/3rd/png/pngerror.c @@ -1,8 +1,8 @@ /* pngerror.c - stub functions for i/o and memory allocation * - * Last changed in libpng 1.4.0 [January 3, 2010] - * Copyright (c) 1998-2010 Glenn Randers-Pehrson + * Last changed in libpng 1.5.0 [January 6, 2011] + * Copyright (c) 1998-2011 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -16,18 +16,17 @@ * at each function. */ -#define PNG_NO_PEDANTIC_WARNINGS -#include "png.h" -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) #include "pngpriv.h" -static void /* PRIVATE */ -png_default_error PNGARG((png_structp png_ptr, - png_const_charp error_message)) PNG_NORETURN; +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) + +static PNG_FUNCTION(void, png_default_error,PNGARG((png_structp png_ptr, + png_const_charp error_message)),PNG_NORETURN); + #ifdef PNG_WARNINGS_SUPPORTED static void /* PRIVATE */ png_default_warning PNGARG((png_structp png_ptr, - png_const_charp warning_message)); + png_const_charp warning_message)); #endif /* PNG_WARNINGS_SUPPORTED */ /* This function is called whenever there is a fatal error. This function @@ -36,42 +35,45 @@ png_default_warning PNGARG((png_structp png_ptr, * to replace the error function at run-time. */ #ifdef PNG_ERROR_TEXT_SUPPORTED -void PNGAPI -png_error(png_structp png_ptr, png_const_charp error_message) +PNG_FUNCTION(void,PNGAPI +png_error,(png_structp png_ptr, png_const_charp error_message),PNG_NORETURN) { #ifdef PNG_ERROR_NUMBERS_SUPPORTED char msg[16]; if (png_ptr != NULL) { - if (png_ptr->flags& - (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) - { - if (*error_message == PNG_LITERAL_SHARP) - { - /* Strip "#nnnn " from beginning of error message. */ - int offset; - for (offset = 1; offset<15; offset++) - if (error_message[offset] == ' ') + if (png_ptr->flags& + (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) + { + if (*error_message == PNG_LITERAL_SHARP) + { + /* Strip "#nnnn " from beginning of error message. */ + int offset; + for (offset = 1; offset<15; offset++) + if (error_message[offset] == ' ') break; - if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT) - { - int i; - for (i = 0; i < offset - 1; i++) - msg[i] = error_message[i + 1]; - msg[i - 1] = '\0'; - error_message = msg; - } - else - error_message += offset; - } - else - { - if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT) - { - msg[0] = '0'; - msg[1] = '\0'; - error_message = msg; - } + + if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT) + { + int i; + for (i = 0; i < offset - 1; i++) + msg[i] = error_message[i + 1]; + msg[i - 1] = '\0'; + error_message = msg; + } + + else + error_message += offset; + } + + else + { + if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT) + { + msg[0] = '0'; + msg[1] = '\0'; + error_message = msg; + } } } } @@ -84,8 +86,8 @@ png_error(png_structp png_ptr, png_const_charp error_message) png_default_error(png_ptr, error_message); } #else -void PNGAPI -png_err(png_structp png_ptr) +PNG_FUNCTION(void,PNGAPI +png_err,(png_structp png_ptr),PNG_NORETURN) { if (png_ptr != NULL && png_ptr->error_fn != NULL) (*(png_ptr->error_fn))(png_ptr, '\0'); @@ -110,16 +112,16 @@ png_warning(png_structp png_ptr, png_const_charp warning_message) { #ifdef PNG_ERROR_NUMBERS_SUPPORTED if (png_ptr->flags& - (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) + (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) #endif - { - if (*warning_message == PNG_LITERAL_SHARP) - { - for (offset = 1; offset < 15; offset++) - if (warning_message[offset] == ' ') + { + if (*warning_message == PNG_LITERAL_SHARP) + { + for (offset = 1; offset < 15; offset++) + if (warning_message[offset] == ' ') break; - } - } + } + } } if (png_ptr != NULL && png_ptr->warning_fn != NULL) (*(png_ptr->warning_fn))(png_ptr, warning_message + offset); @@ -133,9 +135,9 @@ void PNGAPI png_benign_error(png_structp png_ptr, png_const_charp error_message) { if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) - png_warning(png_ptr, error_message); + png_warning(png_ptr, error_message); else - png_error(png_ptr, error_message); + png_error(png_ptr, error_message); } #endif @@ -155,7 +157,7 @@ static PNG_CONST char png_digit[16] = { #if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_ERROR_TEXT_SUPPORTED) static void /* PRIVATE */ png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp - error_message) + error_message) { int iout = 0, iin = 0; @@ -169,6 +171,7 @@ png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp buffer[iout++] = png_digit[c & 0x0f]; buffer[iout++] = PNG_LITERAL_RIGHT_SQUARE_BRACKET; } + else { buffer[iout++] = (png_byte)c; @@ -177,6 +180,7 @@ png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp if (error_message == NULL) buffer[iout] = '\0'; + else { buffer[iout++] = ':'; @@ -185,22 +189,24 @@ png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp buffer[iout + PNG_MAX_ERROR_TEXT - 1] = '\0'; } } +#endif /* PNG_WARNINGS_SUPPORTED || PNG_ERROR_TEXT_SUPPORTED */ -#ifdef PNG_READ_SUPPORTED -void PNGAPI -png_chunk_error(png_structp png_ptr, png_const_charp error_message) +#if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED) +PNG_FUNCTION(void,PNGAPI +png_chunk_error,(png_structp png_ptr, png_const_charp error_message), + PNG_NORETURN) { char msg[18+PNG_MAX_ERROR_TEXT]; if (png_ptr == NULL) - png_error(png_ptr, error_message); + png_error(png_ptr, error_message); + else { - png_format_buffer(png_ptr, msg, error_message); - png_error(png_ptr, msg); + png_format_buffer(png_ptr, msg, error_message); + png_error(png_ptr, msg); } } -#endif /* PNG_READ_SUPPORTED */ -#endif /* PNG_WARNINGS_SUPPORTED || PNG_ERROR_TEXT_SUPPORTED */ +#endif /* PNG_READ_SUPPORTED && PNG_ERROR_TEXT_SUPPORTED */ #ifdef PNG_WARNINGS_SUPPORTED void PNGAPI @@ -208,11 +214,12 @@ png_chunk_warning(png_structp png_ptr, png_const_charp warning_message) { char msg[18+PNG_MAX_ERROR_TEXT]; if (png_ptr == NULL) - png_warning(png_ptr, warning_message); + png_warning(png_ptr, warning_message); + else { - png_format_buffer(png_ptr, msg, warning_message); - png_warning(png_ptr, msg); + png_format_buffer(png_ptr, msg, warning_message); + png_warning(png_ptr, msg); } } #endif /* PNG_WARNINGS_SUPPORTED */ @@ -222,14 +229,37 @@ png_chunk_warning(png_structp png_ptr, png_const_charp warning_message) void PNGAPI png_chunk_benign_error(png_structp png_ptr, png_const_charp error_message) { - if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) - png_chunk_warning(png_ptr, error_message); - else - png_chunk_error(png_ptr, error_message); + if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) + png_chunk_warning(png_ptr, error_message); + + else + png_chunk_error(png_ptr, error_message); } #endif #endif /* PNG_READ_SUPPORTED */ +#ifdef PNG_ERROR_TEXT_SUPPORTED +#ifdef PNG_FLOATING_POINT_SUPPORTED +PNG_FUNCTION(void, +png_fixed_error,(png_structp png_ptr, png_const_charp name),PNG_NORETURN) +{ +# define fixed_message "fixed point overflow in " +# define fixed_message_ln ((sizeof fixed_message)-1) + int iin; + char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT]; + png_memcpy(msg, fixed_message, fixed_message_ln); + iin = 0; + if (name != NULL) while (iin < (PNG_MAX_ERROR_TEXT-1) && name[iin] != 0) + { + msg[fixed_message_ln + iin] = name[iin]; + ++iin; + } + msg[fixed_message_ln + iin] = 0; + png_error(png_ptr, msg); +} +#endif +#endif + #ifdef PNG_SETJMP_SUPPORTED /* This API only exists if ANSI-C style error handling is used, * otherwise it is necessary for png_default_error to be overridden. @@ -242,7 +272,7 @@ png_set_longjmp_fn(png_structp png_ptr, png_longjmp_ptr longjmp_fn, return NULL; png_ptr->longjmp_fn = longjmp_fn; - return &png_ptr->jmpbuf; + return &png_ptr->png_jmpbuf; } #endif @@ -251,35 +281,38 @@ png_set_longjmp_fn(png_structp png_ptr, png_longjmp_ptr longjmp_fn, * function is used by default, or if the program supplies NULL for the * error function pointer in png_set_error_fn(). */ -static void /* PRIVATE */ -png_default_error(png_structp png_ptr, png_const_charp error_message) +static PNG_FUNCTION(void /* PRIVATE */, +png_default_error,(png_structp png_ptr, png_const_charp error_message), + PNG_NORETURN) { #ifdef PNG_CONSOLE_IO_SUPPORTED #ifdef PNG_ERROR_NUMBERS_SUPPORTED if (*error_message == PNG_LITERAL_SHARP) { - /* Strip "#nnnn " from beginning of error message. */ - int offset; - char error_number[16]; - for (offset = 0; offset<15; offset++) - { + /* Strip "#nnnn " from beginning of error message. */ + int offset; + char error_number[16]; + for (offset = 0; offset<15; offset++) + { error_number[offset] = error_message[offset + 1]; if (error_message[offset] == ' ') - break; - } - if ((offset > 1) && (offset < 15)) - { - error_number[offset - 1] = '\0'; - fprintf(stderr, "libpng error no. %s: %s", - error_number, error_message + offset + 1); - fprintf(stderr, PNG_STRING_NEWLINE); - } - else - { - fprintf(stderr, "libpng error: %s, offset=%d", - error_message, offset); - fprintf(stderr, PNG_STRING_NEWLINE); - } + break; + } + + if ((offset > 1) && (offset < 15)) + { + error_number[offset - 1] = '\0'; + fprintf(stderr, "libpng error no. %s: %s", + error_number, error_message + offset + 1); + fprintf(stderr, PNG_STRING_NEWLINE); + } + + else + { + fprintf(stderr, "libpng error: %s, offset=%d", + error_message, offset); + fprintf(stderr, PNG_STRING_NEWLINE); + } } else #endif @@ -288,26 +321,32 @@ png_default_error(png_structp png_ptr, png_const_charp error_message) fprintf(stderr, PNG_STRING_NEWLINE); } #endif +#ifndef PNG_CONSOLE_IO_SUPPORTED + PNG_UNUSED(error_message) /* Make compiler happy */ +#endif + png_longjmp(png_ptr, 1); +} +PNG_FUNCTION(void,PNGAPI +png_longjmp,(png_structp png_ptr, int val),PNG_NORETURN) +{ #ifdef PNG_SETJMP_SUPPORTED if (png_ptr && png_ptr->longjmp_fn) { # ifdef USE_FAR_KEYWORD - { - jmp_buf jmpbuf; - png_memcpy(jmpbuf, png_ptr->jmpbuf, png_sizeof(jmp_buf)); - png_ptr->longjmp_fn(jmpbuf, 1); - } + { + jmp_buf png_jmpbuf; + png_memcpy(png_jmpbuf, png_ptr->png_jmpbuf, png_sizeof(jmp_buf)); + png_ptr->longjmp_fn(png_jmpbuf, val); + } + # else - png_ptr->longjmp_fn(png_ptr->jmpbuf, 1); + png_ptr->longjmp_fn(png_ptr->png_jmpbuf, val); # endif } #endif /* Here if not setjmp support or if png_ptr is null. */ PNG_ABORT(); -#ifndef PNG_CONSOLE_IO_SUPPORTED - error_message = error_message; /* Make compiler happy */ -#endif } #ifdef PNG_WARNINGS_SUPPORTED @@ -323,52 +362,56 @@ png_default_warning(png_structp png_ptr, png_const_charp warning_message) # ifdef PNG_ERROR_NUMBERS_SUPPORTED if (*warning_message == PNG_LITERAL_SHARP) { - int offset; - char warning_number[16]; - for (offset = 0; offset < 15; offset++) - { - warning_number[offset] = warning_message[offset + 1]; - if (warning_message[offset] == ' ') + int offset; + char warning_number[16]; + for (offset = 0; offset < 15; offset++) + { + warning_number[offset] = warning_message[offset + 1]; + if (warning_message[offset] == ' ') break; - } - if ((offset > 1) && (offset < 15)) - { - warning_number[offset + 1] = '\0'; - fprintf(stderr, "libpng warning no. %s: %s", - warning_number, warning_message + offset); - fprintf(stderr, PNG_STRING_NEWLINE); - } - else - { - fprintf(stderr, "libpng warning: %s", - warning_message); - fprintf(stderr, PNG_STRING_NEWLINE); - } + } + + if ((offset > 1) && (offset < 15)) + { + warning_number[offset + 1] = '\0'; + fprintf(stderr, "libpng warning no. %s: %s", + warning_number, warning_message + offset); + fprintf(stderr, PNG_STRING_NEWLINE); + } + + else + { + fprintf(stderr, "libpng warning: %s", + warning_message); + fprintf(stderr, PNG_STRING_NEWLINE); + } } else # endif + { - fprintf(stderr, "libpng warning: %s", warning_message); - fprintf(stderr, PNG_STRING_NEWLINE); + fprintf(stderr, "libpng warning: %s", warning_message); + fprintf(stderr, PNG_STRING_NEWLINE); } #else - warning_message = warning_message; /* Make compiler happy */ + PNG_UNUSED(warning_message) /* Make compiler happy */ #endif - png_ptr = png_ptr; /* Make compiler happy */ + PNG_UNUSED(png_ptr) /* Make compiler happy */ } #endif /* PNG_WARNINGS_SUPPORTED */ /* This function is called when the application wants to use another method * of handling errors and warnings. Note that the error function MUST NOT * return to the calling routine or serious problems will occur. The return - * method used in the default routine calls longjmp(png_ptr->jmpbuf, 1) + * method used in the default routine calls longjmp(png_ptr->png_jmpbuf, 1) */ void PNGAPI png_set_error_fn(png_structp png_ptr, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warning_fn) + png_error_ptr error_fn, png_error_ptr warning_fn) { if (png_ptr == NULL) return; + png_ptr->error_ptr = error_ptr; png_ptr->error_fn = error_fn; png_ptr->warning_fn = warning_fn; @@ -384,6 +427,7 @@ png_get_error_ptr(png_structp png_ptr) { if (png_ptr == NULL) return NULL; + return ((png_voidp)png_ptr->error_ptr); } @@ -394,8 +438,9 @@ png_set_strip_error_numbers(png_structp png_ptr, png_uint_32 strip_mode) { if (png_ptr != NULL) { - png_ptr->flags &= - ((~(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode); + png_ptr->flags &= + ((~(PNG_FLAG_STRIP_ERROR_NUMBERS | + PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode); } } #endif diff --git a/harbour/src/3rd/png/pngget.c b/harbour/src/3rd/png/pngget.c index 9b3a9ccee1..319ac6bc4d 100644 --- a/harbour/src/3rd/png/pngget.c +++ b/harbour/src/3rd/png/pngget.c @@ -1,8 +1,8 @@ /* pngget.c - retrieval of values from info struct * - * Last changed in libpng 1.4.2 [May 6, 2010] - * Copyright (c) 1998-2010 Glenn Randers-Pehrson + * Last changed in libpng 1.5.0 [January 6, 2011] + * Copyright (c) 1998-2011 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -12,19 +12,17 @@ * */ -#define PNG_NO_PEDANTIC_WARNINGS -#include "png.h" -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) #include "pngpriv.h" +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) + png_uint_32 PNGAPI png_get_valid(png_structp png_ptr, png_infop info_ptr, png_uint_32 flag) { if (png_ptr != NULL && info_ptr != NULL) return(info_ptr->valid & flag); - else - return(0); + return(0); } png_size_t PNGAPI @@ -33,8 +31,7 @@ png_get_rowbytes(png_structp png_ptr, png_infop info_ptr) if (png_ptr != NULL && info_ptr != NULL) return(info_ptr->rowbytes); - else - return(0); + return(0); } #ifdef PNG_INFO_IMAGE_SUPPORTED @@ -44,8 +41,7 @@ png_get_rows(png_structp png_ptr, png_infop info_ptr) if (png_ptr != NULL && info_ptr != NULL) return(info_ptr->row_pointers); - else - return(0); + return(0); } #endif @@ -117,220 +113,270 @@ png_get_compression_type(png_structp png_ptr, png_infop info_ptr) png_uint_32 PNGAPI png_get_x_pixels_per_meter(png_structp png_ptr, png_infop info_ptr) { - if (png_ptr != NULL && info_ptr != NULL) #ifdef PNG_pHYs_SUPPORTED - if (info_ptr->valid & PNG_INFO_pHYs) - { - png_debug1(1, "in %s retrieval function", "png_get_x_pixels_per_meter"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) + { + png_debug1(1, "in %s retrieval function", + "png_get_x_pixels_per_meter"); - if (info_ptr->phys_unit_type != PNG_RESOLUTION_METER) - return (0); - - else - return (info_ptr->x_pixels_per_unit); - } -#else - return (0); + if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER) + return (info_ptr->x_pixels_per_unit); + } #endif + return (0); } png_uint_32 PNGAPI png_get_y_pixels_per_meter(png_structp png_ptr, png_infop info_ptr) { - if (png_ptr != NULL && info_ptr != NULL) #ifdef PNG_pHYs_SUPPORTED - if (info_ptr->valid & PNG_INFO_pHYs) + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) { - png_debug1(1, "in %s retrieval function", "png_get_y_pixels_per_meter"); + png_debug1(1, "in %s retrieval function", + "png_get_y_pixels_per_meter"); - if (info_ptr->phys_unit_type != PNG_RESOLUTION_METER) - return (0); - - else - return (info_ptr->y_pixels_per_unit); + if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER) + return (info_ptr->y_pixels_per_unit); } -#else - return (0); #endif + return (0); } png_uint_32 PNGAPI png_get_pixels_per_meter(png_structp png_ptr, png_infop info_ptr) { - if (png_ptr != NULL && info_ptr != NULL) #ifdef PNG_pHYs_SUPPORTED - if (info_ptr->valid & PNG_INFO_pHYs) + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) { png_debug1(1, "in %s retrieval function", "png_get_pixels_per_meter"); - if (info_ptr->phys_unit_type != PNG_RESOLUTION_METER || - info_ptr->x_pixels_per_unit != info_ptr->y_pixels_per_unit) - return (0); - - else - return (info_ptr->x_pixels_per_unit); + if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER && + info_ptr->x_pixels_per_unit == info_ptr->y_pixels_per_unit) + return (info_ptr->x_pixels_per_unit); } -#else - return (0); #endif + return (0); } #ifdef PNG_FLOATING_POINT_SUPPORTED float PNGAPI png_get_pixel_aspect_ratio(png_structp png_ptr, png_infop info_ptr) - { - if (png_ptr != NULL && info_ptr != NULL) -#ifdef PNG_pHYs_SUPPORTED - - if (info_ptr->valid & PNG_INFO_pHYs) +{ +#ifdef PNG_READ_pHYs_SUPPORTED + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) { png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio"); - if (info_ptr->x_pixels_per_unit == 0) - return ((float)0.0); - - else + if (info_ptr->x_pixels_per_unit != 0) return ((float)((float)info_ptr->y_pixels_per_unit - /(float)info_ptr->x_pixels_per_unit)); + /(float)info_ptr->x_pixels_per_unit)); } -#else - return (0.0); #endif + return ((float)0.0); } #endif +#ifdef PNG_FIXED_POINT_SUPPORTED +png_fixed_point PNGAPI +png_get_pixel_aspect_ratio_fixed(png_structp png_ptr, png_infop info_ptr) +{ +#ifdef PNG_READ_pHYs_SUPPORTED + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs) + && info_ptr->x_pixels_per_unit > 0 && info_ptr->y_pixels_per_unit > 0 + && info_ptr->x_pixels_per_unit <= PNG_UINT_31_MAX + && info_ptr->y_pixels_per_unit <= PNG_UINT_31_MAX) + { + png_fixed_point res; + + png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio_fixed"); + + /* The following casts work because a PNG 4 byte integer only has a valid + * range of 0..2^31-1; otherwise the cast might overflow. + */ + if (png_muldiv(&res, (png_int_32)info_ptr->y_pixels_per_unit, PNG_FP_1, + (png_int_32)info_ptr->x_pixels_per_unit)) + return res; + } +#endif + + return 0; +} +#endif + png_int_32 PNGAPI png_get_x_offset_microns(png_structp png_ptr, png_infop info_ptr) { - if (png_ptr != NULL && info_ptr != NULL) #ifdef PNG_oFFs_SUPPORTED - - if (info_ptr->valid & PNG_INFO_oFFs) + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) { png_debug1(1, "in %s retrieval function", "png_get_x_offset_microns"); - if (info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER) - return (0); - - else - return (info_ptr->x_offset); + if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER) + return (info_ptr->x_offset); } -#else - return (0); #endif + return (0); } png_int_32 PNGAPI png_get_y_offset_microns(png_structp png_ptr, png_infop info_ptr) { - if (png_ptr != NULL && info_ptr != NULL) - #ifdef PNG_oFFs_SUPPORTED - if (info_ptr->valid & PNG_INFO_oFFs) + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) { png_debug1(1, "in %s retrieval function", "png_get_y_offset_microns"); - if (info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER) - return (0); - - else - return (info_ptr->y_offset); + if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER) + return (info_ptr->y_offset); } -#else - return (0); #endif + return (0); } png_int_32 PNGAPI png_get_x_offset_pixels(png_structp png_ptr, png_infop info_ptr) { - if (png_ptr != NULL && info_ptr != NULL) - #ifdef PNG_oFFs_SUPPORTED - if (info_ptr->valid & PNG_INFO_oFFs) + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) { - png_debug1(1, "in %s retrieval function", "png_get_x_offset_microns"); + png_debug1(1, "in %s retrieval function", "png_get_x_offset_pixels"); - if (info_ptr->offset_unit_type != PNG_OFFSET_PIXEL) - return (0); - - else - return (info_ptr->x_offset); + if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL) + return (info_ptr->x_offset); } -#else - return (0); #endif + return (0); } png_int_32 PNGAPI png_get_y_offset_pixels(png_structp png_ptr, png_infop info_ptr) { - if (png_ptr != NULL && info_ptr != NULL) - #ifdef PNG_oFFs_SUPPORTED - if (info_ptr->valid & PNG_INFO_oFFs) + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) { - png_debug1(1, "in %s retrieval function", "png_get_y_offset_microns"); + png_debug1(1, "in %s retrieval function", "png_get_y_offset_pixels"); - if (info_ptr->offset_unit_type != PNG_OFFSET_PIXEL) - return (0); - - else - return (info_ptr->y_offset); + if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL) + return (info_ptr->y_offset); } -#else - return (0); #endif + return (0); } -#if defined(PNG_INCH_CONVERSIONS) && defined(PNG_FLOATING_POINT_SUPPORTED) +#ifdef PNG_INCH_CONVERSIONS_SUPPORTED +static png_uint_32 +ppi_from_ppm(png_uint_32 ppm) +{ +#if 0 + /* The conversion is *(2.54/100), in binary (32 digits): + * .00000110100000001001110101001001 + */ + png_uint_32 t1001, t1101; + ppm >>= 1; /* .1 */ + t1001 = ppm + (ppm >> 3); /* .1001 */ + t1101 = t1001 + (ppm >> 1); /* .1101 */ + ppm >>= 20; /* .000000000000000000001 */ + t1101 += t1101 >> 15; /* .1101000000000001101 */ + t1001 >>= 11; /* .000000000001001 */ + t1001 += t1001 >> 12; /* .000000000001001000000001001 */ + ppm += t1001; /* .000000000001001000001001001 */ + ppm += t1101; /* .110100000001001110101001001 */ + return (ppm + 16) >> 5;/* .00000110100000001001110101001001 */ +#else + /* The argument is a PNG unsigned integer, so it is not permitted + * to be bigger than 2^31. + */ + png_fixed_point result; + if (ppm <= PNG_UINT_31_MAX && png_muldiv(&result, (png_int_32)ppm, 127, + 5000)) + return result; + + /* Overflow. */ + return 0; +#endif +} + png_uint_32 PNGAPI png_get_pixels_per_inch(png_structp png_ptr, png_infop info_ptr) { - return ((png_uint_32)((float)png_get_pixels_per_meter(png_ptr, info_ptr) - *.0254 +.5)); + return ppi_from_ppm(png_get_pixels_per_meter(png_ptr, info_ptr)); } png_uint_32 PNGAPI png_get_x_pixels_per_inch(png_structp png_ptr, png_infop info_ptr) { - return ((png_uint_32)((float)png_get_x_pixels_per_meter(png_ptr, info_ptr) - *.0254 +.5)); + return ppi_from_ppm(png_get_x_pixels_per_meter(png_ptr, info_ptr)); } png_uint_32 PNGAPI png_get_y_pixels_per_inch(png_structp png_ptr, png_infop info_ptr) { - return ((png_uint_32)((float)png_get_y_pixels_per_meter(png_ptr, info_ptr) - *.0254 +.5)); + return ppi_from_ppm(png_get_y_pixels_per_meter(png_ptr, info_ptr)); } +#ifdef PNG_FIXED_POINT_SUPPORTED +static png_fixed_point +png_fixed_inches_from_microns(png_structp png_ptr, png_int_32 microns) +{ + /* Convert from metres * 1,000,000 to inches * 100,000, meters to + * inches is simply *(100/2.54), so we want *(10/2.54) == 500/127. + * Notice that this can overflow - a warning is output and 0 is + * returned. + */ + return png_muldiv_warn(png_ptr, microns, 500, 127); +} + +png_fixed_point PNGAPI +png_get_x_offset_inches_fixed(png_structp png_ptr, png_infop info_ptr) +{ + return png_fixed_inches_from_microns(png_ptr, + png_get_x_offset_microns(png_ptr, info_ptr)); +} +#endif + +#ifdef PNG_FIXED_POINT_SUPPORTED +png_fixed_point PNGAPI +png_get_y_offset_inches_fixed(png_structp png_ptr, png_infop info_ptr) +{ + return png_fixed_inches_from_microns(png_ptr, + png_get_y_offset_microns(png_ptr, info_ptr)); +} +#endif + +#ifdef PNG_FLOATING_POINT_SUPPORTED float PNGAPI png_get_x_offset_inches(png_structp png_ptr, png_infop info_ptr) { - return ((float)png_get_x_offset_microns(png_ptr, info_ptr) - *.00003937); + /* To avoid the overflow do the conversion directly in floating + * point. + */ + return (float)(png_get_x_offset_microns(png_ptr, info_ptr) * .00003937); } +#endif +#ifdef PNG_FLOATING_POINT_SUPPORTED float PNGAPI png_get_y_offset_inches(png_structp png_ptr, png_infop info_ptr) { - return ((float)png_get_y_offset_microns(png_ptr, info_ptr) - *.00003937); + /* To avoid the overflow do the conversion directly in floating + * point. + */ + return (float)(png_get_y_offset_microns(png_ptr, info_ptr) * .00003937); } +#endif #ifdef PNG_pHYs_SUPPORTED png_uint_32 PNGAPI png_get_pHYs_dpi(png_structp png_ptr, png_infop info_ptr, - png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type) + png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type) { png_uint_32 retval = 0; @@ -343,15 +389,18 @@ png_get_pHYs_dpi(png_structp png_ptr, png_infop info_ptr, *res_x = info_ptr->x_pixels_per_unit; retval |= PNG_INFO_pHYs; } + if (res_y != NULL) { *res_y = info_ptr->y_pixels_per_unit; retval |= PNG_INFO_pHYs; } + if (unit_type != NULL) { *unit_type = (int)info_ptr->phys_unit_type; retval |= PNG_INFO_pHYs; + if (*unit_type == 1) { if (res_x != NULL) *res_x = (png_uint_32)(*res_x * .0254 + .50); @@ -359,10 +408,11 @@ png_get_pHYs_dpi(png_structp png_ptr, png_infop info_ptr, } } } + return (retval); } #endif /* PNG_pHYs_SUPPORTED */ -#endif /* PNG_INCH_CONVERSIONS && PNG_FLOATING_POINT_SUPPORTED */ +#endif /* PNG_INCH_CONVERSIONS_SUPPORTED */ /* png_get_channels really belongs in here, too, but it's been around longer */ @@ -373,17 +423,17 @@ png_get_channels(png_structp png_ptr, png_infop info_ptr) { if (png_ptr != NULL && info_ptr != NULL) return(info_ptr->channels); - else - return (0); + + return (0); } -png_bytep PNGAPI +png_const_bytep PNGAPI png_get_signature(png_structp png_ptr, png_infop info_ptr) { if (png_ptr != NULL && info_ptr != NULL) return(info_ptr->signature); - else - return (NULL); + + return (NULL); } #ifdef PNG_bKGD_SUPPORTED @@ -392,115 +442,117 @@ png_get_bKGD(png_structp png_ptr, png_infop info_ptr, png_color_16p *background) { if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) - && background != NULL) + && background != NULL) { png_debug1(1, "in %s retrieval function", "bKGD"); *background = &(info_ptr->background); return (PNG_INFO_bKGD); } + return (0); } #endif #ifdef PNG_cHRM_SUPPORTED -#ifdef PNG_FLOATING_POINT_SUPPORTED +# ifdef PNG_FLOATING_POINT_SUPPORTED png_uint_32 PNGAPI png_get_cHRM(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) + double *white_x, double *white_y, double *red_x, double *red_y, + double *green_x, double *green_y, double *blue_x, double *blue_y) { if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) { png_debug1(1, "in %s retrieval function", "cHRM"); if (white_x != NULL) - *white_x = (double)info_ptr->x_white; + *white_x = png_float(png_ptr, info_ptr->x_white, "cHRM white X"); if (white_y != NULL) - *white_y = (double)info_ptr->y_white; + *white_y = png_float(png_ptr, info_ptr->y_white, "cHRM white Y"); if (red_x != NULL) - *red_x = (double)info_ptr->x_red; + *red_x = png_float(png_ptr, info_ptr->x_red, "cHRM red X"); if (red_y != NULL) - *red_y = (double)info_ptr->y_red; + *red_y = png_float(png_ptr, info_ptr->y_red, "cHRM red Y"); if (green_x != NULL) - *green_x = (double)info_ptr->x_green; + *green_x = png_float(png_ptr, info_ptr->x_green, "cHRM green X"); if (green_y != NULL) - *green_y = (double)info_ptr->y_green; + *green_y = png_float(png_ptr, info_ptr->y_green, "cHRM green Y"); if (blue_x != NULL) - *blue_x = (double)info_ptr->x_blue; + *blue_x = png_float(png_ptr, info_ptr->x_blue, "cHRM blue X"); if (blue_y != NULL) - *blue_y = (double)info_ptr->y_blue; + *blue_y = png_float(png_ptr, info_ptr->y_blue, "cHRM blue Y"); return (PNG_INFO_cHRM); } + return (0); } -#endif -#ifdef PNG_FIXED_POINT_SUPPORTED +# endif + +# ifdef PNG_FIXED_POINT_SUPPORTED png_uint_32 PNGAPI png_get_cHRM_fixed(png_structp png_ptr, png_infop info_ptr, - png_fixed_point *white_x, png_fixed_point *white_y, png_fixed_point *red_x, - png_fixed_point *red_y, png_fixed_point *green_x, png_fixed_point *green_y, - png_fixed_point *blue_x, png_fixed_point *blue_y) + png_fixed_point *white_x, png_fixed_point *white_y, png_fixed_point *red_x, + png_fixed_point *red_y, png_fixed_point *green_x, png_fixed_point *green_y, + png_fixed_point *blue_x, png_fixed_point *blue_y) { png_debug1(1, "in %s retrieval function", "cHRM"); if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) { if (white_x != NULL) - *white_x = info_ptr->int_x_white; + *white_x = info_ptr->x_white; if (white_y != NULL) - *white_y = info_ptr->int_y_white; + *white_y = info_ptr->y_white; if (red_x != NULL) - *red_x = info_ptr->int_x_red; + *red_x = info_ptr->x_red; if (red_y != NULL) - *red_y = info_ptr->int_y_red; + *red_y = info_ptr->y_red; if (green_x != NULL) - *green_x = info_ptr->int_x_green; + *green_x = info_ptr->x_green; if (green_y != NULL) - *green_y = info_ptr->int_y_green; + *green_y = info_ptr->y_green; if (blue_x != NULL) - *blue_x = info_ptr->int_x_blue; + *blue_x = info_ptr->x_blue; if (blue_y != NULL) - *blue_y = info_ptr->int_y_blue; + *blue_y = info_ptr->y_blue; return (PNG_INFO_cHRM); } + return (0); } -#endif +# endif #endif #ifdef PNG_gAMA_SUPPORTED -#ifdef PNG_FLOATING_POINT_SUPPORTED +png_uint_32 PNGFAPI +png_get_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, + png_fixed_point *file_gamma) +{ + png_debug1(1, "in %s retrieval function", "gAMA"); + + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) + && file_gamma != NULL) + { + *file_gamma = info_ptr->gamma; + return (PNG_INFO_gAMA); + } + + return (0); +} +# ifdef PNG_FLOATING_POINT_SUPPORTED png_uint_32 PNGAPI png_get_gAMA(png_structp png_ptr, png_infop info_ptr, double *file_gamma) { - png_debug1(1, "in %s retrieval function", "gAMA"); + png_fixed_point igamma; + png_uint_32 ok = png_get_gAMA_fixed(png_ptr, info_ptr, &igamma); - if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) - && file_gamma != NULL) - { - *file_gamma = (double)info_ptr->gamma; - return (PNG_INFO_gAMA); - } - return (0); -} -#endif -#ifdef PNG_FIXED_POINT_SUPPORTED -png_uint_32 PNGAPI -png_get_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, - png_fixed_point *int_file_gamma) -{ - png_debug1(1, "in %s retrieval function", "gAMA"); + if (ok) + *file_gamma = png_float(png_ptr, igamma, "png_get_gAMA"); - if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) - && int_file_gamma != NULL) - { - *int_file_gamma = info_ptr->int_gamma; - return (PNG_INFO_gAMA); - } - return (0); + return ok; } -#endif + +# endif #endif #ifdef PNG_sRGB_SUPPORTED @@ -510,11 +562,12 @@ png_get_sRGB(png_structp png_ptr, png_infop info_ptr, int *file_srgb_intent) png_debug1(1, "in %s retrieval function", "sRGB"); if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB) - && file_srgb_intent != NULL) + && file_srgb_intent != NULL) { *file_srgb_intent = (int)info_ptr->srgb_intent; return (PNG_INFO_sRGB); } + return (0); } #endif @@ -522,13 +575,13 @@ png_get_sRGB(png_structp png_ptr, png_infop info_ptr, int *file_srgb_intent) #ifdef PNG_iCCP_SUPPORTED png_uint_32 PNGAPI png_get_iCCP(png_structp png_ptr, png_infop info_ptr, - png_charpp name, int *compression_type, - png_charpp profile, png_uint_32 *proflen) + png_charpp name, int *compression_type, + png_bytepp profile, png_uint_32 *proflen) { png_debug1(1, "in %s retrieval function", "iCCP"); if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP) - && name != NULL && profile != NULL && proflen != NULL) + && name != NULL && profile != NULL && proflen != NULL) { *name = info_ptr->iccp_name; *profile = info_ptr->iccp_profile; @@ -539,6 +592,7 @@ png_get_iCCP(png_structp png_ptr, png_infop info_ptr, *compression_type = (int)info_ptr->iccp_compression; return (PNG_INFO_iCCP); } + return (0); } #endif @@ -546,13 +600,14 @@ png_get_iCCP(png_structp png_ptr, png_infop info_ptr, #ifdef PNG_sPLT_SUPPORTED png_uint_32 PNGAPI png_get_sPLT(png_structp png_ptr, png_infop info_ptr, - png_sPLT_tpp spalettes) + png_sPLT_tpp spalettes) { if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL) { - *spalettes = info_ptr->splt_palettes; - return ((png_uint_32)info_ptr->splt_palettes_num); + *spalettes = info_ptr->splt_palettes; + return ((png_uint_32)info_ptr->splt_palettes_num); } + return (0); } #endif @@ -564,20 +619,21 @@ png_get_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p *hist) png_debug1(1, "in %s retrieval function", "hIST"); if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) - && hist != NULL) + && hist != NULL) { *hist = info_ptr->hist; return (PNG_INFO_hIST); } + return (0); } #endif png_uint_32 PNGAPI png_get_IHDR(png_structp png_ptr, png_infop info_ptr, - png_uint_32 *width, png_uint_32 *height, int *bit_depth, - int *color_type, int *interlace_type, int *compression_type, - int *filter_type) + png_uint_32 *width, png_uint_32 *height, int *bit_depth, + int *color_type, int *interlace_type, int *compression_type, + int *filter_type) { png_debug1(1, "in %s retrieval function", "IHDR"); @@ -615,18 +671,19 @@ png_get_IHDR(png_structp png_ptr, png_infop info_ptr, #ifdef PNG_oFFs_SUPPORTED png_uint_32 PNGAPI png_get_oFFs(png_structp png_ptr, png_infop info_ptr, - png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type) + png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type) { png_debug1(1, "in %s retrieval function", "oFFs"); if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs) - && offset_x != NULL && offset_y != NULL && unit_type != NULL) + && offset_x != NULL && offset_y != NULL && unit_type != NULL) { *offset_x = info_ptr->x_offset; *offset_y = info_ptr->y_offset; *unit_type = (int)info_ptr->offset_unit_type; return (PNG_INFO_oFFs); } + return (0); } #endif @@ -634,8 +691,8 @@ png_get_oFFs(png_structp png_ptr, png_infop info_ptr, #ifdef PNG_pCAL_SUPPORTED png_uint_32 PNGAPI png_get_pCAL(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) + png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams, + png_charp *units, png_charpp *params) { png_debug1(1, "in %s retrieval function", "pCAL"); @@ -652,57 +709,78 @@ png_get_pCAL(png_structp png_ptr, png_infop info_ptr, *params = info_ptr->pcal_params; return (PNG_INFO_pCAL); } + return (0); } #endif #ifdef PNG_sCAL_SUPPORTED -#ifdef PNG_FLOATING_POINT_SUPPORTED +# ifdef PNG_FIXED_POINT_SUPPORTED +# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED +png_uint_32 PNGAPI +png_get_sCAL_fixed(png_structp png_ptr, png_infop info_ptr, + int *unit, png_fixed_point *width, png_fixed_point *height) +{ + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_sCAL)) + { + *unit = info_ptr->scal_unit; + /*TODO: make this work without FP support */ + *width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), "sCAL width"); + *height = png_fixed(png_ptr, atof(info_ptr->scal_s_height), + "sCAL height"); + return (PNG_INFO_sCAL); + } + + return(0); +} +# endif /* FLOATING_ARITHMETIC */ +# endif /* FIXED_POINT */ +# ifdef PNG_FLOATING_POINT_SUPPORTED png_uint_32 PNGAPI png_get_sCAL(png_structp png_ptr, png_infop info_ptr, - int *unit, double *width, double *height) + int *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); + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_sCAL)) + { + *unit = info_ptr->scal_unit; + *width = atof(info_ptr->scal_s_width); + *height = atof(info_ptr->scal_s_height); + return (PNG_INFO_sCAL); + } + + return(0); } -#else -#ifdef PNG_FIXED_POINT_SUPPORTED +# endif /* FLOATING POINT */ png_uint_32 PNGAPI png_get_sCAL_s(png_structp png_ptr, png_infop info_ptr, - int *unit, png_charpp width, png_charpp height) + int *unit, png_charpp width, png_charpp height) { - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_sCAL)) - { - *unit = info_ptr->scal_unit; - *width = info_ptr->scal_s_width; - *height = info_ptr->scal_s_height; - return (PNG_INFO_sCAL); - } - return(0); + if (png_ptr != NULL && info_ptr != NULL && + (info_ptr->valid & PNG_INFO_sCAL)) + { + *unit = info_ptr->scal_unit; + *width = info_ptr->scal_s_width; + *height = info_ptr->scal_s_height; + return (PNG_INFO_sCAL); + } + + return(0); } -#endif -#endif -#endif +#endif /* sCAL */ #ifdef PNG_pHYs_SUPPORTED png_uint_32 PNGAPI png_get_pHYs(png_structp png_ptr, png_infop info_ptr, - png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type) + png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type) { png_uint_32 retval = 0; png_debug1(1, "in %s retrieval function", "pHYs"); if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_pHYs)) + (info_ptr->valid & PNG_INFO_pHYs)) { if (res_x != NULL) { @@ -722,13 +800,14 @@ png_get_pHYs(png_structp png_ptr, png_infop info_ptr, retval |= PNG_INFO_pHYs; } } + return (retval); } -#endif +#endif /* pHYs */ png_uint_32 PNGAPI png_get_PLTE(png_structp png_ptr, png_infop info_ptr, png_colorp *palette, - int *num_palette) + int *num_palette) { png_debug1(1, "in %s retrieval function", "PLTE"); @@ -740,6 +819,7 @@ png_get_PLTE(png_structp png_ptr, png_infop info_ptr, png_colorp *palette, png_debug1(3, "num_palette = %d", *num_palette); return (PNG_INFO_PLTE); } + return (0); } @@ -750,11 +830,12 @@ png_get_sBIT(png_structp png_ptr, png_infop info_ptr, png_color_8p *sig_bit) png_debug1(1, "in %s retrieval function", "sBIT"); if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT) - && sig_bit != NULL) + && sig_bit != NULL) { *sig_bit = &(info_ptr->sig_bit); return (PNG_INFO_sBIT); } + return (0); } #endif @@ -762,13 +843,13 @@ png_get_sBIT(png_structp png_ptr, png_infop info_ptr, png_color_8p *sig_bit) #ifdef PNG_TEXT_SUPPORTED png_uint_32 PNGAPI png_get_text(png_structp png_ptr, png_infop info_ptr, png_textp *text_ptr, - int *num_text) + int *num_text) { if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0) { png_debug1(1, "in %s retrieval function", - (png_ptr->chunk_name[0] == '\0' ? "text" - : (png_const_charp)png_ptr->chunk_name)); + (png_ptr->chunk_name[0] == '\0' ? "text" : + (png_const_charp)png_ptr->chunk_name)); if (text_ptr != NULL) *text_ptr = info_ptr->text; @@ -778,8 +859,10 @@ png_get_text(png_structp png_ptr, png_infop info_ptr, png_textp *text_ptr, return ((png_uint_32)info_ptr->num_text); } + if (num_text != NULL) - *num_text = 0; + *num_text = 0; + return(0); } #endif @@ -796,6 +879,7 @@ png_get_tIME(png_structp png_ptr, png_infop info_ptr, png_timep *mod_time) *mod_time = &(info_ptr->mod_time); return (PNG_INFO_tIME); } + return (0); } #endif @@ -803,7 +887,7 @@ png_get_tIME(png_structp png_ptr, png_infop info_ptr, png_timep *mod_time) #ifdef PNG_tRNS_SUPPORTED png_uint_32 PNGAPI png_get_tRNS(png_structp png_ptr, png_infop info_ptr, - png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color) + png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color) { png_uint_32 retval = 0; if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) @@ -812,55 +896,59 @@ png_get_tRNS(png_structp png_ptr, png_infop info_ptr, if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { - if (trans_alpha != NULL) - { - *trans_alpha = info_ptr->trans_alpha; - retval |= PNG_INFO_tRNS; - } + if (trans_alpha != NULL) + { + *trans_alpha = info_ptr->trans_alpha; + retval |= PNG_INFO_tRNS; + } - if (trans_color != NULL) - *trans_color = &(info_ptr->trans_color); + if (trans_color != NULL) + *trans_color = &(info_ptr->trans_color); } + else /* if (info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) */ { - if (trans_color != NULL) - { - *trans_color = &(info_ptr->trans_color); - retval |= PNG_INFO_tRNS; - } + if (trans_color != NULL) + { + *trans_color = &(info_ptr->trans_color); + retval |= PNG_INFO_tRNS; + } - if (trans_alpha != NULL) - *trans_alpha = NULL; + if (trans_alpha != NULL) + *trans_alpha = NULL; } + if (num_trans != NULL) { *num_trans = info_ptr->num_trans; retval |= PNG_INFO_tRNS; } } + return (retval); } #endif #ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED -png_uint_32 PNGAPI +int PNGAPI png_get_unknown_chunks(png_structp png_ptr, png_infop info_ptr, - png_unknown_chunkpp unknowns) + png_unknown_chunkpp unknowns) { if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL) { - *unknowns = info_ptr->unknown_chunks; - return ((png_uint_32)info_ptr->unknown_chunks_num); + *unknowns = info_ptr->unknown_chunks; + return info_ptr->unknown_chunks_num; } + return (0); } #endif #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED png_byte PNGAPI -png_get_rgb_to_gray_status(png_structp png_ptr) +png_get_rgb_to_gray_status (png_structp png_ptr) { - return (png_byte)(png_ptr? png_ptr->rgb_to_gray_status : 0); + return (png_byte)(png_ptr ? png_ptr->rgb_to_gray_status : 0); } #endif @@ -868,7 +956,7 @@ png_get_rgb_to_gray_status(png_structp png_ptr) png_voidp PNGAPI png_get_user_chunk_ptr(png_structp png_ptr) { - return (png_ptr? png_ptr->user_chunk_ptr : NULL); + return (png_ptr ? png_ptr->user_chunk_ptr : NULL); } #endif @@ -883,40 +971,42 @@ png_get_compression_buffer_size(png_structp png_ptr) /* These functions were added to libpng 1.2.6 and were enabled * by default in libpng-1.4.0 */ png_uint_32 PNGAPI -png_get_user_width_max(png_structp png_ptr) +png_get_user_width_max (png_structp png_ptr) { - return (png_ptr? png_ptr->user_width_max : 0); + return (png_ptr ? png_ptr->user_width_max : 0); } + png_uint_32 PNGAPI -png_get_user_height_max(png_structp png_ptr) +png_get_user_height_max (png_structp png_ptr) { - return (png_ptr? png_ptr->user_height_max : 0); + return (png_ptr ? png_ptr->user_height_max : 0); } + /* This function was added to libpng 1.4.0 */ png_uint_32 PNGAPI -png_get_chunk_cache_max(png_structp png_ptr) +png_get_chunk_cache_max (png_structp png_ptr) { - return (png_ptr? png_ptr->user_chunk_cache_max : 0); + return (png_ptr ? png_ptr->user_chunk_cache_max : 0); } + /* This function was added to libpng 1.4.1 */ png_alloc_size_t PNGAPI -png_get_chunk_malloc_max(png_structp png_ptr) +png_get_chunk_malloc_max (png_structp png_ptr) { - return (png_ptr? - png_ptr->user_chunk_malloc_max : 0); + return (png_ptr ? png_ptr->user_chunk_malloc_max : 0); } #endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */ /* These functions were added to libpng 1.4.0 */ #ifdef PNG_IO_STATE_SUPPORTED png_uint_32 PNGAPI -png_get_io_state(png_structp png_ptr) +png_get_io_state (png_structp png_ptr) { - return png_ptr->io_state; + return png_ptr->io_state; } -png_bytep PNGAPI -png_get_io_chunk_name(png_structp png_ptr) +png_const_bytep PNGAPI +png_get_io_chunk_name (png_structp png_ptr) { return png_ptr->chunk_name; } diff --git a/harbour/src/3rd/png/pngmem.c b/harbour/src/3rd/png/pngmem.c index c8a3f6f59a..c7e8a9bba5 100644 --- a/harbour/src/3rd/png/pngmem.c +++ b/harbour/src/3rd/png/pngmem.c @@ -1,8 +1,8 @@ /* pngmem.c - stub functions for memory allocation * - * Last changed in libpng 1.4.2 [May 6, 2010] - * Copyright (c) 1998-2010 Glenn Randers-Pehrson + * Last changed in libpng 1.5.0 [January 6, 2011] + * Copyright (c) 1998-2011 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -17,40 +17,42 @@ * identify the replacement functions. */ -#define PNG_NO_PEDANTIC_WARNINGS -#include "png.h" -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) #include "pngpriv.h" +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) + /* Borland DOS special memory handler */ #if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__) /* If you change this, be sure to change the one in png.h also */ /* Allocate memory for a png_struct. The malloc and memset can be replaced by a single call to calloc() if this is thought to improve performance. */ -png_voidp /* PRIVATE */ -png_create_struct(int type) +PNG_FUNCTION(png_voidp /* PRIVATE */, +png_create_struct,(int type),PNG_ALLOCATED) { -#ifdef PNG_USER_MEM_SUPPORTED +# ifdef PNG_USER_MEM_SUPPORTED return (png_create_struct_2(type, NULL, NULL)); } /* Alternate version of png_create_struct, for use with user-defined malloc. */ -png_voidp /* PRIVATE */ -png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr) +PNG_FUNCTION(png_voidp /* PRIVATE */, +png_create_struct_2,(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr), + PNG_ALLOCATED) { -#endif /* PNG_USER_MEM_SUPPORTED */ +# endif /* PNG_USER_MEM_SUPPORTED */ png_size_t size; png_voidp struct_ptr; if (type == PNG_STRUCT_INFO) size = png_sizeof(png_info); + else if (type == PNG_STRUCT_PNG) size = png_sizeof(png_struct); + else return (png_get_copyright(NULL)); -#ifdef PNG_USER_MEM_SUPPORTED +# ifdef PNG_USER_MEM_SUPPORTED if (malloc_fn != NULL) { png_struct dummy_struct; @@ -58,11 +60,13 @@ png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr) png_ptr->mem_ptr=mem_ptr; struct_ptr = (*(malloc_fn))(png_ptr, (png_uint_32)size); } + else -#endif /* PNG_USER_MEM_SUPPORTED */ +# endif /* PNG_USER_MEM_SUPPORTED */ struct_ptr = (png_voidp)farmalloc(size); if (struct_ptr != NULL) png_memset(struct_ptr, 0, size); + return (struct_ptr); } @@ -70,7 +74,7 @@ png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr) void /* PRIVATE */ png_destroy_struct(png_voidp struct_ptr) { -#ifdef PNG_USER_MEM_SUPPORTED +# ifdef PNG_USER_MEM_SUPPORTED png_destroy_struct_2(struct_ptr, NULL, NULL); } @@ -79,10 +83,10 @@ void /* PRIVATE */ png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn, png_voidp mem_ptr) { -#endif +# endif if (struct_ptr != NULL) { -#ifdef PNG_USER_MEM_SUPPORTED +# ifdef PNG_USER_MEM_SUPPORTED if (free_fn != NULL) { png_struct dummy_struct; @@ -91,7 +95,8 @@ png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn, (*(free_fn))(png_ptr, struct_ptr); return; } -#endif /* PNG_USER_MEM_SUPPORTED */ + +# endif /* PNG_USER_MEM_SUPPORTED */ farfree (struct_ptr); } } @@ -115,55 +120,62 @@ png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn, * result, we would be truncating potentially larger memory requests * (which should cause a fatal error) and introducing major problems. */ -png_voidp PNGAPI -png_calloc(png_structp png_ptr, png_alloc_size_t size) +PNG_FUNCTION(png_voidp,PNGAPI +png_calloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) { png_voidp ret; ret = (png_malloc(png_ptr, size)); + if (ret != NULL) png_memset(ret,0,(png_size_t)size); + return (ret); } -png_voidp PNGAPI -png_malloc(png_structp png_ptr, png_alloc_size_t size) +PNG_FUNCTION(png_voidp,PNGAPI +png_malloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) { png_voidp ret; if (png_ptr == NULL || size == 0) return (NULL); -#ifdef PNG_USER_MEM_SUPPORTED +# ifdef PNG_USER_MEM_SUPPORTED if (png_ptr->malloc_fn != NULL) ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size)); + else ret = (png_malloc_default(png_ptr, size)); + if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) png_error(png_ptr, "Out of memory"); + return (ret); } -png_voidp PNGAPI -png_malloc_default(png_structp png_ptr, png_alloc_size_t size) +PNG_FUNCTION(png_voidp,PNGAPI +png_malloc_default,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) { png_voidp ret; -#endif /* PNG_USER_MEM_SUPPORTED */ +# endif /* PNG_USER_MEM_SUPPORTED */ if (png_ptr == NULL || size == 0) return (NULL); -#ifdef PNG_MAX_MALLOC_64K +# ifdef PNG_MAX_MALLOC_64K if (size > (png_uint_32)65536L) { png_warning(png_ptr, "Cannot Allocate > 64K"); ret = NULL; } + else -#endif +# endif if (size != (size_t)size) ret = NULL; + else if (size == (png_uint_32)65536L) { if (png_ptr->offset_table == NULL) @@ -186,10 +198,13 @@ png_malloc_default(png_structp png_ptr, png_alloc_size_t size) if (png_ptr->zlib_window_bits > 14) num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14)); + else num_blocks = 1; + if (png_ptr->zlib_mem_level >= 7) num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7)); + else num_blocks++; @@ -199,25 +214,27 @@ png_malloc_default(png_structp png_ptr, png_alloc_size_t size) if (table == NULL) { -#ifndef PNG_USER_MEM_SUPPORTED +# ifndef PNG_USER_MEM_SUPPORTED if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) png_error(png_ptr, "Out Of Memory"); /* Note "O", "M" */ + else png_warning(png_ptr, "Out Of Memory"); -#endif +# endif return (NULL); } if ((png_size_t)table & 0xfff0) { -#ifndef PNG_USER_MEM_SUPPORTED +# ifndef PNG_USER_MEM_SUPPORTED if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) png_error(png_ptr, "Farmalloc didn't return normalized pointer"); + else png_warning(png_ptr, "Farmalloc didn't return normalized pointer"); -#endif +# endif return (NULL); } @@ -227,12 +244,13 @@ png_malloc_default(png_structp png_ptr, png_alloc_size_t size) if (png_ptr->offset_table_ptr == NULL) { -#ifndef PNG_USER_MEM_SUPPORTED +# ifndef PNG_USER_MEM_SUPPORTED if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) png_error(png_ptr, "Out Of memory"); /* Note "O", "m" */ + else png_warning(png_ptr, "Out Of memory"); -#endif +# endif return (NULL); } @@ -242,6 +260,7 @@ png_malloc_default(png_structp png_ptr, png_alloc_size_t size) hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L); hptr = hptr + 16L; /* "hptr += 16L" fails on Turbo C++ 3.0 */ } + for (i = 0; i < num_blocks; i++) { png_ptr->offset_table_ptr[i] = (png_bytep)hptr; @@ -256,29 +275,32 @@ png_malloc_default(png_structp png_ptr, png_alloc_size_t size) if (png_ptr->offset_table_count >= png_ptr->offset_table_number) { -#ifndef PNG_USER_MEM_SUPPORTED +# ifndef PNG_USER_MEM_SUPPORTED if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) png_error(png_ptr, "Out of Memory"); /* Note "o" and "M" */ + else png_warning(png_ptr, "Out of Memory"); -#endif +# endif return (NULL); } ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++]; } + else ret = farmalloc(size); -#ifndef PNG_USER_MEM_SUPPORTED +# ifndef PNG_USER_MEM_SUPPORTED if (ret == NULL) { if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) png_error(png_ptr, "Out of memory"); /* Note "o" and "m" */ + else png_warning(png_ptr, "Out of memory"); /* Note "o" and "m" */ } -#endif +# endif return (ret); } @@ -293,12 +315,13 @@ png_free(png_structp png_ptr, png_voidp ptr) if (png_ptr == NULL || ptr == NULL) return; -#ifdef PNG_USER_MEM_SUPPORTED +# ifdef PNG_USER_MEM_SUPPORTED if (png_ptr->free_fn != NULL) { (*(png_ptr->free_fn))(png_ptr, ptr); return; } + else png_free_default(png_ptr, ptr); } @@ -306,7 +329,7 @@ png_free(png_structp png_ptr, png_voidp ptr) void PNGAPI png_free_default(png_structp png_ptr, png_voidp ptr) { -#endif /* PNG_USER_MEM_SUPPORTED */ +# endif /* PNG_USER_MEM_SUPPORTED */ if (png_ptr == NULL || ptr == NULL) return; @@ -334,9 +357,7 @@ png_free_default(png_structp png_ptr, png_voidp ptr) } if (ptr != NULL) - { farfree(ptr); - } } #else /* Not the Borland DOS special memory handler */ @@ -344,52 +365,58 @@ png_free_default(png_structp png_ptr, png_voidp ptr) /* Allocate memory for a png_struct or a png_info. The malloc and memset can be replaced by a single call to calloc() if this is thought to improve performance noticably. */ -png_voidp /* PRIVATE */ -png_create_struct(int type) +PNG_FUNCTION(png_voidp /* PRIVATE */, +png_create_struct,(int type),PNG_ALLOCATED) { -#ifdef PNG_USER_MEM_SUPPORTED +# ifdef PNG_USER_MEM_SUPPORTED return (png_create_struct_2(type, NULL, NULL)); } /* Allocate memory for a png_struct or a png_info. The malloc and memset can be replaced by a single call to calloc() if this is thought to improve performance noticably. */ -png_voidp /* PRIVATE */ -png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr) +PNG_FUNCTION(png_voidp /* PRIVATE */, +png_create_struct_2,(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr), + PNG_ALLOCATED) { -#endif /* PNG_USER_MEM_SUPPORTED */ +# endif /* PNG_USER_MEM_SUPPORTED */ png_size_t size; png_voidp struct_ptr; if (type == PNG_STRUCT_INFO) size = png_sizeof(png_info); + else if (type == PNG_STRUCT_PNG) size = png_sizeof(png_struct); + else return (NULL); -#ifdef PNG_USER_MEM_SUPPORTED +# ifdef PNG_USER_MEM_SUPPORTED if (malloc_fn != NULL) { png_struct dummy_struct; png_structp png_ptr = &dummy_struct; png_ptr->mem_ptr=mem_ptr; struct_ptr = (*(malloc_fn))(png_ptr, size); + if (struct_ptr != NULL) png_memset(struct_ptr, 0, size); + return (struct_ptr); } -#endif /* PNG_USER_MEM_SUPPORTED */ +# endif /* PNG_USER_MEM_SUPPORTED */ -#if defined(__TURBOC__) && !defined(__FLAT__) +# if defined(__TURBOC__) && !defined(__FLAT__) struct_ptr = (png_voidp)farmalloc(size); -#else -# if defined(_MSC_VER) && defined(MAXSEG_64K) +# else +# if defined(_MSC_VER) && defined(MAXSEG_64K) struct_ptr = (png_voidp)halloc(size, 1); -# else +# else struct_ptr = (png_voidp)malloc(size); -# endif -#endif +# endif +# endif + if (struct_ptr != NULL) png_memset(struct_ptr, 0, size); @@ -401,7 +428,7 @@ png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr) void /* PRIVATE */ png_destroy_struct(png_voidp struct_ptr) { -#ifdef PNG_USER_MEM_SUPPORTED +# ifdef PNG_USER_MEM_SUPPORTED png_destroy_struct_2(struct_ptr, NULL, NULL); } @@ -410,10 +437,10 @@ void /* PRIVATE */ png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn, png_voidp mem_ptr) { -#endif /* PNG_USER_MEM_SUPPORTED */ +# endif /* PNG_USER_MEM_SUPPORTED */ if (struct_ptr != NULL) { -#ifdef PNG_USER_MEM_SUPPORTED +# ifdef PNG_USER_MEM_SUPPORTED if (free_fn != NULL) { png_struct dummy_struct; @@ -422,16 +449,19 @@ png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn, (*(free_fn))(png_ptr, struct_ptr); return; } -#endif /* PNG_USER_MEM_SUPPORTED */ -#if defined(__TURBOC__) && !defined(__FLAT__) +# endif /* PNG_USER_MEM_SUPPORTED */ +# if defined(__TURBOC__) && !defined(__FLAT__) farfree(struct_ptr); -#else -# if defined(_MSC_VER) && defined(MAXSEG_64K) + +# else +# if defined(_MSC_VER) && defined(MAXSEG_64K) hfree(struct_ptr); -# else + +# else free(struct_ptr); -# endif -#endif + +# endif +# endif } } @@ -442,80 +472,92 @@ png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn, * have the ability to do that. */ -png_voidp PNGAPI -png_calloc(png_structp png_ptr, png_alloc_size_t size) +PNG_FUNCTION(png_voidp,PNGAPI +png_calloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) { png_voidp ret; ret = (png_malloc(png_ptr, size)); + if (ret != NULL) png_memset(ret,0,(png_size_t)size); + return (ret); } -png_voidp PNGAPI -png_malloc(png_structp png_ptr, png_alloc_size_t size) +PNG_FUNCTION(png_voidp,PNGAPI +png_malloc,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) { png_voidp ret; -#ifdef PNG_USER_MEM_SUPPORTED +# ifdef PNG_USER_MEM_SUPPORTED if (png_ptr == NULL || size == 0) return (NULL); if (png_ptr->malloc_fn != NULL) ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size)); + else ret = (png_malloc_default(png_ptr, size)); + if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) png_error(png_ptr, "Out of Memory"); + return (ret); } -png_voidp PNGAPI -png_malloc_default(png_structp png_ptr, png_alloc_size_t size) +PNG_FUNCTION(png_voidp,PNGAPI +png_malloc_default,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) { png_voidp ret; -#endif /* PNG_USER_MEM_SUPPORTED */ +# endif /* PNG_USER_MEM_SUPPORTED */ if (png_ptr == NULL || size == 0) return (NULL); -#ifdef PNG_MAX_MALLOC_64K +# ifdef PNG_MAX_MALLOC_64K if (size > (png_uint_32)65536L) { -#ifndef PNG_USER_MEM_SUPPORTED +# ifndef PNG_USER_MEM_SUPPORTED if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) png_error(png_ptr, "Cannot Allocate > 64K"); + else -#endif +# endif return NULL; } -#endif +# endif /* Check for overflow */ -#if defined(__TURBOC__) && !defined(__FLAT__) +# if defined(__TURBOC__) && !defined(__FLAT__) + if (size != (unsigned long)size) ret = NULL; + else ret = farmalloc(size); -#else -# if defined(_MSC_VER) && defined(MAXSEG_64K) + +# else +# if defined(_MSC_VER) && defined(MAXSEG_64K) if (size != (unsigned long)size) ret = NULL; + else ret = halloc(size, 1); -# else + +# else if (size != (size_t)size) ret = NULL; + else ret = malloc((size_t)size); -# endif -#endif +# endif +# endif -#ifndef PNG_USER_MEM_SUPPORTED +# ifndef PNG_USER_MEM_SUPPORTED if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) png_error(png_ptr, "Out of Memory"); -#endif +# endif return (ret); } @@ -529,34 +571,38 @@ png_free(png_structp png_ptr, png_voidp ptr) if (png_ptr == NULL || ptr == NULL) return; -#ifdef PNG_USER_MEM_SUPPORTED +# ifdef PNG_USER_MEM_SUPPORTED if (png_ptr->free_fn != NULL) { (*(png_ptr->free_fn))(png_ptr, ptr); return; } + else png_free_default(png_ptr, ptr); } + void PNGAPI png_free_default(png_structp png_ptr, png_voidp ptr) { if (png_ptr == NULL || ptr == NULL) return; -#endif /* PNG_USER_MEM_SUPPORTED */ +# endif /* PNG_USER_MEM_SUPPORTED */ -#if defined(__TURBOC__) && !defined(__FLAT__) +# if defined(__TURBOC__) && !defined(__FLAT__) farfree(ptr); -#else -# if defined(_MSC_VER) && defined(MAXSEG_64K) - hfree(ptr); -# else - free(ptr); -# endif -#endif -} +# else +# if defined(_MSC_VER) && defined(MAXSEG_64K) + hfree(ptr); + +# else + free(ptr); + +# endif +# endif +} #endif /* Not Borland DOS special memory handler */ /* This function was added at libpng version 1.2.3. The png_malloc_warn() @@ -564,8 +610,8 @@ png_free_default(png_structp png_ptr, png_voidp ptr) * instead of issuing a png_error, if it fails to allocate the requested * memory. */ -png_voidp PNGAPI -png_malloc_warn(png_structp png_ptr, png_alloc_size_t size) +PNG_FUNCTION(png_voidp,PNGAPI +png_malloc_warn,(png_structp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) { png_voidp ptr; png_uint_32 save_flags; @@ -605,6 +651,7 @@ png_get_mem_ptr(png_structp png_ptr) { if (png_ptr == NULL) return (NULL); + return ((png_voidp)png_ptr->mem_ptr); } #endif /* PNG_USER_MEM_SUPPORTED */ diff --git a/harbour/src/3rd/png/pngpread.c b/harbour/src/3rd/png/pngpread.c index 9c69a89d18..a7452aa65f 100644 --- a/harbour/src/3rd/png/pngpread.c +++ b/harbour/src/3rd/png/pngpread.c @@ -1,8 +1,8 @@ /* pngpread.c - read a png file in push mode * - * Last changed in libpng 1.4.3 [June 26, 2010] - * Copyright (c) 1998-2010 Glenn Randers-Pehrson + * Last changed in libpng 1.5.0 [January 6, 2011] + * Copyright (c) 1998-2011 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -11,11 +11,10 @@ * and license in png.h */ -#define PNG_NO_PEDANTIC_WARNINGS -#include "png.h" -#ifdef PNG_PROGRESSIVE_READ_SUPPORTED #include "pngpriv.h" +#ifdef PNG_PROGRESSIVE_READ_SUPPORTED + /* Push model modes */ #define PNG_READ_SIG_MODE 0 #define PNG_READ_CHUNK_MODE 1 @@ -29,7 +28,7 @@ void PNGAPI png_process_data(png_structp png_ptr, png_infop info_ptr, - png_bytep buffer, png_size_t buffer_size) + png_bytep buffer, png_size_t buffer_size) { if (png_ptr == NULL || info_ptr == NULL) return; @@ -127,7 +126,7 @@ png_push_read_sig(png_structp png_ptr, png_infop info_ptr) } png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]), - num_to_check); + num_to_check); png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check); if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check)) @@ -135,6 +134,7 @@ png_push_read_sig(png_structp png_ptr, png_infop info_ptr) if (num_checked < 4 && png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4)) png_error(png_ptr, "Not a PNG file"); + else png_error(png_ptr, "PNG file corrupted by ASCII conversion"); } @@ -231,8 +231,8 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) } if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) - if (png_ptr->mode & PNG_AFTER_IDAT) - png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; + if (png_ptr->mode & PNG_AFTER_IDAT) + png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4)) { @@ -285,7 +285,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_error(png_ptr, "Missing IHDR before IDAT"); else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && - !(png_ptr->mode & PNG_HAVE_PLTE)) + !(png_ptr->mode & PNG_HAVE_PLTE)) png_error(png_ptr, "Missing PLTE before IDAT"); } } @@ -582,32 +582,47 @@ png_push_crc_finish(png_structp png_ptr) { if (png_ptr->skip_length && png_ptr->save_buffer_size) { - png_size_t save_size; + png_size_t save_size = png_ptr->current_buffer_size; + png_uint_32 skip_length = png_ptr->skip_length; + + /* We want the smaller of 'skip_length' and 'current_buffer_size', but + * they are of different types and we don't know which variable has the + * fewest bits. Carefully select the smaller and cast it to the type of + * the larger - this cannot overflow. Do not cast in the following test + * - it will break on either 16 or 64 bit platforms. + */ + if (skip_length < save_size) + save_size = (png_size_t)skip_length; - if (png_ptr->skip_length < (png_uint_32)png_ptr->save_buffer_size) - save_size = (png_size_t)png_ptr->skip_length; else - save_size = png_ptr->save_buffer_size; + skip_length = (png_uint_32)save_size; png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); - png_ptr->skip_length -= save_size; + png_ptr->skip_length -= skip_length; png_ptr->buffer_size -= save_size; png_ptr->save_buffer_size -= save_size; png_ptr->save_buffer_ptr += save_size; } if (png_ptr->skip_length && png_ptr->current_buffer_size) { - png_size_t save_size; + png_size_t save_size = png_ptr->current_buffer_size; + png_uint_32 skip_length = png_ptr->skip_length; + + /* We want the smaller of 'skip_length' and 'current_buffer_size', but + * they are of different types and we don't know which variable has the + * fewest bits. Carefully select the smaller and cast it to the type of + * the larger - this cannot overflow. + */ + if (skip_length < save_size) + save_size = (png_size_t)skip_length; - if (png_ptr->skip_length < (png_uint_32)png_ptr->current_buffer_size) - save_size = (png_size_t)png_ptr->skip_length; else - save_size = png_ptr->current_buffer_size; + skip_length = (png_uint_32)save_size; png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size); - png_ptr->skip_length -= save_size; + png_ptr->skip_length -= skip_length; png_ptr->buffer_size -= save_size; png_ptr->current_buffer_size -= save_size; png_ptr->current_buffer_ptr += save_size; @@ -625,7 +640,7 @@ png_push_crc_finish(png_structp png_ptr) } } -void PNGAPI +void PNGCBAPI png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length) { png_bytep ptr; @@ -640,6 +655,7 @@ png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length) if (length < png_ptr->save_buffer_size) save_size = length; + else save_size = png_ptr->save_buffer_size; @@ -680,33 +696,35 @@ png_push_save_buffer(png_structp png_ptr) istop = png_ptr->save_buffer_size; for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer; - i < istop; i++, sp++, dp++) + i < istop; i++, sp++, dp++) { *dp = *sp; } } } if (png_ptr->save_buffer_size + png_ptr->current_buffer_size > - png_ptr->save_buffer_max) + png_ptr->save_buffer_max) { png_size_t new_max; png_bytep old_buffer; if (png_ptr->save_buffer_size > PNG_SIZE_MAX - - (png_ptr->current_buffer_size + 256)) + (png_ptr->current_buffer_size + 256)) { - png_error(png_ptr, "Potential overflow of save_buffer"); + png_error(png_ptr, "Potential overflow of save_buffer"); } new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256; old_buffer = png_ptr->save_buffer; png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr, - (png_size_t)new_max); + (png_size_t)new_max); + if (png_ptr->save_buffer == NULL) { - png_free(png_ptr, old_buffer); - png_error(png_ptr, "Insufficient memory for save_buffer"); + png_free(png_ptr, old_buffer); + png_error(png_ptr, "Insufficient memory for save_buffer"); } + png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size); png_free(png_ptr, old_buffer); png_ptr->save_buffer_max = new_max; @@ -755,8 +773,10 @@ png_push_read_IDAT(png_structp png_ptr) if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) { png_ptr->process_mode = PNG_READ_CHUNK_MODE; + if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) png_error(png_ptr, "Not enough compressed data"); + return; } @@ -764,48 +784,52 @@ png_push_read_IDAT(png_structp png_ptr) } if (png_ptr->idat_size && png_ptr->save_buffer_size) { - png_size_t save_size; + png_size_t save_size = png_ptr->save_buffer_size; + png_uint_32 idat_size = png_ptr->idat_size; - if (png_ptr->idat_size < (png_uint_32)png_ptr->save_buffer_size) - { - save_size = (png_size_t)png_ptr->idat_size; + /* We want the smaller of 'idat_size' and 'current_buffer_size', but they + * are of different types and we don't know which variable has the fewest + * bits. Carefully select the smaller and cast it to the type of the + * larger - this cannot overflow. Do not cast in the following test - it + * will break on either 16 or 64 bit platforms. + */ + if (idat_size < save_size) + save_size = (png_size_t)idat_size; - /* Check for overflow */ - if ((png_uint_32)save_size != png_ptr->idat_size) - png_error(png_ptr, "save_size overflowed in pngpread"); - } else - save_size = png_ptr->save_buffer_size; + idat_size = (png_uint_32)save_size; png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size); - png_ptr->idat_size -= save_size; + png_ptr->idat_size -= idat_size; png_ptr->buffer_size -= save_size; png_ptr->save_buffer_size -= save_size; png_ptr->save_buffer_ptr += save_size; } + if (png_ptr->idat_size && png_ptr->current_buffer_size) { - png_size_t save_size; + png_size_t save_size = png_ptr->current_buffer_size; + png_uint_32 idat_size = png_ptr->idat_size; - if (png_ptr->idat_size < (png_uint_32)png_ptr->current_buffer_size) - { - save_size = (png_size_t)png_ptr->idat_size; + /* We want the smaller of 'idat_size' and 'current_buffer_size', but they + * are of different types and we don't know which variable has the fewest + * bits. Carefully select the smaller and cast it to the type of the + * larger - this cannot overflow. + */ + if (idat_size < save_size) + save_size = (png_size_t)idat_size; - /* Check for overflow */ - if ((png_uint_32)save_size != png_ptr->idat_size) - png_error(png_ptr, "save_size overflowed in pngpread"); - } else - save_size = png_ptr->current_buffer_size; + idat_size = (png_uint_32)save_size; png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size); png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size); - png_ptr->idat_size -= save_size; + png_ptr->idat_size -= idat_size; png_ptr->buffer_size -= save_size; png_ptr->current_buffer_size -= save_size; png_ptr->current_buffer_ptr += save_size; @@ -843,12 +867,12 @@ png_process_IDAT_data(png_structp png_ptr, png_bytep buffer, * or the stream marked as finished. */ while (png_ptr->zstream.avail_in > 0 && - !(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) + !(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) { int ret; /* We have data for zlib, but we must check that zlib - * has somewhere to put the results. It doesn't matter + * has someplace to put the results. It doesn't matter * if we don't expect any results -- it may be the input * data is just the LZ end code. */ @@ -857,15 +881,16 @@ png_process_IDAT_data(png_structp png_ptr, png_bytep buffer, png_ptr->zstream.avail_out = (uInt) PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1; + png_ptr->zstream.next_out = png_ptr->row_buf; } /* Using Z_SYNC_FLUSH here means that an unterminated - * LZ stream can still be handled (a stream with a missing - * end code), otherwise (Z_NO_FLUSH) a future zlib - * implementation might defer output and, therefore, - * change the current behavior. (See comments in inflate.c - * for why this doesn't happen at present with zlib 1.2.5.) + * LZ stream (a stream with a missing end code) can still + * be handled, otherwise (Z_NO_FLUSH) a future zlib + * implementation might defer output and therefore + * change the current behavior (see comments in inflate.c + * for why this doesn't happen at present with zlib 1.2.5). */ ret = inflate(&png_ptr->zstream, Z_SYNC_FLUSH); @@ -881,6 +906,7 @@ png_process_IDAT_data(png_structp png_ptr, png_bytep buffer, if (png_ptr->row_number >= png_ptr->num_rows || png_ptr->pass > 6) png_warning(png_ptr, "Truncated compressed data in IDAT"); + else png_error(png_ptr, "Decompression error in IDAT"); @@ -901,6 +927,7 @@ png_process_IDAT_data(png_structp png_ptr, png_bytep buffer, /* Extra data. */ png_warning(png_ptr, "Extra compressed data in IDAT"); png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; + /* Do no more processing; skip the unprocessed * input check below. */ @@ -922,7 +949,7 @@ png_process_IDAT_data(png_structp png_ptr, png_bytep buffer, * after the zlib end code. */ if (png_ptr->zstream.avail_in > 0) - png_warning(png_ptr, "Extra compression data"); + png_warning(png_ptr, "Extra compression data in IDAT"); } void /* PRIVATE */ @@ -1162,15 +1189,15 @@ png_read_push_finish_row(png_structp png_ptr) if (png_ptr->interlaced) { png_ptr->row_number = 0; - png_memset(png_ptr->prev_row, 0, - png_ptr->rowbytes + 1); + png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); + do { png_ptr->pass++; if ((png_ptr->pass == 1 && png_ptr->width < 5) || (png_ptr->pass == 3 && png_ptr->width < 3) || (png_ptr->pass == 5 && png_ptr->width < 2)) - png_ptr->pass++; + png_ptr->pass++; if (png_ptr->pass > 7) png_ptr->pass--; @@ -1179,17 +1206,17 @@ png_read_push_finish_row(png_structp png_ptr) break; png_ptr->iwidth = (png_ptr->width + - png_pass_inc[png_ptr->pass] - 1 - - png_pass_start[png_ptr->pass]) / - png_pass_inc[png_ptr->pass]; + png_pass_inc[png_ptr->pass] - 1 - + png_pass_start[png_ptr->pass]) / + png_pass_inc[png_ptr->pass]; if (png_ptr->transformations & PNG_INTERLACE) break; png_ptr->num_rows = (png_ptr->height + - png_pass_yinc[png_ptr->pass] - 1 - - png_pass_ystart[png_ptr->pass]) / - png_pass_yinc[png_ptr->pass]; + png_pass_yinc[png_ptr->pass] - 1 - + png_pass_ystart[png_ptr->pass]) / + png_pass_yinc[png_ptr->pass]; } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0); } @@ -1199,12 +1226,13 @@ png_read_push_finish_row(png_structp png_ptr) #ifdef PNG_READ_tEXt_SUPPORTED void /* PRIVATE */ png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 - length) + length) { if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) { + PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */ png_error(png_ptr, "Out of place tEXt"); - info_ptr = info_ptr; /* To quiet some compiler warnings */ + /*NOT REACHED*/ } #ifdef PNG_MAX_MALLOC_64K @@ -1219,7 +1247,7 @@ png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 #endif png_ptr->current_text = (png_charp)png_malloc(png_ptr, - (png_size_t)(length + 1)); + (png_size_t)(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; @@ -1272,14 +1300,12 @@ png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr) if (text < key + png_ptr->current_text_size) text++; - text_ptr = (png_textp)png_malloc(png_ptr, - png_sizeof(png_text)); + text_ptr = (png_textp)png_malloc(png_ptr, png_sizeof(png_text)); text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; text_ptr->key = key; -#ifdef PNG_iTXt_SUPPORTED + text_ptr->itxt_length = 0; text_ptr->lang = NULL; text_ptr->lang_key = NULL; -#endif text_ptr->text = text; ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); @@ -1289,7 +1315,7 @@ png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr) png_ptr->current_text = NULL; if (ret) - png_warning(png_ptr, "Insufficient memory to store text chunk"); + png_warning(png_ptr, "Insufficient memory to store text chunk"); } } #endif @@ -1300,10 +1326,11 @@ png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) - { - png_error(png_ptr, "Out of place zTXt"); - info_ptr = info_ptr; /* To quiet some compiler warnings */ - } + { + PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */ + png_error(png_ptr, "Out of place zTXt"); + /*NOT REACHED*/ + } #ifdef PNG_MAX_MALLOC_64K /* We can't handle zTXt chunks > 64K, since we don't have enough space @@ -1319,7 +1346,7 @@ png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 #endif png_ptr->current_text = (png_charp)png_malloc(png_ptr, - (png_size_t)(length + 1)); + (png_size_t)(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; @@ -1384,9 +1411,9 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr) text++; - png_ptr->zstream.next_in = (png_bytep )text; + png_ptr->zstream.next_in = (png_bytep)text; png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size - - (text - key)); + (text - key)); png_ptr->zstream.next_out = png_ptr->zbuf; png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; @@ -1407,42 +1434,45 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr) png_free(png_ptr, text); return; } + if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END) { if (text == NULL) { text = (png_charp)png_malloc(png_ptr, - (png_ptr->zbuf_size - - png_ptr->zstream.avail_out + key_size + 1)); + (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_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; + png_ptr->zstream.avail_out; *(text + text_size) = '\0'; } + else { png_charp tmp; tmp = text; text = (png_charp)png_malloc(png_ptr, text_size + - (png_ptr->zbuf_size - - png_ptr->zstream.avail_out + 1)); + (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); + png_ptr->zbuf_size - png_ptr->zstream.avail_out); text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out; *(text + text_size) = '\0'; } + if (ret != Z_STREAM_END) { png_ptr->zstream.next_out = png_ptr->zbuf; @@ -1478,10 +1508,9 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr) png_sizeof(png_text)); text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt; text_ptr->key = key; -#ifdef PNG_iTXt_SUPPORTED + text_ptr->itxt_length = 0; text_ptr->lang = NULL; text_ptr->lang_key = NULL; -#endif text_ptr->text = text; ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); @@ -1490,7 +1519,7 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr) png_free(png_ptr, text_ptr); if (ret) - png_warning(png_ptr, "Insufficient memory to store text chunk"); + png_warning(png_ptr, "Insufficient memory to store text chunk"); } } #endif @@ -1498,13 +1527,14 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr) #ifdef PNG_READ_iTXt_SUPPORTED void /* PRIVATE */ png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 - length) + length) { if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) - { - png_error(png_ptr, "Out of place iTXt"); - info_ptr = info_ptr; /* To quiet some compiler warnings */ - } + { + PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */ + png_error(png_ptr, "Out of place iTXt"); + /*NOT REACHED*/ + } #ifdef PNG_MAX_MALLOC_64K png_ptr->skip_length = 0; /* This may not be necessary */ @@ -1518,7 +1548,7 @@ png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 #endif png_ptr->current_text = (png_charp)png_malloc(png_ptr, - (png_size_t)(length + 1)); + (png_size_t)(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; @@ -1544,6 +1574,7 @@ png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr) png_ptr->current_text_left -= text_size; png_ptr->current_text_ptr += text_size; } + if (!(png_ptr->current_text_left)) { png_textp text_ptr; @@ -1587,15 +1618,15 @@ png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr) if (lang_key < key + png_ptr->current_text_size - 1) { - for (; *text; text++) - /* Empty loop */ ; + for (; *text; text++) + /* Empty loop */ ; } if (text < key + png_ptr->current_text_size) text++; text_ptr = (png_textp)png_malloc(png_ptr, - png_sizeof(png_text)); + png_sizeof(png_text)); text_ptr->compression = comp_flag + 2; text_ptr->key = key; @@ -1622,7 +1653,7 @@ png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr) */ void /* PRIVATE */ png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 - length) + length) { png_uint_32 skip = 0; @@ -1630,15 +1661,15 @@ png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 { #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != - PNG_HANDLE_CHUNK_ALWAYS + PNG_HANDLE_CHUNK_ALWAYS #ifdef PNG_READ_USER_CHUNKS_SUPPORTED - && png_ptr->read_user_chunk_fn == NULL + && png_ptr->read_user_chunk_fn == NULL #endif - ) + ) #endif png_chunk_error(png_ptr, "unknown critical chunk"); - info_ptr = info_ptr; /* To quiet some compiler warnings */ + PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */ } #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED @@ -1647,16 +1678,16 @@ png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 #ifdef PNG_MAX_MALLOC_64K if (length > (png_uint_32)65535L) { - png_warning(png_ptr, "unknown chunk too large to fit in memory"); - skip = length - (png_uint_32)65535L; - length = (png_uint_32)65535L; + png_warning(png_ptr, "unknown chunk too large to fit in memory"); + skip = length - (png_uint_32)65535L; + length = (png_uint_32)65535L; } #endif png_memcpy((png_charp)png_ptr->unknown_chunk.name, - (png_charp)png_ptr->chunk_name, - png_sizeof(png_ptr->unknown_chunk.name)); + (png_charp)png_ptr->chunk_name, + png_sizeof(png_ptr->unknown_chunk.name)); png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name) - 1] - = '\0'; + = '\0'; png_ptr->unknown_chunk.size = (png_size_t)length; @@ -1666,7 +1697,7 @@ png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 else { png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, - (png_size_t)length); + (png_size_t)length); png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length); } @@ -1676,7 +1707,7 @@ png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 /* Callback to user unknown chunk handler */ int ret; ret = (*(png_ptr->read_user_chunk_fn)) - (png_ptr, &png_ptr->unknown_chunk); + (png_ptr, &png_ptr->unknown_chunk); if (ret < 0) png_chunk_error(png_ptr, "error in user chunk"); @@ -1685,16 +1716,16 @@ png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 { if (!(png_ptr->chunk_name[0] & 0x20)) if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != - PNG_HANDLE_CHUNK_ALWAYS) + PNG_HANDLE_CHUNK_ALWAYS) png_chunk_error(png_ptr, "unknown critical chunk"); png_set_unknown_chunks(png_ptr, info_ptr, - &png_ptr->unknown_chunk, 1); + &png_ptr->unknown_chunk, 1); } } else #endif - png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1); + png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1); png_free(png_ptr, png_ptr->unknown_chunk.data); png_ptr->unknown_chunk.data = NULL; } @@ -1728,8 +1759,8 @@ png_push_have_row(png_structp png_ptr, png_bytep row) } void PNGAPI -png_progressive_combine_row(png_structp png_ptr, - png_bytep old_row, png_bytep new_row) +png_progressive_combine_row (png_structp png_ptr, png_bytep old_row, + png_const_bytep new_row) { PNG_CONST int FARDATA png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff}; @@ -1743,8 +1774,8 @@ png_progressive_combine_row(png_structp png_ptr, void PNGAPI png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr, - png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn, - png_progressive_end_ptr end_fn) + png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn, + png_progressive_end_ptr end_fn) { if (png_ptr == NULL) return; diff --git a/harbour/src/3rd/png/pngpriv.h b/harbour/src/3rd/png/pngpriv.h index 7112c8da11..939da172f4 100644 --- a/harbour/src/3rd/png/pngpriv.h +++ b/harbour/src/3rd/png/pngpriv.h @@ -1,12 +1,13 @@ /* pngpriv.h - private declarations for use inside libpng * - * libpng version 1.4.5 - December 9, 2010 * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2010 Glenn Randers-Pehrson + * Copyright (c) 1998-2011 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * + * Last changed in libpng 1.5.0 [January 6, 2011] + * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer * and license in png.h @@ -24,27 +25,131 @@ #ifndef PNGPRIV_H #define PNGPRIV_H -#ifndef PNG_VERSION_INFO_ONLY - +/* This is required for the definition of abort(), used as a last ditch + * error handler when all else fails. + */ #include +#define PNGLIB_BUILD +#ifdef PNG_USER_CONFIG +# include "pngusr.h" + /* These should have been defined in pngusr.h */ +# ifndef PNG_USER_PRIVATEBUILD +# define PNG_USER_PRIVATEBUILD "Custom libpng build" +# endif +# ifndef PNG_USER_DLLFNAME_POSTFIX +# define PNG_USER_DLLFNAME_POSTFIX "Cb" +# endif +#endif +#include "png.h" +#include "pnginfo.h" +#include "pngstru.h" + +/* This is used for 16 bit gamma tables - only the top level pointers are const, + * this could be changed: + */ +typedef PNG_CONST png_uint_16p FAR * png_const_uint_16pp; + +/* Added at libpng-1.2.9 */ +/* Moved to pngpriv.h at libpng-1.5.0 */ + +/* config.h is created by and PNG_CONFIGURE_LIBPNG is set by the "configure" + * script. We may need it here to get the correct configuration on things + * like limits. + */ +#ifdef PNG_CONFIGURE_LIBPNG +# ifdef HAVE_CONFIG_H +# include "config.h" +# endif +#endif + +/* Moved to pngpriv.h at libpng-1.5.0 */ +/* NOTE: some of these may have been used in external applications as + * these definitions were exposed in pngconf.h prior to 1.5. + */ + +/* If you are running on a machine where you cannot allocate more + * than 64K of memory at once, uncomment this. While libpng will not + * normally need that much memory in a chunk (unless you load up a very + * large file), zlib needs to know how big of a chunk it can use, and + * libpng thus makes sure to check any memory allocation to verify it + * will fit into memory. + * + * zlib provides 'MAXSEG_64K' which, if defined, indicates the + * same limit and pngconf.h (already included) sets the limit + * if certain operating systems are detected. + */ +#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K) +# define PNG_MAX_MALLOC_64K +#endif + +/* Unused formal parameter errors are removed using the following macro + * which is expected to have no bad effects on performance. Note that + * if you replace it with something other than whitespace, you must include + * the terminating semicolon. + */ +#ifndef PNG_UNUSED +# define PNG_UNUSED(param) param = param; +#endif + +/* Just a little check that someone hasn't tried to define something + * contradictory. + */ +#if (PNG_ZBUF_SIZE > 65536L) && defined(PNG_MAX_MALLOC_64K) +# undef PNG_ZBUF_SIZE +# define PNG_ZBUF_SIZE 65536L +#endif + +/* If warnings or errors are turned off the code is disabled + * or redirected here. + */ +#ifndef PNG_WARNINGS_SUPPORTED +# define png_warning(s1,s2) ((void)0) +# define png_chunk_warning(s1,s2) ((void)0) +#endif +#ifndef PNG_ERROR_TEXT_SUPPORTED +# define png_error(s1,s2) png_err(s1) +# define png_chunk_error(s1,s2) png_err(s1) +# define png_fixed_error(s1,s2) png_err(s1) +#endif + #ifndef PNG_EXTERN /* The functions exported by PNG_EXTERN are internal functions, which * aren't usually used outside the library (as far as I know), so it is * debatable if they should be exported at all. In the future, when it * is possible to have run-time registry of chunk-handling functions, - * some of these will be made available again. + * some of these might be made available again. # define PNG_EXTERN extern */ # define PNG_EXTERN #endif +/* Some fixed point APIs are still required even if not exported because + * they get used by the corresponding floating point APIs. This magic + * deals with this: + */ +#ifdef PNG_FIXED_POINT_SUPPORTED +# define PNGFAPI PNGAPI +#else +# define PNGFAPI /* PRIVATE */ +#endif + /* Other defines specific to compilers can go here. Try to keep * them inside an appropriate ifdef/endif pair for portability. */ +#if defined(PNG_FLOATING_POINT_SUPPORTED) ||\ + defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) + /* png.c requires the following ANSI-C constants if the conversion of + * floating point to ASCII is implemented therein: + * + * DBL_DIG Maximum number of decimal digits (can be set to any constant) + * DBL_MIN Smallest normalized fp number (can be set to an arbitrary value) + * DBL_MAX Maximum floating point number (can be set to an arbitrary value) + */ +# include -#ifdef PNG_FLOATING_POINT_SUPPORTED -# ifdef MACOS +# if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \ + defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC) /* We need to check that hasn't already been included earlier * as it seems it doesn't agree with , yet we should really use * if possible. @@ -63,11 +168,6 @@ # endif #endif -/* Codewarrior on NT has linking problems without this. */ -#if (defined(__MWERKS__) && defined(WIN32)) || defined(__STDC__) -# define PNG_ALWAYS_EXTERN -#endif - /* This provides the non-ANSI (far) memory allocation routines. */ #if defined(__TURBOC__) && defined(__MSDOS__) # include @@ -79,6 +179,86 @@ # include /* defines _WINDOWS_ macro */ #endif +/* Moved here around 1.5.0beta36 from pngconf.h */ +/* Users may want to use these so they are not private. Any library + * functions that are passed far data must be model-independent. + */ + +/* Memory model/platform independent fns */ +#ifndef PNG_ABORT +# ifdef _WINDOWS_ +# define PNG_ABORT() ExitProcess(0) +# else +# define PNG_ABORT() abort() +# endif +#endif + +#ifdef USE_FAR_KEYWORD +/* Use this to make far-to-near assignments */ +# define CHECK 1 +# define NOCHECK 0 +# define CVT_PTR(ptr) (png_far_to_near(png_ptr,ptr,CHECK)) +# define CVT_PTR_NOCHECK(ptr) (png_far_to_near(png_ptr,ptr,NOCHECK)) +# define png_strcpy _fstrcpy +# define png_strncpy _fstrncpy /* Added to v 1.2.6 */ +# define png_strlen _fstrlen +# define png_memcmp _fmemcmp /* SJT: added */ +# define png_memcpy _fmemcpy +# define png_memset _fmemset +# define png_sprintf sprintf +#else +# ifdef _WINDOWS_ /* Favor Windows over C runtime fns */ +# define CVT_PTR(ptr) (ptr) +# define CVT_PTR_NOCHECK(ptr) (ptr) +# define png_strcpy lstrcpyA +# define png_strncpy lstrcpynA +# define png_strlen lstrlenA +# define png_memcmp memcmp +# define png_memcpy CopyMemory +# define png_memset memset +# define png_sprintf wsprintfA +# else +# define CVT_PTR(ptr) (ptr) +# define CVT_PTR_NOCHECK(ptr) (ptr) +# define png_strcpy strcpy +# define png_strncpy strncpy /* Added to v 1.2.6 */ +# define png_strlen strlen +# define png_memcmp memcmp /* SJT: added */ +# define png_memcpy memcpy +# define png_memset memset +# define png_sprintf sprintf +# endif +#endif +/* End of memory model/platform independent support */ + +#ifndef PNG_NO_SNPRINTF +# ifdef _MSC_VER +# define png_snprintf _snprintf /* Added to v 1.2.19 */ +# define png_snprintf2 _snprintf +# define png_snprintf6 _snprintf +# else +# define png_snprintf snprintf /* Added to v 1.2.19 */ +# define png_snprintf2 snprintf +# define png_snprintf6 snprintf +# endif +#else + /* You don't have or don't want to use snprintf(). Caution: Using + * sprintf instead of snprintf exposes your application to accidental + * or malevolent buffer overflows. If you don't have snprintf() + * as a general rule you should provide one (you can get one from + * Portable OpenSSH). + */ +# define png_snprintf(s1,n,fmt,x1) png_sprintf(s1,fmt,x1) +# define png_snprintf2(s1,n,fmt,x1,x2) png_sprintf(s1,fmt,x1,x2) +# define png_snprintf6(s1,n,fmt,x1,x2,x3,x4,x5,x6) \ + png_sprintf(s1,fmt,x1,x2,x3,x4,x5,x6) +#endif +/* End of 1.5.0beta36 move from pngconf.h */ + +/* CONSTANTS and UTILITY MACROS + * These are used internally by libpng and not exposed in the API + */ + /* Various modes of operation. Note that after an init, mode is set to * zero automatically when the structure is created. */ @@ -104,7 +284,7 @@ #define PNG_SHIFT 0x0008 #define PNG_SWAP_BYTES 0x0010 #define PNG_INVERT_MONO 0x0020 -#define PNG_QUANTIZE 0x0040 /* formerly PNG_DITHER */ +#define PNG_QUANTIZE 0x0040 #define PNG_BACKGROUND 0x0080 #define PNG_BACKGROUND_EXPAND 0x0100 /* 0x0200 unused */ @@ -136,9 +316,7 @@ #define PNG_STRUCT_INFO 0x0002 /* Scaling factor for filter heuristic weighting calculations */ -#define PNG_WEIGHT_SHIFT 8 #define PNG_WEIGHT_FACTOR (1<<(PNG_WEIGHT_SHIFT)) -#define PNG_COST_SHIFT 3 #define PNG_COST_FACTOR (1<<(PNG_COST_SHIFT)) /* Flags for the png_ptr->flags rather than declaring a byte for each one */ @@ -183,6 +361,18 @@ #define PNG_FLAG_CRC_MASK (PNG_FLAG_CRC_ANCILLARY_MASK | \ PNG_FLAG_CRC_CRITICAL_MASK) +/* zlib.h declares a magic type 'uInt' that limits the amount of data that zlib + * can handle at once. This type need be no larger than 16 bits (so maximum of + * 65535), this define allows us to discover how big it is, but limited by the + * maximuum for png_size_t. The value can be overriden in a library build + * (pngusr.h, or set it in CPPFLAGS) and it works to set it to a considerably + * lower value (e.g. 255 works). A lower value may help memory usage (slightly) + * and may even improve performance on some systems (and degrade it on others.) + */ +#ifndef ZLIB_IO_MAX +# define ZLIB_IO_MAX ((uInt)-1) +#endif + /* Save typing and make code easier to understand */ #define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \ @@ -201,7 +391,46 @@ * integers, "value" a variable. Added to libpng-1.2.6 JB */ #define PNG_OUT_OF_RANGE(value, ideal, delta) \ - ( (value) < (ideal)-(delta) || (value) > (ideal)+(delta) ) + ( (value) < (ideal)-(delta) || (value) > (ideal)+(delta) ) + +/* Conversions between fixed and floating point, only defined if + * required (to make sure the code doesn't accidentally use float + * when it is supposedly disabled.) + */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +/* The floating point conversion can't overflow, though it can and + * does lose accuracy relative to the original fixed point value. + * In practice this doesn't matter because png_fixed_point only + * stores numbers with very low precision. The png_ptr and s + * arguments are unused by default but are there in case error + * checking becomes a requirement. + */ +#define png_float(png_ptr, fixed, s) (.00001 * (fixed)) + +/* The fixed point conversion performs range checking and evaluates + * its argument multiple times, so must be used with care. The + * range checking uses the PNG specification values for a signed + * 32 bit fixed point value except that the values are deliberately + * rounded-to-zero to an integral value - 21474 (21474.83 is roughly + * (2^31-1) * 100000). 's' is a string that describes the value being + * converted. + * + * NOTE: this macro will raise a png_error if the range check fails, + * therefore it is normally only appropriate to use this on values + * that come from API calls or other sources where an out of range + * error indicates a programming error, not a data error! + * + * NOTE: by default this is off - the macro is not used - because the + * function call saves a lot of code. + */ +#ifdef PNG_FIXED_POINT_MACRO_SUPPORTED +#define png_fixed(png_ptr, fp, s) ((fp) <= 21474 && (fp) >= -21474 ?\ + ((png_fixed_point)(100000 * (fp))) : (png_fixed_error(png_ptr, s),0)) +#else +PNG_EXTERN png_fixed_point png_fixed PNGARG((png_structp png_ptr, double fp, + png_const_charp text)); +#endif +#endif /* Constant strings for known chunk types. If you need to add a chunk, * define the name here, and add an invocation of the macro wherever it's @@ -243,52 +472,57 @@ extern "C" { */ /* Allocate memory for an internal libpng struct */ -PNG_EXTERN png_voidp png_create_struct PNGARG((int type)); +PNG_EXTERN PNG_FUNCTION(png_voidp,png_create_struct,PNGARG((int type)), + PNG_ALLOCATED); /* 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 - malloc_fn, png_voidp mem_ptr)); +PNG_EXTERN PNG_FUNCTION(png_voidp,png_create_struct_2, + PNGARG((int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)), + PNG_ALLOCATED); PNG_EXTERN void png_destroy_struct_2 PNGARG((png_voidp struct_ptr, - png_free_ptr free_fn, png_voidp mem_ptr)); + png_free_ptr free_fn, png_voidp mem_ptr)); /* 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)); + png_infop info_ptr)); /* Function to allocate memory for zlib. PNGAPI is disallowed. */ -PNG_EXTERN voidpf png_zalloc PNGARG((voidpf png_ptr, uInt items, uInt size)); +PNG_EXTERN PNG_FUNCTION(voidpf,png_zalloc,PNGARG((voidpf png_ptr, uInt items, + uInt size)),PNG_ALLOCATED); /* Function to free memory for zlib. PNGAPI is disallowed. */ PNG_EXTERN void png_zfree PNGARG((voidpf png_ptr, voidpf ptr)); -/* Next four functions are used internally as callbacks. PNGAPI is required - * but not PNG_EXPORT. PNGAPI added at libpng version 1.2.3. */ +/* Next four functions are used internally as callbacks. PNGCBAPI is required + * but not PNG_EXPORT. PNGAPI added at libpng version 1.2.3, changed to + * PNGCBAPI at 1.5.0 + */ -PNG_EXTERN void PNGAPI png_default_read_data PNGARG((png_structp png_ptr, - png_bytep data, png_size_t length)); +PNG_EXTERN void PNGCBAPI png_default_read_data PNGARG((png_structp png_ptr, + png_bytep data, png_size_t length)); #ifdef PNG_PROGRESSIVE_READ_SUPPORTED -PNG_EXTERN void PNGAPI png_push_fill_buffer PNGARG((png_structp png_ptr, - png_bytep buffer, png_size_t length)); +PNG_EXTERN void PNGCBAPI png_push_fill_buffer PNGARG((png_structp png_ptr, + png_bytep buffer, png_size_t length)); #endif -PNG_EXTERN void PNGAPI png_default_write_data PNGARG((png_structp png_ptr, - png_bytep data, png_size_t length)); +PNG_EXTERN void PNGCBAPI png_default_write_data PNGARG((png_structp png_ptr, + png_bytep data, png_size_t length)); #ifdef PNG_WRITE_FLUSH_SUPPORTED -#ifdef PNG_STDIO_SUPPORTED -PNG_EXTERN void PNGAPI png_default_flush PNGARG((png_structp png_ptr)); -#endif +# ifdef PNG_STDIO_SUPPORTED +PNG_EXTERN void PNGCBAPI png_default_flush PNGARG((png_structp png_ptr)); +# endif #endif /* 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 */ -PNG_EXTERN void png_write_data PNGARG((png_structp png_ptr, png_bytep data, - png_size_t length)); +PNG_EXTERN void png_write_data PNGARG((png_structp png_ptr, + png_const_bytep data, png_size_t length)); /* Read and check the PNG file signature */ PNG_EXTERN void png_read_sig PNGARG((png_structp png_ptr, png_infop info_ptr)); @@ -298,18 +532,18 @@ PNG_EXTERN png_uint_32 png_read_chunk_header PNGARG((png_structp png_ptr)); /* Read data from whatever input you are using into the "data" buffer */ PNG_EXTERN void png_read_data PNGARG((png_structp png_ptr, png_bytep data, - png_size_t length)); + png_size_t length)); /* 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)); + png_size_t length)); /* Decompress data in a chunk that uses compression */ #if defined(PNG_zTXt_SUPPORTED) || defined(PNG_iTXt_SUPPORTED) || \ defined(PNG_iCCP_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) PNG_EXTERN void png_decompress_chunk PNGARG((png_structp png_ptr, - int comp_type, png_size_t chunklength, png_size_t prefix_length, - png_size_t *data_length)); + int comp_type, png_size_t chunklength, png_size_t prefix_length, + png_size_t *data_length)); #endif /* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */ @@ -322,8 +556,8 @@ PNG_EXTERN int png_crc_error PNGARG((png_structp png_ptr)); * passing a maximum of 64K on systems that have this as a memory limit, * since this is the maximum buffer size we can specify. */ -PNG_EXTERN void png_calculate_crc PNGARG((png_structp png_ptr, png_bytep ptr, - png_size_t length)); +PNG_EXTERN void png_calculate_crc PNGARG((png_structp png_ptr, + png_const_bytep ptr, png_size_t length)); #ifdef PNG_WRITE_FLUSH_SUPPORTED PNG_EXTERN void png_flush PNGARG((png_structp png_ptr)); @@ -335,138 +569,132 @@ PNG_EXTERN void png_flush PNGARG((png_structp png_ptr)); * information. */ PNG_EXTERN void png_write_IHDR PNGARG((png_structp png_ptr, png_uint_32 width, - png_uint_32 height, - int bit_depth, int color_type, int compression_method, int filter_method, - int interlace_method)); + png_uint_32 height, + int bit_depth, int color_type, int compression_method, int filter_method, + int interlace_method)); -PNG_EXTERN void png_write_PLTE PNGARG((png_structp png_ptr, png_colorp palette, - png_uint_32 num_pal)); +PNG_EXTERN void png_write_PLTE PNGARG((png_structp png_ptr, + png_const_colorp palette, png_uint_32 num_pal)); PNG_EXTERN void png_write_IDAT PNGARG((png_structp png_ptr, png_bytep data, - png_size_t length)); + png_size_t length)); PNG_EXTERN void png_write_IEND PNGARG((png_structp png_ptr)); #ifdef PNG_WRITE_gAMA_SUPPORTED -#ifdef PNG_FLOATING_POINT_SUPPORTED +# ifdef PNG_FLOATING_POINT_SUPPORTED PNG_EXTERN void png_write_gAMA PNGARG((png_structp png_ptr, double file_gamma)); -#endif -#ifdef PNG_FIXED_POINT_SUPPORTED +# endif +# ifdef PNG_FIXED_POINT_SUPPORTED PNG_EXTERN void png_write_gAMA_fixed PNGARG((png_structp png_ptr, png_fixed_point file_gamma)); -#endif +# endif #endif #ifdef PNG_WRITE_sBIT_SUPPORTED -PNG_EXTERN void png_write_sBIT PNGARG((png_structp png_ptr, png_color_8p sbit, - int color_type)); +PNG_EXTERN void png_write_sBIT PNGARG((png_structp png_ptr, + png_const_color_8p sbit, int color_type)); #endif #ifdef PNG_WRITE_cHRM_SUPPORTED -#ifdef PNG_FLOATING_POINT_SUPPORTED +# ifdef PNG_FLOATING_POINT_SUPPORTED PNG_EXTERN void png_write_cHRM PNGARG((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)); -#endif + 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_EXTERN void png_write_cHRM_fixed PNGARG((png_structp png_ptr, - png_fixed_point int_white_x, png_fixed_point int_white_y, - png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point - int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x, - png_fixed_point int_blue_y)); + png_fixed_point int_white_x, png_fixed_point int_white_y, + png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point + int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x, + png_fixed_point int_blue_y)); #endif #ifdef PNG_WRITE_sRGB_SUPPORTED PNG_EXTERN void png_write_sRGB PNGARG((png_structp png_ptr, - int intent)); + int intent)); #endif #ifdef 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)); + png_const_charp name, int compression_type, + png_const_charp profile, int proflen)); /* Note to maintainer: profile should be png_bytep */ #endif #ifdef PNG_WRITE_sPLT_SUPPORTED PNG_EXTERN void png_write_sPLT PNGARG((png_structp png_ptr, - png_sPLT_tp palette)); + png_const_sPLT_tp palette)); #endif #ifdef 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)); +PNG_EXTERN void png_write_tRNS PNGARG((png_structp png_ptr, + png_const_bytep trans, png_const_color_16p values, int number, + int color_type)); #endif #ifdef PNG_WRITE_bKGD_SUPPORTED PNG_EXTERN void png_write_bKGD PNGARG((png_structp png_ptr, - png_color_16p values, int color_type)); + png_const_color_16p values, int color_type)); #endif #ifdef PNG_WRITE_hIST_SUPPORTED -PNG_EXTERN void png_write_hIST PNGARG((png_structp png_ptr, png_uint_16p hist, - int num_hist)); +PNG_EXTERN void png_write_hIST PNGARG((png_structp png_ptr, + png_const_uint_16p hist, int num_hist)); #endif #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)); + png_const_charp key, png_charpp new_key)); #endif #ifdef PNG_WRITE_tEXt_SUPPORTED -PNG_EXTERN void png_write_tEXt PNGARG((png_structp png_ptr, png_charp key, - png_charp text, png_size_t text_len)); +PNG_EXTERN void png_write_tEXt PNGARG((png_structp png_ptr, png_const_charp key, + png_const_charp text, png_size_t text_len)); #endif #ifdef PNG_WRITE_zTXt_SUPPORTED -PNG_EXTERN void png_write_zTXt PNGARG((png_structp png_ptr, png_charp key, - png_charp text, png_size_t text_len, int compression)); +PNG_EXTERN void png_write_zTXt PNGARG((png_structp png_ptr, png_const_charp key, + png_const_charp text, png_size_t text_len, int compression)); #endif #ifdef 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 lang_key, - png_charp text)); + int compression, png_const_charp key, png_const_charp lang, + png_const_charp lang_key, png_const_charp text)); #endif #ifdef PNG_TEXT_SUPPORTED /* Added at version 1.0.14 and 1.2.4 */ PNG_EXTERN int png_set_text_2 PNGARG((png_structp png_ptr, - png_infop info_ptr, png_textp text_ptr, int num_text)); + png_infop info_ptr, png_const_textp text_ptr, int num_text)); #endif #ifdef PNG_WRITE_oFFs_SUPPORTED PNG_EXTERN void png_write_oFFs PNGARG((png_structp png_ptr, - png_int_32 x_offset, png_int_32 y_offset, int unit_type)); + png_int_32 x_offset, png_int_32 y_offset, int unit_type)); #endif #ifdef PNG_WRITE_pCAL_SUPPORTED PNG_EXTERN void png_write_pCAL PNGARG((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)); + png_int_32 X0, png_int_32 X1, int type, int nparams, + png_const_charp units, png_charpp params)); #endif #ifdef PNG_WRITE_pHYs_SUPPORTED PNG_EXTERN void png_write_pHYs PNGARG((png_structp png_ptr, - png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit, - int unit_type)); + png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit, + int unit_type)); #endif #ifdef PNG_WRITE_tIME_SUPPORTED PNG_EXTERN void png_write_tIME PNGARG((png_structp png_ptr, - png_timep mod_time)); + png_const_timep mod_time)); #endif #ifdef PNG_WRITE_sCAL_SUPPORTED -#if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_STDIO_SUPPORTED) -PNG_EXTERN void png_write_sCAL PNGARG((png_structp png_ptr, - int unit, double width, double height)); -#else -#ifdef PNG_FIXED_POINT_SUPPORTED PNG_EXTERN void png_write_sCAL_s PNGARG((png_structp png_ptr, - int unit, png_charp width, png_charp height)); -#endif -#endif + int unit, png_const_charp width, png_const_charp height)); #endif /* Called when finished processing a row of data */ @@ -475,20 +703,15 @@ PNG_EXTERN void png_write_finish_row PNGARG((png_structp png_ptr)); /* Internal use only. Called before first row of data */ PNG_EXTERN void png_write_start_row PNGARG((png_structp png_ptr)); -#ifdef PNG_READ_GAMMA_SUPPORTED -PNG_EXTERN void png_build_gamma_table PNGARG((png_structp png_ptr, - png_byte bit_depth)); -#endif - /* Combine a row of data, dealing with alpha, etc. if requested */ PNG_EXTERN void png_combine_row PNGARG((png_structp png_ptr, png_bytep row, - int mask)); + int mask)); #ifdef PNG_READ_INTERLACING_SUPPORTED /* Expand an interlaced row */ /* OLD pre-1.0.9 interface: PNG_EXTERN void png_do_read_interlace PNGARG((png_row_infop row_info, - png_bytep row, int pass, png_uint_32 transformations)); + png_bytep row, int pass, png_uint_32 transformations)); */ PNG_EXTERN void png_do_read_interlace PNGARG((png_structp png_ptr)); #endif @@ -498,20 +721,21 @@ PNG_EXTERN void png_do_read_interlace PNGARG((png_structp png_ptr)); #ifdef PNG_WRITE_INTERLACING_SUPPORTED /* Grab pixels out of a row for an interlaced pass */ PNG_EXTERN void png_do_write_interlace PNGARG((png_row_infop row_info, - png_bytep row, int pass)); + png_bytep row, int pass)); #endif /* Unfilter a row */ PNG_EXTERN void png_read_filter_row PNGARG((png_structp png_ptr, - png_row_infop row_info, png_bytep row, png_bytep prev_row, int filter)); + png_row_infop row_info, png_bytep row, png_const_bytep prev_row, + int filter)); /* Choose the best filter to use and filter the row data */ PNG_EXTERN void png_write_find_filter PNGARG((png_structp png_ptr, - png_row_infop row_info)); + png_row_infop row_info)); /* Write out the filtered row. */ PNG_EXTERN void png_write_filtered_row PNGARG((png_structp png_ptr, - png_bytep filtered_row)); + png_bytep filtered_row)); /* Finish a row while reading, dealing with interlacing passes, etc. */ PNG_EXTERN void png_read_finish_row PNGARG((png_structp png_ptr)); @@ -519,88 +743,97 @@ PNG_EXTERN void png_read_finish_row PNGARG((png_structp png_ptr)); PNG_EXTERN void png_read_start_row PNGARG((png_structp png_ptr)); /* Optional call to update the users info structure */ PNG_EXTERN void png_read_transform_info PNGARG((png_structp png_ptr, - png_infop info_ptr)); + png_infop info_ptr)); /* These are the functions that do the transformations */ #ifdef PNG_READ_FILLER_SUPPORTED PNG_EXTERN void png_do_read_filler PNGARG((png_row_infop row_info, - png_bytep row, png_uint_32 filler, png_uint_32 flags)); + png_bytep row, png_uint_32 filler, png_uint_32 flags)); #endif #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED PNG_EXTERN void png_do_read_swap_alpha PNGARG((png_row_infop row_info, - png_bytep row)); + png_bytep row)); #endif #ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED PNG_EXTERN void png_do_write_swap_alpha PNGARG((png_row_infop row_info, - png_bytep row)); + png_bytep row)); #endif #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED PNG_EXTERN void png_do_read_invert_alpha PNGARG((png_row_infop row_info, - png_bytep row)); + png_bytep row)); #endif #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED PNG_EXTERN void png_do_write_invert_alpha PNGARG((png_row_infop row_info, - png_bytep row)); + png_bytep row)); #endif #if defined(PNG_WRITE_FILLER_SUPPORTED) || \ defined(PNG_READ_STRIP_ALPHA_SUPPORTED) PNG_EXTERN void png_do_strip_filler PNGARG((png_row_infop row_info, - png_bytep row, png_uint_32 flags)); + png_bytep row, png_uint_32 flags)); #endif +#ifdef PNG_16BIT_SUPPORTED #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) -PNG_EXTERN void png_do_swap PNGARG((png_row_infop row_info, png_bytep row)); +PNG_EXTERN void png_do_swap PNGARG((png_row_infop row_info, + png_bytep row)); +#endif #endif #if defined(PNG_READ_PACKSWAP_SUPPORTED) || \ defined(PNG_WRITE_PACKSWAP_SUPPORTED) -PNG_EXTERN void png_do_packswap PNGARG((png_row_infop row_info, png_bytep row)); +PNG_EXTERN void png_do_packswap PNGARG((png_row_infop row_info, + png_bytep row)); #endif #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -PNG_EXTERN int png_do_rgb_to_gray PNGARG((png_structp png_ptr, png_row_infop - row_info, png_bytep row)); +PNG_EXTERN int png_do_rgb_to_gray PNGARG((png_structp png_ptr, + png_row_infop row_info, png_bytep row)); #endif #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED PNG_EXTERN void png_do_gray_to_rgb PNGARG((png_row_infop row_info, - png_bytep row)); + png_bytep row)); #endif #ifdef PNG_READ_PACK_SUPPORTED -PNG_EXTERN void png_do_unpack PNGARG((png_row_infop row_info, png_bytep row)); +PNG_EXTERN void png_do_unpack PNGARG((png_row_infop row_info, + png_bytep row)); #endif #ifdef PNG_READ_SHIFT_SUPPORTED -PNG_EXTERN void png_do_unshift PNGARG((png_row_infop row_info, png_bytep row, - png_color_8p sig_bits)); +PNG_EXTERN void png_do_unshift PNGARG((png_row_infop row_info, + png_bytep row, png_const_color_8p sig_bits)); #endif #if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED) -PNG_EXTERN void png_do_invert PNGARG((png_row_infop row_info, png_bytep row)); +PNG_EXTERN void png_do_invert PNGARG((png_row_infop row_info, + png_bytep row)); #endif #ifdef PNG_READ_16_TO_8_SUPPORTED -PNG_EXTERN void png_do_chop PNGARG((png_row_infop row_info, png_bytep row)); +PNG_EXTERN void png_do_chop PNGARG((png_row_infop row_info, + png_bytep row)); #endif #ifdef PNG_READ_QUANTIZE_SUPPORTED PNG_EXTERN void png_do_quantize PNGARG((png_row_infop row_info, - png_bytep row, png_bytep palette_lookup, png_bytep quantize_lookup)); + png_bytep row, png_const_bytep palette_lookup, + png_const_bytep quantize_lookup)); # ifdef PNG_CORRECT_PALETTE_SUPPORTED PNG_EXTERN void png_correct_palette PNGARG((png_structp png_ptr, - png_colorp palette, int num_palette)); + png_colorp palette, int num_palette)); # endif #endif #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) -PNG_EXTERN void png_do_bgr PNGARG((png_row_infop row_info, png_bytep row)); +PNG_EXTERN void png_do_bgr PNGARG((png_row_infop row_info, + png_bytep row)); #endif #ifdef PNG_WRITE_PACK_SUPPORTED @@ -609,35 +842,38 @@ PNG_EXTERN void png_do_pack PNGARG((png_row_infop row_info, #endif #ifdef PNG_WRITE_SHIFT_SUPPORTED -PNG_EXTERN void png_do_shift PNGARG((png_row_infop row_info, png_bytep row, - png_color_8p bit_depth)); +PNG_EXTERN void png_do_shift PNGARG((png_row_infop row_info, + png_bytep row, png_const_color_8p bit_depth)); #endif #ifdef PNG_READ_BACKGROUND_SUPPORTED -#ifdef PNG_READ_GAMMA_SUPPORTED -PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row, - png_color_16p trans_color, png_color_16p background, - png_color_16p background_1, - png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1, - png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1, - png_uint_16pp gamma_16_to_1, int gamma_shift)); -#else -PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row, - png_color_16p trans_color, png_color_16p background)); -#endif +# ifdef PNG_READ_GAMMA_SUPPORTED +PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, + png_bytep row, png_const_color_16p trans_color, + png_const_color_16p background, png_const_color_16p background_1, + png_const_bytep gamma_table, png_const_bytep gamma_from_1, + png_const_bytep gamma_to_1, png_const_uint_16pp gamma_16, + png_const_uint_16pp gamma_16_from_1, png_const_uint_16pp gamma_16_to_1, + int gamma_shift)); +# else +PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, + png_bytep row, png_const_color_16p trans_color, + png_const_color_16p background)); +# endif #endif #ifdef PNG_READ_GAMMA_SUPPORTED -PNG_EXTERN void png_do_gamma PNGARG((png_row_infop row_info, png_bytep row, - png_bytep gamma_table, png_uint_16pp gamma_16_table, - int gamma_shift)); +PNG_EXTERN void png_do_gamma PNGARG((png_row_infop row_info, + png_bytep row, png_const_bytep gamma_table, + png_const_uint_16pp gamma_16_table, int gamma_shift)); #endif #ifdef PNG_READ_EXPAND_SUPPORTED PNG_EXTERN void png_do_expand_palette PNGARG((png_row_infop row_info, - png_bytep row, png_colorp palette, png_bytep trans, int num_trans)); + png_bytep row, png_const_colorp palette, png_const_bytep trans, + int num_trans)); PNG_EXTERN void png_do_expand PNGARG((png_row_infop row_info, - png_bytep row, png_color_16p trans_value)); + png_bytep row, png_const_color_16p trans_color)); #endif /* The following decodes the appropriate chunks, and does error correction, @@ -646,102 +882,102 @@ PNG_EXTERN void png_do_expand PNGARG((png_row_infop row_info, /* Decode the IHDR chunk */ PNG_EXTERN void png_handle_IHDR PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); + png_uint_32 length)); PNG_EXTERN void png_handle_PLTE PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); + png_uint_32 length)); PNG_EXTERN void png_handle_IEND PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); + png_uint_32 length)); #ifdef PNG_READ_bKGD_SUPPORTED PNG_EXTERN void png_handle_bKGD PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); + png_uint_32 length)); #endif #ifdef PNG_READ_cHRM_SUPPORTED PNG_EXTERN void png_handle_cHRM PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); + png_uint_32 length)); #endif #ifdef PNG_READ_gAMA_SUPPORTED PNG_EXTERN void png_handle_gAMA PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); + png_uint_32 length)); #endif #ifdef PNG_READ_hIST_SUPPORTED PNG_EXTERN void png_handle_hIST PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); + png_uint_32 length)); #endif #ifdef PNG_READ_iCCP_SUPPORTED PNG_EXTERN void png_handle_iCCP PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); + png_uint_32 length)); #endif /* PNG_READ_iCCP_SUPPORTED */ #ifdef PNG_READ_iTXt_SUPPORTED PNG_EXTERN void png_handle_iTXt PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); + png_uint_32 length)); #endif #ifdef PNG_READ_oFFs_SUPPORTED PNG_EXTERN void png_handle_oFFs PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); + png_uint_32 length)); #endif #ifdef PNG_READ_pCAL_SUPPORTED PNG_EXTERN void png_handle_pCAL PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); + png_uint_32 length)); #endif #ifdef PNG_READ_pHYs_SUPPORTED PNG_EXTERN void png_handle_pHYs PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); + png_uint_32 length)); #endif #ifdef PNG_READ_sBIT_SUPPORTED PNG_EXTERN void png_handle_sBIT PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); + png_uint_32 length)); #endif #ifdef PNG_READ_sCAL_SUPPORTED PNG_EXTERN void png_handle_sCAL PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); + png_uint_32 length)); #endif #ifdef PNG_READ_sPLT_SUPPORTED PNG_EXTERN void png_handle_sPLT PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); + png_uint_32 length)); #endif /* PNG_READ_sPLT_SUPPORTED */ #ifdef PNG_READ_sRGB_SUPPORTED PNG_EXTERN void png_handle_sRGB PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); + png_uint_32 length)); #endif #ifdef PNG_READ_tEXt_SUPPORTED PNG_EXTERN void png_handle_tEXt PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); + png_uint_32 length)); #endif #ifdef PNG_READ_tIME_SUPPORTED PNG_EXTERN void png_handle_tIME PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); + png_uint_32 length)); #endif #ifdef PNG_READ_tRNS_SUPPORTED PNG_EXTERN void png_handle_tRNS PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); + png_uint_32 length)); #endif #ifdef PNG_READ_zTXt_SUPPORTED PNG_EXTERN void png_handle_zTXt PNGARG((png_structp png_ptr, png_infop info_ptr, - png_uint_32 length)); + png_uint_32 length)); #endif PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr, - png_infop info_ptr, png_uint_32 length)); + png_infop info_ptr, png_uint_32 length)); PNG_EXTERN void png_check_chunk_name PNGARG((png_structp png_ptr, - png_bytep chunk_name)); + png_const_bytep chunk_name)); /* Handle the transformations for reading and writing */ PNG_EXTERN void png_do_read_transformations PNGARG((png_structp png_ptr)); @@ -751,19 +987,19 @@ PNG_EXTERN void png_init_read_transformations PNGARG((png_structp png_ptr)); #ifdef PNG_PROGRESSIVE_READ_SUPPORTED PNG_EXTERN void png_push_read_chunk PNGARG((png_structp png_ptr, - png_infop info_ptr)); + png_infop info_ptr)); PNG_EXTERN void png_push_read_sig PNGARG((png_structp png_ptr, - png_infop info_ptr)); + png_infop info_ptr)); PNG_EXTERN void png_push_check_crc PNGARG((png_structp png_ptr)); PNG_EXTERN void png_push_crc_skip PNGARG((png_structp png_ptr, - png_uint_32 length)); + png_uint_32 length)); PNG_EXTERN void png_push_crc_finish PNGARG((png_structp png_ptr)); PNG_EXTERN void png_push_save_buffer PNGARG((png_structp png_ptr)); PNG_EXTERN void png_push_restore_buffer PNGARG((png_structp png_ptr, - png_bytep buffer, png_size_t buffer_length)); + png_bytep buffer, png_size_t buffer_length)); PNG_EXTERN void png_push_read_IDAT PNGARG((png_structp png_ptr)); PNG_EXTERN void png_process_IDAT_data PNGARG((png_structp png_ptr, - png_bytep buffer, png_size_t buffer_length)); + png_bytep buffer, png_size_t buffer_length)); PNG_EXTERN void png_push_process_row PNGARG((png_structp png_ptr)); PNG_EXTERN void png_push_handle_unknown PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); @@ -773,185 +1009,232 @@ PNG_EXTERN void png_push_have_end PNGARG((png_structp png_ptr, png_infop info_ptr)); PNG_EXTERN void png_push_have_row PNGARG((png_structp png_ptr, png_bytep row)); PNG_EXTERN void png_push_read_end PNGARG((png_structp png_ptr, - png_infop info_ptr)); + png_infop info_ptr)); PNG_EXTERN void png_process_some_data PNGARG((png_structp png_ptr, - png_infop info_ptr)); + png_infop info_ptr)); PNG_EXTERN void png_read_push_finish_row PNGARG((png_structp png_ptr)); -#ifdef PNG_READ_tEXt_SUPPORTED +# ifdef PNG_READ_tEXt_SUPPORTED PNG_EXTERN void png_push_handle_tEXt PNGARG((png_structp png_ptr, - png_infop info_ptr, png_uint_32 length)); + png_infop info_ptr, png_uint_32 length)); PNG_EXTERN void png_push_read_tEXt PNGARG((png_structp png_ptr, - png_infop info_ptr)); -#endif -#ifdef PNG_READ_zTXt_SUPPORTED + png_infop info_ptr)); +# endif +# ifdef PNG_READ_zTXt_SUPPORTED PNG_EXTERN void png_push_handle_zTXt PNGARG((png_structp png_ptr, - png_infop info_ptr, png_uint_32 length)); + png_infop info_ptr, png_uint_32 length)); PNG_EXTERN void png_push_read_zTXt PNGARG((png_structp png_ptr, - png_infop info_ptr)); -#endif -#ifdef PNG_READ_iTXt_SUPPORTED + png_infop info_ptr)); +# endif +# ifdef 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_infop info_ptr, png_uint_32 length)); PNG_EXTERN void png_push_read_iTXt PNGARG((png_structp png_ptr, - png_infop info_ptr)); -#endif + png_infop info_ptr)); +# endif #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ #ifdef PNG_MNG_FEATURES_SUPPORTED PNG_EXTERN void png_do_read_intrapixel PNGARG((png_row_infop row_info, - png_bytep row)); + png_bytep row)); PNG_EXTERN void png_do_write_intrapixel PNGARG((png_row_infop row_info, - png_bytep row)); + png_bytep row)); #endif /* Added at libpng version 1.4.0 */ -#ifdef PNG_cHRM_SUPPORTED +#ifdef PNG_CHECK_cHRM_SUPPORTED PNG_EXTERN int png_check_cHRM_fixed PNGARG((png_structp png_ptr, - png_fixed_point int_white_x, png_fixed_point int_white_y, - png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point - int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x, - png_fixed_point int_blue_y)); + png_fixed_point int_white_x, png_fixed_point int_white_y, + png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point + int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x, + png_fixed_point int_blue_y)); #endif -#ifdef PNG_cHRM_SUPPORTED #ifdef PNG_CHECK_cHRM_SUPPORTED /* Added at libpng version 1.2.34 and 1.4.0 */ +/* Currently only used by png_check_cHRM_fixed */ PNG_EXTERN void png_64bit_product PNGARG((long v1, long v2, - unsigned long *hi_product, unsigned long *lo_product)); -#endif + unsigned long *hi_product, unsigned long *lo_product)); #endif /* Added at libpng version 1.4.0 */ PNG_EXTERN void png_check_IHDR PNGARG((png_structp png_ptr, - png_uint_32 width, png_uint_32 height, int bit_depth, - int color_type, int interlace_type, int compression_type, - int filter_type)); + png_uint_32 width, png_uint_32 height, int bit_depth, + int color_type, int interlace_type, int compression_type, + int filter_type)); /* Free all memory used by the read (old method - NOT DLL EXPORTED) */ -PNG_EXTERN void png_read_destroy PNGARG((png_structp png_ptr, png_infop info_ptr, - png_infop end_info_ptr)); +PNG_EXTERN void png_read_destroy PNGARG((png_structp png_ptr, + png_infop info_ptr, png_infop end_info_ptr)); /* Free any memory used in png_ptr struct (old method - NOT DLL EXPORTED) */ PNG_EXTERN void png_write_destroy PNGARG((png_structp png_ptr)); #ifdef USE_FAR_KEYWORD /* memory model conversion function */ -PNG_EXTERN void *png_far_to_near PNGARG((png_structp png_ptr,png_voidp ptr, - int check)); +PNG_EXTERN void *png_far_to_near PNGARG((png_structp png_ptr, png_voidp ptr, + int check)); #endif /* USE_FAR_KEYWORD */ -/* Define PNG_DEBUG at compile time for debugging information. Higher - * numbers for PNG_DEBUG mean more debugging information. This has - * only been added since version 0.95 so it is not implemented throughout - * libpng yet, but more support will be added as needed. - */ -#ifdef PNG_DEBUG -#if (PNG_DEBUG > 0) -#if !defined(PNG_DEBUG_FILE) && defined(_MSC_VER) -#include -#if (PNG_DEBUG > 1) -#ifndef _DEBUG -# define _DEBUG +#if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED) +PNG_EXTERN PNG_FUNCTION(void, png_fixed_error, (png_structp png_ptr, + png_const_charp name),PNG_NORETURN); #endif -#ifndef png_debug -#define png_debug(l,m) _RPT0(_CRT_WARN,m PNG_STRING_NEWLINE) -#endif -#ifndef png_debug1 -#define png_debug1(l,m,p1) _RPT1(_CRT_WARN,m PNG_STRING_NEWLINE,p1) -#endif -#ifndef png_debug2 -#define png_debug2(l,m,p1,p2) _RPT2(_CRT_WARN,m PNG_STRING_NEWLINE,p1,p2) -#endif -#endif -#else /* PNG_DEBUG_FILE || !_MSC_VER */ -#ifndef PNG_DEBUG_FILE -#define PNG_DEBUG_FILE stderr -#endif /* PNG_DEBUG_FILE */ -#if (PNG_DEBUG > 1) -/* Note: ["%s"m PNG_STRING_NEWLINE] probably does not work on - * non-ISO compilers +/* ASCII to FP interfaces, currently only implemented if sCAL + * support is required. */ -# ifdef __STDC__ -# ifndef png_debug -# define png_debug(l,m) \ - { \ - int num_tabs=l; \ - fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \ - (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":"")))); \ - } -# endif -# ifndef png_debug1 -# define png_debug1(l,m,p1) \ - { \ - int num_tabs=l; \ - fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \ - (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1); \ - } -# endif -# ifndef png_debug2 -# define png_debug2(l,m,p1,p2) \ - { \ - int num_tabs=l; \ - fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \ - (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1,p2); \ - } -# endif -# else /* __STDC __ */ -# ifndef png_debug -# define png_debug(l,m) \ - { \ - int num_tabs=l; \ - char format[256]; \ - snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \ - (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \ - m,PNG_STRING_NEWLINE); \ - fprintf(PNG_DEBUG_FILE,format); \ - } -# endif -# ifndef png_debug1 -# define png_debug1(l,m,p1) \ - { \ - int num_tabs=l; \ - char format[256]; \ - snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \ - (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \ - m,PNG_STRING_NEWLINE); \ - fprintf(PNG_DEBUG_FILE,format,p1); \ - } -# endif -# ifndef png_debug2 -# define png_debug2(l,m,p1,p2) \ - { \ - int num_tabs=l; \ - char format[256]; \ - snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \ - (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \ - m,PNG_STRING_NEWLINE); \ - fprintf(PNG_DEBUG_FILE,format,p1,p2); \ - } -# endif -# endif /* __STDC __ */ -#endif /* (PNG_DEBUG > 1) */ +#if defined(PNG_READ_sCAL_SUPPORTED) +/* MAX_DIGITS is actually the maximum number of characters in an sCAL + * width or height, derived from the precision (number of significant + * digits - a build time settable option) and assumpitions about the + * maximum ridiculous exponent. + */ +#define PNG_sCAL_MAX_DIGITS (PNG_sCAL_PRECISION+1/*.*/+1/*E*/+10/*exponent*/) -#endif /* _MSC_VER */ -#endif /* (PNG_DEBUG > 0) */ -#endif /* PNG_DEBUG */ -#ifndef png_debug -#define png_debug(l, m) +#ifdef PNG_FLOATING_POINT_SUPPORTED +PNG_EXTERN void png_ascii_from_fp PNGARG((png_structp png_ptr, png_charp ascii, + png_size_t size, double fp, unsigned int precision)); +#endif /* FLOATING_POINT */ + +#ifdef PNG_FIXED_POINT_SUPPORTED +PNG_EXTERN void png_ascii_from_fixed PNGARG((png_structp png_ptr, + png_charp ascii, png_size_t size, png_fixed_point fp)); +#endif /* FIXED_POINT */ +#endif /* READ_sCAL */ + +#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED) +/* An internal API to validate the format of a floating point number. + * The result is the index of the next character. If the number is + * not valid it will be the index of a character in the supposed number. + * + * The format of a number is defined in the PNG extensions specification + * and this API is strictly conformant to that spec, not anyone elses! + * + * The format as a regular expression is: + * + * [+-]?[0-9]+.?([Ee][+-]?[0-9]+)? + * + * or: + * + * [+-]?.[0-9]+(.[0-9]+)?([Ee][+-]?[0-9]+)? + * + * The complexity is that either integer or fraction must be present and the + * fraction is permitted to have no digits only if the integer is present. + * + * NOTE: The dangling E problem. + * There is a PNG valid floating point number in the following: + * + * PNG floating point numb1.ers are not greedy. + * + * Working this out requires *TWO* character lookahead (because of the + * sign), the parser does not do this - it will fail at the 'r' - this + * doesn't matter for PNG sCAL chunk values, but it requires more care + * if the value were ever to be embedded in something more complex. Use + * ANSI-C strtod if you need the lookahead. + */ +/* State table for the parser. */ +#define PNG_FP_INTEGER 0 /* before or in integer */ +#define PNG_FP_FRACTION 1 /* before or in fraction */ +#define PNG_FP_EXPONENT 2 /* before or in exponent */ +#define PNG_FP_STATE 3 /* mask for the above */ +#define PNG_FP_SAW_SIGN 4 /* Saw +/- in current state */ +#define PNG_FP_SAW_DIGIT 8 /* Saw a digit in current state */ +#define PNG_FP_SAW_DOT 16 /* Saw a dot in current state */ +#define PNG_FP_SAW_E 32 /* Saw an E (or e) in current state */ +#define PNG_FP_SAW_ANY 60 /* Saw any of the above 4 */ +#define PNG_FP_WAS_VALID 64 /* Preceding substring is a valid fp number */ +#define PNG_FP_INVALID 128 /* Available for callers as a distinct value */ + +/* Result codes for the parser (boolean - true meants ok, false means + * not ok yet.) + */ +#define PNG_FP_MAYBE 0 /* The number may be valid in the future */ +#define PNG_FP_OK 1 /* The number is valid */ + +/* The actual parser. This can be called repeatedly, it updates + * the index into the string and the state variable (which must + * be initialzed to 0). It returns a result code, as above. There + * is no point calling the parser any more if it fails to advance to + * the end of the string - it is stuck on an invalid character (or + * terminated by '\0'). + * + * Note that the pointer will consume an E or even an E+ then leave + * a 'maybe' state even though a preceding integer.fraction is valid. + * The PNG_FP_WAS_VALID flag indicates that a preceding substring was + * a valid number. It's possible to recover from this by calling + * the parser again (from the start, with state 0) but with a string + * that omits the last character (i.e. set the size to the index of + * the problem character.) This has not been tested within libpng. + */ +PNG_EXTERN int png_check_fp_number PNGARG((png_const_charp string, + png_size_t size, int *statep, png_size_tp whereami)); + +/* This is the same but it checks a complete string and returns true + * only if it just contains a floating point number. + */ +PNG_EXTERN int png_check_fp_string PNGARG((png_const_charp string, + png_size_t size)); +#endif /* pCAL || sCAL */ + +#if defined(PNG_READ_GAMMA_SUPPORTED) ||\ + defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED) +/* Added at libpng version 1.5.0 */ +/* This is a utility to provide a*times/div (rounded) and indicate + * if there is an overflow. The result is a boolean - false (0) + * for overflow, true (1) if no overflow, in which case *res + * holds the result. + */ +PNG_EXTERN int png_muldiv PNGARG((png_fixed_point_p res, png_fixed_point a, + png_int_32 times, png_int_32 div)); #endif -#ifndef png_debug1 -#define png_debug1(l, m, p1) + +#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED) +/* Same deal, but issue a warning on overflow and return 0. */ +PNG_EXTERN png_fixed_point png_muldiv_warn PNGARG((png_structp png_ptr, + png_fixed_point a, png_int_32 times, png_int_32 div)); #endif -#ifndef png_debug2 -#define png_debug2(l, m, p1, p2) + +#ifdef PNG_READ_GAMMA_SUPPORTED +/* Calculate a reciprocal - used for gamma values. This returns + * 0 if the argument is 0 in order to maintain an undefined value, + * there are no warnings. + */ +PNG_EXTERN png_fixed_point png_reciprocal PNGARG((png_fixed_point a)); + +/* The same but gives a reciprocal of the product of two fixed point + * values. Accuracy is suitable for gamma calculations but this is + * not exact - use png_muldiv for that. + */ +PNG_EXTERN png_fixed_point png_reciprocal2 PNGARG((png_fixed_point a, + png_fixed_point b)); +#endif + +#ifdef PNG_READ_GAMMA_SUPPORTED +/* Internal fixed point gamma correction. These APIs are called as + * required to convert single values - they don't need to be fast, + * they are not used when processing image pixel values. + * + * While the input is an 'unsigned' value it must actually be the + * correct bit value - 0..255 or 0..65535 as required. + */ +PNG_EXTERN png_uint_16 png_gamma_correct PNGARG((png_structp png_ptr, + unsigned int value, png_fixed_point gamma)); +PNG_EXTERN int png_gamma_significant PNGARG((png_fixed_point gamma)); +PNG_EXTERN png_uint_16 png_gamma_16bit_correct PNGARG((unsigned int value, + png_fixed_point gamma)); +PNG_EXTERN png_byte png_gamma_8bit_correct PNGARG((unsigned int value, + png_fixed_point gamma)); +PNG_EXTERN void png_build_gamma_table PNGARG((png_structp png_ptr, + int bit_depth)); #endif /* Maintainer: Put new private prototypes here ^ and in libpngpf.3 */ + +#include "pngdebug.h" + #ifdef __cplusplus } #endif -#endif /* PNG_VERSION_INFO_ONLY */ #endif /* PNGPRIV_H */ diff --git a/harbour/src/3rd/png/pngread.c b/harbour/src/3rd/png/pngread.c index 4806448075..e092ccefd5 100644 --- a/harbour/src/3rd/png/pngread.c +++ b/harbour/src/3rd/png/pngread.c @@ -1,8 +1,8 @@ /* pngread.c - read a PNG file * - * Last changed in libpng 1.4.5 [December 9, 2010] - * Copyright (c) 1998-2010 Glenn Randers-Pehrson + * Last changed in libpng 1.5.0 [January 6, 2011] + * Copyright (c) 1998-2011 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -14,30 +14,28 @@ * read a PNG file or stream. */ -#define PNG_NO_PEDANTIC_WARNINGS -#include "png.h" -#ifdef PNG_READ_SUPPORTED #include "pngpriv.h" +#ifdef PNG_READ_SUPPORTED /* Create a PNG structure for reading, and allocate any memory needed. */ -png_structp PNGAPI -png_create_read_struct(png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn) +PNG_FUNCTION(png_structp,PNGAPI +png_create_read_struct,(png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED) { #ifdef PNG_USER_MEM_SUPPORTED return (png_create_read_struct_2(user_png_ver, error_ptr, error_fn, - warn_fn, NULL, NULL, NULL)); + warn_fn, NULL, NULL, NULL)); } /* Alternate create PNG structure for reading, and allocate any memory * needed. */ -png_structp PNGAPI -png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, - png_malloc_ptr malloc_fn, png_free_ptr free_fn) +PNG_FUNCTION(png_structp,PNGAPI +png_create_read_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, + png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED) { #endif /* PNG_USER_MEM_SUPPORTED */ @@ -49,7 +47,7 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, #ifdef PNG_SETJMP_SUPPORTED #ifdef USE_FAR_KEYWORD - jmp_buf jmpbuf; + jmp_buf png_jmpbuf; #endif #endif @@ -59,7 +57,7 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, #ifdef PNG_USER_MEM_SUPPORTED png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG, - malloc_fn, mem_ptr); + malloc_fn, mem_ptr); #else png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); #endif @@ -70,10 +68,12 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, #ifdef PNG_USER_LIMITS_SUPPORTED png_ptr->user_width_max = PNG_USER_WIDTH_MAX; png_ptr->user_height_max = PNG_USER_HEIGHT_MAX; + # ifdef PNG_USER_CHUNK_CACHE_MAX /* Added at libpng-1.2.43 and 1.4.0 */ png_ptr->user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX; # endif + # ifdef PNG_SET_USER_CHUNK_MALLOC_MAX /* Added at libpng-1.2.43 and 1.4.1 */ png_ptr->user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX; @@ -85,13 +85,13 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, encounter a png_error() will longjmp here. Since the jmpbuf is then meaningless we abort instead of returning. */ #ifdef USE_FAR_KEYWORD - if (setjmp(jmpbuf)) + if (setjmp(png_jmpbuf)) #else if (setjmp(png_jmpbuf(png_ptr))) /* Sets longjmp to match setjmp */ #endif PNG_ABORT(); #ifdef USE_FAR_KEYWORD - png_memcpy(png_jmpbuf(png_ptr), jmpbuf, png_sizeof(jmp_buf)); + png_memcpy(png_jmpbuf(png_ptr), png_jmpbuf, png_sizeof(jmp_buf)); #endif #endif /* PNG_SETJMP_SUPPORTED */ @@ -104,46 +104,47 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, if (user_png_ver) { i = 0; + do { if (user_png_ver[i] != png_libpng_ver[i]) png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; } while (png_libpng_ver[i++]); - } - else - png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; + } + + else + png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; - if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH) - { - /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so - * we must recompile any applications that use any older library version. - * For versions after libpng 1.0, we will be compatible, so we need - * only check the first digit. - */ + if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH) + { + /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so + * we must recompile any applications that use any older library version. + * For versions after libpng 1.0, we will be compatible, so we need + * only check the first digit. + */ if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] || (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) || (user_png_ver[0] == '0' && user_png_ver[2] < '9')) { -#ifdef PNG_STDIO_SUPPORTED +#ifdef PNG_CONSOLE_IO_SUPPORTED char msg[80]; if (user_png_ver) { - png_snprintf(msg, 80, - "Application was compiled with png.h from libpng-%.20s", - user_png_ver); - png_warning(png_ptr, msg); + png_snprintf2(msg, 80, + "Application built with libpng-%.20s" + " but running with %.20s", + user_png_ver, + png_libpng_ver); + png_warning(png_ptr, msg); } - png_snprintf(msg, 80, - "Application is running with png.c from libpng-%.20s", - png_libpng_ver); - png_warning(png_ptr, msg); +#else + png_warning(png_ptr, + "Incompatible libpng version in application and library"); #endif #ifdef PNG_ERROR_NUMBERS_SUPPORTED png_ptr->flags = 0; #endif - png_warning(png_ptr, - "Incompatible libpng version in application and library"); png_cleanup_needed = 1; } @@ -153,11 +154,12 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, { /* Initialize zbuf - compression buffer */ png_ptr->zbuf_size = PNG_ZBUF_SIZE; - png_ptr->zbuf = (png_bytep)png_malloc_warn(png_ptr, - png_ptr->zbuf_size); + png_ptr->zbuf = (png_bytep)png_malloc_warn(png_ptr, png_ptr->zbuf_size); + if (png_ptr->zbuf == NULL) - png_cleanup_needed = 1; + png_cleanup_needed = 1; } + png_ptr->zstream.zalloc = png_zalloc; png_ptr->zstream.zfree = png_zfree; png_ptr->zstream.opaque = (voidpf)png_ptr; @@ -166,12 +168,24 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, { switch (inflateInit(&png_ptr->zstream)) { - case Z_OK: /* Do nothing */ break; + case Z_OK: + break; /* Do nothing */ + case Z_MEM_ERROR: - case Z_STREAM_ERROR: png_warning(png_ptr, "zlib memory error"); - png_cleanup_needed = 1; break; - case Z_VERSION_ERROR: png_warning(png_ptr, "zlib version error"); - png_cleanup_needed = 1; break; + png_warning(png_ptr, "zlib memory error"); + png_cleanup_needed = 1; + break; + + case Z_STREAM_ERROR: + png_warning(png_ptr, "zlib stream error"); + png_cleanup_needed = 1; + break; + + case Z_VERSION_ERROR: + png_warning(png_ptr, "zlib version error"); + png_cleanup_needed = 1; + break; + default: png_warning(png_ptr, "Unknown zlib error"); png_cleanup_needed = 1; } @@ -184,7 +198,7 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, png_ptr->zbuf = NULL; #ifdef PNG_USER_MEM_SUPPORTED png_destroy_struct_2((png_voidp)png_ptr, - (png_free_ptr)free_fn, (png_voidp)mem_ptr); + (png_free_ptr)free_fn, (png_voidp)mem_ptr); #else png_destroy_struct((png_voidp)png_ptr); #endif @@ -285,114 +299,141 @@ png_read_info(png_structp png_ptr, png_infop info_ptr) * matching the chunk name rather than a linear search. */ if (!png_memcmp(chunk_name, png_IDAT, 4)) - if (png_ptr->mode & PNG_AFTER_IDAT) - png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; + if (png_ptr->mode & PNG_AFTER_IDAT) + png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; if (!png_memcmp(chunk_name, png_IHDR, 4)) png_handle_IHDR(png_ptr, info_ptr, length); + else if (!png_memcmp(chunk_name, png_IEND, 4)) png_handle_IEND(png_ptr, info_ptr, length); + #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED else if (png_handle_as_unknown(png_ptr, chunk_name)) { if (!png_memcmp(chunk_name, png_IDAT, 4)) png_ptr->mode |= PNG_HAVE_IDAT; + png_handle_unknown(png_ptr, info_ptr, length); + if (!png_memcmp(chunk_name, png_PLTE, 4)) png_ptr->mode |= PNG_HAVE_PLTE; + else if (!png_memcmp(chunk_name, png_IDAT, 4)) { if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before IDAT"); + else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && - !(png_ptr->mode & PNG_HAVE_PLTE)) + !(png_ptr->mode & PNG_HAVE_PLTE)) png_error(png_ptr, "Missing PLTE before IDAT"); + break; } } #endif else if (!png_memcmp(chunk_name, png_PLTE, 4)) png_handle_PLTE(png_ptr, info_ptr, length); + else if (!png_memcmp(chunk_name, png_IDAT, 4)) { if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before IDAT"); + else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && - !(png_ptr->mode & PNG_HAVE_PLTE)) + !(png_ptr->mode & PNG_HAVE_PLTE)) png_error(png_ptr, "Missing PLTE before IDAT"); png_ptr->idat_size = length; png_ptr->mode |= PNG_HAVE_IDAT; break; } + #ifdef PNG_READ_bKGD_SUPPORTED else if (!png_memcmp(chunk_name, png_bKGD, 4)) png_handle_bKGD(png_ptr, info_ptr, length); #endif + #ifdef PNG_READ_cHRM_SUPPORTED else if (!png_memcmp(chunk_name, png_cHRM, 4)) png_handle_cHRM(png_ptr, info_ptr, length); #endif + #ifdef PNG_READ_gAMA_SUPPORTED else if (!png_memcmp(chunk_name, png_gAMA, 4)) png_handle_gAMA(png_ptr, info_ptr, length); #endif + #ifdef PNG_READ_hIST_SUPPORTED else if (!png_memcmp(chunk_name, png_hIST, 4)) png_handle_hIST(png_ptr, info_ptr, length); #endif + #ifdef PNG_READ_oFFs_SUPPORTED else if (!png_memcmp(chunk_name, png_oFFs, 4)) png_handle_oFFs(png_ptr, info_ptr, length); #endif + #ifdef PNG_READ_pCAL_SUPPORTED else if (!png_memcmp(chunk_name, png_pCAL, 4)) png_handle_pCAL(png_ptr, info_ptr, length); #endif + #ifdef PNG_READ_sCAL_SUPPORTED else if (!png_memcmp(chunk_name, png_sCAL, 4)) png_handle_sCAL(png_ptr, info_ptr, length); #endif + #ifdef PNG_READ_pHYs_SUPPORTED else if (!png_memcmp(chunk_name, png_pHYs, 4)) png_handle_pHYs(png_ptr, info_ptr, length); #endif + #ifdef PNG_READ_sBIT_SUPPORTED else if (!png_memcmp(chunk_name, png_sBIT, 4)) png_handle_sBIT(png_ptr, info_ptr, length); #endif + #ifdef PNG_READ_sRGB_SUPPORTED else if (!png_memcmp(chunk_name, png_sRGB, 4)) png_handle_sRGB(png_ptr, info_ptr, length); #endif + #ifdef PNG_READ_iCCP_SUPPORTED else if (!png_memcmp(chunk_name, png_iCCP, 4)) png_handle_iCCP(png_ptr, info_ptr, length); #endif + #ifdef PNG_READ_sPLT_SUPPORTED else if (!png_memcmp(chunk_name, png_sPLT, 4)) png_handle_sPLT(png_ptr, info_ptr, length); #endif + #ifdef PNG_READ_tEXt_SUPPORTED else if (!png_memcmp(chunk_name, png_tEXt, 4)) png_handle_tEXt(png_ptr, info_ptr, length); #endif + #ifdef PNG_READ_tIME_SUPPORTED else if (!png_memcmp(chunk_name, png_tIME, 4)) png_handle_tIME(png_ptr, info_ptr, length); #endif + #ifdef PNG_READ_tRNS_SUPPORTED else if (!png_memcmp(chunk_name, png_tRNS, 4)) png_handle_tRNS(png_ptr, info_ptr, length); #endif + #ifdef PNG_READ_zTXt_SUPPORTED else if (!png_memcmp(chunk_name, png_zTXt, 4)) png_handle_zTXt(png_ptr, info_ptr, length); #endif + #ifdef PNG_READ_iTXt_SUPPORTED else if (!png_memcmp(chunk_name, png_iTXt, 4)) png_handle_iTXt(png_ptr, info_ptr, length); #endif + else png_handle_unknown(png_ptr, info_ptr, length); } @@ -407,11 +448,14 @@ png_read_update_info(png_structp png_ptr, png_infop info_ptr) if (png_ptr == NULL) return; + if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) png_read_start_row(png_ptr); + else png_warning(png_ptr, - "Ignoring extra png_read_update_info() call; row buffer not reallocated"); + "Ignoring extra png_read_update_info() call;" + " row buffer not reallocated"); png_read_transform_info(png_ptr, info_ptr); } @@ -429,8 +473,13 @@ png_start_read_image(png_structp png_ptr) if (png_ptr == NULL) return; + if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) png_read_start_row(png_ptr); + else + png_warning(png_ptr, + "Ignoring extra png_start_read_image() call;" + " row buffer not reallocated"); } #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ @@ -440,7 +489,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) { PNG_IDAT; PNG_CONST int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, - 0xff}; + 0xff}; PNG_CONST int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff}; int ret; @@ -448,10 +497,11 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) return; png_debug2(1, "in png_read_row (row %lu, pass %d)", - (unsigned long) png_ptr->row_number, png_ptr->pass); + (unsigned long)png_ptr->row_number, png_ptr->pass); if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) png_read_start_row(png_ptr); + if (png_ptr->row_number == 0 && png_ptr->pass == 0) { /* Check for transforms that have been set but were defined out */ @@ -459,27 +509,33 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) if (png_ptr->transformations & PNG_INVERT_MONO) png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined"); #endif + #if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED) if (png_ptr->transformations & PNG_FILLER) png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined"); #endif + #if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \ !defined(PNG_READ_PACKSWAP_SUPPORTED) if (png_ptr->transformations & PNG_PACKSWAP) png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined"); #endif + #if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED) if (png_ptr->transformations & PNG_PACK) png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined"); #endif + #if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) if (png_ptr->transformations & PNG_SHIFT) png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined"); #endif + #if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED) if (png_ptr->transformations & PNG_BGR) png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined"); #endif + #if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED) if (png_ptr->transformations & PNG_SWAP_BYTES) png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined"); @@ -508,7 +564,8 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) { if (dsp_row != NULL) png_combine_row(png_ptr, dsp_row, - png_pass_dsp_mask[png_ptr->pass]); + png_pass_dsp_mask[png_ptr->pass]); + png_read_finish_row(png_ptr); return; } @@ -519,7 +576,8 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) { if (dsp_row != NULL && (png_ptr->row_number & 4)) png_combine_row(png_ptr, dsp_row, - png_pass_dsp_mask[png_ptr->pass]); + png_pass_dsp_mask[png_ptr->pass]); + png_read_finish_row(png_ptr); return; } @@ -530,7 +588,8 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) { if (dsp_row != NULL) png_combine_row(png_ptr, dsp_row, - png_pass_dsp_mask[png_ptr->pass]); + png_pass_dsp_mask[png_ptr->pass]); + png_read_finish_row(png_ptr); return; } @@ -541,18 +600,19 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) { if (dsp_row != NULL && (png_ptr->row_number & 2)) png_combine_row(png_ptr, dsp_row, - png_pass_dsp_mask[png_ptr->pass]); + png_pass_dsp_mask[png_ptr->pass]); + png_read_finish_row(png_ptr); return; } break; - case 5: if ((png_ptr->row_number & 1) || png_ptr->width < 2) { if (dsp_row != NULL) png_combine_row(png_ptr, dsp_row, - png_pass_dsp_mask[png_ptr->pass]); + png_pass_dsp_mask[png_ptr->pass]); + png_read_finish_row(png_ptr); return; } @@ -577,6 +637,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) png_ptr->zstream.avail_out = (uInt)(PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1); + do { if (!(png_ptr->zstream.avail_in)) @@ -594,10 +655,12 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) if (png_ptr->zbuf_size > png_ptr->idat_size) png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size; png_crc_read(png_ptr, png_ptr->zbuf, - (png_size_t)png_ptr->zstream.avail_in); + (png_size_t)png_ptr->zstream.avail_in); png_ptr->idat_size -= png_ptr->zstream.avail_in; } + ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); + if (ret == Z_STREAM_END) { if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in || @@ -607,9 +670,10 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; break; } + if (ret != Z_OK) png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg : - "Decompression error"); + "Decompression error"); } while (png_ptr->zstream.avail_out); @@ -623,14 +687,14 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) if (png_ptr->row_buf[0]) png_read_filter_row(png_ptr, &(png_ptr->row_info), - png_ptr->row_buf + 1, png_ptr->prev_row + 1, - (int)(png_ptr->row_buf[0])); + png_ptr->row_buf + 1, png_ptr->prev_row + 1, + (int)(png_ptr->row_buf[0])); png_memcpy(png_ptr->prev_row, png_ptr->row_buf, png_ptr->rowbytes + 1); #ifdef PNG_MNG_FEATURES_SUPPORTED if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && - (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) + (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) { /* Intrapixel differencing */ png_do_read_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1); @@ -654,17 +718,18 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) png_do_read_interlace(png_ptr); if (dsp_row != NULL) - png_combine_row(png_ptr, dsp_row, - png_pass_dsp_mask[png_ptr->pass]); + png_combine_row(png_ptr, dsp_row, png_pass_dsp_mask[png_ptr->pass]); + if (row != NULL) - png_combine_row(png_ptr, row, - png_pass_mask[png_ptr->pass]); + png_combine_row(png_ptr, row, png_pass_mask[png_ptr->pass]); } + else #endif { if (row != NULL) png_combine_row(png_ptr, row, 0xff); + if (dsp_row != NULL) png_combine_row(png_ptr, dsp_row, 0xff); } @@ -702,7 +767,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) void PNGAPI png_read_rows(png_structp png_ptr, png_bytepp row, - png_bytepp display_row, png_uint_32 num_rows) + png_bytepp display_row, png_uint_32 num_rows) { png_uint_32 i; png_bytepp rp; @@ -712,6 +777,7 @@ png_read_rows(png_structp png_ptr, png_bytepp row, if (png_ptr == NULL) return; + rp = row; dp = display_row; if (rp != NULL && dp != NULL) @@ -722,6 +788,7 @@ png_read_rows(png_structp png_ptr, png_bytepp row, png_read_row(png_ptr, rptr, dptr); } + else if (rp != NULL) for (i = 0; i < num_rows; i++) { @@ -729,6 +796,7 @@ png_read_rows(png_structp png_ptr, png_bytepp row, png_read_row(png_ptr, rptr, NULL); rp++; } + else if (dp != NULL) for (i = 0; i < num_rows; i++) { @@ -765,17 +833,40 @@ png_read_image(png_structp png_ptr, png_bytepp image) return; #ifdef PNG_READ_INTERLACING_SUPPORTED - pass = png_set_interlace_handling(png_ptr); + if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) + { + pass = png_set_interlace_handling(png_ptr); + /* And make sure transforms are initialized. */ + png_start_read_image(png_ptr); + } + else + { + if (!(png_ptr->transformations & PNG_INTERLACE)) + { + /* Caller called png_start_read_image or png_read_update_info without + * first turning on the PNG_INTERLACE transform. We can fix this here, + * but the caller should do it! + */ + png_warning(png_ptr, "Interlace handling should be turned on when " + "using png_read_image"); + /* Make sure this is set correctly */ + png_ptr->num_rows = png_ptr->height; + } + + /* Obtain the pass number, which also turns on the PNG_INTERLACE flag in + * the above error case. + */ + pass = png_set_interlace_handling(png_ptr); + } #else if (png_ptr->interlaced) png_error(png_ptr, - "Cannot read interlaced image -- interlace handler disabled"); + "Cannot read interlaced image -- interlace handler disabled"); + pass = 1; #endif - image_height=png_ptr->height; - png_ptr->num_rows = image_height; /* Make sure this is set correctly */ for (j = 0; j < pass; j++) { @@ -801,6 +892,7 @@ png_read_end(png_structp png_ptr, png_infop info_ptr) if (png_ptr == NULL) return; + png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */ do @@ -865,8 +957,10 @@ png_read_end(png_structp png_ptr, png_infop info_ptr) if (!png_memcmp(chunk_name, png_IHDR, 4)) png_handle_IHDR(png_ptr, info_ptr, length); + else if (!png_memcmp(chunk_name, png_IEND, 4)) png_handle_IEND(png_ptr, info_ptr, length); + #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED else if (png_handle_as_unknown(png_ptr, chunk_name)) { @@ -880,6 +974,7 @@ png_read_end(png_structp png_ptr, png_infop info_ptr) png_ptr->mode |= PNG_HAVE_PLTE; } #endif + else if (!png_memcmp(chunk_name, png_IDAT, 4)) { /* Zero length IDATs are legal after the last IDAT has been @@ -887,78 +982,97 @@ png_read_end(png_structp png_ptr, png_infop info_ptr) */ if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) png_benign_error(png_ptr, "Too many IDATs found"); + png_crc_finish(png_ptr, length); } else if (!png_memcmp(chunk_name, png_PLTE, 4)) png_handle_PLTE(png_ptr, info_ptr, length); + #ifdef PNG_READ_bKGD_SUPPORTED else if (!png_memcmp(chunk_name, png_bKGD, 4)) png_handle_bKGD(png_ptr, info_ptr, length); #endif + #ifdef PNG_READ_cHRM_SUPPORTED else if (!png_memcmp(chunk_name, png_cHRM, 4)) png_handle_cHRM(png_ptr, info_ptr, length); #endif + #ifdef PNG_READ_gAMA_SUPPORTED else if (!png_memcmp(chunk_name, png_gAMA, 4)) png_handle_gAMA(png_ptr, info_ptr, length); #endif + #ifdef PNG_READ_hIST_SUPPORTED else if (!png_memcmp(chunk_name, png_hIST, 4)) png_handle_hIST(png_ptr, info_ptr, length); #endif + #ifdef PNG_READ_oFFs_SUPPORTED else if (!png_memcmp(chunk_name, png_oFFs, 4)) png_handle_oFFs(png_ptr, info_ptr, length); #endif + #ifdef PNG_READ_pCAL_SUPPORTED else if (!png_memcmp(chunk_name, png_pCAL, 4)) png_handle_pCAL(png_ptr, info_ptr, length); #endif + #ifdef PNG_READ_sCAL_SUPPORTED else if (!png_memcmp(chunk_name, png_sCAL, 4)) png_handle_sCAL(png_ptr, info_ptr, length); #endif + #ifdef PNG_READ_pHYs_SUPPORTED else if (!png_memcmp(chunk_name, png_pHYs, 4)) png_handle_pHYs(png_ptr, info_ptr, length); #endif + #ifdef PNG_READ_sBIT_SUPPORTED else if (!png_memcmp(chunk_name, png_sBIT, 4)) png_handle_sBIT(png_ptr, info_ptr, length); #endif + #ifdef PNG_READ_sRGB_SUPPORTED else if (!png_memcmp(chunk_name, png_sRGB, 4)) png_handle_sRGB(png_ptr, info_ptr, length); #endif + #ifdef PNG_READ_iCCP_SUPPORTED else if (!png_memcmp(chunk_name, png_iCCP, 4)) png_handle_iCCP(png_ptr, info_ptr, length); #endif + #ifdef PNG_READ_sPLT_SUPPORTED else if (!png_memcmp(chunk_name, png_sPLT, 4)) png_handle_sPLT(png_ptr, info_ptr, length); #endif + #ifdef PNG_READ_tEXt_SUPPORTED else if (!png_memcmp(chunk_name, png_tEXt, 4)) png_handle_tEXt(png_ptr, info_ptr, length); #endif + #ifdef PNG_READ_tIME_SUPPORTED else if (!png_memcmp(chunk_name, png_tIME, 4)) png_handle_tIME(png_ptr, info_ptr, length); #endif + #ifdef PNG_READ_tRNS_SUPPORTED else if (!png_memcmp(chunk_name, png_tRNS, 4)) png_handle_tRNS(png_ptr, info_ptr, length); #endif + #ifdef PNG_READ_zTXt_SUPPORTED else if (!png_memcmp(chunk_name, png_zTXt, 4)) png_handle_zTXt(png_ptr, info_ptr, length); #endif + #ifdef PNG_READ_iTXt_SUPPORTED else if (!png_memcmp(chunk_name, png_iTXt, 4)) png_handle_iTXt(png_ptr, info_ptr, length); #endif + else png_handle_unknown(png_ptr, info_ptr, length); } while (!(png_ptr->mode & PNG_HAVE_IEND)); @@ -968,7 +1082,7 @@ png_read_end(png_structp png_ptr, png_infop info_ptr) /* Free all memory used by the read */ void PNGAPI png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr, - png_infopp end_info_ptr_ptr) + png_infopp end_info_ptr_ptr) { png_structp png_ptr = NULL; png_infop info_ptr = NULL, end_info_ptr = NULL; @@ -1019,7 +1133,7 @@ png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr, #endif #ifdef PNG_USER_MEM_SUPPORTED png_destroy_struct_2((png_voidp)end_info_ptr, (png_free_ptr)free_fn, - (png_voidp)mem_ptr); + (png_voidp)mem_ptr); #else png_destroy_struct((png_voidp)end_info_ptr); #endif @@ -1065,31 +1179,38 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_free(png_ptr, png_ptr->big_row_buf); png_free(png_ptr, png_ptr->prev_row); png_free(png_ptr, png_ptr->chunkdata); + #ifdef PNG_READ_QUANTIZE_SUPPORTED png_free(png_ptr, png_ptr->palette_lookup); png_free(png_ptr, png_ptr->quantize_index); #endif + #ifdef PNG_READ_GAMMA_SUPPORTED png_free(png_ptr, png_ptr->gamma_table); #endif + #ifdef PNG_READ_BACKGROUND_SUPPORTED png_free(png_ptr, png_ptr->gamma_from_1); png_free(png_ptr, png_ptr->gamma_to_1); #endif + if (png_ptr->free_me & PNG_FREE_PLTE) png_zfree(png_ptr, png_ptr->palette); png_ptr->free_me &= ~PNG_FREE_PLTE; + #if defined(PNG_tRNS_SUPPORTED) || \ defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) if (png_ptr->free_me & PNG_FREE_TRNS) png_free(png_ptr, png_ptr->trans_alpha); png_ptr->free_me &= ~PNG_FREE_TRNS; #endif + #ifdef PNG_READ_hIST_SUPPORTED if (png_ptr->free_me & PNG_FREE_HIST) png_free(png_ptr, png_ptr->hist); png_ptr->free_me &= ~PNG_FREE_HIST; #endif + #ifdef PNG_READ_GAMMA_SUPPORTED if (png_ptr->gamma_16_table != NULL) { @@ -1101,6 +1222,7 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr, } png_free(png_ptr, png_ptr->gamma_16_table); } + #ifdef PNG_READ_BACKGROUND_SUPPORTED if (png_ptr->gamma_16_from_1 != NULL) { @@ -1124,11 +1246,13 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr, } #endif #endif + #ifdef PNG_TIME_RFC1123_SUPPORTED png_free(png_ptr, png_ptr->time_buffer); #endif inflateEnd(&png_ptr->zstream); + #ifdef PNG_PROGRESSIVE_READ_SUPPORTED png_free(png_ptr, png_ptr->save_buffer); #endif @@ -1143,7 +1267,7 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr, * being used again. */ #ifdef PNG_SETJMP_SUPPORTED - png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof(jmp_buf)); + png_memcpy(tmp_jmp, png_ptr->png_jmpbuf, png_sizeof(jmp_buf)); #endif error_fn = png_ptr->error_fn; @@ -1163,7 +1287,7 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr, #endif #ifdef PNG_SETJMP_SUPPORTED - png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof(jmp_buf)); + png_memcpy(png_ptr->png_jmpbuf, tmp_jmp, png_sizeof(jmp_buf)); #endif } @@ -1173,6 +1297,7 @@ png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn) { if (png_ptr == NULL) return; + png_ptr->read_row_fn = read_row_fn; } @@ -1268,40 +1393,35 @@ png_read_png(png_structp png_ptr, png_infop info_ptr, #endif #ifdef PNG_READ_BGR_SUPPORTED - /* Flip the RGB pixels to BGR (or RGBA to BGRA) - */ + /* Flip the RGB pixels to BGR (or RGBA to BGRA) */ if (transforms & PNG_TRANSFORM_BGR) png_set_bgr(png_ptr); #endif #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED - /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) - */ + /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */ if (transforms & PNG_TRANSFORM_SWAP_ALPHA) - png_set_swap_alpha(png_ptr); + png_set_swap_alpha(png_ptr); #endif #ifdef PNG_READ_SWAP_SUPPORTED - /* Swap bytes of 16 bit files to least significant byte first - */ + /* Swap bytes of 16 bit files to least significant byte first */ if (transforms & PNG_TRANSFORM_SWAP_ENDIAN) png_set_swap(png_ptr); #endif /* Added at libpng-1.2.41 */ #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED - /* Invert the alpha channel from opacity to transparency - */ + /* Invert the alpha channel from opacity to transparency */ if (transforms & PNG_TRANSFORM_INVERT_ALPHA) - png_set_invert_alpha(png_ptr); + png_set_invert_alpha(png_ptr); #endif /* Added at libpng-1.2.41 */ #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED - /* Expand grayscale image to RGB - */ + /* Expand grayscale image to RGB */ if (transforms & PNG_TRANSFORM_GRAY_TO_RGB) - png_set_gray_to_rgb(png_ptr); + png_set_gray_to_rgb(png_ptr); #endif /* We don't handle adding filler bytes */ @@ -1317,10 +1437,10 @@ png_read_png(png_structp png_ptr, png_infop info_ptr, png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0); if (info_ptr->row_pointers == NULL) { - png_uint_32 iptr; + png_uint_32 iptr; info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr, - info_ptr->height * png_sizeof(png_bytep)); + info_ptr->height * png_sizeof(png_bytep)); for (iptr=0; iptrheight; iptr++) info_ptr->row_pointers[iptr] = NULL; @@ -1337,8 +1457,8 @@ png_read_png(png_structp png_ptr, png_infop info_ptr, /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */ png_read_end(png_ptr, info_ptr); - transforms = transforms; /* Quiet compiler warnings */ - params = params; + PNG_UNUSED(transforms) /* Quiet compiler warnings */ + PNG_UNUSED(params) } #endif /* PNG_INFO_IMAGE_SUPPORTED */ diff --git a/harbour/src/3rd/png/pngrio.c b/harbour/src/3rd/png/pngrio.c index cab7114a92..e9c381c5ba 100644 --- a/harbour/src/3rd/png/pngrio.c +++ b/harbour/src/3rd/png/pngrio.c @@ -1,8 +1,8 @@ /* pngrio.c - functions for data input * - * Last changed in libpng 1.4.5 [December 9, 2010] - * Copyright (c) 1998-2010 Glenn Randers-Pehrson + * Last changed in libpng 1.5.0 [January 6, 2011] + * Copyright (c) 1998-2011 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -18,11 +18,10 @@ * libpng use it at run time with png_set_read_fn(...). */ -#define PNG_NO_PEDANTIC_WARNINGS -#include "png.h" -#ifdef PNG_READ_SUPPORTED #include "pngpriv.h" +#ifdef PNG_READ_SUPPORTED + /* Read the data from whatever input you are using. The default routine * reads from a file pointer. Note that this routine sometimes gets called * with very small lengths, so you should implement some kind of simple @@ -36,6 +35,7 @@ png_read_data(png_structp png_ptr, png_bytep data, png_size_t length) if (png_ptr->read_data_fn != NULL) (*(png_ptr->read_data_fn))(png_ptr, data, length); + else png_error(png_ptr, "Call to NULL read function"); } @@ -46,14 +46,15 @@ png_read_data(png_structp png_ptr, png_bytep data, png_size_t length) * read_data function and use it at run time with png_set_read_fn(), rather * than changing the library. */ -#ifndef USE_FAR_KEYWORD -void PNGAPI +# ifndef USE_FAR_KEYWORD +void PNGCBAPI png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length) { png_size_t check; if (png_ptr == NULL) return; + /* fread() returns 0 on error, so it is OK to store this in a png_size_t * instead of an int, which is what fread() actually returns. */ @@ -62,7 +63,7 @@ png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length) if (check != length) png_error(png_ptr, "Read Error"); } -#else +# else /* This is the model-independent version. Since the standard I/O library can't handle far buffers in the medium and small models, we have to copy the data. @@ -71,7 +72,7 @@ png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length) #define NEAR_BUF_SIZE 1024 #define MIN(a,b) (a <= b ? a : b) -static void PNGAPI +static void PNGCBAPI png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length) { png_size_t check; @@ -80,46 +81,57 @@ png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length) if (png_ptr == NULL) return; + /* Check if data really is near. If so, use usual code. */ n_data = (png_byte *)CVT_PTR_NOCHECK(data); io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr); + if ((png_bytep)n_data == data) { check = fread(n_data, 1, length, io_ptr); } + else { png_byte buf[NEAR_BUF_SIZE]; png_size_t read, remaining, err; check = 0; remaining = length; + do { read = MIN(NEAR_BUF_SIZE, remaining); err = fread(buf, 1, read, io_ptr); png_memcpy(data, buf, read); /* copy far buffer to near buffer */ + if (err != read) break; + else check += err; + data += read; remaining -= read; } while (remaining != 0); } + if ((png_uint_32)check != (png_uint_32)length) png_error(png_ptr, "read Error"); } -#endif +# endif #endif /* This function allows the application to supply a new input function * for libpng if standard C streams aren't being used. * * This function takes as its arguments: + * * png_ptr - pointer to a png input data structure + * * io_ptr - pointer to user supplied structure containing info about * the input functions. May be NULL. + * * read_data_fn - pointer to a new input function that takes as its * arguments a pointer to a png_struct, a pointer to * a location where input data can be stored, and a 32-bit @@ -135,11 +147,13 @@ png_set_read_fn(png_structp png_ptr, png_voidp io_ptr, { if (png_ptr == NULL) return; + png_ptr->io_ptr = io_ptr; #ifdef PNG_STDIO_SUPPORTED if (read_data_fn != NULL) png_ptr->read_data_fn = read_data_fn; + else png_ptr->read_data_fn = png_default_read_data; #else @@ -151,9 +165,8 @@ png_set_read_fn(png_structp png_ptr, png_voidp io_ptr, { png_ptr->write_data_fn = NULL; png_warning(png_ptr, - "It's an error to set both read_data_fn and write_data_fn in the "); - png_warning(png_ptr, - "same structure. Resetting write_data_fn to NULL"); + "Can't set both read_data_fn and write_data_fn in the" + " same structure"); } #ifdef PNG_WRITE_FLUSH_SUPPORTED diff --git a/harbour/src/3rd/png/pngrtran.c b/harbour/src/3rd/png/pngrtran.c index 4497514311..7da7886f6a 100644 --- a/harbour/src/3rd/png/pngrtran.c +++ b/harbour/src/3rd/png/pngrtran.c @@ -1,8 +1,8 @@ /* pngrtran.c - transforms the data in a row for PNG readers * - * Last changed in libpng 1.4.5 [December 9, 2010] - * Copyright (c) 1998-2010 Glenn Randers-Pehrson + * Last changed in libpng 1.5.0 [January 6, 2011] + * Copyright (c) 1998-2011 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -16,11 +16,10 @@ * in pngtrans.c. */ -#define PNG_NO_PEDANTIC_WARNINGS -#include "png.h" -#ifdef PNG_READ_SUPPORTED #include "pngpriv.h" +#ifdef PNG_READ_SUPPORTED + /* Set the action on getting a CRC error for an ancillary or critical chunk. */ void PNGAPI png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action) @@ -89,18 +88,18 @@ png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action) } } -#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ - defined(PNG_FLOATING_POINT_SUPPORTED) +#ifdef PNG_READ_BACKGROUND_SUPPORTED /* Handle alpha and tRNS via a background color */ -void PNGAPI -png_set_background(png_structp png_ptr, - png_color_16p background_color, int background_gamma_code, - int need_expand, double background_gamma) +void PNGFAPI +png_set_background_fixed(png_structp png_ptr, + png_const_color_16p background_color, int background_gamma_code, + int need_expand, png_fixed_point background_gamma) { - png_debug(1, "in png_set_background"); + png_debug(1, "in png_set_background_fixed"); if (png_ptr == NULL) return; + if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN) { png_warning(png_ptr, "Application must supply a known background gamma"); @@ -110,11 +109,22 @@ png_set_background(png_structp png_ptr, png_ptr->transformations |= PNG_BACKGROUND; png_memcpy(&(png_ptr->background), background_color, png_sizeof(png_color_16)); - png_ptr->background_gamma = (float)background_gamma; + png_ptr->background_gamma = background_gamma; png_ptr->background_gamma_type = (png_byte)(background_gamma_code); png_ptr->transformations |= (need_expand ? PNG_BACKGROUND_EXPAND : 0); } -#endif + +# ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_background(png_structp png_ptr, + png_const_color_16p background_color, int background_gamma_code, + int need_expand, double background_gamma) +{ + png_set_background_fixed(png_ptr, background_color, background_gamma_code, + need_expand, png_fixed(png_ptr, background_gamma, "png_set_background")); +} +# endif /* FLOATING_POINT */ +#endif /* READ_BACKGROUND */ #ifdef PNG_READ_16_TO_8_SUPPORTED /* Strip 16 bit depth files to 8 bit depth */ @@ -125,6 +135,7 @@ png_set_strip_16(png_structp png_ptr) if (png_ptr == NULL) return; + png_ptr->transformations |= PNG_16_TO_8; } #endif @@ -137,17 +148,18 @@ png_set_strip_alpha(png_structp png_ptr) if (png_ptr == NULL) return; + png_ptr->flags |= PNG_FLAG_STRIP_ALPHA; } #endif #ifdef PNG_READ_QUANTIZE_SUPPORTED -/* Quantize file to 8 bit. Supply a palette, the current number +/* Dither file to 8 bit. Supply a palette, the current number * of elements in the palette, the maximum number of elements * allowed, and a histogram if possible. If the current number * of colors is greater then the maximum number, the palette will be * modified to fit in the maximum number. "full_quantize" indicates - * whether we need a quantizeing cube set up for RGB images, or if we + * whether we need a quantizing cube set up for RGB images, or if we * simply are reducing the number of colors in a paletted image. */ @@ -162,13 +174,14 @@ typedef png_dsort FAR * FAR * png_dsortpp; void PNGAPI png_set_quantize(png_structp png_ptr, png_colorp palette, - int num_palette, int maximum_colors, png_uint_16p histogram, - int full_quantize) + int num_palette, int maximum_colors, png_const_uint_16p histogram, + int full_quantize) { png_debug(1, "in png_set_quantize"); if (png_ptr == NULL) return; + png_ptr->transformations |= PNG_QUANTIZE; if (!full_quantize) @@ -176,7 +189,7 @@ png_set_quantize(png_structp png_ptr, png_colorp palette, int i; png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr, - (png_uint_32)(num_palette * png_sizeof(png_byte))); + (png_uint_32)(num_palette * png_sizeof(png_byte))); for (i = 0; i < num_palette; i++) png_ptr->quantize_index[i] = (png_byte)i; } @@ -193,7 +206,7 @@ png_set_quantize(png_structp png_ptr, png_colorp palette, /* Initialize an array to sort colors */ png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr, - (png_uint_32)(num_palette * png_sizeof(png_byte))); + (png_uint_32)(num_palette * png_sizeof(png_byte))); /* Initialize the quantize_sort array */ for (i = 0; i < num_palette; i++) @@ -225,6 +238,7 @@ png_set_quantize(png_structp png_ptr, png_colorp palette, done = 0; } } + if (done) break; } @@ -244,6 +258,7 @@ png_set_quantize(png_structp png_ptr, png_colorp palette, do j--; while ((int)png_ptr->quantize_sort[j] >= maximum_colors); + palette[i] = palette[j]; } } @@ -325,9 +340,9 @@ png_set_quantize(png_structp png_ptr, png_colorp palette, /* Initialize palette index arrays */ png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr, - (png_uint_32)(num_palette * png_sizeof(png_byte))); + (png_uint_32)(num_palette * png_sizeof(png_byte))); png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr, - (png_uint_32)(num_palette * png_sizeof(png_byte))); + (png_uint_32)(num_palette * png_sizeof(png_byte))); /* Initialize the sort array */ for (i = 0; i < num_palette; i++) @@ -337,7 +352,7 @@ png_set_quantize(png_structp png_ptr, png_colorp palette, } hash = (png_dsortpp)png_calloc(png_ptr, (png_uint_32)(769 * - png_sizeof(png_dsortp))); + png_sizeof(png_dsortp))); num_new_palette = num_palette; @@ -368,8 +383,10 @@ png_set_quantize(png_structp png_ptr, png_colorp palette, t = (png_dsortp)png_malloc_warn(png_ptr, (png_uint_32)(png_sizeof(png_dsort))); + if (t == NULL) break; + t->next = hash[d]; t->left = (png_byte)i; t->right = (png_byte)j; @@ -390,9 +407,9 @@ png_set_quantize(png_structp png_ptr, png_colorp palette, for (p = hash[i]; p; p = p->next) { if ((int)png_ptr->index_to_palette[p->left] - < num_new_palette && - (int)png_ptr->index_to_palette[p->right] - < num_new_palette) + < num_new_palette && + (int)png_ptr->index_to_palette[p->right] + < num_new_palette) { int j, next_j; @@ -409,7 +426,7 @@ png_set_quantize(png_structp png_ptr, png_colorp palette, num_new_palette--; palette[png_ptr->index_to_palette[j]] - = palette[num_new_palette]; + = palette[num_new_palette]; if (!full_quantize) { int k; @@ -417,23 +434,26 @@ png_set_quantize(png_structp png_ptr, png_colorp palette, for (k = 0; k < num_palette; k++) { if (png_ptr->quantize_index[k] == - png_ptr->index_to_palette[j]) + png_ptr->index_to_palette[j]) png_ptr->quantize_index[k] = - png_ptr->index_to_palette[next_j]; + png_ptr->index_to_palette[next_j]; + if ((int)png_ptr->quantize_index[k] == - num_new_palette) + num_new_palette) png_ptr->quantize_index[k] = - png_ptr->index_to_palette[j]; + png_ptr->index_to_palette[j]; } } png_ptr->index_to_palette[png_ptr->palette_to_index - [num_new_palette]] = png_ptr->index_to_palette[j]; + [num_new_palette]] = png_ptr->index_to_palette[j]; + png_ptr->palette_to_index[png_ptr->index_to_palette[j]] - = png_ptr->palette_to_index[num_new_palette]; + = png_ptr->palette_to_index[num_new_palette]; png_ptr->index_to_palette[j] = (png_byte)num_new_palette; + png_ptr->palette_to_index[num_new_palette] = (png_byte)j; } @@ -480,17 +500,18 @@ png_set_quantize(png_structp png_ptr, png_colorp palette, int i; png_bytep distance; int total_bits = PNG_QUANTIZE_RED_BITS + PNG_QUANTIZE_GREEN_BITS + - PNG_QUANTIZE_BLUE_BITS; + PNG_QUANTIZE_BLUE_BITS; int num_red = (1 << PNG_QUANTIZE_RED_BITS); int num_green = (1 << PNG_QUANTIZE_GREEN_BITS); int num_blue = (1 << PNG_QUANTIZE_BLUE_BITS); png_size_t num_entries = ((png_size_t)1 << total_bits); - png_ptr->palette_lookup = (png_bytep )png_calloc(png_ptr, - (png_uint_32)(num_entries * png_sizeof(png_byte))); + png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr, + (png_uint_32)(num_entries * png_sizeof(png_byte))); distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries * - png_sizeof(png_byte))); + png_sizeof(png_byte))); + png_memset(distance, 0xff, num_entries * png_sizeof(png_byte)); for (i = 0; i < num_palette; i++) @@ -538,7 +559,7 @@ png_set_quantize(png_structp png_ptr, png_colorp palette, } #endif /* PNG_READ_QUANTIZE_SUPPORTED */ -#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED) +#ifdef PNG_READ_GAMMA_SUPPORTED /* Transform the image from the file_gamma to the screen_gamma. We * only do transformations on images where the file_gamma and screen_gamma * are not close reciprocals, otherwise it slows things down slightly, and @@ -548,22 +569,48 @@ png_set_quantize(png_structp png_ptr, png_colorp palette, * are present in the tRNS array for palette images. We can't do it here * because we don't necessarily have the tRNS chunk yet. */ -void PNGAPI -png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma) +static int /* PRIVATE */ +png_gamma_threshold(png_fixed_point scrn_gamma, png_fixed_point file_gamma) { - png_debug(1, "in png_set_gamma"); + /* PNG_GAMMA_THRESHOLD is the threshold for performing gamma + * correction as a difference of the overall transform from 1.0 + * + * We want to compare the threshold with s*f - 1, if we get + * overflow here it is because of wacky gamma values so we + * turn on processing anyway. + */ + png_fixed_point gtest; + return !png_muldiv(>est, scrn_gamma, file_gamma, PNG_FP_1) || + png_gamma_significant(gtest); +} + +void PNGFAPI +png_set_gamma_fixed(png_structp png_ptr, png_fixed_point scrn_gamma, + png_fixed_point file_gamma) +{ + png_debug(1, "in png_set_gamma_fixed"); if (png_ptr == NULL) return; - if ((fabs(scrn_gamma * file_gamma - 1.0) > PNG_GAMMA_THRESHOLD) || - (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) || - (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)) - png_ptr->transformations |= PNG_GAMMA; - png_ptr->gamma = (float)file_gamma; - png_ptr->screen_gamma = (float)scrn_gamma; + if ((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) || + (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) || + png_gamma_threshold(scrn_gamma, file_gamma)) + png_ptr->transformations |= PNG_GAMMA; + png_ptr->gamma = file_gamma; + png_ptr->screen_gamma = scrn_gamma; } -#endif + +# ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma) +{ + png_set_gamma_fixed(png_ptr, + png_fixed(png_ptr, scrn_gamma, "png_set_gamma screen gamma"), + png_fixed(png_ptr, file_gamma, "png_set_gamma file gamma")); +} +# endif /* FLOATING_POINT_SUPPORTED */ +#endif /* READ_GAMMA */ #ifdef PNG_READ_EXPAND_SUPPORTED /* Expand paletted images to RGB, expand grayscale images of @@ -651,26 +698,9 @@ png_set_gray_to_rgb(png_structp png_ptr) #endif #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED -#ifdef PNG_FLOATING_POINT_SUPPORTED -/* Convert a RGB image to a grayscale of the same width. This allows us, - * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image. - */ - -void PNGAPI -png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red, - double green) -{ - int red_fixed = (int)((float)red*100000.0 + 0.5); - int green_fixed = (int)((float)green*100000.0 + 0.5); - if (png_ptr == NULL) - return; - png_set_rgb_to_gray_fixed(png_ptr, error_action, red_fixed, green_fixed); -} -#endif - -void PNGAPI +void PNGFAPI png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action, - png_fixed_point red, png_fixed_point green) + png_fixed_point red, png_fixed_point green) { png_debug(1, "in png_set_rgb_to_gray"); @@ -679,17 +709,20 @@ png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action, switch(error_action) { - case 1: png_ptr->transformations |= PNG_RGB_TO_GRAY; - break; + case 1: + png_ptr->transformations |= PNG_RGB_TO_GRAY; + break; - case 2: png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN; - break; + case 2: + png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN; + break; - case 3: png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR; + case 3: + png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR; break; default: - png_error(png_ptr, "invalid error action in png_set_rgb_to_gray"); + png_error(png_ptr, "invalid error action to rgb_to_gray"); break; } if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) @@ -699,6 +732,7 @@ png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action, { png_warning(png_ptr, "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED"); + png_ptr->transformations &= ~PNG_RGB_TO_GRAY; } #endif @@ -709,30 +743,52 @@ png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action, red_int = 6968; /* .212671 * 32768 + .5 */ green_int = 23434; /* .715160 * 32768 + .5 */ } + else if (red + green < 100000L) { red_int = (png_uint_16)(((png_uint_32)red*32768L)/100000L); green_int = (png_uint_16)(((png_uint_32)green*32768L)/100000L); } + else { png_warning(png_ptr, "ignoring out of range rgb_to_gray coefficients"); red_int = 6968; green_int = 23434; } + png_ptr->rgb_to_gray_red_coeff = red_int; png_ptr->rgb_to_gray_green_coeff = green_int; png_ptr->rgb_to_gray_blue_coeff = - (png_uint_16)(32768 - red_int - green_int); + (png_uint_16)(32768 - red_int - green_int); } } + +#ifdef PNG_FLOATING_POINT_SUPPORTED +/* Convert a RGB image to a grayscale of the same width. This allows us, + * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image. + */ + +void PNGAPI +png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red, + double green) +{ + if (png_ptr == NULL) + return; + + png_set_rgb_to_gray_fixed(png_ptr, error_action, + png_fixed(png_ptr, red, "rgb to gray red coefficient"), + png_fixed(png_ptr, green, "rgb to gray green coefficient")); +} +#endif /* FLOATING POINT */ + #endif #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) void PNGAPI png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr - read_user_transform_fn) + read_user_transform_fn) { png_debug(1, "in png_set_read_user_transform_fn"); @@ -777,15 +833,17 @@ png_init_read_transformations(png_structp png_ptr) if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) && !(color_type & PNG_COLOR_MASK_COLOR)) { - png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; - } else if ((png_ptr->transformations & PNG_BACKGROUND) && - !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) && - (png_ptr->transformations & PNG_GRAY_TO_RGB) && - png_ptr->background.red == png_ptr->background.green && - png_ptr->background.red == png_ptr->background.blue) + png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; + } + + else if ((png_ptr->transformations & PNG_BACKGROUND) && + !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) && + (png_ptr->transformations & PNG_GRAY_TO_RGB) && + png_ptr->background.red == png_ptr->background.green && + png_ptr->background.red == png_ptr->background.blue) { - png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; - png_ptr->background.gray = png_ptr->background.red; + png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; + png_ptr->background.gray = png_ptr->background.red; } #endif @@ -800,36 +858,36 @@ png_init_read_transformations(png_structp png_ptr) case 1: png_ptr->background.gray *= (png_uint_16)0xff; png_ptr->background.red = png_ptr->background.green - = png_ptr->background.blue = png_ptr->background.gray; + = png_ptr->background.blue = png_ptr->background.gray; if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) { png_ptr->trans_color.gray *= (png_uint_16)0xff; png_ptr->trans_color.red = png_ptr->trans_color.green - = png_ptr->trans_color.blue = png_ptr->trans_color.gray; + = png_ptr->trans_color.blue = png_ptr->trans_color.gray; } break; case 2: png_ptr->background.gray *= (png_uint_16)0x55; png_ptr->background.red = png_ptr->background.green - = png_ptr->background.blue = png_ptr->background.gray; + = png_ptr->background.blue = png_ptr->background.gray; if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) { - png_ptr->trans_color.gray *= (png_uint_16)0x55; - png_ptr->trans_color.red = png_ptr->trans_color.green - = png_ptr->trans_color.blue = png_ptr->trans_color.gray; + png_ptr->trans_color.gray *= (png_uint_16)0x55; + png_ptr->trans_color.red = png_ptr->trans_color.green + = png_ptr->trans_color.blue = png_ptr->trans_color.gray; } break; case 4: png_ptr->background.gray *= (png_uint_16)0x11; png_ptr->background.red = png_ptr->background.green - = png_ptr->background.blue = png_ptr->background.gray; + = png_ptr->background.blue = png_ptr->background.gray; if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) { - png_ptr->trans_color.gray *= (png_uint_16)0x11; - png_ptr->trans_color.red = png_ptr->trans_color.green - = png_ptr->trans_color.blue = png_ptr->trans_color.gray; + png_ptr->trans_color.gray *= (png_uint_16)0x11; + png_ptr->trans_color.red = png_ptr->trans_color.green + = png_ptr->trans_color.blue = png_ptr->trans_color.gray; } break; @@ -839,18 +897,18 @@ png_init_read_transformations(png_structp png_ptr) case 16: png_ptr->background.red = png_ptr->background.green - = png_ptr->background.blue = png_ptr->background.gray; + = png_ptr->background.blue = png_ptr->background.gray; break; } } else if (color_type == PNG_COLOR_TYPE_PALETTE) { png_ptr->background.red = - png_ptr->palette[png_ptr->background.index].red; + png_ptr->palette[png_ptr->background.index].red; png_ptr->background.green = - png_ptr->palette[png_ptr->background.index].green; + png_ptr->palette[png_ptr->background.index].green; png_ptr->background.blue = - png_ptr->palette[png_ptr->background.index].blue; + png_ptr->palette[png_ptr->background.index].blue; #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED if (png_ptr->transformations & PNG_INVERT_ALPHA) @@ -859,13 +917,14 @@ png_init_read_transformations(png_structp png_ptr) if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) #endif { - /* Invert the alpha channel (in tRNS) unless the pixels are - * going to be expanded, in which case leave it for later - */ + /* Invert the alpha channel (in tRNS) unless the pixels are + * going to be expanded, in which case leave it for later + */ int i, istop; istop=(int)png_ptr->num_trans; for (i=0; itrans_alpha[i] = (png_byte)(255 - png_ptr->trans_alpha[i]); + png_ptr->trans_alpha[i] = (png_byte)(255 - + png_ptr->trans_alpha[i]); } } #endif @@ -877,25 +936,24 @@ png_init_read_transformations(png_structp png_ptr) #if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED) png_ptr->background_1 = png_ptr->background; #endif -#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED) +#ifdef PNG_READ_GAMMA_SUPPORTED if ((color_type == PNG_COLOR_TYPE_PALETTE && png_ptr->num_trans != 0) - && (fabs(png_ptr->screen_gamma * png_ptr->gamma - 1.0) - < PNG_GAMMA_THRESHOLD)) + && png_gamma_threshold(png_ptr->screen_gamma, png_ptr->gamma)) { - int i, k; - k=0; - for (i=0; inum_trans; i++) - { - if (png_ptr->trans_alpha[i] != 0 && png_ptr->trans_alpha[i] != 0xff) - k=1; /* Partial transparency is present */ - } - if (k == 0) - png_ptr->transformations &= ~PNG_GAMMA; + int i, k; + k=0; + for (i=0; inum_trans; i++) + { + if (png_ptr->trans_alpha[i] != 0 && png_ptr->trans_alpha[i] != 0xff) + k=1; /* Partial transparency is present */ + } + if (k == 0) + png_ptr->transformations &= ~PNG_GAMMA; } if ((png_ptr->transformations & (PNG_GAMMA | PNG_RGB_TO_GRAY)) && - png_ptr->gamma != 0.0) + png_ptr->gamma != 0) { png_build_gamma_table(png_ptr, png_ptr->bit_depth); @@ -904,13 +962,14 @@ png_init_read_transformations(png_structp png_ptr) { if (color_type == PNG_COLOR_TYPE_PALETTE) { - /* Could skip if no transparency */ + /* Could skip if no transparency */ png_color back, back_1; png_colorp palette = png_ptr->palette; int num_palette = png_ptr->num_palette; int i; if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE) { + back.red = png_ptr->gamma_table[png_ptr->background.red]; back.green = png_ptr->gamma_table[png_ptr->background.green]; back.blue = png_ptr->gamma_table[png_ptr->background.blue]; @@ -921,57 +980,58 @@ png_init_read_transformations(png_structp png_ptr) } else { - double g, gs; + png_fixed_point g, gs; switch (png_ptr->background_gamma_type) { case PNG_BACKGROUND_GAMMA_SCREEN: g = (png_ptr->screen_gamma); - gs = 1.0; + gs = PNG_FP_1; break; case PNG_BACKGROUND_GAMMA_FILE: - g = 1.0 / (png_ptr->gamma); - gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma); + g = png_reciprocal(png_ptr->gamma); + gs = png_reciprocal2(png_ptr->gamma, + png_ptr->screen_gamma); break; case PNG_BACKGROUND_GAMMA_UNIQUE: - g = 1.0 / (png_ptr->background_gamma); - gs = 1.0 / (png_ptr->background_gamma * - png_ptr->screen_gamma); + g = png_reciprocal(png_ptr->background_gamma); + gs = png_reciprocal2(png_ptr->background_gamma, + png_ptr->screen_gamma); break; default: - g = 1.0; /* back_1 */ - gs = 1.0; /* back */ + g = PNG_FP_1; /* back_1 */ + gs = PNG_FP_1; /* back */ + break; } - if ( fabs(gs - 1.0) < PNG_GAMMA_THRESHOLD) + if (png_gamma_significant(gs)) { back.red = (png_byte)png_ptr->background.red; back.green = (png_byte)png_ptr->background.green; back.blue = (png_byte)png_ptr->background.blue; } + else { - back.red = (png_byte)(pow( - (double)png_ptr->background.red/255.0, gs) * 255.0 + .5); - back.green = (png_byte)(pow( - (double)png_ptr->background.green/255.0, gs) * 255.0 - + .5); - back.blue = (png_byte)(pow( - (double)png_ptr->background.blue/255.0, gs) * 255.0 + .5); + back.red = png_gamma_8bit_correct(png_ptr->background.red, + gs); + back.green = png_gamma_8bit_correct(png_ptr->background.green, + gs); + back.blue = png_gamma_8bit_correct(png_ptr->background.blue, + gs); } - - back_1.red = (png_byte)(pow( - (double)png_ptr->background.red/255.0, g) * 255.0 + .5); - back_1.green = (png_byte)(pow( - (double)png_ptr->background.green/255.0, g) * 255.0 + .5); - back_1.blue = (png_byte)(pow( - (double)png_ptr->background.blue/255.0, g) * 255.0 + .5); + back_1.red = png_gamma_8bit_correct(png_ptr->background.red, g); + back_1.green = png_gamma_8bit_correct(png_ptr->background.green, + g); + back_1.blue = png_gamma_8bit_correct(png_ptr->background.blue, + g); } for (i = 0; i < num_palette; i++) { - if (i < (int)png_ptr->num_trans && png_ptr->trans_alpha[i] != 0xff) + if (i < (int)png_ptr->num_trans && + png_ptr->trans_alpha[i] != 0xff) { if (png_ptr->trans_alpha[i] == 0) { @@ -1008,68 +1068,76 @@ png_init_read_transformations(png_structp png_ptr) */ png_ptr->transformations &= ~PNG_BACKGROUND; png_ptr->transformations &= ~PNG_GAMMA; - png_ptr->transformations |= PNG_STRIP_ALPHA; + png_ptr->flags |= PNG_FLAG_STRIP_ALPHA; } + /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */ else /* color_type != PNG_COLOR_TYPE_PALETTE */ { - double m = (double)(((png_uint_32)1 << png_ptr->bit_depth) - 1); - double g = 1.0; - double gs = 1.0; + png_fixed_point g = PNG_FP_1; + png_fixed_point gs = PNG_FP_1; switch (png_ptr->background_gamma_type) { case PNG_BACKGROUND_GAMMA_SCREEN: - g = (png_ptr->screen_gamma); - gs = 1.0; + g = png_ptr->screen_gamma; + /* gs = PNG_FP_1; */ break; case PNG_BACKGROUND_GAMMA_FILE: - g = 1.0 / (png_ptr->gamma); - gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma); + g = png_reciprocal(png_ptr->gamma); + gs = png_reciprocal2(png_ptr->gamma, png_ptr->screen_gamma); break; case PNG_BACKGROUND_GAMMA_UNIQUE: - g = 1.0 / (png_ptr->background_gamma); - gs = 1.0 / (png_ptr->background_gamma * - png_ptr->screen_gamma); + g = png_reciprocal(png_ptr->background_gamma); + gs = png_reciprocal2(png_ptr->background_gamma, + png_ptr->screen_gamma); break; default: png_error(png_ptr, "invalid background gamma type"); } - png_ptr->background_1.gray = (png_uint_16)(pow( - (double)png_ptr->background.gray / m, g) * m + .5); - png_ptr->background.gray = (png_uint_16)(pow( - (double)png_ptr->background.gray / m, gs) * m + .5); + png_ptr->background_1.gray = png_gamma_correct(png_ptr, + png_ptr->background.gray, g); + + png_ptr->background.gray = png_gamma_correct(png_ptr, + png_ptr->background.gray, gs); if ((png_ptr->background.red != png_ptr->background.green) || (png_ptr->background.red != png_ptr->background.blue) || (png_ptr->background.red != png_ptr->background.gray)) { /* RGB or RGBA with color background */ - png_ptr->background_1.red = (png_uint_16)(pow( - (double)png_ptr->background.red / m, g) * m + .5); - png_ptr->background_1.green = (png_uint_16)(pow( - (double)png_ptr->background.green / m, g) * m + .5); - png_ptr->background_1.blue = (png_uint_16)(pow( - (double)png_ptr->background.blue / m, g) * m + .5); - png_ptr->background.red = (png_uint_16)(pow( - (double)png_ptr->background.red / m, gs) * m + .5); - png_ptr->background.green = (png_uint_16)(pow( - (double)png_ptr->background.green / m, gs) * m + .5); - png_ptr->background.blue = (png_uint_16)(pow( - (double)png_ptr->background.blue / m, gs) * m + .5); + png_ptr->background_1.red = png_gamma_correct(png_ptr, + png_ptr->background.red, g); + + png_ptr->background_1.green = png_gamma_correct(png_ptr, + png_ptr->background.green, g); + + png_ptr->background_1.blue = png_gamma_correct(png_ptr, + png_ptr->background.blue, g); + + png_ptr->background.red = png_gamma_correct(png_ptr, + png_ptr->background.red, gs); + + png_ptr->background.green = png_gamma_correct(png_ptr, + png_ptr->background.green, gs); + + png_ptr->background.blue = png_gamma_correct(png_ptr, + png_ptr->background.blue, gs); } + else { /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */ png_ptr->background_1.red = png_ptr->background_1.green - = png_ptr->background_1.blue = png_ptr->background_1.gray; + = png_ptr->background_1.blue = png_ptr->background_1.gray; + png_ptr->background.red = png_ptr->background.green - = png_ptr->background.blue = png_ptr->background.gray; + = png_ptr->background.blue = png_ptr->background.gray; } } } @@ -1096,7 +1164,7 @@ png_init_read_transformations(png_structp png_ptr) #ifdef PNG_READ_BACKGROUND_SUPPORTED else #endif -#endif /* PNG_READ_GAMMA_SUPPORTED && PNG_FLOATING_POINT_SUPPORTED */ +#endif /* PNG_READ_GAMMA_SUPPORTED */ #ifdef PNG_READ_BACKGROUND_SUPPORTED /* No GAMMA transformation */ if ((png_ptr->transformations & PNG_BACKGROUND) && @@ -1117,27 +1185,30 @@ png_init_read_transformations(png_structp png_ptr) { palette[i] = back; } + else if (png_ptr->trans_alpha[i] != 0xff) { /* The png_composite() macro is defined in png.h */ png_composite(palette[i].red, palette[i].red, - png_ptr->trans_alpha[i], back.red); + png_ptr->trans_alpha[i], back.red); + png_composite(palette[i].green, palette[i].green, - png_ptr->trans_alpha[i], back.green); + png_ptr->trans_alpha[i], back.green); + png_composite(palette[i].blue, palette[i].blue, - png_ptr->trans_alpha[i], back.blue); + png_ptr->trans_alpha[i], back.blue); } } /* Handled alpha, still need to strip the channel. */ png_ptr->transformations &= ~PNG_BACKGROUND; - png_ptr->transformations |= PNG_STRIP_ALPHA; + png_ptr->flags |= PNG_FLAG_STRIP_ALPHA; } #endif /* PNG_READ_BACKGROUND_SUPPORTED */ #ifdef PNG_READ_SHIFT_SUPPORTED if ((png_ptr->transformations & PNG_SHIFT) && - (color_type == PNG_COLOR_TYPE_PALETTE)) + (color_type == PNG_COLOR_TYPE_PALETTE)) { png_uint_16 i; png_uint_16 istop = png_ptr->num_palette; @@ -1147,10 +1218,13 @@ png_init_read_transformations(png_structp png_ptr) if (sr < 0 || sr > 8) sr = 0; + if (sg < 0 || sg > 8) sg = 0; + if (sb < 0 || sb > 8) sb = 0; + for (i = 0; i < istop; i++) { png_ptr->palette[i].red >>= sr; @@ -1182,10 +1256,12 @@ png_read_transform_info(png_structp png_ptr, png_infop info_ptr) if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { if (png_ptr->num_trans && - (png_ptr->transformations & PNG_EXPAND_tRNS)) + (png_ptr->transformations & PNG_EXPAND_tRNS)) info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA; + else info_ptr->color_type = PNG_COLOR_TYPE_RGB; + info_ptr->bit_depth = 8; info_ptr->num_trans = 0; } @@ -1194,10 +1270,11 @@ png_read_transform_info(png_structp png_ptr, png_infop info_ptr) if (png_ptr->num_trans) { if (png_ptr->transformations & PNG_EXPAND_tRNS) - info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; + info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; } if (info_ptr->bit_depth < 8) info_ptr->bit_depth = 8; + info_ptr->num_trans = 0; } } @@ -1206,7 +1283,8 @@ png_read_transform_info(png_structp png_ptr, png_infop info_ptr) #ifdef PNG_READ_BACKGROUND_SUPPORTED if (png_ptr->transformations & PNG_BACKGROUND) { - info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA; + info_ptr->color_type = (png_byte)(info_ptr->color_type & + ~PNG_COLOR_MASK_ALPHA); info_ptr->num_trans = 0; info_ptr->background = png_ptr->background; } @@ -1215,18 +1293,22 @@ png_read_transform_info(png_structp png_ptr, png_infop info_ptr) #ifdef PNG_READ_GAMMA_SUPPORTED if (png_ptr->transformations & PNG_GAMMA) { -#ifdef PNG_FLOATING_POINT_SUPPORTED info_ptr->gamma = png_ptr->gamma; -#endif -#ifdef PNG_FIXED_POINT_SUPPORTED - info_ptr->int_gamma = png_ptr->int_gamma; -#endif } #endif #ifdef PNG_READ_16_TO_8_SUPPORTED +#ifdef PNG_READ_16BIT_SUPPORTED if ((png_ptr->transformations & PNG_16_TO_8) && (info_ptr->bit_depth == 16)) info_ptr->bit_depth = 8; +#else + /* Force chopping 16-bit input down to 8 */ + if (info_ptr->bit_depth == 16) + { + png_ptr->transformations |=PNG_16_TO_8; + info_ptr->bit_depth = 8; + } +#endif #endif #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED @@ -1258,8 +1340,10 @@ png_read_transform_info(png_structp png_ptr, png_infop info_ptr) if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) info_ptr->channels = 1; + else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) info_ptr->channels = 3; + else info_ptr->channels = 1; @@ -1280,23 +1364,24 @@ png_read_transform_info(png_structp png_ptr, png_infop info_ptr) info_ptr->channels++; /* If adding a true alpha channel not just filler */ if (png_ptr->transformations & PNG_ADD_ALPHA) - info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; + info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; } #endif #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \ defined(PNG_READ_USER_TRANSFORM_SUPPORTED) if (png_ptr->transformations & PNG_USER_TRANSFORM) - { - if (info_ptr->bit_depth < png_ptr->user_transform_depth) + { + if (info_ptr->bit_depth < png_ptr->user_transform_depth) info_ptr->bit_depth = png_ptr->user_transform_depth; - if (info_ptr->channels < png_ptr->user_transform_channels) + + if (info_ptr->channels < png_ptr->user_transform_channels) info_ptr->channels = png_ptr->user_transform_channels; - } + } #endif info_ptr->pixel_depth = (png_byte)(info_ptr->channels * - info_ptr->bit_depth); + info_ptr->bit_depth); info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width); @@ -1317,12 +1402,12 @@ png_do_read_transformations(png_structp png_ptr) if (png_ptr->row_buf == NULL) { -#ifdef PNG_STDIO_SUPPORTED +#ifdef PNG_CONSOLE_IO_SUPPORTED char msg[50]; png_snprintf2(msg, 50, - "NULL row buffer for row %ld, pass %d", (long)png_ptr->row_number, - png_ptr->pass); + "NULL row buffer for row %ld, pass %d", (long)png_ptr->row_number, + png_ptr->pass); png_error(png_ptr, msg); #else png_error(png_ptr, "NULL row buffer"); @@ -1347,17 +1432,18 @@ png_do_read_transformations(png_structp png_ptr) if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE) { png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1, - png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans); + png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans); } else { if (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND_tRNS)) png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1, - &(png_ptr->trans_color)); + &(png_ptr->trans_color)); else + png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1, - NULL); + NULL); } } #endif @@ -1365,21 +1451,23 @@ png_do_read_transformations(png_structp png_ptr) #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA) png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1, - PNG_FLAG_FILLER_AFTER | (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)); + PNG_FLAG_FILLER_AFTER | (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)); #endif #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED if (png_ptr->transformations & PNG_RGB_TO_GRAY) { int rgb_error = - png_do_rgb_to_gray(png_ptr, &(png_ptr->row_info), - png_ptr->row_buf + 1); + png_do_rgb_to_gray(png_ptr, &(png_ptr->row_info), + png_ptr->row_buf + 1); + if (rgb_error) { png_ptr->rgb_to_gray_status=1; if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == PNG_RGB_TO_GRAY_WARN) png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel"); + if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == PNG_RGB_TO_GRAY_ERR) png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel"); @@ -1429,18 +1517,18 @@ png_do_read_transformations(png_structp png_ptr) #ifdef PNG_READ_BACKGROUND_SUPPORTED if ((png_ptr->transformations & PNG_BACKGROUND) && - ((png_ptr->num_trans != 0 ) || - (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) + ((png_ptr->num_trans != 0) || + (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1, - &(png_ptr->trans_color), &(png_ptr->background) + &(png_ptr->trans_color), &(png_ptr->background) #ifdef PNG_READ_GAMMA_SUPPORTED - , &(png_ptr->background_1), - png_ptr->gamma_table, png_ptr->gamma_from_1, - png_ptr->gamma_to_1, png_ptr->gamma_16_table, - png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1, - png_ptr->gamma_shift + , &(png_ptr->background_1), + png_ptr->gamma_table, png_ptr->gamma_from_1, + png_ptr->gamma_to_1, png_ptr->gamma_16_table, + png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1, + png_ptr->gamma_shift #endif -); + ); #endif #ifdef PNG_READ_GAMMA_SUPPORTED @@ -1464,12 +1552,13 @@ png_do_read_transformations(png_structp png_ptr) #ifdef PNG_READ_QUANTIZE_SUPPORTED if (png_ptr->transformations & PNG_QUANTIZE) { - png_do_quantize((png_row_infop)&(png_ptr->row_info), png_ptr->row_buf + 1, - png_ptr->palette_lookup, png_ptr->quantize_index); - if (png_ptr->row_info.rowbytes == (png_uint_32)0) + png_do_quantize(&(png_ptr->row_info), png_ptr->row_buf + 1, + png_ptr->palette_lookup, png_ptr->quantize_index); + + if (png_ptr->row_info.rowbytes == 0) png_error(png_ptr, "png_do_quantize returned rowbytes=0"); } -#endif +#endif /* PNG_READ_QUANTIZE_SUPPORTED */ #ifdef PNG_READ_INVERT_SUPPORTED if (png_ptr->transformations & PNG_INVERT_MONO) @@ -1479,7 +1568,7 @@ png_do_read_transformations(png_structp png_ptr) #ifdef PNG_READ_SHIFT_SUPPORTED if (png_ptr->transformations & PNG_SHIFT) png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1, - &(png_ptr->shift)); + &(png_ptr->shift)); #endif #ifdef PNG_READ_PACK_SUPPORTED @@ -1507,7 +1596,7 @@ png_do_read_transformations(png_structp png_ptr) #ifdef PNG_READ_FILLER_SUPPORTED if (png_ptr->transformations & PNG_FILLER) png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1, - (png_uint_32)png_ptr->filler, png_ptr->flags); + (png_uint_32)png_ptr->filler, png_ptr->flags); #endif #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED @@ -1520,35 +1609,39 @@ png_do_read_transformations(png_structp png_ptr) png_do_read_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); #endif +#ifdef PNG_READ_16BIT_SUPPORTED #ifdef PNG_READ_SWAP_SUPPORTED if (png_ptr->transformations & PNG_SWAP_BYTES) png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1); #endif +#endif #ifdef PNG_READ_USER_TRANSFORM_SUPPORTED if (png_ptr->transformations & PNG_USER_TRANSFORM) { if (png_ptr->read_user_transform_fn != NULL) (*(png_ptr->read_user_transform_fn)) /* User read transform function */ - (png_ptr, /* png_ptr */ - &(png_ptr->row_info), /* row_info: */ - /* png_uint_32 width; width of row */ - /* png_uint_32 rowbytes; number of bytes in row */ - /* png_byte color_type; color type of pixels */ - /* png_byte bit_depth; bit depth of samples */ - /* png_byte channels; number of channels (1-4) */ - /* png_byte pixel_depth; bits per pixel (depth*channels) */ - png_ptr->row_buf + 1); /* start of pixel data for row */ + (png_ptr, /* png_ptr */ + &(png_ptr->row_info), /* row_info: */ + /* png_uint_32 width; width of row */ + /* png_size_t rowbytes; number of bytes in row */ + /* png_byte color_type; color type of pixels */ + /* png_byte bit_depth; bit depth of samples */ + /* png_byte channels; number of channels (1-4) */ + /* png_byte pixel_depth; bits per pixel (depth*channels) */ + png_ptr->row_buf + 1); /* start of pixel data for row */ #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED if (png_ptr->user_transform_depth) png_ptr->row_info.bit_depth = png_ptr->user_transform_depth; + if (png_ptr->user_transform_channels) png_ptr->row_info.channels = png_ptr->user_transform_channels; #endif png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth * - png_ptr->row_info.channels); + png_ptr->row_info.channels); + png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, - png_ptr->row_info.width); + png_ptr->row_info.width); } #endif @@ -1581,11 +1674,13 @@ png_do_unpack(png_row_infop row_info, png_bytep row) for (i = 0; i < row_width; i++) { *dp = (png_byte)((*sp >> shift) & 0x01); + if (shift == 7) { shift = 0; sp--; } + else shift++; @@ -1603,11 +1698,13 @@ png_do_unpack(png_row_infop row_info, png_bytep row) for (i = 0; i < row_width; i++) { *dp = (png_byte)((*sp >> shift) & 0x03); + if (shift == 6) { shift = 0; sp--; } + else shift += 2; @@ -1624,11 +1721,13 @@ png_do_unpack(png_row_infop row_info, png_bytep row) for (i = 0; i < row_width; i++) { *dp = (png_byte)((*sp >> shift) & 0x0f); + if (shift == 4) { shift = 0; sp--; } + else shift = 4; @@ -1654,7 +1753,8 @@ png_do_unpack(png_row_infop row_info, png_bytep row) * the values back to 0 through 31. */ void /* PRIVATE */ -png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits) +png_do_unshift(png_row_infop row_info, png_bytep row, + png_const_color_8p sig_bits) { png_debug(1, "in png_do_unshift"); @@ -1673,10 +1773,12 @@ png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits) shift[channels++] = row_info->bit_depth - sig_bits->green; shift[channels++] = row_info->bit_depth - sig_bits->blue; } + else { shift[channels++] = row_info->bit_depth - sig_bits->gray; } + if (row_info->color_type & PNG_COLOR_MASK_ALPHA) { shift[channels++] = row_info->bit_depth - sig_bits->alpha; @@ -1686,6 +1788,7 @@ png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits) { if (shift[c] <= 0) shift[c] = 0; + else value = 1; } @@ -1701,8 +1804,8 @@ png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits) case 2: { png_bytep bp; - png_uint_32 i; - png_uint_32 istop = row_info->rowbytes; + png_size_t i; + png_size_t istop = row_info->rowbytes; for (bp = row, i = 0; i < istop; i++) { @@ -1715,10 +1818,10 @@ png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits) case 4: { png_bytep bp = row; - png_uint_32 i; - png_uint_32 istop = row_info->rowbytes; + png_size_t i; + png_size_t istop = row_info->rowbytes; png_byte mask = (png_byte)((((int)0xf0 >> shift[0]) & (int)0xf0) | - (png_byte)((int)0xf >> shift[0])); + (png_byte)((int)0xf >> shift[0])); for (i = 0; i < istop; i++) { @@ -1741,6 +1844,7 @@ png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits) break; } +#ifdef PNG_READ_16BIT_SUPPORTED case 16: { png_bytep bp = row; @@ -1756,6 +1860,7 @@ png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits) } break; } +#endif } } } @@ -1843,6 +1948,8 @@ png_do_read_swap_alpha(png_row_infop row_info, png_bytep row) *(--dp) = save; } } + +#ifdef PNG_READ_16BIT_SUPPORTED /* This converts from RRGGBBAA to AARRGGBB */ else { @@ -1865,7 +1972,9 @@ png_do_read_swap_alpha(png_row_infop row_info, png_bytep row) *(--dp) = save[1]; } } +#endif } + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { /* This converts from GA to AG */ @@ -1883,6 +1992,8 @@ png_do_read_swap_alpha(png_row_infop row_info, png_bytep row) *(--dp) = save; } } + +#ifdef PNG_READ_16BIT_SUPPORTED /* This converts from GGAA to AAGG */ else { @@ -1901,6 +2012,7 @@ png_do_read_swap_alpha(png_row_infop row_info, png_bytep row) *(--dp) = save[1]; } } +#endif } } } @@ -1910,94 +2022,99 @@ png_do_read_swap_alpha(png_row_infop row_info, png_bytep row) void /* PRIVATE */ png_do_read_invert_alpha(png_row_infop row_info, png_bytep row) { + png_uint_32 row_width; png_debug(1, "in png_do_read_invert_alpha"); + row_width = row_info->width; + if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) { - png_uint_32 row_width = row_info->width; - if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + if (row_info->bit_depth == 8) { /* This inverts the alpha channel in RGBA */ - if (row_info->bit_depth == 8) + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_uint_32 i; + + for (i = 0; i < row_width; i++) { - png_bytep sp = row + row_info->rowbytes; - png_bytep dp = sp; - png_uint_32 i; + *(--dp) = (png_byte)(255 - *(--sp)); - for (i = 0; i < row_width; i++) - { - *(--dp) = (png_byte)(255 - *(--sp)); - -/* This does nothing: - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - We can replace it with: +/* This does nothing: + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + We can replace it with: */ - sp-=3; - dp=sp; - } - } - /* This inverts the alpha channel in RRGGBBAA */ - else - { - png_bytep sp = row + row_info->rowbytes; - png_bytep dp = sp; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - *(--dp) = (png_byte)(255 - *(--sp)); - *(--dp) = (png_byte)(255 - *(--sp)); - -/* This does nothing: - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - *(--dp) = *(--sp); - We can replace it with: -*/ - sp-=6; - dp=sp; - } + sp-=3; + dp=sp; } } - else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + +#ifdef PNG_READ_16BIT_SUPPORTED + /* This inverts the alpha channel in RRGGBBAA */ + else + { + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + *(--dp) = (png_byte)(255 - *(--sp)); + *(--dp) = (png_byte)(255 - *(--sp)); + +/* This does nothing: + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + *(--dp) = *(--sp); + We can replace it with: +*/ + sp-=6; + dp=sp; + } + } +#endif + } + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + if (row_info->bit_depth == 8) { /* This inverts the alpha channel in GA */ - if (row_info->bit_depth == 8) - { - png_bytep sp = row + row_info->rowbytes; - png_bytep dp = sp; - png_uint_32 i; + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_uint_32 i; - for (i = 0; i < row_width; i++) - { - *(--dp) = (png_byte)(255 - *(--sp)); - *(--dp) = *(--sp); - } - } - /* This inverts the alpha channel in GGAA */ - else + for (i = 0; i < row_width; i++) { - png_bytep sp = row + row_info->rowbytes; - png_bytep dp = sp; - png_uint_32 i; - - for (i = 0; i < row_width; i++) - { - *(--dp) = (png_byte)(255 - *(--sp)); - *(--dp) = (png_byte)(255 - *(--sp)); -/* - *(--dp) = *(--sp); - *(--dp) = *(--sp); -*/ - sp-=2; - dp=sp; - } + *(--dp) = (png_byte)(255 - *(--sp)); + *(--dp) = *(--sp); } } + +#ifdef PNG_READ_16BIT_SUPPORTED + else + { + /* This inverts the alpha channel in GGAA */ + png_bytep sp = row + row_info->rowbytes; + png_bytep dp = sp; + png_uint_32 i; + + for (i = 0; i < row_width; i++) + { + *(--dp) = (png_byte)(255 - *(--sp)); + *(--dp) = (png_byte)(255 - *(--sp)); +/* + *(--dp) = *(--sp); + *(--dp) = *(--sp); +*/ + sp-=2; + dp=sp; + } + } +#endif } } #endif @@ -2006,12 +2123,14 @@ png_do_read_invert_alpha(png_row_infop row_info, png_bytep row) /* Add filler channel if we have RGB color */ void /* PRIVATE */ png_do_read_filler(png_row_infop row_info, png_bytep row, - png_uint_32 filler, png_uint_32 flags) + png_uint_32 filler, png_uint_32 flags) { png_uint_32 i; png_uint_32 row_width = row_info->width; +#ifdef PNG_READ_16BIT_SUPPORTED png_byte hi_filler = (png_byte)((filler>>8) & 0xff); +#endif png_byte lo_filler = (png_byte)(filler & 0xff); png_debug(1, "in png_do_read_filler"); @@ -2021,9 +2140,9 @@ png_do_read_filler(png_row_infop row_info, png_bytep row, { if (row_info->bit_depth == 8) { - /* This changes the data from G to GX */ if (flags & PNG_FLAG_FILLER_AFTER) { + /* This changes the data from G to GX */ png_bytep sp = row + (png_size_t)row_width; png_bytep dp = sp + (png_size_t)row_width; for (i = 1; i < row_width; i++) @@ -2036,9 +2155,10 @@ png_do_read_filler(png_row_infop row_info, png_bytep row, row_info->pixel_depth = 16; row_info->rowbytes = row_width * 2; } - /* This changes the data from G to XG */ + else { + /* This changes the data from G to XG */ png_bytep sp = row + (png_size_t)row_width; png_bytep dp = sp + (png_size_t)row_width; for (i = 0; i < row_width; i++) @@ -2051,11 +2171,13 @@ png_do_read_filler(png_row_infop row_info, png_bytep row, row_info->rowbytes = row_width * 2; } } + +#ifdef PNG_READ_16BIT_SUPPORTED else if (row_info->bit_depth == 16) { - /* This changes the data from GG to GGXX */ if (flags & PNG_FLAG_FILLER_AFTER) { + /* This changes the data from GG to GGXX */ png_bytep sp = row + (png_size_t)row_width * 2; png_bytep dp = sp + (png_size_t)row_width * 2; for (i = 1; i < row_width; i++) @@ -2071,9 +2193,10 @@ png_do_read_filler(png_row_infop row_info, png_bytep row, row_info->pixel_depth = 32; row_info->rowbytes = row_width * 4; } - /* This changes the data from GG to XXGG */ + else { + /* This changes the data from GG to XXGG */ png_bytep sp = row + (png_size_t)row_width * 2; png_bytep dp = sp + (png_size_t)row_width * 2; for (i = 0; i < row_width; i++) @@ -2088,14 +2211,15 @@ png_do_read_filler(png_row_infop row_info, png_bytep row, row_info->rowbytes = row_width * 4; } } +#endif } /* COLOR_TYPE == GRAY */ else if (row_info->color_type == PNG_COLOR_TYPE_RGB) { if (row_info->bit_depth == 8) { - /* This changes the data from RGB to RGBX */ if (flags & PNG_FLAG_FILLER_AFTER) { + /* This changes the data from RGB to RGBX */ png_bytep sp = row + (png_size_t)row_width * 3; png_bytep dp = sp + (png_size_t)row_width; for (i = 1; i < row_width; i++) @@ -2110,9 +2234,10 @@ png_do_read_filler(png_row_infop row_info, png_bytep row, row_info->pixel_depth = 32; row_info->rowbytes = row_width * 4; } - /* This changes the data from RGB to XRGB */ + else { + /* This changes the data from RGB to XRGB */ png_bytep sp = row + (png_size_t)row_width * 3; png_bytep dp = sp + (png_size_t)row_width; for (i = 0; i < row_width; i++) @@ -2127,11 +2252,13 @@ png_do_read_filler(png_row_infop row_info, png_bytep row, row_info->rowbytes = row_width * 4; } } + +#ifdef PNG_READ_16BIT_SUPPORTED else if (row_info->bit_depth == 16) { - /* This changes the data from RRGGBB to RRGGBBXX */ if (flags & PNG_FLAG_FILLER_AFTER) { + /* This changes the data from RRGGBB to RRGGBBXX */ png_bytep sp = row + (png_size_t)row_width * 6; png_bytep dp = sp + (png_size_t)row_width * 2; for (i = 1; i < row_width; i++) @@ -2151,9 +2278,10 @@ png_do_read_filler(png_row_infop row_info, png_bytep row, row_info->pixel_depth = 64; row_info->rowbytes = row_width * 8; } - /* This changes the data from RRGGBB to XXRRGGBB */ + else { + /* This changes the data from RRGGBB to XXRRGGBB */ png_bytep sp = row + (png_size_t)row_width * 6; png_bytep dp = sp + (png_size_t)row_width * 2; for (i = 0; i < row_width; i++) @@ -2167,11 +2295,13 @@ png_do_read_filler(png_row_infop row_info, png_bytep row, *(--dp) = hi_filler; *(--dp) = lo_filler; } + row_info->channels = 4; row_info->pixel_depth = 64; row_info->rowbytes = row_width * 8; } } +#endif } /* COLOR_TYPE == RGB */ } #endif @@ -2187,12 +2317,13 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) png_debug(1, "in png_do_gray_to_rgb"); if (row_info->bit_depth >= 8 && - !(row_info->color_type & PNG_COLOR_MASK_COLOR)) + !(row_info->color_type & PNG_COLOR_MASK_COLOR)) { if (row_info->color_type == PNG_COLOR_TYPE_GRAY) { if (row_info->bit_depth == 8) { + /* This changes G to RGB */ png_bytep sp = row + (png_size_t)row_width - 1; png_bytep dp = sp + (png_size_t)row_width * 2; for (i = 0; i < row_width; i++) @@ -2202,8 +2333,10 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) *(dp--) = *(sp--); } } + else { + /* This changes GG to RRGGBB */ png_bytep sp = row + (png_size_t)row_width * 2 - 1; png_bytep dp = sp + (png_size_t)row_width * 4; for (i = 0; i < row_width; i++) @@ -2217,10 +2350,12 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) } } } + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { if (row_info->bit_depth == 8) { + /* This changes GA to RGBA */ png_bytep sp = row + (png_size_t)row_width * 2 - 1; png_bytep dp = sp + (png_size_t)row_width * 2; for (i = 0; i < row_width; i++) @@ -2231,8 +2366,10 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) *(dp--) = *(sp--); } } + else { + /* This changes GGAA to RRGGBBAA */ png_bytep sp = row + (png_size_t)row_width * 4 - 1; png_bytep dp = sp + (png_size_t)row_width * 4; for (i = 0; i < row_width; i++) @@ -2251,7 +2388,7 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) row_info->channels += (png_byte)2; row_info->color_type |= PNG_COLOR_MASK_COLOR; row_info->pixel_depth = (png_byte)(row_info->channels * - row_info->bit_depth); + row_info->bit_depth); row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); } } @@ -2291,7 +2428,7 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) png_debug(1, "in png_do_rgb_to_gray"); if ( - (row_info->color_type & PNG_COLOR_MASK_COLOR)) + (row_info->color_type & PNG_COLOR_MASK_COLOR)) { png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff; png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff; @@ -2312,12 +2449,14 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) png_byte red = png_ptr->gamma_to_1[*(sp++)]; png_byte green = png_ptr->gamma_to_1[*(sp++)]; png_byte blue = png_ptr->gamma_to_1[*(sp++)]; + if (red != green || red != blue) { rgb_error |= 1; *(dp++) = png_ptr->gamma_from_1[ - (rc*red + gc*green + bc*blue)>>15]; + (rc*red + gc*green + bc*blue)>>15]; } + else *(dp++) = *(sp - 1); } @@ -2332,11 +2471,13 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) png_byte red = *(sp++); png_byte green = *(sp++); png_byte blue = *(sp++); + if (red != green || red != blue) { rgb_error |= 1; *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15); } + else *(dp++) = *(sp - 1); } @@ -2355,23 +2496,24 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) { png_uint_16 red, green, blue, w; - red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; - green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; - blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; + red = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; + green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; + blue = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; if (red == green && red == blue) w = red; + else { - png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >> - png_ptr->gamma_shift][red>>8]; + png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) + >> png_ptr->gamma_shift][red>>8]; png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >> - png_ptr->gamma_shift][green>>8]; - png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >> - png_ptr->gamma_shift][blue>>8]; + png_ptr->gamma_shift][green>>8]; + png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) + >> png_ptr->gamma_shift][blue>>8]; png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1 - + bc*blue_1)>>15); + + bc*blue_1)>>15); w = png_ptr->gamma_16_from_1[(gray16&0xff) >> png_ptr->gamma_shift][gray16 >> 8]; rgb_error |= 1; @@ -2390,12 +2532,13 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) { png_uint_16 red, green, blue, gray16; - red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; - green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; - blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; + red = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; + green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; + blue = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; if (red != green || red != blue) rgb_error |= 1; + gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15); *(dp++) = (png_byte)((gray16>>8) & 0xff); *(dp++) = (png_byte)(gray16 & 0xff); @@ -2417,10 +2560,13 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) png_byte red = png_ptr->gamma_to_1[*(sp++)]; png_byte green = png_ptr->gamma_to_1[*(sp++)]; png_byte blue = png_ptr->gamma_to_1[*(sp++)]; + if (red != green || red != blue) rgb_error |= 1; + *(dp++) = png_ptr->gamma_from_1 - [(rc*red + gc*green + bc*blue)>>15]; + [(rc*red + gc*green + bc*blue)>>15]; + *(dp++) = *(sp++); /* alpha */ } } @@ -2436,6 +2582,7 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) png_byte blue = *(sp++); if (red != green || red != blue) rgb_error |= 1; + *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15); *(dp++) = *(sp++); /* alpha */ } @@ -2453,25 +2600,31 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) { png_uint_16 red, green, blue, w; - red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; - green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; - blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2; + red = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; + green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; + blue = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2; if (red == green && red == blue) w = red; + else { png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >> png_ptr->gamma_shift][red>>8]; + png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >> png_ptr->gamma_shift][green>>8]; + png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >> png_ptr->gamma_shift][blue>>8]; + png_uint_16 gray16 = (png_uint_16)((rc * red_1 + gc * green_1 + bc * blue_1)>>15); + w = png_ptr->gamma_16_from_1[(gray16&0xff) >> png_ptr->gamma_shift][gray16 >> 8]; + rgb_error |= 1; } @@ -2489,11 +2642,13 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) for (i = 0; i < row_width; i++) { png_uint_16 red, green, blue, gray16; - red = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2; - green = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2; - blue = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2; + red = (png_uint_16)((*(sp)<<8) | *(sp + 1)); sp += 2; + green = (png_uint_16)((*(sp)<<8) | *(sp + 1)); sp += 2; + blue = (png_uint_16)((*(sp)<<8) | *(sp + 1)); sp += 2; + if (red != green || red != blue) rgb_error |= 1; + gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15); *(dp++) = (png_byte)((gray16>>8) & 0xff); *(dp++) = (png_byte)(gray16 & 0xff); @@ -2503,10 +2658,11 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) } } } - row_info->channels -= (png_byte)2; - row_info->color_type &= ~PNG_COLOR_MASK_COLOR; + row_info->channels -= 2; + row_info->color_type = (png_byte)(row_info->color_type & + ~PNG_COLOR_MASK_COLOR); row_info->pixel_depth = (png_byte)(row_info->channels * - row_info->bit_depth); + row_info->bit_depth); row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); } return rgb_error; @@ -2575,18 +2731,18 @@ png_build_grayscale_palette(int bit_depth, png_colorp palette) */ void /* PRIVATE */ png_do_background(png_row_infop row_info, png_bytep row, - png_color_16p trans_color, png_color_16p background + png_const_color_16p trans_color, png_const_color_16p background #ifdef PNG_READ_GAMMA_SUPPORTED - , png_color_16p background_1, - png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1, - png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1, - png_uint_16pp gamma_16_to_1, int gamma_shift + , png_const_color_16p background_1, png_const_bytep gamma_table, + png_const_bytep gamma_from_1, png_const_bytep gamma_to_1, + png_const_uint_16pp gamma_16, png_const_uint_16pp gamma_16_from_1, + png_const_uint_16pp gamma_16_to_1, int gamma_shift #endif - ) + ) { png_bytep sp, dp; png_uint_32 i; - png_uint_32 row_width=row_info->width; + png_uint_32 row_width = row_info->width; int shift; png_debug(1, "in png_do_background"); @@ -2613,11 +2769,13 @@ png_do_background(png_row_infop row_info, png_bytep row, *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff); *sp |= (png_byte)(background->gray << shift); } + if (!shift) { shift = 7; sp++; } + else shift--; } @@ -2639,6 +2797,7 @@ png_do_background(png_row_infop row_info, png_bytep row, *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); *sp |= (png_byte)(background->gray << shift); } + else { png_byte p = (png_byte)((*sp >> shift) & 0x03); @@ -2647,15 +2806,18 @@ png_do_background(png_row_infop row_info, png_bytep row, *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); *sp |= (png_byte)(g << shift); } + if (!shift) { shift = 6; sp++; } + else shift -= 2; } } + else #endif { @@ -2669,11 +2831,13 @@ png_do_background(png_row_infop row_info, png_bytep row, *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); *sp |= (png_byte)(background->gray << shift); } + if (!shift) { shift = 6; sp++; } + else shift -= 2; } @@ -2696,23 +2860,27 @@ png_do_background(png_row_infop row_info, png_bytep row, *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); *sp |= (png_byte)(background->gray << shift); } + else { png_byte p = (png_byte)((*sp >> shift) & 0x0f); png_byte g = (png_byte)((gamma_table[p | - (p << 4)] >> 4) & 0x0f); + (p << 4)] >> 4) & 0x0f); *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); *sp |= (png_byte)(g << shift); } + if (!shift) { shift = 4; sp++; } + else shift -= 4; } } + else #endif { @@ -2726,11 +2894,13 @@ png_do_background(png_row_infop row_info, png_bytep row, *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); *sp |= (png_byte)(background->gray << shift); } + if (!shift) { shift = 4; sp++; } + else shift -= 4; } @@ -2747,13 +2917,10 @@ png_do_background(png_row_infop row_info, png_bytep row, for (i = 0; i < row_width; i++, sp++) { if (*sp == trans_color->gray) - { *sp = (png_byte)background->gray; - } + else - { *sp = gamma_table[*sp]; - } } } else @@ -2763,9 +2930,7 @@ png_do_background(png_row_infop row_info, png_bytep row, for (i = 0; i < row_width; i++, sp++) { if (*sp == trans_color->gray) - { *sp = (png_byte)background->gray; - } } } break; @@ -2782,12 +2947,14 @@ png_do_background(png_row_infop row_info, png_bytep row, png_uint_16 v; v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); + if (v == trans_color->gray) { /* Background is already in screen gamma */ *sp = (png_byte)((background->gray >> 8) & 0xff); *(sp + 1) = (png_byte)(background->gray & 0xff); } + else { v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; @@ -2805,6 +2972,7 @@ png_do_background(png_row_infop row_info, png_bytep row, png_uint_16 v; v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); + if (v == trans_color->gray) { *sp = (png_byte)((background->gray >> 8) & 0xff); @@ -2832,13 +3000,14 @@ png_do_background(png_row_infop row_info, png_bytep row, for (i = 0; i < row_width; i++, sp += 3) { if (*sp == trans_color->red && - *(sp + 1) == trans_color->green && - *(sp + 2) == trans_color->blue) + *(sp + 1) == trans_color->green && + *(sp + 2) == trans_color->blue) { *sp = (png_byte)background->red; *(sp + 1) = (png_byte)background->green; *(sp + 2) = (png_byte)background->blue; } + else { *sp = gamma_table[*sp]; @@ -2854,8 +3023,8 @@ png_do_background(png_row_infop row_info, png_bytep row, for (i = 0; i < row_width; i++, sp += 3) { if (*sp == trans_color->red && - *(sp + 1) == trans_color->green && - *(sp + 2) == trans_color->blue) + *(sp + 1) == trans_color->green && + *(sp + 2) == trans_color->blue) { *sp = (png_byte)background->red; *(sp + 1) = (png_byte)background->green; @@ -2873,10 +3042,15 @@ png_do_background(png_row_infop row_info, png_bytep row, for (i = 0; i < row_width; i++, sp += 6) { png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); - png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3)); - png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5)); + + png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) + + *(sp + 3)); + + png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) + + *(sp + 5)); + if (r == trans_color->red && g == trans_color->green && - b == trans_color->blue) + b == trans_color->blue) { /* Background is already in screen gamma */ *sp = (png_byte)((background->red >> 8) & 0xff); @@ -2886,32 +3060,40 @@ png_do_background(png_row_infop row_info, png_bytep row, *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff); *(sp + 5) = (png_byte)(background->blue & 0xff); } + else { png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; *sp = (png_byte)((v >> 8) & 0xff); *(sp + 1) = (png_byte)(v & 0xff); + v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; *(sp + 2) = (png_byte)((v >> 8) & 0xff); *(sp + 3) = (png_byte)(v & 0xff); + v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; *(sp + 4) = (png_byte)((v >> 8) & 0xff); *(sp + 5) = (png_byte)(v & 0xff); } } } + else #endif { sp = row; for (i = 0; i < row_width; i++, sp += 6) { - png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp+1)); - png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3)); - png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5)); + png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1)); + + png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8) + + *(sp + 3)); + + png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8) + + *(sp + 5)); if (r == trans_color->red && g == trans_color->green && - b == trans_color->blue) + b == trans_color->blue) { *sp = (png_byte)((background->red >> 8) & 0xff); *(sp + 1) = (png_byte)(background->red & 0xff); @@ -2941,14 +3123,14 @@ png_do_background(png_row_infop row_info, png_bytep row, png_uint_16 a = *(sp + 1); if (a == 0xff) - { *dp = gamma_table[*sp]; - } + else if (a == 0) { /* Background is already in screen gamma */ *dp = (png_byte)background->gray; } + else { png_byte v, w; @@ -2969,18 +3151,15 @@ png_do_background(png_row_infop row_info, png_bytep row, png_byte a = *(sp + 1); if (a == 0xff) - { *dp = *sp; - } + #ifdef PNG_READ_GAMMA_SUPPORTED else if (a == 0) - { *dp = (png_byte)background->gray; - } + else - { png_composite(*dp, *sp, a, background_1->gray); - } + #else *dp = (png_byte)background->gray; #endif @@ -2997,7 +3176,8 @@ png_do_background(png_row_infop row_info, png_bytep row, dp = row; for (i = 0; i < row_width; i++, sp += 4, dp += 2) { - png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3)); + png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8) + + *(sp + 3)); if (a == (png_uint_16)0xffff) { @@ -3007,6 +3187,7 @@ png_do_background(png_row_infop row_info, png_bytep row, *dp = (png_byte)((v >> 8) & 0xff); *(dp + 1) = (png_byte)(v & 0xff); } + #ifdef PNG_READ_GAMMA_SUPPORTED else if (a == 0) #else @@ -3017,6 +3198,7 @@ png_do_background(png_row_infop row_info, png_bytep row, *dp = (png_byte)((background->gray >> 8) & 0xff); *(dp + 1) = (png_byte)(background->gray & 0xff); } + #ifdef PNG_READ_GAMMA_SUPPORTED else { @@ -3038,11 +3220,12 @@ png_do_background(png_row_infop row_info, png_bytep row, dp = row; for (i = 0; i < row_width; i++, sp += 4, dp += 2) { - png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3)); + png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8) + + *(sp + 3)); + if (a == (png_uint_16)0xffff) - { png_memcpy(dp, sp, 2); - } + #ifdef PNG_READ_GAMMA_SUPPORTED else if (a == 0) #else @@ -3052,6 +3235,7 @@ png_do_background(png_row_infop row_info, png_bytep row, *dp = (png_byte)((background->gray >> 8) & 0xff); *(dp + 1) = (png_byte)(background->gray & 0xff); } + #ifdef PNG_READ_GAMMA_SUPPORTED else { @@ -3089,6 +3273,7 @@ png_do_background(png_row_infop row_info, png_bytep row, *(dp + 1) = gamma_table[*(sp + 1)]; *(dp + 2) = gamma_table[*(sp + 2)]; } + else if (a == 0) { /* Background is already in screen gamma */ @@ -3096,6 +3281,7 @@ png_do_background(png_row_infop row_info, png_bytep row, *(dp + 1) = (png_byte)background->green; *(dp + 2) = (png_byte)background->blue; } + else { png_byte v, w; @@ -3103,9 +3289,11 @@ png_do_background(png_row_infop row_info, png_bytep row, v = gamma_to_1[*sp]; png_composite(w, v, a, background_1->red); *dp = gamma_from_1[w]; + v = gamma_to_1[*(sp + 1)]; png_composite(w, v, a, background_1->green); *(dp + 1) = gamma_from_1[w]; + v = gamma_to_1[*(sp + 2)]; png_composite(w, v, a, background_1->blue); *(dp + 2) = gamma_from_1[w]; @@ -3127,19 +3315,23 @@ png_do_background(png_row_infop row_info, png_bytep row, *(dp + 1) = *(sp + 1); *(dp + 2) = *(sp + 2); } + else if (a == 0) { *dp = (png_byte)background->red; *(dp + 1) = (png_byte)background->green; *(dp + 2) = (png_byte)background->blue; } + else { png_composite(*dp, *sp, a, background->red); + png_composite(*(dp + 1), *(sp + 1), a, - background->green); + background->green); + png_composite(*(dp + 2), *(sp + 2), a, - background->blue); + background->blue); } } } @@ -3156,6 +3348,7 @@ png_do_background(png_row_infop row_info, png_bytep row, { png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) << 8) + (png_uint_16)(*(sp + 7))); + if (a == (png_uint_16)0xffff) { png_uint_16 v; @@ -3163,13 +3356,16 @@ png_do_background(png_row_infop row_info, png_bytep row, v = gamma_16[*(sp + 1) >> gamma_shift][*sp]; *dp = (png_byte)((v >> 8) & 0xff); *(dp + 1) = (png_byte)(v & 0xff); + v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)]; *(dp + 2) = (png_byte)((v >> 8) & 0xff); *(dp + 3) = (png_byte)(v & 0xff); + v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)]; *(dp + 4) = (png_byte)((v >> 8) & 0xff); *(dp + 5) = (png_byte)(v & 0xff); } + else if (a == 0) { /* Background is already in screen gamma */ @@ -3180,28 +3376,35 @@ png_do_background(png_row_infop row_info, png_bytep row, *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff); *(dp + 5) = (png_byte)(background->blue & 0xff); } + else { png_uint_16 v, w, x; v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp]; png_composite_16(w, v, a, background_1->red); + x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8]; *dp = (png_byte)((x >> 8) & 0xff); *(dp + 1) = (png_byte)(x & 0xff); + v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)]; png_composite_16(w, v, a, background_1->green); + x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8]; *(dp + 2) = (png_byte)((x >> 8) & 0xff); *(dp + 3) = (png_byte)(x & 0xff); + v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)]; png_composite_16(w, v, a, background_1->blue); + x = gamma_16_from_1[(w & 0xff) >> gamma_shift][w >> 8]; *(dp + 4) = (png_byte)((x >> 8) & 0xff); *(dp + 5) = (png_byte)(x & 0xff); } } } + else #endif { @@ -3210,11 +3413,13 @@ png_do_background(png_row_infop row_info, png_bytep row, for (i = 0; i < row_width; i++, sp += 8, dp += 6) { png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6)) - << 8) + (png_uint_16)(*(sp + 7))); + << 8) + (png_uint_16)(*(sp + 7))); + if (a == (png_uint_16)0xffff) { png_memcpy(dp, sp, 6); } + else if (a == 0) { *dp = (png_byte)((background->red >> 8) & 0xff); @@ -3224,6 +3429,7 @@ png_do_background(png_row_infop row_info, png_bytep row, *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff); *(dp + 5) = (png_byte)(background->blue & 0xff); } + else { png_uint_16 v; @@ -3237,9 +3443,11 @@ png_do_background(png_row_infop row_info, png_bytep row, png_composite_16(v, r, a, background->red); *dp = (png_byte)((v >> 8) & 0xff); *(dp + 1) = (png_byte)(v & 0xff); + png_composite_16(v, g, a, background->green); *(dp + 2) = (png_byte)((v >> 8) & 0xff); *(dp + 3) = (png_byte)(v & 0xff); + png_composite_16(v, b, a, background->blue); *(dp + 4) = (png_byte)((v >> 8) & 0xff); *(dp + 5) = (png_byte)(v & 0xff); @@ -3256,10 +3464,11 @@ png_do_background(png_row_infop row_info, png_bytep row, if (row_info->color_type & PNG_COLOR_MASK_ALPHA) { - row_info->color_type &= ~PNG_COLOR_MASK_ALPHA; + row_info->color_type = (png_byte)(row_info->color_type & + ~PNG_COLOR_MASK_ALPHA); row_info->channels--; row_info->pixel_depth = (png_byte)(row_info->channels * - row_info->bit_depth); + row_info->bit_depth); row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); } } @@ -3275,8 +3484,8 @@ png_do_background(png_row_infop row_info, png_bytep row, */ void /* PRIVATE */ png_do_gamma(png_row_infop row_info, png_bytep row, - png_bytep gamma_table, png_uint_16pp gamma_16_table, - int gamma_shift) + png_const_bytep gamma_table, png_const_uint_16pp gamma_16_table, + int gamma_shift) { png_bytep sp; png_uint_32 i; @@ -3284,9 +3493,8 @@ png_do_gamma(png_row_infop row_info, png_bytep row, png_debug(1, "in png_do_gamma"); - if ( - ((row_info->bit_depth <= 8 && gamma_table != NULL) || - (row_info->bit_depth == 16 && gamma_16_table != NULL))) + if (((row_info->bit_depth <= 8 && gamma_table != NULL) || + (row_info->bit_depth == 16 && gamma_16_table != NULL))) { switch (row_info->color_type) { @@ -3305,6 +3513,7 @@ png_do_gamma(png_row_infop row_info, png_bytep row, sp++; } } + else /* if (row_info->bit_depth == 16) */ { sp = row; @@ -3316,10 +3525,12 @@ png_do_gamma(png_row_infop row_info, png_bytep row, *sp = (png_byte)((v >> 8) & 0xff); *(sp + 1) = (png_byte)(v & 0xff); sp += 2; + v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; *sp = (png_byte)((v >> 8) & 0xff); *(sp + 1) = (png_byte)(v & 0xff); sp += 2; + v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; *sp = (png_byte)((v >> 8) & 0xff); *(sp + 1) = (png_byte)(v & 0xff); @@ -3338,13 +3549,17 @@ png_do_gamma(png_row_infop row_info, png_bytep row, { *sp = gamma_table[*sp]; sp++; + *sp = gamma_table[*sp]; sp++; + *sp = gamma_table[*sp]; sp++; + sp++; } } + else /* if (row_info->bit_depth == 16) */ { sp = row; @@ -3354,10 +3569,12 @@ png_do_gamma(png_row_infop row_info, png_bytep row, *sp = (png_byte)((v >> 8) & 0xff); *(sp + 1) = (png_byte)(v & 0xff); sp += 2; + v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; *sp = (png_byte)((v >> 8) & 0xff); *(sp + 1) = (png_byte)(v & 0xff); sp += 2; + v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp]; *sp = (png_byte)((v >> 8) & 0xff); *(sp + 1) = (png_byte)(v & 0xff); @@ -3378,6 +3595,7 @@ png_do_gamma(png_row_infop row_info, png_bytep row, sp += 2; } } + else /* if (row_info->bit_depth == 16) */ { sp = row; @@ -3464,7 +3682,7 @@ png_do_gamma(png_row_infop row_info, png_bytep row, */ void /* PRIVATE */ png_do_expand_palette(png_row_infop row_info, png_bytep row, - png_colorp palette, png_bytep trans_alpha, int num_trans) + png_const_colorp palette, png_const_bytep trans_alpha, int num_trans) { int shift, value; png_bytep sp, dp; @@ -3473,8 +3691,7 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row, png_debug(1, "in png_do_expand_palette"); - if ( - row_info->color_type == PNG_COLOR_TYPE_PALETTE) + if (row_info->color_type == PNG_COLOR_TYPE_PALETTE) { if (row_info->bit_depth < 8) { @@ -3489,13 +3706,16 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row, { if ((*sp >> shift) & 0x01) *dp = 1; + else *dp = 0; + if (shift == 7) { shift = 0; sp--; } + else shift++; @@ -3518,6 +3738,7 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row, shift = 0; sp--; } + else shift += 2; @@ -3540,6 +3761,7 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row, shift = 0; sp--; } + else shift += 4; @@ -3555,9 +3777,9 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row, row_info->pixel_depth = 8; row_info->rowbytes = row_width; } - switch (row_info->bit_depth) + + else if (row_info->bit_depth == 8) { - case 8: { if (trans_alpha != NULL) { @@ -3568,8 +3790,10 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row, { if ((int)(*sp) >= num_trans) *dp-- = 0xff; + else *dp-- = trans_alpha[*sp]; + *dp-- = palette[*sp].blue; *dp-- = palette[*sp].green; *dp-- = palette[*sp].red; @@ -3581,6 +3805,7 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row, row_info->color_type = 6; row_info->channels = 4; } + else { sp = row + (png_size_t)row_width - 1; @@ -3600,7 +3825,6 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row, row_info->color_type = 2; row_info->channels = 3; } - break; } } } @@ -3611,7 +3835,7 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row, */ void /* PRIVATE */ png_do_expand(png_row_infop row_info, png_bytep row, - png_color_16p trans_value) + png_const_color_16p trans_value) { int shift, value; png_bytep sp, dp; @@ -3631,7 +3855,7 @@ png_do_expand(png_row_infop row_info, png_bytep row, { case 1: { - gray = (png_uint_16)((gray&0x01)*0xff); + gray = (png_uint_16)((gray & 0x01) * 0xff); sp = row + (png_size_t)((row_width - 1) >> 3); dp = row + (png_size_t)row_width - 1; shift = 7 - (int)((row_width + 7) & 0x07); @@ -3639,13 +3863,16 @@ png_do_expand(png_row_infop row_info, png_bytep row, { if ((*sp >> shift) & 0x01) *dp = 0xff; + else *dp = 0; + if (shift == 7) { shift = 0; sp--; } + else shift++; @@ -3656,7 +3883,7 @@ png_do_expand(png_row_infop row_info, png_bytep row, case 2: { - gray = (png_uint_16)((gray&0x03)*0x55); + gray = (png_uint_16)((gray & 0x03) * 0x55); sp = row + (png_size_t)((row_width - 1) >> 2); dp = row + (png_size_t)row_width - 1; shift = (int)((3 - ((row_width + 3) & 0x03)) << 1); @@ -3670,6 +3897,7 @@ png_do_expand(png_row_infop row_info, png_bytep row, shift = 0; sp--; } + else shift += 2; @@ -3680,7 +3908,7 @@ png_do_expand(png_row_infop row_info, png_bytep row, case 4: { - gray = (png_uint_16)((gray&0x0f)*0x11); + gray = (png_uint_16)((gray & 0x0f) * 0x11); sp = row + (png_size_t)((row_width - 1) >> 1); dp = row + (png_size_t)row_width - 1; shift = (int)((1 - ((row_width + 1) & 0x01)) << 2); @@ -3693,6 +3921,7 @@ png_do_expand(png_row_infop row_info, png_bytep row, shift = 0; sp--; } + else shift = 4; @@ -3717,20 +3946,23 @@ png_do_expand(png_row_infop row_info, png_bytep row, gray = gray & 0xff; sp = row + (png_size_t)row_width - 1; dp = row + (png_size_t)(row_width << 1) - 1; + for (i = 0; i < row_width; i++) { if (*sp == gray) *dp-- = 0; + else *dp-- = 0xff; + *dp-- = *sp--; } } else if (row_info->bit_depth == 16) { - png_byte gray_high = (gray >> 8) & 0xff; - png_byte gray_low = gray & 0xff; + png_byte gray_high = (png_byte)((gray >> 8) & 0xff); + png_byte gray_low = (png_byte)(gray & 0xff); sp = row + row_info->rowbytes - 1; dp = row + (row_info->rowbytes << 1) - 1; for (i = 0; i < row_width; i++) @@ -3740,11 +3972,13 @@ png_do_expand(png_row_infop row_info, png_bytep row, *dp-- = 0; *dp-- = 0; } + else { *dp-- = 0xff; *dp-- = 0xff; } + *dp-- = *sp--; *dp-- = *sp--; } @@ -3761,17 +3995,19 @@ png_do_expand(png_row_infop row_info, png_bytep row, { if (row_info->bit_depth == 8) { - png_byte red = trans_value->red & 0xff; - png_byte green = trans_value->green & 0xff; - png_byte blue = trans_value->blue & 0xff; + png_byte red = (png_byte)(trans_value->red & 0xff); + png_byte green = (png_byte)(trans_value->green & 0xff); + png_byte blue = (png_byte)(trans_value->blue & 0xff); sp = row + (png_size_t)row_info->rowbytes - 1; dp = row + (png_size_t)(row_width << 2) - 1; for (i = 0; i < row_width; i++) { if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue) *dp-- = 0; + else *dp-- = 0xff; + *dp-- = *sp--; *dp-- = *sp--; *dp-- = *sp--; @@ -3779,31 +4015,33 @@ png_do_expand(png_row_infop row_info, png_bytep row, } else if (row_info->bit_depth == 16) { - png_byte red_high = (trans_value->red >> 8) & 0xff; - png_byte green_high = (trans_value->green >> 8) & 0xff; - png_byte blue_high = (trans_value->blue >> 8) & 0xff; - png_byte red_low = trans_value->red & 0xff; - png_byte green_low = trans_value->green & 0xff; - png_byte blue_low = trans_value->blue & 0xff; + png_byte red_high = (png_byte)((trans_value->red >> 8) & 0xff); + png_byte green_high = (png_byte)((trans_value->green >> 8) & 0xff); + png_byte blue_high = (png_byte)((trans_value->blue >> 8) & 0xff); + png_byte red_low = (png_byte)(trans_value->red & 0xff); + png_byte green_low = (png_byte)(trans_value->green & 0xff); + png_byte blue_low = (png_byte)(trans_value->blue & 0xff); sp = row + row_info->rowbytes - 1; dp = row + (png_size_t)(row_width << 3) - 1; for (i = 0; i < row_width; i++) { if (*(sp - 5) == red_high && - *(sp - 4) == red_low && - *(sp - 3) == green_high && - *(sp - 2) == green_low && - *(sp - 1) == blue_high && - *(sp ) == blue_low) + *(sp - 4) == red_low && + *(sp - 3) == green_high && + *(sp - 2) == green_low && + *(sp - 1) == blue_high && + *(sp ) == blue_low) { *dp-- = 0; *dp-- = 0; } + else { *dp-- = 0xff; *dp-- = 0xff; } + *dp-- = *sp--; *dp-- = *sp--; *dp-- = *sp--; @@ -3824,7 +4062,7 @@ png_do_expand(png_row_infop row_info, png_bytep row, #ifdef PNG_READ_QUANTIZE_SUPPORTED void /* PRIVATE */ png_do_quantize(png_row_infop row_info, png_bytep row, - png_bytep palette_lookup, png_bytep quantize_lookup) + png_const_bytep palette_lookup, png_const_bytep quantize_lookup) { png_bytep sp, dp; png_uint_32 i; @@ -3832,9 +4070,9 @@ png_do_quantize(png_row_infop row_info, png_bytep row, png_debug(1, "in png_do_quantize"); + if (row_info->bit_depth == 8) { - if (row_info->color_type == PNG_COLOR_TYPE_RGB && - palette_lookup && row_info->bit_depth == 8) + if (row_info->color_type == PNG_COLOR_TYPE_RGB && palette_lookup) { int r, g, b, p; sp = row; @@ -3853,23 +4091,25 @@ png_do_quantize(png_row_infop row_info, png_bytep row, * ((b >> 3) & 0x1f); */ p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) & - ((1 << PNG_QUANTIZE_RED_BITS) - 1)) << - (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) | - (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) & - ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) << - (PNG_QUANTIZE_BLUE_BITS)) | - ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) & - ((1 << PNG_QUANTIZE_BLUE_BITS) - 1)); + ((1 << PNG_QUANTIZE_RED_BITS) - 1)) << + (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) | + (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) & + ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) << + (PNG_QUANTIZE_BLUE_BITS)) | + ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) & + ((1 << PNG_QUANTIZE_BLUE_BITS) - 1)); *dp++ = palette_lookup[p]; } + row_info->color_type = PNG_COLOR_TYPE_PALETTE; row_info->channels = 1; row_info->pixel_depth = row_info->bit_depth; row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); } + else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA && - palette_lookup != NULL && row_info->bit_depth == 8) + palette_lookup != NULL) { int r, g, b, p; sp = row; @@ -3882,25 +4122,28 @@ png_do_quantize(png_row_infop row_info, png_bytep row, sp++; p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) & - ((1 << PNG_QUANTIZE_RED_BITS) - 1)) << - (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) | - (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) & - ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) << - (PNG_QUANTIZE_BLUE_BITS)) | - ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) & - ((1 << PNG_QUANTIZE_BLUE_BITS) - 1)); + ((1 << PNG_QUANTIZE_RED_BITS) - 1)) << + (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) | + (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) & + ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) << + (PNG_QUANTIZE_BLUE_BITS)) | + ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) & + ((1 << PNG_QUANTIZE_BLUE_BITS) - 1)); *dp++ = palette_lookup[p]; } + row_info->color_type = PNG_COLOR_TYPE_PALETTE; row_info->channels = 1; row_info->pixel_depth = row_info->bit_depth; row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); } + else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE && - quantize_lookup && row_info->bit_depth == 8) + quantize_lookup) { sp = row; + for (i = 0; i < row_width; i++, sp++) { *sp = quantize_lookup[*sp]; @@ -3908,266 +4151,7 @@ png_do_quantize(png_row_infop row_info, png_bytep row, } } } -#endif - -#ifdef PNG_FLOATING_POINT_SUPPORTED -#ifdef PNG_READ_GAMMA_SUPPORTED -static PNG_CONST int png_gamma_shift[] = - {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0, 0x00}; - -/* We build the 8- or 16-bit gamma tables here. Note that for 16-bit - * tables, we don't make a full table if we are reducing to 8-bit in - * the future. Note also how the gamma_16 tables are segmented so that - * we don't need to allocate > 64K chunks for a full 16-bit table. - * - * See the PNG extensions document for an integer algorithm for creating - * the gamma tables. Maybe we will implement that here someday. - * - * We should only reach this point if - * - * the file_gamma is known (i.e., the gAMA or sRGB chunk is present, - * or the application has provided a file_gamma) - * - * AND - * { - * the screen_gamma is known - * - * OR - * - * RGB_to_gray transformation is being performed - * } - * - * AND - * { - * the screen_gamma is different from the reciprocal of the - * file_gamma by more than the specified threshold - * - * OR - * - * a background color has been specified and the file_gamma - * and screen_gamma are not 1.0, within the specified threshold. - * } - */ - -void /* PRIVATE */ -png_build_gamma_table(png_structp png_ptr, png_byte bit_depth) -{ - png_debug(1, "in png_build_gamma_table"); - - if (bit_depth <= 8) - { - int i; - double g; - - if (png_ptr->screen_gamma > .000001) - g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma); - - else - g = 1.0; - - png_ptr->gamma_table = (png_bytep)png_malloc(png_ptr, - (png_uint_32)256); - - for (i = 0; i < 256; i++) - { - png_ptr->gamma_table[i] = (png_byte)(pow((double)i / 255.0, - g) * 255.0 + .5); - } - -#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ - defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) - if (png_ptr->transformations & ((PNG_BACKGROUND) | PNG_RGB_TO_GRAY)) - { - - g = 1.0 / (png_ptr->gamma); - - png_ptr->gamma_to_1 = (png_bytep)png_malloc(png_ptr, - (png_uint_32)256); - - for (i = 0; i < 256; i++) - { - png_ptr->gamma_to_1[i] = (png_byte)(pow((double)i / 255.0, - g) * 255.0 + .5); - } - - - png_ptr->gamma_from_1 = (png_bytep)png_malloc(png_ptr, - (png_uint_32)256); - - if (png_ptr->screen_gamma > 0.000001) - g = 1.0 / png_ptr->screen_gamma; - - else - g = png_ptr->gamma; /* Probably doing rgb_to_gray */ - - for (i = 0; i < 256; i++) - { - png_ptr->gamma_from_1[i] = (png_byte)(pow((double)i / 255.0, - g) * 255.0 + .5); - - } - } -#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */ - } - else - { - double g; - int i, j, shift, num; - int sig_bit; - png_uint_32 ig; - - if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) - { - sig_bit = (int)png_ptr->sig_bit.red; - - if ((int)png_ptr->sig_bit.green > sig_bit) - sig_bit = png_ptr->sig_bit.green; - - if ((int)png_ptr->sig_bit.blue > sig_bit) - sig_bit = png_ptr->sig_bit.blue; - } - else - { - sig_bit = (int)png_ptr->sig_bit.gray; - } - - if (sig_bit > 0) - shift = 16 - sig_bit; - - else - shift = 0; - - if (png_ptr->transformations & PNG_16_TO_8) - { - if (shift < (16 - PNG_MAX_GAMMA_8)) - shift = (16 - PNG_MAX_GAMMA_8); - } - - if (shift > 8) - shift = 8; - - if (shift < 0) - shift = 0; - - png_ptr->gamma_shift = (png_byte)shift; - - num = (1 << (8 - shift)); - - if (png_ptr->screen_gamma > .000001) - g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma); - else - g = 1.0; - - png_ptr->gamma_16_table = (png_uint_16pp)png_calloc(png_ptr, - (png_uint_32)(num * png_sizeof(png_uint_16p))); - - if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND)) - { - double fin, fout; - png_uint_32 last, max; - - for (i = 0; i < num; i++) - { - png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr, - (png_uint_32)(256 * png_sizeof(png_uint_16))); - } - - g = 1.0 / g; - last = 0; - for (i = 0; i < 256; i++) - { - fout = ((double)i + 0.5) / 256.0; - fin = pow(fout, g); - max = (png_uint_32)(fin * (double)((png_uint_32)num << 8)); - while (last <= max) - { - png_ptr->gamma_16_table[(int)(last & (0xff >> shift))] - [(int)(last >> (8 - shift))] = (png_uint_16)( - (png_uint_16)i | ((png_uint_16)i << 8)); - last++; - } - } - while (last < ((png_uint_32)num << 8)) - { - png_ptr->gamma_16_table[(int)(last & (0xff >> shift))] - [(int)(last >> (8 - shift))] = (png_uint_16)65535L; - last++; - } - } - else - { - for (i = 0; i < num; i++) - { - png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr, - (png_uint_32)(256 * png_sizeof(png_uint_16))); - - ig = (((png_uint_32)i * (png_uint_32)png_gamma_shift[shift]) >> 4); - - for (j = 0; j < 256; j++) - { - png_ptr->gamma_16_table[i][j] = - (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) / - 65535.0, g) * 65535.0 + .5); - } - } - } - -#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \ - defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) - if (png_ptr->transformations & (PNG_BACKGROUND | PNG_RGB_TO_GRAY)) - { - - g = 1.0 / (png_ptr->gamma); - - png_ptr->gamma_16_to_1 = (png_uint_16pp)png_calloc(png_ptr, - (png_uint_32)(num * png_sizeof(png_uint_16p ))); - - for (i = 0; i < num; i++) - { - png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_malloc(png_ptr, - (png_uint_32)(256 * png_sizeof(png_uint_16))); - - ig = (((png_uint_32)i * - (png_uint_32)png_gamma_shift[shift]) >> 4); - for (j = 0; j < 256; j++) - { - png_ptr->gamma_16_to_1[i][j] = - (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) / - 65535.0, g) * 65535.0 + .5); - } - } - - if (png_ptr->screen_gamma > 0.000001) - g = 1.0 / png_ptr->screen_gamma; - - else - g = png_ptr->gamma; /* Probably doing rgb_to_gray */ - - png_ptr->gamma_16_from_1 = (png_uint_16pp)png_calloc(png_ptr, - (png_uint_32)(num * png_sizeof(png_uint_16p))); - - for (i = 0; i < num; i++) - { - png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_malloc(png_ptr, - (png_uint_32)(256 * png_sizeof(png_uint_16))); - - ig = (((png_uint_32)i * - (png_uint_32)png_gamma_shift[shift]) >> 4); - - for (j = 0; j < 256; j++) - { - png_ptr->gamma_16_from_1[i][j] = - (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) / - 65535.0, g) * 65535.0 + .5); - } - } - } -#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */ - } -} -#endif -/* To do: install integer version of png_build_gamma_table here */ -#endif +#endif /* PNG_READ_QUANTIZE_SUPPORTED */ #ifdef PNG_MNG_FEATURES_SUPPORTED /* Undoes intrapixel differencing */ @@ -4181,6 +4165,7 @@ png_do_read_intrapixel(png_row_infop row_info, png_bytep row) { int bytes_per_pixel; png_uint_32 row_width = row_info->width; + if (row_info->bit_depth == 8) { png_bytep rp; @@ -4197,8 +4182,8 @@ png_do_read_intrapixel(png_row_infop row_info, png_bytep row) for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) { - *(rp) = (png_byte)((256 + *rp + *(rp+1))&0xff); - *(rp+2) = (png_byte)((256 + *(rp+2) + *(rp+1))&0xff); + *(rp) = (png_byte)((256 + *rp + *(rp + 1)) & 0xff); + *(rp+2) = (png_byte)((256 + *(rp + 2) + *(rp + 1)) & 0xff); } } else if (row_info->bit_depth == 16) @@ -4222,10 +4207,10 @@ png_do_read_intrapixel(png_row_infop row_info, png_bytep row) png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5); png_uint_32 red = (png_uint_32)((s0 + s1 + 65536L) & 0xffffL); png_uint_32 blue = (png_uint_32)((s2 + s1 + 65536L) & 0xffffL); - *(rp ) = (png_byte)((red >> 8) & 0xff); - *(rp+1) = (png_byte)(red & 0xff); - *(rp+4) = (png_byte)((blue >> 8) & 0xff); - *(rp+5) = (png_byte)(blue & 0xff); + *(rp ) = (png_byte)((red >> 8) & 0xff); + *(rp + 1) = (png_byte)(red & 0xff); + *(rp + 4) = (png_byte)((blue >> 8) & 0xff); + *(rp + 5) = (png_byte)(blue & 0xff); } } } diff --git a/harbour/src/3rd/png/pngrutil.c b/harbour/src/3rd/png/pngrutil.c index 5429887a51..78000abbad 100644 --- a/harbour/src/3rd/png/pngrutil.c +++ b/harbour/src/3rd/png/pngrutil.c @@ -1,8 +1,8 @@ /* pngrutil.c - utilities to read a PNG file * - * Last changed in libpng 1.4.5 [December 9, 2010] - * Copyright (c) 1998-2010 Glenn Randers-Pehrson + * Last changed in libpng 1.5.0 [January 6, 2011] + * Copyright (c) 1998-2011 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -14,38 +14,68 @@ * libpng itself during the course of reading an image. */ -#define PNG_NO_PEDANTIC_WARNINGS -#include "png.h" -#ifdef PNG_READ_SUPPORTED #include "pngpriv.h" -# define png_strtod(p,a,b) strtod(a,b) -png_uint_32 PNGAPI -png_get_uint_31(png_structp png_ptr, png_bytep buf) -{ - png_uint_32 val = png_get_uint_32(buf); +#ifdef PNG_READ_SUPPORTED - if (val > PNG_UINT_31_MAX) - png_error(png_ptr, "PNG unsigned integer out of range"); - return (val); +#define png_strtod(p,a,b) strtod(a,b) + +png_uint_32 PNGAPI +png_get_uint_31(png_structp png_ptr, png_const_bytep buf) +{ + png_uint_32 uval = png_get_uint_32(buf); + + if (uval > PNG_UINT_31_MAX) + png_error(png_ptr, "PNG unsigned integer out of range"); + + return (uval); } -#ifndef PNG_USE_READ_MACROS -/* The parentheses around "PNGAPI function_name" in the following three +#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_READ_cHRM_SUPPORTED) +/* The following is a variation on the above for use with the fixed + * point values used for gAMA and cHRM. Instead of png_error it + * issues a warning and returns (-1) - an invalid value because both + * gAMA and cHRM use *unsigned* integers for fixed point values. + */ +#define PNG_FIXED_ERROR (-1) + +static png_fixed_point /* PRIVATE */ +png_get_fixed_point(png_structp png_ptr, png_const_bytep buf) +{ + png_uint_32 uval = png_get_uint_32(buf); + + if (uval <= PNG_UINT_31_MAX) + return (png_fixed_point)uval; /* known to be in range */ + + /* The caller can turn off the warning by passing NULL. */ + if (png_ptr != NULL) + png_warning(png_ptr, "PNG fixed point integer out of range"); + + return PNG_FIXED_ERROR; +} +#endif + +#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED +/* NOTE: the read macros will obscure these definitions, so that if + * PNG_USE_READ_MACROS is set the library will not use them internally, + * but the APIs will still be available externally. + * + * The parentheses around "PNGAPI function_name" in the following three * functions are necessary because they allow the macros to co-exist with * these (unused but exported) functions. */ /* Grab an unsigned 32-bit integer from a buffer in big-endian format. */ png_uint_32 (PNGAPI -png_get_uint_32)(png_bytep buf) +png_get_uint_32)(png_const_bytep buf) { - png_uint_32 uval = png_get_uint_32(buf); - if ((uval & 0x80000000L) == 0) /* non-negative */ - return uval; + png_uint_32 uval = + ((png_uint_32)(*(buf )) << 24) + + ((png_uint_32)(*(buf + 1)) << 16) + + ((png_uint_32)(*(buf + 2)) << 8) + + ((png_uint_32)(*(buf + 3)) ) ; - uval = (uval ^ 0xffffffffL) + 1; /* 2's complement: -x = ~x+1 */ - return -(png_int_32)uval; + return uval; } /* Grab a signed 32-bit integer from a buffer in big-endian format. The @@ -54,7 +84,7 @@ png_get_uint_32)(png_bytep buf) * the following code does a two's complement to native conversion. */ png_int_32 (PNGAPI -png_get_int_32)(png_bytep buf) +png_get_int_32)(png_const_bytep buf) { png_uint_32 uval = png_get_uint_32(buf); if ((uval & 0x80000000L) == 0) /* non-negative */ @@ -66,7 +96,7 @@ png_get_int_32)(png_bytep buf) /* Grab an unsigned 16-bit integer from a buffer in big-endian format. */ png_uint_16 (PNGAPI -png_get_uint_16)(png_bytep buf) +png_get_uint_16)(png_const_bytep buf) { /* ANSI-C requires an int value to accomodate at least 16 bits so this * works and allows the compiler not to worry about possible narrowing @@ -79,7 +109,8 @@ png_get_uint_16)(png_bytep buf) return (png_uint_16)val; } -#endif /* PNG_USE_READ_MACROS */ + +#endif /* PNG_READ_INT_FUNCTIONS_SUPPORTED */ /* Read and check the PNG file signature */ void /* PRIVATE */ @@ -107,7 +138,6 @@ png_read_sig(png_structp png_ptr, png_infop info_ptr) if (num_checked < 4 && png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4)) png_error(png_ptr, "Not a PNG file"); - else png_error(png_ptr, "PNG file corrupted by ASCII conversion"); } @@ -137,8 +167,8 @@ png_read_chunk_header(png_structp png_ptr) /* Put the chunk name into png_ptr->chunk_name. */ png_memcpy(png_ptr->chunk_name, buf + 4, 4); - png_debug2(0, "Reading %s chunk, length = %lu", - png_ptr->chunk_name, length); + png_debug2(0, "Reading %s chunk, length = %u", + png_ptr->chunk_name, length); /* Reset the crc and run it over the chunk name. */ png_reset_crc(png_ptr); @@ -148,9 +178,6 @@ png_read_chunk_header(png_structp png_ptr) png_check_chunk_name(png_ptr, png_ptr->chunk_name); #ifdef PNG_IO_STATE_SUPPORTED - /* It is unspecified how many I/O calls will be performed - * during the serialization of the chunk data. - */ png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA; #endif @@ -254,18 +281,51 @@ png_crc_error(png_structp png_ptr) #if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \ defined(PNG_READ_iCCP_SUPPORTED) static png_size_t -png_inflate(png_structp png_ptr, const png_byte *data, png_size_t size, - png_bytep output, png_size_t output_size) +png_inflate(png_structp png_ptr, png_bytep data, png_size_t size, + png_bytep output, png_size_t output_size) { png_size_t count = 0; - png_ptr->zstream.next_in = (png_bytep)data; /* const_cast: VALID */ - png_ptr->zstream.avail_in = size; + /* zlib can't necessarily handle more than 65535 bytes at once (i.e. it can't + * even necessarily handle 65536 bytes) because the type uInt is "16 bits or + * more". Consequently it is necessary to chunk the input to zlib. This + * code uses ZLIB_IO_MAX, from pngpriv.h, as the maximum (the maximum value + * that can be stored in a uInt.) It is possible to set ZLIB_IO_MAX to a + * lower value in pngpriv.h and this may sometimes have a performance + * advantage, because it forces access of the input data to be separated from + * at least some of the use by some period of time. + */ + png_ptr->zstream.next_in = data; + /* avail_in is set below from 'size' */ + png_ptr->zstream.avail_in = 0; while (1) { int ret, avail; + /* The setting of 'avail_in' used to be outside the loop, by setting it + * inside it is possible to chunk the input to zlib and simply rely on + * zlib to advance the 'next_in' pointer. This allows arbitrary amounts o + * data to be passed through zlib at the unavoidable cost of requiring a + * window save (memcpy of up to 32768 output bytes) every ZLIB_IO_MAX + * input bytes. + */ + if (png_ptr->zstream.avail_in == 0 && size > 0) + { + if (size <= ZLIB_IO_MAX) + { + /* The value is less than ZLIB_IO_MAX so the cast is safe: */ + png_ptr->zstream.avail_in = (uInt)size; + size = 0; + } + + else + { + png_ptr->zstream.avail_in = ZLIB_IO_MAX; + size -= ZLIB_IO_MAX; + } + } + /* Reset the output buffer each time round - we empty it * after every inflate call. */ @@ -280,14 +340,18 @@ png_inflate(png_structp png_ptr, const png_byte *data, png_size_t size, */ if ((ret == Z_OK || ret == Z_STREAM_END) && avail > 0) { + png_size_t space = avail; /* > 0, see above */ + if (output != 0 && output_size > count) { - int copy = output_size - count; - if (avail < copy) copy = avail; + png_size_t copy = output_size - count; + + if (space < copy) + copy = space; + png_memcpy(output + count, png_ptr->zbuf, copy); } - - count += avail; + count += space; } if (ret == Z_OK) @@ -308,13 +372,15 @@ png_inflate(png_structp png_ptr, const png_byte *data, png_size_t size, */ { PNG_CONST char *msg; +#ifdef PNG_CONSOLE_IO_SUPPORTED + char umsg[52]; +#endif if (png_ptr->zstream.msg != 0) msg = png_ptr->zstream.msg; + else { -#ifdef PNG_STDIO_SUPPORTED - char umsg[52]; - +#ifdef PNG_CONSOLE_IO_SUPPORTED switch (ret) { case Z_BUF_ERROR: @@ -340,7 +406,7 @@ png_inflate(png_structp png_ptr, const png_byte *data, png_size_t size, png_warning(png_ptr, msg); } - /* 0 means an error - notice that this code simple ignores + /* 0 means an error - notice that this code simply ignores * zero length compressed chunks as a result. */ return 0; @@ -370,9 +436,10 @@ png_decompress_chunk(png_structp png_ptr, int comp_type, else if (comp_type == PNG_COMPRESSION_TYPE_BASE) { png_size_t expanded_size = png_inflate(png_ptr, - (png_bytep)(png_ptr->chunkdata + prefix_size), - chunklength - prefix_size, - 0/*output*/, 0/*output size*/); + (png_bytep)(png_ptr->chunkdata + prefix_size), + chunklength - prefix_size, + 0, /*output*/ + 0); /*output size*/ /* Now check the limits on this chunk - if the limit fails the * compressed data will be removed, the prefix will remain. @@ -395,14 +462,15 @@ png_decompress_chunk(png_structp png_ptr, int comp_type, */ #if defined(PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED) || \ defined(PNG_USER_CHUNK_MALLOC_MAX) - else -#endif + else if (expanded_size > 0) +#else if (expanded_size > 0) +#endif { /* Success (maybe) - really uncompress the chunk. */ png_size_t new_size = 0; png_charp text = png_malloc_warn(png_ptr, - prefix_size + expanded_size + 1); + prefix_size + expanded_size + 1); if (text != NULL) { @@ -426,7 +494,7 @@ png_decompress_chunk(png_structp png_ptr, int comp_type, } else - png_warning(png_ptr, "Not enough memory to decompress chunk"); + png_warning(png_ptr, "Not enough memory to decompress chunk"); } } @@ -435,8 +503,8 @@ png_decompress_chunk(png_structp png_ptr, int comp_type, #ifdef PNG_STDIO_SUPPORTED char umsg[50]; - png_snprintf(umsg, sizeof umsg, "Unknown zTXt compression type %d", - comp_type); + png_snprintf(umsg, sizeof umsg, + "Unknown zTXt compression type %d", comp_type); png_warning(png_ptr, umsg); #else png_warning(png_ptr, "Unknown zTXt compression type"); @@ -451,10 +519,12 @@ png_decompress_chunk(png_structp png_ptr, int comp_type, */ { png_charp text = png_malloc_warn(png_ptr, prefix_size + 1); + if (text != NULL) { if (prefix_size > 0) png_memcpy(text, png_ptr->chunkdata, prefix_size); + png_free(png_ptr, png_ptr->chunkdata); png_ptr->chunkdata = text; @@ -513,6 +583,7 @@ png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) /* Find number of channels */ switch (png_ptr->color_type) { + default: /* invalid, png_set_IHDR calls png_error */ case PNG_COLOR_TYPE_GRAY: case PNG_COLOR_TYPE_PALETTE: png_ptr->channels = 1; @@ -537,9 +608,9 @@ png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width); png_debug1(3, "bit_depth = %d", png_ptr->bit_depth); png_debug1(3, "channels = %d", png_ptr->channels); - png_debug1(3, "rowbytes = %lu", png_ptr->rowbytes); + png_debug1(3, "rowbytes = %u", png_ptr->rowbytes); png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, - color_type, interlace_type, compression_type, filter_type); + color_type, interlace_type, compression_type, filter_type); } /* Read and check the palette */ @@ -572,10 +643,11 @@ png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR)) { png_warning(png_ptr, - "Ignoring PLTE chunk in grayscale PNG"); + "Ignoring PLTE chunk in grayscale PNG"); png_crc_finish(png_ptr, length); return; } + #ifndef PNG_READ_OPT_PLTE_SUPPORTED if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) { @@ -624,7 +696,7 @@ png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } #endif - /* If we actually NEED the PLTE chunk (ie for a paletted image), we do + /* If we actually need the PLTE chunk (ie for a paletted image), we do * whatever the normal CRC configuration tells us. However, if we * have an RGB image, the PLTE can be considered ancillary, so * we will act as though it is. @@ -635,25 +707,29 @@ png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { png_crc_finish(png_ptr, 0); } + #ifndef PNG_READ_OPT_PLTE_SUPPORTED else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */ { /* If we don't want to use the data from an ancillary chunk, - we have two options: an error abort, or a warning and we - ignore the data in this chunk (which should be OK, since - it's considered ancillary for a RGB or RGBA image). */ + * we have two options: an error abort, or a warning and we + * ignore the data in this chunk (which should be OK, since + * it's considered ancillary for a RGB or RGBA image). + */ if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE)) { if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) { png_chunk_benign_error(png_ptr, "CRC error"); } + else { png_chunk_warning(png_ptr, "CRC error"); return; } } + /* Otherwise, we (optionally) emit a warning and use the chunk. */ else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) { @@ -674,6 +750,7 @@ png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_warning(png_ptr, "Truncating incorrect tRNS chunk length"); png_ptr->num_trans = (png_uint_16)num; } + if (info_ptr->num_trans > (png_uint_16)num) { png_warning(png_ptr, "Truncating incorrect info tRNS chunk length"); @@ -701,9 +778,10 @@ png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { png_warning(png_ptr, "Incorrect IEND chunk length"); } + png_crc_finish(png_ptr, length); - info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */ + PNG_UNUSED(info_ptr) /* Quiet compiler warnings about unused info_ptr */ } #ifdef PNG_READ_gAMA_SUPPORTED @@ -711,30 +789,29 @@ void /* PRIVATE */ png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { png_fixed_point igamma; -#ifdef PNG_FLOATING_POINT_SUPPORTED - float file_gamma; -#endif png_byte buf[4]; png_debug(1, "in png_handle_gAMA"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before gAMA"); + else if (png_ptr->mode & PNG_HAVE_IDAT) { png_warning(png_ptr, "Invalid gAMA 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 gAMA chunk"); if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) #ifdef PNG_READ_sRGB_SUPPORTED - && !(info_ptr->valid & PNG_INFO_sRGB) + && !(info_ptr->valid & PNG_INFO_sRGB) #endif - ) + ) { png_warning(png_ptr, "Duplicate gAMA chunk"); png_crc_finish(png_ptr, length); @@ -749,41 +826,43 @@ png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } png_crc_read(png_ptr, buf, 4); + if (png_crc_finish(png_ptr, 0)) return; - igamma = (png_fixed_point)png_get_uint_32(buf); - /* Check for zero gamma */ - if (igamma == 0) - { - png_warning(png_ptr, - "Ignoring gAMA chunk with gamma=0"); - return; - } + igamma = png_get_fixed_point(NULL, buf); -#ifdef PNG_READ_sRGB_SUPPORTED + /* Check for zero gamma or an error. */ + if (igamma <= 0) + { + png_warning(png_ptr, + "Ignoring gAMA chunk with out of range gamma"); + + return; + } + +# ifdef PNG_READ_sRGB_SUPPORTED if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)) + { if (PNG_OUT_OF_RANGE(igamma, 45500L, 500)) { png_warning(png_ptr, - "Ignoring incorrect gAMA value when sRGB is also present"); -#ifdef PNG_CONSOLE_IO_SUPPORTED + "Ignoring incorrect gAMA value when sRGB is also present"); + +# ifdef PNG_CONSOLE_IO_SUPPORTED fprintf(stderr, "gamma = (%d/100000)", (int)igamma); -#endif +# endif return; } -#endif /* PNG_READ_sRGB_SUPPORTED */ + } +# endif /* PNG_READ_sRGB_SUPPORTED */ -#ifdef PNG_FLOATING_POINT_SUPPORTED - file_gamma = (float)igamma / (float)100000.0; # ifdef PNG_READ_GAMMA_SUPPORTED - png_ptr->gamma = file_gamma; + /* Gamma correction on read is supported. */ + png_ptr->gamma = igamma; # endif - png_set_gAMA(png_ptr, info_ptr, file_gamma); -#endif -#ifdef PNG_FIXED_POINT_SUPPORTED + /* And set the 'info' structure members. */ png_set_gAMA_fixed(png_ptr, info_ptr, igamma); -#endif } #endif @@ -800,17 +879,20 @@ png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before sBIT"); + else if (png_ptr->mode & PNG_HAVE_IDAT) { png_warning(png_ptr, "Invalid sBIT 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 sBIT chunk"); } + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT)) { png_warning(png_ptr, "Duplicate sBIT chunk"); @@ -820,6 +902,7 @@ png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) truelen = 3; + else truelen = (png_size_t)png_ptr->channels; @@ -831,6 +914,7 @@ png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } png_crc_read(png_ptr, buf, truelen); + if (png_crc_finish(png_ptr, 0)) return; @@ -841,6 +925,7 @@ png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_ptr->sig_bit.blue = buf[2]; png_ptr->sig_bit.alpha = buf[3]; } + else { png_ptr->sig_bit.gray = buf[0]; @@ -849,6 +934,7 @@ png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_ptr->sig_bit.blue = buf[0]; png_ptr->sig_bit.alpha = buf[1]; } + png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit)); } #endif @@ -858,32 +944,29 @@ void /* PRIVATE */ png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { png_byte buf[32]; -#ifdef PNG_FLOATING_POINT_SUPPORTED - float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y; -#endif - png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green, - int_y_green, int_x_blue, int_y_blue; - - png_uint_32 uint_x, uint_y; + png_fixed_point x_white, y_white, x_red, y_red, x_green, y_green, x_blue, + y_blue; png_debug(1, "in png_handle_cHRM"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before cHRM"); + else if (png_ptr->mode & PNG_HAVE_IDAT) { png_warning(png_ptr, "Invalid cHRM 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, "Missing PLTE before cHRM"); if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM) -#ifdef PNG_READ_sRGB_SUPPORTED - && !(info_ptr->valid & PNG_INFO_sRGB) -#endif +# ifdef PNG_READ_sRGB_SUPPORTED + && !(info_ptr->valid & PNG_INFO_sRGB) +# endif ) { png_warning(png_ptr, "Duplicate cHRM chunk"); @@ -899,83 +982,61 @@ png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } png_crc_read(png_ptr, buf, 32); + if (png_crc_finish(png_ptr, 0)) return; - uint_x = png_get_uint_32(buf); - uint_y = png_get_uint_32(buf + 4); - int_x_white = (png_fixed_point)uint_x; - int_y_white = (png_fixed_point)uint_y; + x_white = png_get_fixed_point(NULL, buf); + y_white = png_get_fixed_point(NULL, buf + 4); + x_red = png_get_fixed_point(NULL, buf + 8); + y_red = png_get_fixed_point(NULL, buf + 12); + x_green = png_get_fixed_point(NULL, buf + 16); + y_green = png_get_fixed_point(NULL, buf + 20); + x_blue = png_get_fixed_point(NULL, buf + 24); + y_blue = png_get_fixed_point(NULL, buf + 28); - uint_x = png_get_uint_32(buf + 8); - uint_y = png_get_uint_32(buf + 12); - int_x_red = (png_fixed_point)uint_x; - int_y_red = (png_fixed_point)uint_y; - - uint_x = png_get_uint_32(buf + 16); - uint_y = png_get_uint_32(buf + 20); - int_x_green = (png_fixed_point)uint_x; - int_y_green = (png_fixed_point)uint_y; - - uint_x = png_get_uint_32(buf + 24); - uint_y = png_get_uint_32(buf + 28); - int_x_blue = (png_fixed_point)uint_x; - int_y_blue = (png_fixed_point)uint_y; - -#ifdef PNG_FLOATING_POINT_SUPPORTED - white_x = (float)int_x_white / (float)100000.0; - white_y = (float)int_y_white / (float)100000.0; - red_x = (float)int_x_red / (float)100000.0; - red_y = (float)int_y_red / (float)100000.0; - green_x = (float)int_x_green / (float)100000.0; - green_y = (float)int_y_green / (float)100000.0; - blue_x = (float)int_x_blue / (float)100000.0; - blue_y = (float)int_y_blue / (float)100000.0; -#endif + if (x_white == PNG_FIXED_ERROR || + y_white == PNG_FIXED_ERROR || + x_red == PNG_FIXED_ERROR || + y_red == PNG_FIXED_ERROR || + x_green == PNG_FIXED_ERROR || + y_green == PNG_FIXED_ERROR || + x_blue == PNG_FIXED_ERROR || + y_blue == PNG_FIXED_ERROR) + { + png_warning(png_ptr, "Ignoring cHRM chunk with negative chromaticities"); + return; + } #ifdef PNG_READ_sRGB_SUPPORTED if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB)) + { + if (PNG_OUT_OF_RANGE(x_white, 31270, 1000) || + PNG_OUT_OF_RANGE(y_white, 32900, 1000) || + PNG_OUT_OF_RANGE(x_red, 64000L, 1000) || + PNG_OUT_OF_RANGE(y_red, 33000, 1000) || + PNG_OUT_OF_RANGE(x_green, 30000, 1000) || + PNG_OUT_OF_RANGE(y_green, 60000L, 1000) || + PNG_OUT_OF_RANGE(x_blue, 15000, 1000) || + PNG_OUT_OF_RANGE(y_blue, 6000, 1000)) { - if (PNG_OUT_OF_RANGE(int_x_white, 31270, 1000) || - PNG_OUT_OF_RANGE(int_y_white, 32900, 1000) || - PNG_OUT_OF_RANGE(int_x_red, 64000L, 1000) || - PNG_OUT_OF_RANGE(int_y_red, 33000, 1000) || - PNG_OUT_OF_RANGE(int_x_green, 30000, 1000) || - PNG_OUT_OF_RANGE(int_y_green, 60000L, 1000) || - PNG_OUT_OF_RANGE(int_x_blue, 15000, 1000) || - PNG_OUT_OF_RANGE(int_y_blue, 6000, 1000)) - { - png_warning(png_ptr, - "Ignoring incorrect cHRM value when sRGB is also present"); + png_warning(png_ptr, + "Ignoring incorrect cHRM value when sRGB is also present"); + #ifdef PNG_CONSOLE_IO_SUPPORTED -#ifdef PNG_FLOATING_POINT_SUPPORTED - fprintf(stderr, "wx=%f, wy=%f, rx=%f, ry=%f\n", - white_x, white_y, red_x, red_y); - fprintf(stderr, "gx=%f, gy=%f, bx=%f, by=%f\n", - green_x, green_y, blue_x, blue_y); -#else - fprintf(stderr, "wx=%ld, wy=%ld, rx=%ld, ry=%ld\n", - (long)int_x_white, (long)int_y_white, - (long)int_x_red, (long)int_y_red); - fprintf(stderr, "gx=%ld, gy=%ld, bx=%ld, by=%ld\n", - (long)int_x_green, (long)int_y_green, - (long)int_x_blue, (long)int_y_blue); -#endif + fprintf(stderr, "wx=%d, wy=%d, rx=%d, ry=%d\n", + x_white, y_white, x_red, y_red); + + fprintf(stderr, "gx=%d, gy=%d, bx=%d, by=%d\n", + x_green, y_green, x_blue, y_blue); #endif /* PNG_CONSOLE_IO_SUPPORTED */ - } - return; } + return; + } #endif /* PNG_READ_sRGB_SUPPORTED */ -#ifdef PNG_FLOATING_POINT_SUPPORTED - png_set_cHRM(png_ptr, info_ptr, - white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y); -#endif -#ifdef PNG_FIXED_POINT_SUPPORTED - png_set_cHRM_fixed(png_ptr, info_ptr, - int_x_white, int_y_white, int_x_red, int_y_red, int_x_green, - int_y_green, int_x_blue, int_y_blue); -#endif + png_set_cHRM_fixed(png_ptr, info_ptr, x_white, y_white, x_red, y_red, + x_green, y_green, x_blue, y_blue); } #endif @@ -990,12 +1051,14 @@ png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before sRGB"); + else if (png_ptr->mode & PNG_HAVE_IDAT) { png_warning(png_ptr, "Invalid sRGB 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 sRGB chunk"); @@ -1015,10 +1078,12 @@ png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } png_crc_read(png_ptr, buf, 1); + if (png_crc_finish(png_ptr, 0)) return; intent = buf[0]; + /* Check for bad intent */ if (intent >= PNG_sRGB_INTENT_LAST) { @@ -1029,48 +1094,31 @@ png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) #if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED) if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)) { - png_fixed_point igamma; -#ifdef PNG_FIXED_POINT_SUPPORTED - igamma=info_ptr->int_gamma; -#else -# ifdef PNG_FLOATING_POINT_SUPPORTED - igamma=(png_fixed_point)(info_ptr->gamma * 100000.); -# endif -#endif - if (PNG_OUT_OF_RANGE(igamma, 45500L, 500)) + if (PNG_OUT_OF_RANGE(info_ptr->gamma, 45500L, 500)) { png_warning(png_ptr, - "Ignoring incorrect gAMA value when sRGB is also present"); + "Ignoring incorrect gAMA value when sRGB is also present"); #ifdef PNG_CONSOLE_IO_SUPPORTED -# ifdef PNG_FIXED_POINT_SUPPORTED - fprintf(stderr, "incorrect gamma=(%d/100000)\n", - (int)png_ptr->int_gamma); -# else -# ifdef PNG_FLOATING_POINT_SUPPORTED - fprintf(stderr, "incorrect gamma=%f\n", png_ptr->gamma); -# endif -# endif + fprintf(stderr, "incorrect gamma=(%d/100000)\n", info_ptr->gamma); #endif } } #endif /* PNG_READ_gAMA_SUPPORTED */ #ifdef PNG_READ_cHRM_SUPPORTED -#ifdef PNG_FIXED_POINT_SUPPORTED if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) - if (PNG_OUT_OF_RANGE(info_ptr->int_x_white, 31270, 1000) || - PNG_OUT_OF_RANGE(info_ptr->int_y_white, 32900, 1000) || - PNG_OUT_OF_RANGE(info_ptr->int_x_red, 64000L, 1000) || - PNG_OUT_OF_RANGE(info_ptr->int_y_red, 33000, 1000) || - PNG_OUT_OF_RANGE(info_ptr->int_x_green, 30000, 1000) || - PNG_OUT_OF_RANGE(info_ptr->int_y_green, 60000L, 1000) || - PNG_OUT_OF_RANGE(info_ptr->int_x_blue, 15000, 1000) || - PNG_OUT_OF_RANGE(info_ptr->int_y_blue, 6000, 1000)) - { - png_warning(png_ptr, - "Ignoring incorrect cHRM value when sRGB is also present"); - } -#endif /* PNG_FIXED_POINT_SUPPORTED */ + if (PNG_OUT_OF_RANGE(info_ptr->x_white, 31270, 1000) || + PNG_OUT_OF_RANGE(info_ptr->y_white, 32900, 1000) || + PNG_OUT_OF_RANGE(info_ptr->x_red, 64000L, 1000) || + PNG_OUT_OF_RANGE(info_ptr->y_red, 33000, 1000) || + PNG_OUT_OF_RANGE(info_ptr->x_green, 30000, 1000) || + PNG_OUT_OF_RANGE(info_ptr->y_green, 60000L, 1000) || + PNG_OUT_OF_RANGE(info_ptr->x_blue, 15000, 1000) || + PNG_OUT_OF_RANGE(info_ptr->y_blue, 6000, 1000)) + { + png_warning(png_ptr, + "Ignoring incorrect cHRM value when sRGB is also present"); + } #endif /* PNG_READ_cHRM_SUPPORTED */ png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent); @@ -1086,19 +1134,22 @@ png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_bytep pC; png_charp profile; png_uint_32 skip = 0; - png_uint_32 profile_size, profile_length; + png_uint_32 profile_size; + png_alloc_size_t profile_length; png_size_t slength, prefix_length, data_length; png_debug(1, "in png_handle_iCCP"); 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"); @@ -1141,7 +1192,7 @@ png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) /* There should be at least one zero (the compression type byte) * following the separator, and we should be on it */ - if ( profile >= png_ptr->chunkdata + slength - 1) + if (profile >= png_ptr->chunkdata + slength - 1) { png_free(png_ptr, png_ptr->chunkdata); png_ptr->chunkdata = NULL; @@ -1151,6 +1202,7 @@ png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) /* Compression_type should always be zero */ compression_type = *profile++; + if (compression_type) { png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk"); @@ -1160,11 +1212,11 @@ png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) prefix_length = profile - png_ptr->chunkdata; png_decompress_chunk(png_ptr, compression_type, - slength, prefix_length, &data_length); + slength, prefix_length, &data_length); profile_length = data_length - prefix_length; - if ( prefix_length > data_length || profile_length < 4) + if (prefix_length > data_length || profile_length < 4) { png_free(png_ptr, png_ptr->chunkdata); png_ptr->chunkdata = NULL; @@ -1174,36 +1226,41 @@ png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) /* Check the profile_size recorded in the first 32 bits of the ICC profile */ pC = (png_bytep)(png_ptr->chunkdata + prefix_length); - profile_size = ((*(pC ))<<24) | - ((*(pC + 1))<<16) | - ((*(pC + 2))<< 8) | - ((*(pC + 3)) ); + profile_size = ((*(pC )) << 24) | + ((*(pC + 1)) << 16) | + ((*(pC + 2)) << 8) | + ((*(pC + 3)) ); + /* NOTE: the following guarantees that 'profile_length' fits into 32 bits, + * because profile_size is a 32 bit value. + */ if (profile_size < profile_length) profile_length = profile_size; + /* And the following guarantees that profile_size == profile_length. */ if (profile_size > profile_length) { -#ifdef PNG_STDIO_SUPPORTED - char umsg[50]; -#endif png_free(png_ptr, png_ptr->chunkdata); png_ptr->chunkdata = NULL; - png_warning(png_ptr, "Ignoring truncated iCCP profile"); #ifdef PNG_STDIO_SUPPORTED + { + char umsg[80]; - png_snprintf(umsg, 50, "declared profile size = %lu", - (unsigned long)profile_size); - png_warning(png_ptr, umsg); - png_snprintf(umsg, 50, "actual profile length = %lu", - (unsigned long)profile_length); - png_warning(png_ptr, umsg); + png_snprintf2(umsg, 80, + "Ignoring iCCP chunk with declared size = %u " + "and actual length = %u", profile_size, profile_length); + png_warning(png_ptr, umsg); + } +#else + png_warning(png_ptr, + "Ignoring iCCP chunk with uncompressed size mismatch"); #endif return; } png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata, - compression_type, png_ptr->chunkdata + prefix_length, profile_length); + compression_type, (png_bytep)png_ptr->chunkdata + prefix_length, + profile_size); png_free(png_ptr, png_ptr->chunkdata); png_ptr->chunkdata = NULL; } @@ -1219,9 +1276,12 @@ png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) #ifdef PNG_POINTER_INDEXING_SUPPORTED png_sPLT_entryp pp; #endif - int data_length, entry_size, i; + png_uint_32 data_length; + int entry_size, i; png_uint_32 skip = 0; png_size_t slength; + png_uint_32 dl; + png_size_t max_dl; png_debug(1, "in png_handle_sPLT"); @@ -1234,6 +1294,7 @@ png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_crc_finish(png_ptr, length); return; } + if (--png_ptr->user_chunk_cache_max == 1) { png_warning(png_ptr, "No space in chunk cache for sPLT"); @@ -1245,6 +1306,7 @@ png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 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"); @@ -1263,6 +1325,11 @@ png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_free(png_ptr, png_ptr->chunkdata); png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1); + + /* WARNING: this may break if size_t is less than 32 bits; it is assumed + * that the PNG_MAX_MALLOC_64K test is enabled in this case, but this is a + * potential breakage point if the types in pngconf.h aren't exactly right. + */ slength = (png_size_t)length; png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); @@ -1278,6 +1345,7 @@ png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) for (entry_start = (png_bytep)png_ptr->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 */ @@ -1291,7 +1359,12 @@ png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) new_palette.depth = *entry_start++; entry_size = (new_palette.depth == 8 ? 6 : 10); - data_length = (slength - (entry_start - (png_bytep)png_ptr->chunkdata)); + /* This must fit in a png_uint_32 because it is derived from the original + * chunk data length (and use 'length', not 'slength' here for clarity - + * they are guaranteed to be the same, see the tests above.) + */ + data_length = length - (png_uint_32)(entry_start - + (png_bytep)png_ptr->chunkdata); /* Integrity-check the data length */ if (data_length % entry_size) @@ -1302,15 +1375,20 @@ png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) return; } - new_palette.nentries = (png_int_32) ( data_length / entry_size); - if ((png_uint_32) new_palette.nentries > - (png_uint_32) (PNG_SIZE_MAX / png_sizeof(png_sPLT_entry))) + dl = (png_int_32)(data_length / entry_size); + max_dl = PNG_SIZE_MAX / png_sizeof(png_sPLT_entry); + + if (dl > max_dl) { png_warning(png_ptr, "sPLT chunk too long"); return; } + + new_palette.nentries = (png_int_32)(data_length / entry_size); + new_palette.entries = (png_sPLT_entryp)png_malloc_warn( png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry)); + if (new_palette.entries == NULL) { png_warning(png_ptr, "sPLT chunk requires too much memory"); @@ -1324,39 +1402,44 @@ png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) if (new_palette.depth == 8) { - pp->red = *entry_start++; - pp->green = *entry_start++; - pp->blue = *entry_start++; - pp->alpha = *entry_start++; + 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->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; } #else pp = new_palette.entries; + for (i = 0; i < new_palette.nentries; i++) { if (new_palette.depth == 8) { - pp[i].red = *entry_start++; - pp[i].green = *entry_start++; - pp[i].blue = *entry_start++; - pp[i].alpha = *entry_start++; + pp[i].red = *entry_start++; + pp[i].green = *entry_start++; + pp[i].blue = *entry_start++; + pp[i].alpha = *entry_start++; } + else { - pp[i].red = png_get_uint_16(entry_start); entry_start += 2; - pp[i].green = png_get_uint_16(entry_start); entry_start += 2; - pp[i].blue = png_get_uint_16(entry_start); entry_start += 2; - pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2; + pp[i].red = png_get_uint_16(entry_start); entry_start += 2; + pp[i].green = png_get_uint_16(entry_start); entry_start += 2; + pp[i].blue = png_get_uint_16(entry_start); entry_start += 2; + pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2; } + pp->frequency = png_get_uint_16(entry_start); entry_start += 2; } #endif @@ -1382,12 +1465,14 @@ png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before tRNS"); + else if (png_ptr->mode & PNG_HAVE_IDAT) { png_warning(png_ptr, "Invalid tRNS after IDAT"); png_crc_finish(png_ptr, length); return; } + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) { png_warning(png_ptr, "Duplicate tRNS chunk"); @@ -1410,6 +1495,7 @@ png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_ptr->num_trans = 1; png_ptr->trans_color.gray = png_get_uint_16(buf); } + else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) { png_byte buf[6]; @@ -1420,12 +1506,14 @@ png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_crc_finish(png_ptr, length); return; } + png_crc_read(png_ptr, buf, (png_size_t)length); png_ptr->num_trans = 1; png_ptr->trans_color.red = png_get_uint_16(buf); png_ptr->trans_color.green = png_get_uint_16(buf + 2); png_ptr->trans_color.blue = png_get_uint_16(buf + 4); } + else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { if (!(png_ptr->mode & PNG_HAVE_PLTE)) @@ -1433,6 +1521,7 @@ png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) /* Should be an error, but we can cope with it. */ png_warning(png_ptr, "Missing PLTE before tRNS"); } + if (length > (png_uint_32)png_ptr->num_palette || length > PNG_MAX_PALETTE_LENGTH) { @@ -1440,15 +1529,18 @@ png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_crc_finish(png_ptr, length); return; } + if (length == 0) { png_warning(png_ptr, "Zero length tRNS chunk"); png_crc_finish(png_ptr, length); return; } + png_crc_read(png_ptr, readbuf, (png_size_t)length); png_ptr->num_trans = (png_uint_16)length; } + else { png_warning(png_ptr, "tRNS chunk not allowed with alpha channel"); @@ -1463,7 +1555,7 @@ png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans, - &(png_ptr->trans_color)); + &(png_ptr->trans_color)); } #endif @@ -1478,19 +1570,22 @@ png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before bKGD"); + else if (png_ptr->mode & PNG_HAVE_IDAT) { png_warning(png_ptr, "Invalid bKGD after IDAT"); png_crc_finish(png_ptr, length); return; } + else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && - !(png_ptr->mode & PNG_HAVE_PLTE)) + !(png_ptr->mode & PNG_HAVE_PLTE)) { png_warning(png_ptr, "Missing PLTE before bKGD"); png_crc_finish(png_ptr, length); return; } + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)) { png_warning(png_ptr, "Duplicate bKGD chunk"); @@ -1500,8 +1595,10 @@ png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) truelen = 1; + else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) truelen = 6; + else truelen = 2; @@ -1513,31 +1610,38 @@ png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } png_crc_read(png_ptr, buf, truelen); + if (png_crc_finish(png_ptr, 0)) return; /* We convert the index value into RGB components so that we can allow * arbitrary RGB values for background when we have transparency, and * so it is easy to determine the RGB values of the background color - * from the info_ptr struct. */ + * from the info_ptr struct. + */ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { png_ptr->background.index = buf[0]; + if (info_ptr && info_ptr->num_palette) { - if (buf[0] >= info_ptr->num_palette) - { - png_warning(png_ptr, "Incorrect bKGD chunk index value"); - return; - } - png_ptr->background.red = + if (buf[0] >= info_ptr->num_palette) + { + png_warning(png_ptr, "Incorrect bKGD chunk index value"); + return; + } + + png_ptr->background.red = (png_uint_16)png_ptr->palette[buf[0]].red; - png_ptr->background.green = + + png_ptr->background.green = (png_uint_16)png_ptr->palette[buf[0]].green; - png_ptr->background.blue = + + png_ptr->background.blue = (png_uint_16)png_ptr->palette[buf[0]].blue; } } + else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */ { png_ptr->background.red = @@ -1545,6 +1649,7 @@ png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_ptr->background.blue = png_ptr->background.gray = png_get_uint_16(buf); } + else { png_ptr->background.red = png_get_uint_16(buf); @@ -1567,18 +1672,21 @@ png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before hIST"); + else if (png_ptr->mode & PNG_HAVE_IDAT) { png_warning(png_ptr, "Invalid hIST after IDAT"); png_crc_finish(png_ptr, length); return; } + else if (!(png_ptr->mode & PNG_HAVE_PLTE)) { png_warning(png_ptr, "Missing PLTE before hIST"); png_crc_finish(png_ptr, length); return; } + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)) { png_warning(png_ptr, "Duplicate hIST chunk"); @@ -1587,8 +1695,9 @@ png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } num = length / 2 ; - if (num != (unsigned int) png_ptr->num_palette || num > - (unsigned int) PNG_MAX_PALETTE_LENGTH) + + if (num != (unsigned int)png_ptr->num_palette || num > + (unsigned int)PNG_MAX_PALETTE_LENGTH) { png_warning(png_ptr, "Incorrect hIST chunk length"); png_crc_finish(png_ptr, length); @@ -1622,12 +1731,14 @@ png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before pHYs"); + else if (png_ptr->mode & PNG_HAVE_IDAT) { png_warning(png_ptr, "Invalid pHYs after IDAT"); png_crc_finish(png_ptr, length); return; } + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) { png_warning(png_ptr, "Duplicate pHYs chunk"); @@ -1643,6 +1754,7 @@ png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } png_crc_read(png_ptr, buf, 9); + if (png_crc_finish(png_ptr, 0)) return; @@ -1665,12 +1777,14 @@ png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before oFFs"); + else if (png_ptr->mode & PNG_HAVE_IDAT) { png_warning(png_ptr, "Invalid oFFs after IDAT"); png_crc_finish(png_ptr, length); return; } + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) { png_warning(png_ptr, "Duplicate oFFs chunk"); @@ -1686,6 +1800,7 @@ png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } png_crc_read(png_ptr, buf, 9); + if (png_crc_finish(png_ptr, 0)) return; @@ -1712,12 +1827,14 @@ png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before pCAL"); + else if (png_ptr->mode & PNG_HAVE_IDAT) { png_warning(png_ptr, "Invalid pCAL after IDAT"); png_crc_finish(png_ptr, length); return; } + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL)) { png_warning(png_ptr, "Duplicate pCAL chunk"); @@ -1725,15 +1842,17 @@ png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) return; } - png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)", - length + 1); + png_debug1(2, "Allocating and reading pCAL chunk data (%u bytes)", + length + 1); png_free(png_ptr, png_ptr->chunkdata); png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); + if (png_ptr->chunkdata == NULL) - { - png_warning(png_ptr, "No memory for pCAL purpose"); - return; - } + { + png_warning(png_ptr, "No memory for pCAL purpose"); + return; + } + slength = (png_size_t)length; png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); @@ -1753,7 +1872,8 @@ png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) endptr = png_ptr->chunkdata + slength; /* We need to have at least 12 bytes after the purpose string - in order to get the parameter information. */ + * in order to get the parameter information. + */ if (endptr <= buf + 12) { png_warning(png_ptr, "Invalid pCAL data"); @@ -1771,7 +1891,8 @@ png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_debug(3, "Checking pCAL equation type and number of parameters"); /* Check that we have the right number of parameters for known - equation types. */ + * equation types. + */ if ((type == PNG_EQUATION_LINEAR && nparams != 2) || (type == PNG_EQUATION_BASE_E && nparams != 3) || (type == PNG_EQUATION_ARBITRARY && nparams != 3) || @@ -1782,6 +1903,7 @@ png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_ptr->chunkdata = NULL; return; } + else if (type >= PNG_EQUATION_LAST) { png_warning(png_ptr, "Unrecognized equation type for pCAL chunk"); @@ -1791,15 +1913,17 @@ png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) /* Empty loop to move past the units string. */ ; png_debug(3, "Allocating pCAL parameters array"); + params = (png_charpp)png_malloc_warn(png_ptr, - (png_size_t)(nparams * png_sizeof(png_charp))); + (png_size_t)(nparams * png_sizeof(png_charp))); + if (params == NULL) - { - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - png_warning(png_ptr, "No memory for pCAL params"); - return; - } + { + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + png_warning(png_ptr, "No memory for pCAL params"); + return; + } /* Get pointers to the start of each parameter string. */ for (i = 0; i < (int)nparams; i++) @@ -1807,6 +1931,7 @@ png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) buf++; /* Skip the null string terminator from previous parameter. */ png_debug1(3, "Reading pCAL parameter %d", i); + for (params[i] = buf; buf <= endptr && *buf != 0x00; buf++) /* Empty loop to move past each parameter string */ ; @@ -1835,27 +1960,21 @@ png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) void /* PRIVATE */ png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { - png_charp ep; -#ifdef PNG_FLOATING_POINT_SUPPORTED - double width, height; - png_charp vp; -#else -#ifdef PNG_FIXED_POINT_SUPPORTED - png_charp swidth, sheight; -#endif -#endif - png_size_t slength; + png_size_t slength, index; + int state; png_debug(1, "in png_handle_sCAL"); 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"); @@ -1863,17 +1982,21 @@ png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) return; } - png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)", + png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)", length + 1); + png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); + if (png_ptr->chunkdata == NULL) { png_warning(png_ptr, "Out of memory while processing sCAL chunk"); png_crc_finish(png_ptr, length); return; } + slength = (png_size_t)length; png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); + png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */ if (png_crc_finish(png_ptr, 0)) { @@ -1882,103 +2005,44 @@ png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) return; } - png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */ - - ep = png_ptr->chunkdata + 1; /* Skip unit byte */ - -#ifdef PNG_FLOATING_POINT_SUPPORTED - width = png_strtod(png_ptr, ep, &vp); - if (*vp) + /* Validate the unit. */ + if (png_ptr->chunkdata[0] != 1 && png_ptr->chunkdata[0] != 2) { - png_warning(png_ptr, "malformed width string in sCAL chunk"); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - return; - } -#else -#ifdef PNG_FIXED_POINT_SUPPORTED - swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1); - if (swidth == NULL) - { - png_warning(png_ptr, "Out of memory while processing sCAL chunk width"); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - return; - } - png_memcpy(swidth, ep, png_strlen(ep)); -#endif -#endif - - for (ep = png_ptr->chunkdata; *ep; ep++) - /* Empty loop */ ; - ep++; - - if (png_ptr->chunkdata + slength < ep) - { - png_warning(png_ptr, "Truncated sCAL chunk"); -#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) - png_free(png_ptr, swidth); -#endif + png_warning(png_ptr, "Invalid sCAL ignored: invalid unit"); png_free(png_ptr, png_ptr->chunkdata); png_ptr->chunkdata = NULL; return; } -#ifdef PNG_FLOATING_POINT_SUPPORTED - height = png_strtod(png_ptr, ep, &vp); - if (*vp) - { - png_warning(png_ptr, "malformed height string in sCAL chunk"); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - return; - } -#else -#ifdef PNG_FIXED_POINT_SUPPORTED - sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1); - if (sheight == NULL) - { - png_warning(png_ptr, "Out of memory while processing sCAL chunk height"); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - png_free(png_ptr, swidth); - return; - } - png_memcpy(sheight, ep, png_strlen(ep)); -#endif -#endif + /* Validate the ASCII numbers, need two ASCII numbers separated by + * a '\0' and they need to fit exactly in the chunk data. + */ + index = 0; + state = 0; - if (png_ptr->chunkdata + slength < ep -#ifdef PNG_FLOATING_POINT_SUPPORTED - || width <= 0. || height <= 0. -#endif - ) + if (png_ptr->chunkdata[1] == 45 /* negative width */ || + !png_check_fp_number(png_ptr->chunkdata, slength, &state, &index) || + index >= slength || png_ptr->chunkdata[index++] != 0) + png_warning(png_ptr, "Invalid sCAL chunk ignored: bad width format"); + + else { - png_warning(png_ptr, "Invalid sCAL data"); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; -#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) - png_free(png_ptr, swidth); - png_free(png_ptr, sheight); -#endif - return; + png_size_t heighti = index; + + if (png_ptr->chunkdata[index] == 45 /* negative height */ || + !png_check_fp_number(png_ptr->chunkdata, slength, &state, &index) || + index != slength) + png_warning(png_ptr, "Invalid sCAL chunk ignored: bad height format"); + + else + /* This is the (only) success case. */ + png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0], + png_ptr->chunkdata+1, png_ptr->chunkdata+heighti); } - -#ifdef PNG_FLOATING_POINT_SUPPORTED - png_set_sCAL(png_ptr, info_ptr, png_ptr->chunkdata[0], width, height); -#else -#ifdef PNG_FIXED_POINT_SUPPORTED - png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0], swidth, sheight); -#endif -#endif - + /* Clean up - just free the temporarily allocated buffer. */ png_free(png_ptr, png_ptr->chunkdata); png_ptr->chunkdata = NULL; -#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) - png_free(png_ptr, swidth); - png_free(png_ptr, sheight); -#endif } #endif @@ -1993,6 +2057,7 @@ png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Out of place tIME chunk"); + else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME)) { png_warning(png_ptr, "Duplicate tIME chunk"); @@ -2011,6 +2076,7 @@ png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } png_crc_read(png_ptr, buf, 7); + if (png_crc_finish(png_ptr, 0)) return; @@ -2047,6 +2113,7 @@ png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_crc_finish(png_ptr, length); return; } + if (--png_ptr->user_chunk_cache_max == 1) { png_warning(png_ptr, "No space in chunk cache for tEXt"); @@ -2074,11 +2141,13 @@ png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_free(png_ptr, png_ptr->chunkdata); png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); + if (png_ptr->chunkdata == NULL) { png_warning(png_ptr, "No memory to process text chunk"); return; } + slength = (png_size_t)length; png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); @@ -2100,21 +2169,21 @@ png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) text++; text_ptr = (png_textp)png_malloc_warn(png_ptr, - png_sizeof(png_text)); + png_sizeof(png_text)); + if (text_ptr == NULL) { - png_warning(png_ptr, "Not enough memory to process text chunk"); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - return; + png_warning(png_ptr, "Not enough memory to process text chunk"); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; } + text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; text_ptr->key = key; -#ifdef PNG_iTXt_SUPPORTED text_ptr->lang = NULL; text_ptr->lang_key = NULL; text_ptr->itxt_length = 0; -#endif text_ptr->text = text; text_ptr->text_length = png_strlen(text); @@ -2123,8 +2192,9 @@ png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_free(png_ptr, png_ptr->chunkdata); png_ptr->chunkdata = NULL; png_free(png_ptr, text_ptr); + if (ret) - png_warning(png_ptr, "Insufficient memory to process text chunk"); + png_warning(png_ptr, "Insufficient memory to process text chunk"); } #endif @@ -2149,6 +2219,7 @@ png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_crc_finish(png_ptr, length); return; } + if (--png_ptr->user_chunk_cache_max == 1) { png_warning(png_ptr, "No space in chunk cache for zTXt"); @@ -2166,24 +2237,28 @@ png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) #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. */ + * there is no hard and fast rule to tell us where to stop. + */ if (length > (png_uint_32)65535L) { - png_warning(png_ptr, "zTXt chunk too large to fit in memory"); - png_crc_finish(png_ptr, length); - return; + png_warning(png_ptr, "zTXt chunk too large to fit in memory"); + png_crc_finish(png_ptr, length); + return; } #endif png_free(png_ptr, png_ptr->chunkdata); png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); + if (png_ptr->chunkdata == NULL) { - png_warning(png_ptr, "Out of memory processing zTXt chunk"); - return; + png_warning(png_ptr, "Out of memory processing zTXt chunk"); + return; } + slength = (png_size_t)length; png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); + if (png_crc_finish(png_ptr, 0)) { png_free(png_ptr, png_ptr->chunkdata); @@ -2204,37 +2279,41 @@ png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_ptr->chunkdata = NULL; return; } + else { comp_type = *(++text); + if (comp_type != PNG_TEXT_COMPRESSION_zTXt) { png_warning(png_ptr, "Unknown compression type in zTXt chunk"); comp_type = PNG_TEXT_COMPRESSION_zTXt; } + text++; /* Skip the compression_method byte */ } + prefix_len = text - png_ptr->chunkdata; png_decompress_chunk(png_ptr, comp_type, - (png_size_t)length, prefix_len, &data_len); + (png_size_t)length, prefix_len, &data_len); text_ptr = (png_textp)png_malloc_warn(png_ptr, - png_sizeof(png_text)); + png_sizeof(png_text)); + if (text_ptr == NULL) { - png_warning(png_ptr, "Not enough memory to process zTXt chunk"); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - return; + png_warning(png_ptr, "Not enough memory to process zTXt chunk"); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; } + text_ptr->compression = comp_type; text_ptr->key = png_ptr->chunkdata; -#ifdef PNG_iTXt_SUPPORTED text_ptr->lang = NULL; text_ptr->lang_key = NULL; text_ptr->itxt_length = 0; -#endif text_ptr->text = png_ptr->chunkdata + prefix_len; text_ptr->text_length = data_len; @@ -2243,8 +2322,9 @@ png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_free(png_ptr, text_ptr); png_free(png_ptr, png_ptr->chunkdata); png_ptr->chunkdata = NULL; + if (ret) - png_error(png_ptr, "Insufficient memory to store zTXt chunk"); + png_error(png_ptr, "Insufficient memory to store zTXt chunk"); } #endif @@ -2270,6 +2350,7 @@ png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_crc_finish(png_ptr, length); return; } + if (--png_ptr->user_chunk_cache_max == 1) { png_warning(png_ptr, "No space in chunk cache for iTXt"); @@ -2287,24 +2368,28 @@ png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) #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. */ + * 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; + png_warning(png_ptr, "iTXt chunk too large to fit in memory"); + png_crc_finish(png_ptr, length); + return; } #endif png_free(png_ptr, png_ptr->chunkdata); png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); + if (png_ptr->chunkdata == NULL) { - png_warning(png_ptr, "No memory to process iTXt chunk"); - return; + png_warning(png_ptr, "No memory to process iTXt chunk"); + return; } + slength = (png_size_t)length; png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); + if (png_crc_finish(png_ptr, 0)) { png_free(png_ptr, png_ptr->chunkdata); @@ -2316,6 +2401,7 @@ png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) for (lang = png_ptr->chunkdata; *lang; lang++) /* Empty loop */ ; + lang++; /* Skip NUL separator */ /* iTXt must have a language tag (possibly empty), two compression bytes, @@ -2330,14 +2416,16 @@ png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_ptr->chunkdata = NULL; return; } + else { - comp_flag = *lang++; - comp_type = *lang++; + comp_flag = *lang++; + comp_type = *lang++; } for (lang_key = lang; *lang_key; lang_key++) /* Empty loop */ ; + lang_key++; /* Skip NUL separator */ if (lang_key >= png_ptr->chunkdata + slength) @@ -2350,7 +2438,9 @@ png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) for (text = lang_key; *text; text++) /* Empty loop */ ; + text++; /* Skip NUL separator */ + if (text >= png_ptr->chunkdata + slength) { png_warning(png_ptr, "Malformed iTXt chunk"); @@ -2362,20 +2452,25 @@ png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) prefix_len = text - png_ptr->chunkdata; key=png_ptr->chunkdata; + if (comp_flag) - png_decompress_chunk(png_ptr, comp_type, - (size_t)length, prefix_len, &data_len); + png_decompress_chunk(png_ptr, comp_type, + (size_t)length, prefix_len, &data_len); + else - data_len = png_strlen(png_ptr->chunkdata + prefix_len); + data_len = png_strlen(png_ptr->chunkdata + prefix_len); + text_ptr = (png_textp)png_malloc_warn(png_ptr, - png_sizeof(png_text)); + png_sizeof(png_text)); + if (text_ptr == NULL) { - png_warning(png_ptr, "Not enough memory to process iTXt chunk"); - png_free(png_ptr, png_ptr->chunkdata); - png_ptr->chunkdata = NULL; - return; + png_warning(png_ptr, "Not enough memory to process iTXt chunk"); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; } + text_ptr->compression = (int)comp_flag + 1; text_ptr->lang_key = png_ptr->chunkdata + (lang_key - key); text_ptr->lang = png_ptr->chunkdata + (lang - key); @@ -2389,16 +2484,18 @@ png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_free(png_ptr, text_ptr); png_free(png_ptr, png_ptr->chunkdata); png_ptr->chunkdata = NULL; + if (ret) - png_error(png_ptr, "Insufficient memory to store iTXt chunk"); + png_error(png_ptr, "Insufficient memory to store iTXt chunk"); } #endif /* This function is called when we haven't found a handler for a - chunk. If there isn't a problem with the chunk itself (ie bad - chunk name, CRC, or a critical chunk), the chunk is silently ignored - -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which - case it will be saved away to be written out later. */ + * chunk. If there isn't a problem with the chunk itself (ie bad + * chunk name, CRC, or a critical chunk), the chunk is silently ignored + * -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which + * case it will be saved away to be written out later. + */ void /* PRIVATE */ png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { @@ -2414,6 +2511,7 @@ png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_crc_finish(png_ptr, length); return; } + if (--png_ptr->user_chunk_cache_max == 1) { png_warning(png_ptr, "No space in chunk cache for unknown chunk"); @@ -2426,6 +2524,7 @@ png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) if (png_ptr->mode & PNG_HAVE_IDAT) { PNG_IDAT; + if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) /* Not an IDAT */ png_ptr->mode |= PNG_AFTER_IDAT; } @@ -2434,13 +2533,13 @@ png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != - PNG_HANDLE_CHUNK_ALWAYS + PNG_HANDLE_CHUNK_ALWAYS #ifdef PNG_READ_USER_CHUNKS_SUPPORTED - && png_ptr->read_user_chunk_fn == NULL + && png_ptr->read_user_chunk_fn == NULL #endif - ) + ) #endif - png_chunk_error(png_ptr, "unknown critical chunk"); + png_chunk_error(png_ptr, "unknown critical chunk"); } #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED @@ -2448,56 +2547,71 @@ png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) #ifdef PNG_READ_USER_CHUNKS_SUPPORTED || (png_ptr->read_user_chunk_fn != NULL) #endif - ) + ) { #ifdef PNG_MAX_MALLOC_64K - if (length > (png_uint_32)65535L) - { - png_warning(png_ptr, "unknown chunk too large to fit in memory"); - skip = length - (png_uint_32)65535L; - length = (png_uint_32)65535L; - } + if (length > (png_uint_32)65535L) + { + png_warning(png_ptr, "unknown chunk too large to fit in memory"); + skip = length - (png_uint_32)65535L; + length = (png_uint_32)65535L; + } #endif - png_memcpy((png_charp)png_ptr->unknown_chunk.name, - (png_charp)png_ptr->chunk_name, - png_sizeof(png_ptr->unknown_chunk.name)); - png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name)-1] - = '\0'; - png_ptr->unknown_chunk.size = (png_size_t)length; - if (length == 0) + + png_memcpy((png_charp)png_ptr->unknown_chunk.name, + (png_charp)png_ptr->chunk_name, + png_sizeof(png_ptr->unknown_chunk.name)); + + png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name)-1] + = '\0'; + + png_ptr->unknown_chunk.size = (png_size_t)length; + + if (length == 0) png_ptr->unknown_chunk.data = NULL; - else - { + + else + { png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length); png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length); - } + } + #ifdef PNG_READ_USER_CHUNKS_SUPPORTED - if (png_ptr->read_user_chunk_fn != NULL) - { - /* Callback to user unknown chunk handler */ - int ret; - ret = (*(png_ptr->read_user_chunk_fn)) - (png_ptr, &png_ptr->unknown_chunk); - if (ret < 0) - png_chunk_error(png_ptr, "error in user chunk"); - if (ret == 0) - { - if (!(png_ptr->chunk_name[0] & 0x20)) + if (png_ptr->read_user_chunk_fn != NULL) + { + /* Callback to user unknown chunk handler */ + int ret; + + ret = (*(png_ptr->read_user_chunk_fn)) + (png_ptr, &png_ptr->unknown_chunk); + + if (ret < 0) + png_chunk_error(png_ptr, "error in user chunk"); + + if (ret == 0) + { + if (!(png_ptr->chunk_name[0] & 0x20)) + { #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != - PNG_HANDLE_CHUNK_ALWAYS) + if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != + PNG_HANDLE_CHUNK_ALWAYS) #endif - png_chunk_error(png_ptr, "unknown critical chunk"); - png_set_unknown_chunks(png_ptr, info_ptr, - &png_ptr->unknown_chunk, 1); - } - } - else + png_chunk_error(png_ptr, "unknown critical chunk"); + } + + png_set_unknown_chunks(png_ptr, info_ptr, + &png_ptr->unknown_chunk, 1); + } + } + + else #endif - png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1); - png_free(png_ptr, png_ptr->unknown_chunk.data); - png_ptr->unknown_chunk.data = NULL; + png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1); + + png_free(png_ptr, png_ptr->unknown_chunk.data); + png_ptr->unknown_chunk.data = NULL; } + else #endif skip = length; @@ -2505,20 +2619,21 @@ png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_crc_finish(png_ptr, skip); #ifndef PNG_READ_USER_CHUNKS_SUPPORTED - info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */ + PNG_UNUSED(info_ptr) /* Quiet compiler warnings about unused info_ptr */ #endif } /* This function is called to verify that a chunk name is valid. - This function can't have the "critical chunk check" incorporated - into it, since in the future we will need to be able to call user - functions to handle unknown critical chunks after we check that - the chunk name itself is valid. */ + * This function can't have the "critical chunk check" incorporated + * into it, since in the future we will need to be able to call user + * functions to handle unknown critical chunks after we check that + * the chunk name itself is valid. + */ #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) void /* PRIVATE */ -png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name) +png_check_chunk_name(png_structp png_ptr, png_const_bytep chunk_name) { png_debug(1, "in png_check_chunk_name"); if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) || @@ -2529,25 +2644,28 @@ png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name) } /* Combines the row recently read in with the existing pixels in the - row. This routine takes care of alpha and transparency if requested. - This routine also handles the two methods of progressive display - of interlaced images, depending on the mask value. - The mask value describes which pixels are to be combined with - the row. The pattern always repeats every 8 pixels, so just 8 - bits are needed. A one indicates the pixel is to be combined, - a zero indicates the pixel is to be skipped. This is in addition - to any alpha or transparency value associated with the pixel. If - you want all pixels to be combined, pass 0xff (255) in mask. */ + * row. This routine takes care of alpha and transparency if requested. + * This routine also handles the two methods of progressive display + * of interlaced images, depending on the mask value. + * The mask value describes which pixels are to be combined with + * the row. The pattern always repeats every 8 pixels, so just 8 + * bits are needed. A one indicates the pixel is to be combined, + * a zero indicates the pixel is to be skipped. This is in addition + * to any alpha or transparency value associated with the pixel. If + * you want all pixels to be combined, pass 0xff (255) in mask. + */ void /* PRIVATE */ png_combine_row(png_structp png_ptr, png_bytep row, int mask) { png_debug(1, "in png_combine_row"); + if (mask == 0xff) { png_memcpy(row, png_ptr->row_buf + 1, - PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width)); + PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width)); } + else { switch (png_ptr->row_info.pixel_depth) @@ -2569,6 +2687,7 @@ png_combine_row(png_structp png_ptr, png_bytep row, int mask) s_end = 7; s_inc = 1; } + else #endif { @@ -2596,16 +2715,19 @@ png_combine_row(png_structp png_ptr, png_bytep row, int mask) sp++; dp++; } + else shift += s_inc; if (m == 1) m = 0x80; + else m >>= 1; } break; } + case 2: { png_bytep sp = png_ptr->row_buf + 1; @@ -2624,6 +2746,7 @@ png_combine_row(png_structp png_ptr, png_bytep row, int mask) s_end = 6; s_inc = 2; } + else #endif { @@ -2649,15 +2772,19 @@ png_combine_row(png_structp png_ptr, png_bytep row, int mask) sp++; dp++; } + else shift += s_inc; + if (m == 1) m = 0x80; + else m >>= 1; } break; } + case 4: { png_bytep sp = png_ptr->row_buf + 1; @@ -2676,6 +2803,7 @@ png_combine_row(png_structp png_ptr, png_bytep row, int mask) s_end = 4; s_inc = 4; } + else #endif { @@ -2700,15 +2828,19 @@ png_combine_row(png_structp png_ptr, png_bytep row, int mask) sp++; dp++; } + else shift += s_inc; + if (m == 1) m = 0x80; + else m >>= 1; } break; } + default: { png_bytep sp = png_ptr->row_buf + 1; @@ -2718,7 +2850,6 @@ png_combine_row(png_structp png_ptr, png_bytep row, int mask) png_uint_32 row_width = png_ptr->width; png_byte m = 0x80; - for (i = 0; i < row_width; i++) { if (m & mask) @@ -2731,6 +2862,7 @@ png_combine_row(png_structp png_ptr, png_bytep row, int mask) if (m == 1) m = 0x80; + else m >>= 1; } @@ -2741,10 +2873,6 @@ png_combine_row(png_structp png_ptr, png_bytep row, int mask) } #ifdef PNG_READ_INTERLACING_SUPPORTED -/* OLD pre-1.0.9 interface: -void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, - png_uint_32 transformations) - */ void /* PRIVATE */ png_do_read_interlace(png_structp png_ptr) { @@ -2785,6 +2913,7 @@ png_do_read_interlace(png_structp png_ptr) s_end = 0; s_inc = -1; } + else #endif { @@ -2802,24 +2931,29 @@ png_do_read_interlace(png_structp png_ptr) { *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff); *dp |= (png_byte)(v << dshift); + if (dshift == s_end) { dshift = s_start; dp--; } + else dshift += s_inc; } + if (sshift == s_end) { sshift = s_start; sp--; } + else sshift += s_inc; } break; } + case 2: { png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2); @@ -2838,6 +2972,7 @@ png_do_read_interlace(png_structp png_ptr) s_end = 0; s_inc = -2; } + else #endif { @@ -2858,24 +2993,29 @@ png_do_read_interlace(png_structp png_ptr) { *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff); *dp |= (png_byte)(v << dshift); + if (dshift == s_end) { dshift = s_start; dp--; } + else dshift += s_inc; } + if (sshift == s_end) { sshift = s_start; sp--; } + else sshift += s_inc; } break; } + case 4: { png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1); @@ -2894,6 +3034,7 @@ png_do_read_interlace(png_structp png_ptr) s_end = 0; s_inc = -4; } + else #endif { @@ -2913,19 +3054,23 @@ png_do_read_interlace(png_structp png_ptr) { *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff); *dp |= (png_byte)(v << dshift); + if (dshift == s_end) { dshift = s_start; dp--; } + else dshift += s_inc; } + if (sshift == s_end) { sshift = s_start; sp--; } + else sshift += s_inc; } @@ -2934,8 +3079,10 @@ png_do_read_interlace(png_structp png_ptr) default: { png_size_t pixel_bytes = (row_info->pixel_depth >> 3); + png_bytep sp = row + (png_size_t)(row_info->width - 1) * pixel_bytes; + png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes; int jstop = png_pass_inc[pass]; @@ -2947,11 +3094,13 @@ png_do_read_interlace(png_structp png_ptr) int j; png_memcpy(v, sp, pixel_bytes); + for (j = 0; j < jstop; j++) { png_memcpy(dp, v, pixel_bytes); dp -= pixel_bytes; } + sp -= pixel_bytes; } break; @@ -2961,26 +3110,27 @@ png_do_read_interlace(png_structp png_ptr) row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width); } #ifndef PNG_READ_PACKSWAP_SUPPORTED - transformations = transformations; /* Silence compiler warning */ + PNG_UNUSED(transformations) /* Silence compiler warning */ #endif } #endif /* PNG_READ_INTERLACING_SUPPORTED */ void /* PRIVATE */ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row, - png_bytep prev_row, int filter) + png_const_bytep prev_row, int filter) { png_debug(1, "in png_read_filter_row"); - png_debug2(2, "row = %lu, filter = %d", png_ptr->row_number, filter); + png_debug2(2, "row = %u, filter = %d", png_ptr->row_number, filter); switch (filter) { case PNG_FILTER_VALUE_NONE: break; + case PNG_FILTER_VALUE_SUB: { - png_uint_32 i; - png_uint_32 istop = row_info->rowbytes; - png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; + png_size_t i; + png_size_t istop = row_info->rowbytes; + unsigned int bpp = (row_info->pixel_depth + 7) >> 3; png_bytep rp = row + bpp; png_bytep lp = row; @@ -2993,10 +3143,10 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row, } case PNG_FILTER_VALUE_UP: { - png_uint_32 i; - png_uint_32 istop = row_info->rowbytes; + png_size_t i; + png_size_t istop = row_info->rowbytes; png_bytep rp = row; - png_bytep pp = prev_row; + png_const_bytep pp = prev_row; for (i = 0; i < istop; i++) { @@ -3007,37 +3157,39 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row, } case PNG_FILTER_VALUE_AVG: { - png_uint_32 i; + png_size_t i; png_bytep rp = row; - png_bytep pp = prev_row; + png_const_bytep pp = prev_row; png_bytep lp = row; - png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; - png_uint_32 istop = row_info->rowbytes - bpp; + unsigned int bpp = (row_info->pixel_depth + 7) >> 3; + png_size_t istop = row_info->rowbytes - bpp; for (i = 0; i < bpp; i++) { *rp = (png_byte)(((int)(*rp) + - ((int)(*pp++) / 2 )) & 0xff); + ((int)(*pp++) / 2 )) & 0xff); + rp++; } for (i = 0; i < istop; i++) { *rp = (png_byte)(((int)(*rp) + - (int)(*pp++ + *lp++) / 2 ) & 0xff); + (int)(*pp++ + *lp++) / 2 ) & 0xff); + rp++; } break; } case PNG_FILTER_VALUE_PAETH: { - png_uint_32 i; + png_size_t i; png_bytep rp = row; - png_bytep pp = prev_row; + png_const_bytep pp = prev_row; png_bytep lp = row; - png_bytep cp = prev_row; - png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; - png_uint_32 istop=row_info->rowbytes - bpp; + png_const_bytep cp = prev_row; + unsigned int bpp = (row_info->pixel_depth + 7) >> 3; + png_size_t istop=row_info->rowbytes - bpp; for (i = 0; i < bpp; i++) { @@ -3069,8 +3221,10 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row, /* if (pa <= pb && pa <= pc) p = a; + else if (pb <= pc) p = b; + else p = c; */ @@ -3083,8 +3237,8 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row, break; } default: - png_warning(png_ptr, "Ignoring bad adaptive filter type"); - *row = 0; + png_error(png_ptr, "Ignoring bad adaptive filter type"); + /*NOT REACHED */ break; } } @@ -3118,13 +3272,16 @@ png_read_finish_row(png_structp png_ptr) if (png_ptr->interlaced) { png_ptr->row_number = 0; - png_memset(png_ptr->prev_row, 0, - png_ptr->rowbytes + 1); + + png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); + do { png_ptr->pass++; + if (png_ptr->pass >= 7) break; + png_ptr->iwidth = (png_ptr->width + png_pass_inc[png_ptr->pass] - 1 - png_pass_start[png_ptr->pass]) / @@ -3133,15 +3290,15 @@ png_read_finish_row(png_structp png_ptr) if (!(png_ptr->transformations & PNG_INTERLACE)) { png_ptr->num_rows = (png_ptr->height + - png_pass_yinc[png_ptr->pass] - 1 - - png_pass_ystart[png_ptr->pass]) / - png_pass_yinc[png_ptr->pass]; - if (!(png_ptr->num_rows)) - continue; + png_pass_yinc[png_ptr->pass] - 1 - + png_pass_ystart[png_ptr->pass]) / + png_pass_yinc[png_ptr->pass]; } + else /* if (png_ptr->transformations & PNG_INTERLACE) */ - break; - } while (png_ptr->iwidth == 0); + break; /* libpng deinterlacing sees every row */ + + } while (png_ptr->num_rows == 0 || png_ptr->iwidth == 0); if (png_ptr->pass < 7) return; @@ -3156,6 +3313,7 @@ png_read_finish_row(png_structp png_ptr) png_ptr->zstream.next_out = (Byte *)&extra; png_ptr->zstream.avail_out = (uInt)1; + for (;;) { if (!(png_ptr->zstream.avail_in)) @@ -3167,26 +3325,33 @@ png_read_finish_row(png_structp png_ptr) if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) png_error(png_ptr, "Not enough image data"); } + png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size; png_ptr->zstream.next_in = png_ptr->zbuf; + if (png_ptr->zbuf_size > png_ptr->idat_size) png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size; + png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in); png_ptr->idat_size -= png_ptr->zstream.avail_in; } + ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); + if (ret == Z_STREAM_END) { if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in || - png_ptr->idat_size) + png_ptr->idat_size) png_warning(png_ptr, "Extra compressed data"); + png_ptr->mode |= PNG_AFTER_IDAT; png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; break; } + if (ret != Z_OK) png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg : - "Decompression Error"); + "Decompression Error"); if (!(png_ptr->zstream.avail_out)) { @@ -3239,21 +3404,24 @@ png_read_start_row(png_structp png_ptr) { if (!(png_ptr->transformations & PNG_INTERLACE)) png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - - png_pass_ystart[0]) / png_pass_yinc[0]; + png_pass_ystart[0]) / png_pass_yinc[0]; + else png_ptr->num_rows = png_ptr->height; png_ptr->iwidth = (png_ptr->width + - png_pass_inc[png_ptr->pass] - 1 - - png_pass_start[png_ptr->pass]) / - png_pass_inc[png_ptr->pass]; + png_pass_inc[png_ptr->pass] - 1 - + png_pass_start[png_ptr->pass]) / + png_pass_inc[png_ptr->pass]; } + else #endif /* PNG_READ_INTERLACING_SUPPORTED */ { png_ptr->num_rows = png_ptr->height; png_ptr->iwidth = png_ptr->width; } + max_pixel_depth = png_ptr->pixel_depth; #ifdef PNG_READ_PACK_SUPPORTED @@ -3268,16 +3436,20 @@ png_read_start_row(png_structp png_ptr) { if (png_ptr->num_trans) max_pixel_depth = 32; + else max_pixel_depth = 24; } + else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) { if (max_pixel_depth < 8) max_pixel_depth = 8; + if (png_ptr->num_trans) max_pixel_depth *= 2; } + else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) { if (png_ptr->num_trans) @@ -3294,17 +3466,21 @@ png_read_start_row(png_structp png_ptr) { if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) max_pixel_depth = 32; + else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) { if (max_pixel_depth <= 8) max_pixel_depth = 16; + else max_pixel_depth = 32; } + else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) { if (max_pixel_depth <= 32) max_pixel_depth = 32; + else max_pixel_depth = 64; } @@ -3316,29 +3492,34 @@ png_read_start_row(png_structp png_ptr) { if ( #ifdef PNG_READ_EXPAND_SUPPORTED - (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) || + (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) || #endif #ifdef PNG_READ_FILLER_SUPPORTED - (png_ptr->transformations & (PNG_FILLER)) || + (png_ptr->transformations & (PNG_FILLER)) || #endif - png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { if (max_pixel_depth <= 16) max_pixel_depth = 32; + else max_pixel_depth = 64; } + else { if (max_pixel_depth <= 8) - { - if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) + { + if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) max_pixel_depth = 32; - else + + else max_pixel_depth = 24; - } + } + else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) max_pixel_depth = 64; + else max_pixel_depth = 48; } @@ -3348,12 +3529,13 @@ png_read_start_row(png_structp png_ptr) #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \ defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) if (png_ptr->transformations & PNG_USER_TRANSFORM) - { - int user_pixel_depth = png_ptr->user_transform_depth* + { + int user_pixel_depth = png_ptr->user_transform_depth* png_ptr->user_transform_channels; - if (user_pixel_depth > max_pixel_depth) + + if (user_pixel_depth > max_pixel_depth) max_pixel_depth=user_pixel_depth; - } + } #endif /* Align the width on the next larger 8 pixels. Mainly used @@ -3364,7 +3546,8 @@ defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) * for safety's sake */ row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) + - 1 + ((max_pixel_depth + 7) >> 3); + 1 + ((max_pixel_depth + 7) >> 3); + #ifdef PNG_MAX_MALLOC_64K if (row_bytes > (png_uint_32)65536L) png_error(png_ptr, "This image requires a row greater than 64KB"); @@ -3373,20 +3556,24 @@ defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) if (row_bytes + 48 > png_ptr->old_big_row_buf_size) { png_free(png_ptr, png_ptr->big_row_buf); + if (png_ptr->interlaced) png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr, row_bytes + 48); + else png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 48); + png_ptr->old_big_row_buf_size = row_bytes + 48; #ifdef PNG_ALIGNED_MEMORY_SUPPORTED /* Use 16-byte aligned memory for row_buf with at least 16 bytes * of padding before and after row_buf. */ - png_ptr->row_buf = png_ptr->big_row_buf + 32 - - (((png_alloc_size_t)&(png_ptr->big_row_buf[0]) + 15) % 16); + png_ptr->row_buf = png_ptr->big_row_buf + 32 - + (((png_alloc_size_t)png_ptr->big_row_buf + 15) & 0x0F); + png_ptr->old_big_row_buf_size = row_bytes + 48; #else /* Use 32 bytes of padding before and 16 bytes after row_buf. */ @@ -3396,28 +3583,30 @@ defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) } #ifdef PNG_MAX_MALLOC_64K - if ((png_uint_32)png_ptr->rowbytes + 1 > (png_uint_32)65536L) + if (png_ptr->rowbytes > 65535) png_error(png_ptr, "This image requires a row greater than 64KB"); + #endif - if ((png_uint_32)png_ptr->rowbytes > (png_uint_32)(PNG_SIZE_MAX - 1)) + if (png_ptr->rowbytes > (PNG_SIZE_MAX - 1)) png_error(png_ptr, "Row has too many bytes to allocate in memory"); if (png_ptr->rowbytes + 1 > png_ptr->old_prev_row_size) { png_free(png_ptr, png_ptr->prev_row); - png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)( - png_ptr->rowbytes + 1)); + + png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, png_ptr->rowbytes + 1); + png_ptr->old_prev_row_size = png_ptr->rowbytes + 1; } png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); - png_debug1(3, "width = %lu,", png_ptr->width); - png_debug1(3, "height = %lu,", png_ptr->height); - png_debug1(3, "iwidth = %lu,", png_ptr->iwidth); - png_debug1(3, "num_rows = %lu,", png_ptr->num_rows); - png_debug1(3, "rowbytes = %lu,", png_ptr->rowbytes); - png_debug1(3, "irowbytes = %lu", + png_debug1(3, "width = %u,", png_ptr->width); + png_debug1(3, "height = %u,", png_ptr->height); + png_debug1(3, "iwidth = %u,", png_ptr->iwidth); + png_debug1(3, "num_rows = %u,", png_ptr->num_rows); + png_debug1(3, "rowbytes = %u,", png_ptr->rowbytes); + png_debug1(3, "irowbytes = %u", PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1); png_ptr->flags |= PNG_FLAG_ROW_INIT; diff --git a/harbour/src/3rd/png/pngset.c b/harbour/src/3rd/png/pngset.c index 76f173e4e0..113cd795b0 100644 --- a/harbour/src/3rd/png/pngset.c +++ b/harbour/src/3rd/png/pngset.c @@ -1,8 +1,8 @@ /* pngset.c - storage of image information into info struct * - * Last changed in libpng 1.4.5 [December 9, 2010] - * Copyright (c) 1998-2010 Glenn Randers-Pehrson + * Last changed in libpng 1.5.0 [January 6, 2011] + * Copyright (c) 1998-2011 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -16,14 +16,14 @@ * info struct and allows us to change the structure in the future. */ -#define PNG_NO_PEDANTIC_WARNINGS -#include "png.h" -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) #include "pngpriv.h" +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) + #ifdef PNG_bKGD_SUPPORTED void PNGAPI -png_set_bKGD(png_structp png_ptr, png_infop info_ptr, png_color_16p background) +png_set_bKGD(png_structp png_ptr, png_infop info_ptr, + png_const_color_16p background) { png_debug1(1, "in %s storage function", "bKGD"); @@ -36,150 +36,94 @@ png_set_bKGD(png_structp png_ptr, png_infop info_ptr, png_color_16p background) #endif #ifdef PNG_cHRM_SUPPORTED -#ifdef PNG_FLOATING_POINT_SUPPORTED -void PNGAPI -png_set_cHRM(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) -{ - png_debug1(1, "in %s storage function", "cHRM"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - info_ptr->x_white = (float)white_x; - info_ptr->y_white = (float)white_y; - info_ptr->x_red = (float)red_x; - info_ptr->y_red = (float)red_y; - info_ptr->x_green = (float)green_x; - info_ptr->y_green = (float)green_y; - info_ptr->x_blue = (float)blue_x; - info_ptr->y_blue = (float)blue_y; -#ifdef PNG_FIXED_POINT_SUPPORTED - info_ptr->int_x_white = (png_fixed_point)(white_x*100000.+0.5); - info_ptr->int_y_white = (png_fixed_point)(white_y*100000.+0.5); - info_ptr->int_x_red = (png_fixed_point)( red_x*100000.+0.5); - info_ptr->int_y_red = (png_fixed_point)( red_y*100000.+0.5); - info_ptr->int_x_green = (png_fixed_point)(green_x*100000.+0.5); - info_ptr->int_y_green = (png_fixed_point)(green_y*100000.+0.5); - info_ptr->int_x_blue = (png_fixed_point)( blue_x*100000.+0.5); - info_ptr->int_y_blue = (png_fixed_point)( blue_y*100000.+0.5); -#endif - info_ptr->valid |= PNG_INFO_cHRM; -} -#endif /* PNG_FLOATING_POINT_SUPPORTED */ - -#ifdef PNG_FIXED_POINT_SUPPORTED -void PNGAPI +void PNGFAPI png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr, - png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x, - png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y, - png_fixed_point blue_x, png_fixed_point blue_y) + png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x, + png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y, + png_fixed_point blue_x, png_fixed_point blue_y) { png_debug1(1, "in %s storage function", "cHRM fixed"); if (png_ptr == NULL || info_ptr == NULL) return; -#ifdef PNG_CHECK_cHRM_SUPPORTED +# ifdef PNG_CHECK_cHRM_SUPPORTED if (png_check_cHRM_fixed(png_ptr, - white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y)) -#endif + white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y)) +# endif { - info_ptr->int_x_white = white_x; - info_ptr->int_y_white = white_y; - info_ptr->int_x_red = red_x; - info_ptr->int_y_red = red_y; - info_ptr->int_x_green = green_x; - info_ptr->int_y_green = green_y; - info_ptr->int_x_blue = blue_x; - info_ptr->int_y_blue = blue_y; -#ifdef PNG_FLOATING_POINT_SUPPORTED - info_ptr->x_white = (float)(white_x/100000.); - info_ptr->y_white = (float)(white_y/100000.); - info_ptr->x_red = (float)( red_x/100000.); - info_ptr->y_red = (float)( red_y/100000.); - info_ptr->x_green = (float)(green_x/100000.); - info_ptr->y_green = (float)(green_y/100000.); - info_ptr->x_blue = (float)( blue_x/100000.); - info_ptr->y_blue = (float)( blue_y/100000.); -#endif + info_ptr->x_white = white_x; + info_ptr->y_white = white_y; + info_ptr->x_red = red_x; + info_ptr->y_red = red_y; + info_ptr->x_green = green_x; + info_ptr->y_green = green_y; + info_ptr->x_blue = blue_x; + info_ptr->y_blue = blue_y; info_ptr->valid |= PNG_INFO_cHRM; } } -#endif /* PNG_FIXED_POINT_SUPPORTED */ + +# ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_cHRM(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) +{ + png_set_cHRM_fixed(png_ptr, info_ptr, + png_fixed(png_ptr, white_x, "cHRM White X"), + png_fixed(png_ptr, white_y, "cHRM White Y"), + png_fixed(png_ptr, red_x, "cHRM Red X"), + png_fixed(png_ptr, red_y, "cHRM Red Y"), + png_fixed(png_ptr, green_x, "cHRM Green X"), + png_fixed(png_ptr, green_y, "cHRM Green Y"), + png_fixed(png_ptr, blue_x, "cHRM Blue X"), + png_fixed(png_ptr, blue_y, "cHRM Blue Y")); +} +# endif /* PNG_FLOATING_POINT_SUPPORTED */ + #endif /* PNG_cHRM_SUPPORTED */ #ifdef PNG_gAMA_SUPPORTED -#ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGFAPI +png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point + gamma) +{ + png_debug1(1, "in %s storage function", "gAMA"); + + if (png_ptr == NULL || info_ptr == NULL) + return; + + /* Previously these values were limited, however they must be + * wrong, therefore storing them (and setting PNG_INFO_gAMA) + * must be wrong too. + */ + if (gamma > (png_fixed_point)PNG_UINT_31_MAX) + png_warning(png_ptr, "Gamma too large, ignored"); + + else if (gamma <= 0) + png_warning(png_ptr, "Negative or zero gamma ignored"); + + else + { + info_ptr->gamma = gamma; + info_ptr->valid |= PNG_INFO_gAMA; + } +} + +# ifdef PNG_FLOATING_POINT_SUPPORTED void PNGAPI png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma) { - double png_gamma; - - png_debug1(1, "in %s storage function", "gAMA"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - /* Check for overflow */ - if (file_gamma > 21474.83) - { - png_warning(png_ptr, "Limiting gamma to 21474.83"); - png_gamma=21474.83; - } - else - png_gamma = file_gamma; - info_ptr->gamma = (float)png_gamma; -#ifdef PNG_FIXED_POINT_SUPPORTED - info_ptr->int_gamma = (int)(png_gamma*100000.+.5); -#endif - info_ptr->valid |= PNG_INFO_gAMA; - if (png_gamma == 0.0) - png_warning(png_ptr, "Setting gamma=0"); -} -#endif -void PNGAPI -png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point - int_gamma) -{ - png_fixed_point png_gamma; - - png_debug1(1, "in %s storage function", "gAMA"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - if (int_gamma > (png_fixed_point)PNG_UINT_31_MAX) - { - png_warning(png_ptr, "Limiting gamma to 21474.83"); - png_gamma=PNG_UINT_31_MAX; - } - else - { - if (int_gamma < 0) - { - png_warning(png_ptr, "Setting negative gamma to zero"); - png_gamma = 0; - } - else - png_gamma = int_gamma; - } -#ifdef PNG_FLOATING_POINT_SUPPORTED - info_ptr->gamma = (float)(png_gamma/100000.); -#endif -#ifdef PNG_FIXED_POINT_SUPPORTED - info_ptr->int_gamma = png_gamma; -#endif - info_ptr->valid |= PNG_INFO_gAMA; - if (png_gamma == 0) - png_warning(png_ptr, "Setting gamma=0"); + png_set_gAMA_fixed(png_ptr, info_ptr, png_fixed(png_ptr, file_gamma, + "png_set_gAMA")); } +# endif #endif #ifdef PNG_hIST_SUPPORTED void PNGAPI -png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p hist) +png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_const_uint_16p hist) { int i; @@ -192,16 +136,19 @@ png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p hist) > PNG_MAX_PALETTE_LENGTH) { png_warning(png_ptr, - "Invalid palette size, hIST allocation skipped"); + "Invalid palette size, hIST allocation skipped"); + return; } png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0); + /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in * version 1.2.1 */ png_ptr->hist = (png_uint_16p)png_malloc_warn(png_ptr, - PNG_MAX_PALETTE_LENGTH * png_sizeof(png_uint_16)); + PNG_MAX_PALETTE_LENGTH * png_sizeof(png_uint_16)); + if (png_ptr->hist == NULL) { png_warning(png_ptr, "Insufficient memory for hIST chunk data"); @@ -210,18 +157,18 @@ png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p hist) for (i = 0; i < info_ptr->num_palette; i++) png_ptr->hist[i] = hist[i]; + info_ptr->hist = png_ptr->hist; info_ptr->valid |= PNG_INFO_hIST; - info_ptr->free_me |= PNG_FREE_HIST; } #endif void PNGAPI png_set_IHDR(png_structp png_ptr, png_infop info_ptr, - png_uint_32 width, png_uint_32 height, int bit_depth, - int color_type, int interlace_type, int compression_type, - int filter_type) + png_uint_32 width, png_uint_32 height, int bit_depth, + int color_type, int interlace_type, int compression_type, + int filter_type) { png_debug1(1, "in %s storage function", "IHDR"); @@ -242,21 +189,25 @@ png_set_IHDR(png_structp png_ptr, png_infop info_ptr, if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) info_ptr->channels = 1; + else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) info_ptr->channels = 3; + else info_ptr->channels = 1; + if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA) info_ptr->channels++; + info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth); /* Check for potential overflow */ - if (width > (PNG_UINT_32_MAX - >> 3) /* 8-byte RGBA pixels */ - - 64 /* bigrowbuf hack */ - - 1 /* filter byte */ - - 7*8 /* rounding of width to multiple of 8 pixels */ - - 8) /* extra max_pixel_depth pad */ + if (width > + (PNG_UINT_32_MAX >> 3) /* 8-byte RRGGBBAA pixels */ + - 48 /* bigrowbuf hack */ + - 1 /* filter byte */ + - 7*8 /* rounding of width to multiple of 8 pixels */ + - 8) /* extra max_pixel_depth pad */ info_ptr->rowbytes = 0; else info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width); @@ -265,7 +216,7 @@ png_set_IHDR(png_structp png_ptr, png_infop info_ptr, #ifdef PNG_oFFs_SUPPORTED void PNGAPI png_set_oFFs(png_structp png_ptr, png_infop info_ptr, - png_int_32 offset_x, png_int_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", "oFFs"); @@ -282,8 +233,8 @@ png_set_oFFs(png_structp png_ptr, png_infop info_ptr, #ifdef PNG_pCAL_SUPPORTED void PNGAPI 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, - png_charp units, png_charpp params) + png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type, + int nparams, png_const_charp units, png_charpp params) { png_size_t length; int i; @@ -295,13 +246,27 @@ png_set_pCAL(png_structp png_ptr, png_infop info_ptr, length = png_strlen(purpose) + 1; png_debug1(3, "allocating purpose for info (%lu bytes)", - (unsigned long)length); + (unsigned long)length); + + /* TODO: validate format of calibration name and unit name */ + + /* Check that the type matches the specification. */ + if (type < 0 || type > 3) + png_error(png_ptr, "Invalid pCAL equation type"); + + /* Validate params[nparams] */ + for (i=0; ipcal_purpose = (png_charp)png_malloc_warn(png_ptr, length); + if (info_ptr->pcal_purpose == NULL) { png_warning(png_ptr, "Insufficient memory for pCAL purpose"); return; } + png_memcpy(info_ptr->pcal_purpose, purpose, length); png_debug(3, "storing X0, X1, type, and nparams in info"); @@ -313,16 +278,20 @@ png_set_pCAL(png_structp png_ptr, png_infop info_ptr, length = png_strlen(units) + 1; png_debug1(3, "allocating units for info (%lu bytes)", (unsigned long)length); + info_ptr->pcal_units = (png_charp)png_malloc_warn(png_ptr, length); + if (info_ptr->pcal_units == NULL) { png_warning(png_ptr, "Insufficient memory for pCAL units"); return; } + png_memcpy(info_ptr->pcal_units, units, length); info_ptr->pcal_params = (png_charpp)png_malloc_warn(png_ptr, - (png_size_t)((nparams + 1) * png_sizeof(png_charp))); + (png_size_t)((nparams + 1) * png_sizeof(png_charp))); + if (info_ptr->pcal_params == NULL) { png_warning(png_ptr, "Insufficient memory for pCAL params"); @@ -335,13 +304,16 @@ png_set_pCAL(png_structp png_ptr, png_infop info_ptr, { length = png_strlen(params[i]) + 1; png_debug2(3, "allocating parameter %d for info (%lu bytes)", i, - (unsigned long)length); + (unsigned long)length); + info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length); + if (info_ptr->pcal_params[i] == NULL) { png_warning(png_ptr, "Insufficient memory for pCAL parameter"); return; } + png_memcpy(info_ptr->pcal_params[i], params[i], length); } @@ -350,74 +322,132 @@ png_set_pCAL(png_structp png_ptr, png_infop info_ptr, } #endif -#if defined(PNG_READ_sCAL_SUPPORTED) || defined(PNG_WRITE_sCAL_SUPPORTED) -#ifdef PNG_FLOATING_POINT_SUPPORTED -void PNGAPI -png_set_sCAL(png_structp png_ptr, png_infop info_ptr, - int unit, double width, double height) -{ - png_debug1(1, "in %s storage function", "sCAL"); - - if (png_ptr == NULL || info_ptr == NULL) - return; - - info_ptr->scal_unit = (png_byte)unit; - info_ptr->scal_pixel_width = width; - info_ptr->scal_pixel_height = height; - - info_ptr->valid |= PNG_INFO_sCAL; -} -#else -#ifdef PNG_FIXED_POINT_SUPPORTED +#ifdef PNG_sCAL_SUPPORTED void PNGAPI png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr, - int unit, png_charp swidth, png_charp sheight) + int unit, png_const_charp swidth, png_const_charp sheight) { - png_size_t length; + png_size_t lengthw = 0, lengthh = 0; png_debug1(1, "in %s storage function", "sCAL"); if (png_ptr == NULL || info_ptr == NULL) return; + /* Double check the unit (should never get here with an invalid + * unit unless this is an API call.) + */ + if (unit != 1 && unit != 2) + png_error(png_ptr, "Invalid sCAL unit"); + + if (swidth == NULL || (lengthw = png_strlen(swidth)) <= 0 || + swidth[0] == 45 /*'-'*/ || !png_check_fp_string(swidth, lengthw)) + png_error(png_ptr, "Invalid sCAL width"); + + if (sheight == NULL || (lengthh = png_strlen(sheight)) <= 0 || + sheight[0] == 45 /*'-'*/ || !png_check_fp_string(sheight, lengthh)) + png_error(png_ptr, "Invalid sCAL height"); + info_ptr->scal_unit = (png_byte)unit; - length = png_strlen(swidth) + 1; - png_debug1(3, "allocating unit for info (%u bytes)", - (unsigned int)length); - info_ptr->scal_s_width = (png_charp)png_malloc_warn(png_ptr, length); + ++lengthw; + + png_debug1(3, "allocating unit for info (%u bytes)", lengthw); + + info_ptr->scal_s_width = (png_charp)png_malloc_warn(png_ptr, lengthw); + if (info_ptr->scal_s_width == NULL) { - png_warning(png_ptr, - "Memory allocation failed while processing sCAL"); + png_warning(png_ptr, "Memory allocation failed while processing sCAL"); return; } - png_memcpy(info_ptr->scal_s_width, swidth, length); - length = png_strlen(sheight) + 1; - png_debug1(3, "allocating unit for info (%u bytes)", - (unsigned int)length); - info_ptr->scal_s_height = (png_charp)png_malloc_warn(png_ptr, length); + png_memcpy(info_ptr->scal_s_width, swidth, lengthw); + + ++lengthh; + + png_debug1(3, "allocating unit for info (%u bytes)", lengthh); + + info_ptr->scal_s_height = (png_charp)png_malloc_warn(png_ptr, lengthh); + if (info_ptr->scal_s_height == NULL) { png_free (png_ptr, info_ptr->scal_s_width); info_ptr->scal_s_width = NULL; - png_warning(png_ptr, - "Memory allocation failed while processing sCAL"); + + png_warning(png_ptr, "Memory allocation failed while processing sCAL"); return; } - png_memcpy(info_ptr->scal_s_height, sheight, length); + + png_memcpy(info_ptr->scal_s_height, sheight, lengthh); + info_ptr->valid |= PNG_INFO_sCAL; info_ptr->free_me |= PNG_FREE_SCAL; } -#endif -#endif + +# ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_sCAL(png_structp png_ptr, png_infop info_ptr, int unit, double width, + double height) +{ + png_debug1(1, "in %s storage function", "sCAL"); + + /* Check the arguments. */ + if (width <= 0) + png_warning(png_ptr, "Invalid sCAL width ignored"); + + else if (height <= 0) + png_warning(png_ptr, "Invalid sCAL height ignored"); + + else + { + /* Convert 'width' and 'height' to ASCII. */ + char swidth[PNG_sCAL_MAX_DIGITS+1]; + char sheight[PNG_sCAL_MAX_DIGITS+1]; + + png_ascii_from_fp(png_ptr, swidth, sizeof swidth, width, + PNG_sCAL_PRECISION); + png_ascii_from_fp(png_ptr, sheight, sizeof sheight, height, + PNG_sCAL_PRECISION); + + png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight); + } +} +# endif + +# ifdef PNG_FIXED_POINT_SUPPORTED +void PNGAPI +png_set_sCAL_fixed(png_structp png_ptr, png_infop info_ptr, int unit, + png_fixed_point width, png_fixed_point height) +{ + png_debug1(1, "in %s storage function", "sCAL"); + + /* Check the arguments. */ + if (width <= 0) + png_warning(png_ptr, "Invalid sCAL width ignored"); + + else if (height <= 0) + png_warning(png_ptr, "Invalid sCAL height ignored"); + + else + { + /* Convert 'width' and 'height' to ASCII. */ + char swidth[PNG_sCAL_MAX_DIGITS+1]; + char sheight[PNG_sCAL_MAX_DIGITS+1]; + + png_ascii_from_fixed(png_ptr, swidth, sizeof swidth, width); + png_ascii_from_fixed(png_ptr, sheight, sizeof sheight, height); + + png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight); + } +} +# endif #endif #ifdef PNG_pHYs_SUPPORTED void PNGAPI png_set_pHYs(png_structp png_ptr, png_infop info_ptr, - png_uint_32 res_x, png_uint_32 res_y, int unit_type) + png_uint_32 res_x, png_uint_32 res_y, int unit_type) { png_debug1(1, "in %s storage function", "pHYs"); @@ -433,7 +463,7 @@ png_set_pHYs(png_structp png_ptr, png_infop info_ptr, void PNGAPI png_set_PLTE(png_structp png_ptr, png_infop info_ptr, - png_colorp palette, int num_palette) + png_const_colorp palette, int num_palette) { png_debug1(1, "in %s storage function", "PLTE"); @@ -445,6 +475,7 @@ png_set_PLTE(png_structp png_ptr, png_infop info_ptr, { if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) png_error(png_ptr, "Invalid palette length"); + else { png_warning(png_ptr, "Invalid palette length"); @@ -463,7 +494,8 @@ png_set_PLTE(png_structp png_ptr, png_infop info_ptr, * too-large sample values. */ png_ptr->palette = (png_colorp)png_calloc(png_ptr, - PNG_MAX_PALETTE_LENGTH * png_sizeof(png_color)); + PNG_MAX_PALETTE_LENGTH * png_sizeof(png_color)); + png_memcpy(png_ptr->palette, palette, num_palette * png_sizeof(png_color)); info_ptr->palette = png_ptr->palette; info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette; @@ -476,7 +508,7 @@ png_set_PLTE(png_structp png_ptr, png_infop info_ptr, #ifdef PNG_sBIT_SUPPORTED void PNGAPI png_set_sBIT(png_structp png_ptr, png_infop info_ptr, - png_color_8p sig_bit) + png_const_color_8p sig_bit) { png_debug1(1, "in %s storage function", "sBIT"); @@ -503,23 +535,8 @@ png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int intent) void PNGAPI png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr, - int intent) + int intent) { -#ifdef PNG_gAMA_SUPPORTED -#ifdef PNG_FLOATING_POINT_SUPPORTED - float file_gamma; -#endif -#ifdef PNG_FIXED_POINT_SUPPORTED - png_fixed_point int_file_gamma; -#endif -#endif -#ifdef PNG_cHRM_SUPPORTED -#ifdef PNG_FLOATING_POINT_SUPPORTED - float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y; -#endif - png_fixed_point int_white_x, int_white_y, int_red_x, int_red_y, int_green_x, - int_green_y, int_blue_x, int_blue_y; -#endif png_debug1(1, "in %s storage function", "sRGB_gAMA_and_cHRM"); if (png_ptr == NULL || info_ptr == NULL) @@ -527,48 +544,19 @@ png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr, png_set_sRGB(png_ptr, info_ptr, intent); -#ifdef PNG_gAMA_SUPPORTED -#ifdef PNG_FLOATING_POINT_SUPPORTED - file_gamma = (float).45455; - png_set_gAMA(png_ptr, info_ptr, file_gamma); -#endif -#ifdef PNG_FIXED_POINT_SUPPORTED - int_file_gamma = 45455L; - png_set_gAMA_fixed(png_ptr, info_ptr, int_file_gamma); -#endif -#endif +# ifdef PNG_gAMA_SUPPORTED + png_set_gAMA_fixed(png_ptr, info_ptr, 45455L); +# endif -#ifdef PNG_cHRM_SUPPORTED - int_white_x = 31270L; - int_white_y = 32900L; - int_red_x = 64000L; - int_red_y = 33000L; - int_green_x = 30000L; - int_green_y = 60000L; - int_blue_x = 15000L; - int_blue_y = 6000L; - -#ifdef PNG_FLOATING_POINT_SUPPORTED - white_x = (float).3127; - white_y = (float).3290; - red_x = (float).64; - red_y = (float).33; - green_x = (float).30; - green_y = (float).60; - blue_x = (float).15; - blue_y = (float).06; -#endif - -#ifdef PNG_FIXED_POINT_SUPPORTED +# ifdef PNG_cHRM_SUPPORTED png_set_cHRM_fixed(png_ptr, info_ptr, - int_white_x, int_white_y, int_red_x, int_red_y, int_green_x, - int_green_y, int_blue_x, int_blue_y); -#endif -#ifdef PNG_FLOATING_POINT_SUPPORTED - png_set_cHRM(png_ptr, info_ptr, - white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y); -#endif -#endif /* cHRM */ + /* color x y */ + /* white */ 31270L, 32900L, + /* red */ 64000L, 33000L, + /* green */ 30000L, 60000L, + /* blue */ 15000L, 6000L + ); +# endif /* cHRM */ } #endif /* sRGB */ @@ -576,11 +564,11 @@ png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr, #ifdef PNG_iCCP_SUPPORTED void PNGAPI png_set_iCCP(png_structp png_ptr, png_infop info_ptr, - png_charp name, int compression_type, - png_charp profile, png_uint_32 proflen) + png_const_charp name, int compression_type, + png_const_bytep profile, png_uint_32 proflen) { png_charp new_iccp_name; - png_charp new_iccp_profile; + png_bytep new_iccp_profile; png_uint_32 length; png_debug1(1, "in %s storage function", "iCCP"); @@ -590,13 +578,16 @@ png_set_iCCP(png_structp png_ptr, png_infop info_ptr, length = png_strlen(name)+1; new_iccp_name = (png_charp)png_malloc_warn(png_ptr, length); + if (new_iccp_name == NULL) { png_warning(png_ptr, "Insufficient memory to process iCCP chunk"); return; } + png_memcpy(new_iccp_name, name, length); - new_iccp_profile = (png_charp)png_malloc_warn(png_ptr, proflen); + new_iccp_profile = (png_bytep)png_malloc_warn(png_ptr, proflen); + if (new_iccp_profile == NULL) { png_free (png_ptr, new_iccp_name); @@ -604,6 +595,7 @@ png_set_iCCP(png_structp png_ptr, png_infop info_ptr, "Insufficient memory to process iCCP profile"); return; } + png_memcpy(new_iccp_profile, profile, (png_size_t)proflen); png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0); @@ -622,24 +614,25 @@ png_set_iCCP(png_structp png_ptr, png_infop info_ptr, #ifdef PNG_TEXT_SUPPORTED void PNGAPI -png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, - int num_text) +png_set_text(png_structp png_ptr, png_infop info_ptr, png_const_textp text_ptr, + int num_text) { int ret; ret = png_set_text_2(png_ptr, info_ptr, text_ptr, num_text); + if (ret) png_error(png_ptr, "Insufficient memory to store text"); } int /* PRIVATE */ -png_set_text_2(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, - int num_text) +png_set_text_2(png_structp png_ptr, png_infop info_ptr, + png_const_textp text_ptr, int num_text) { int i; png_debug1(1, "in %s storage function", ((png_ptr == NULL || - png_ptr->chunk_name[0] == '\0') ? - "text" : (png_const_charp)png_ptr->chunk_name)); + png_ptr->chunk_name[0] == '\0') ? + "text" : (png_const_charp)png_ptr->chunk_name)); if (png_ptr == NULL || info_ptr == NULL || num_text == 0) return(0); @@ -659,27 +652,31 @@ png_set_text_2(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, old_text = info_ptr->text; info_ptr->text = (png_textp)png_malloc_warn(png_ptr, (png_size_t)(info_ptr->max_text * png_sizeof(png_text))); + if (info_ptr->text == NULL) { png_free(png_ptr, old_text); return(1); } + png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max * - png_sizeof(png_text))); + png_sizeof(png_text))); png_free(png_ptr, old_text); } + else { info_ptr->max_text = num_text + 8; info_ptr->num_text = 0; info_ptr->text = (png_textp)png_malloc_warn(png_ptr, - (png_size_t)(info_ptr->max_text * png_sizeof(png_text))); + (png_size_t)(info_ptr->max_text * png_sizeof(png_text))); if (info_ptr->text == NULL) return(1); info_ptr->free_me |= PNG_FREE_TEXT; } + png_debug1(3, "allocated %d entries for info_ptr->text", - info_ptr->max_text); + info_ptr->max_text); } for (i = 0; i < num_text; i++) { @@ -706,34 +703,38 @@ png_set_text_2(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, } else -#ifdef PNG_iTXt_SUPPORTED +# ifdef PNG_iTXt_SUPPORTED { /* Set iTXt data */ if (text_ptr[i].lang != NULL) lang_len = png_strlen(text_ptr[i].lang); + else lang_len = 0; + if (text_ptr[i].lang_key != NULL) lang_key_len = png_strlen(text_ptr[i].lang_key); + else lang_key_len = 0; } -#else /* PNG_iTXt_SUPPORTED */ +# else /* PNG_iTXt_SUPPORTED */ { png_warning(png_ptr, "iTXt chunk not supported"); continue; } -#endif +# endif if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0') { text_length = 0; -#ifdef PNG_iTXt_SUPPORTED +# ifdef PNG_iTXt_SUPPORTED if (text_ptr[i].compression > 0) textp->compression = PNG_ITXT_COMPRESSION_NONE; + else -#endif +# endif textp->compression = PNG_TEXT_COMPRESSION_NONE; } @@ -744,18 +745,20 @@ png_set_text_2(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, } textp->key = (png_charp)png_malloc_warn(png_ptr, - (png_size_t) - (key_len + text_length + lang_len + lang_key_len + 4)); + (png_size_t) + (key_len + text_length + lang_len + lang_key_len + 4)); + if (textp->key == NULL) return(1); + png_debug2(2, "Allocated %lu bytes at %x in png_set_text", - (unsigned long)(png_uint_32) - (key_len + lang_len + lang_key_len + text_length + 4), - (int)textp->key); + (unsigned long)(png_uint_32) + (key_len + lang_len + lang_key_len + text_length + 4), + (int)textp->key); png_memcpy(textp->key, text_ptr[i].key,(png_size_t)(key_len)); *(textp->key + key_len) = '\0'; -#ifdef PNG_iTXt_SUPPORTED + if (text_ptr[i].compression > 0) { textp->lang = textp->key + key_len + 1; @@ -766,35 +769,34 @@ png_set_text_2(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, *(textp->lang_key + lang_key_len) = '\0'; textp->text = textp->lang_key + lang_key_len + 1; } + else -#endif { -#ifdef PNG_iTXt_SUPPORTED textp->lang=NULL; textp->lang_key=NULL; -#endif textp->text = textp->key + key_len + 1; } + if (text_length) png_memcpy(textp->text, text_ptr[i].text, - (png_size_t)(text_length)); + (png_size_t)(text_length)); + *(textp->text + text_length) = '\0'; -#ifdef PNG_iTXt_SUPPORTED +# ifdef PNG_iTXt_SUPPORTED if (textp->compression > 0) { textp->text_length = 0; textp->itxt_length = text_length; } - else -#endif + else +# endif { textp->text_length = text_length; -#ifdef PNG_iTXt_SUPPORTED textp->itxt_length = 0; -#endif } + info_ptr->num_text++; png_debug1(3, "transferred text chunk %d", info_ptr->num_text); } @@ -804,7 +806,7 @@ png_set_text_2(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, #ifdef PNG_tIME_SUPPORTED void PNGAPI -png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_timep mod_time) +png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_const_timep mod_time) { png_debug1(1, "in %s storage function", "tIME"); @@ -820,7 +822,7 @@ png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_timep mod_time) #ifdef PNG_tRNS_SUPPORTED void PNGAPI png_set_tRNS(png_structp png_ptr, png_infop info_ptr, - png_bytep trans_alpha, int num_trans, png_color_16p trans_color) + png_const_bytep trans_alpha, int num_trans, png_const_color_16p trans_color) { png_debug1(1, "in %s storage function", "tRNS"); @@ -837,8 +839,9 @@ png_set_tRNS(png_structp png_ptr, png_infop info_ptr, png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0); /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */ - png_ptr->trans_alpha = info_ptr->trans_alpha = (png_bytep)png_malloc(png_ptr, - (png_size_t)PNG_MAX_PALETTE_LENGTH); + png_ptr->trans_alpha = info_ptr->trans_alpha = + (png_bytep)png_malloc(png_ptr, (png_size_t)PNG_MAX_PALETTE_LENGTH); + if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH) png_memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans); } @@ -846,6 +849,7 @@ png_set_tRNS(png_structp png_ptr, png_infop info_ptr, if (trans_color != NULL) { int sample_max = (1 << info_ptr->bit_depth); + if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY && (int)trans_color->gray > sample_max) || (info_ptr->color_type == PNG_COLOR_TYPE_RGB && @@ -854,13 +858,16 @@ png_set_tRNS(png_structp png_ptr, png_infop info_ptr, (int)trans_color->blue > sample_max))) png_warning(png_ptr, "tRNS chunk has out-of-range samples for bit_depth"); + png_memcpy(&(info_ptr->trans_color), trans_color, png_sizeof(png_color_16)); + if (num_trans == 0) num_trans = 1; } info_ptr->num_trans = (png_uint_16)num_trans; + if (num_trans != 0) { info_ptr->valid |= PNG_INFO_tRNS; @@ -872,11 +879,12 @@ png_set_tRNS(png_structp png_ptr, png_infop info_ptr, #ifdef PNG_sPLT_SUPPORTED void PNGAPI png_set_sPLT(png_structp png_ptr, - png_infop info_ptr, png_sPLT_tp entries, int nentries) + png_infop info_ptr, png_const_sPLT_tp entries, int nentries) /* * entries - array of png_sPLT_t structures * to be added to the list of palettes * in the info structure. + * * nentries - number of palette structures to be * added. */ @@ -889,7 +897,8 @@ png_set_sPLT(png_structp png_ptr, np = (png_sPLT_tp)png_malloc_warn(png_ptr, (info_ptr->splt_palettes_num + nentries) * - (png_size_t)png_sizeof(png_sPLT_t)); + (png_size_t)png_sizeof(png_sPLT_t)); + if (np == NULL) { png_warning(png_ptr, "No memory for sPLT palettes"); @@ -898,36 +907,42 @@ png_set_sPLT(png_structp png_ptr, png_memcpy(np, info_ptr->splt_palettes, info_ptr->splt_palettes_num * png_sizeof(png_sPLT_t)); + png_free(png_ptr, info_ptr->splt_palettes); info_ptr->splt_palettes=NULL; for (i = 0; i < nentries; i++) { png_sPLT_tp to = np + info_ptr->splt_palettes_num + i; - png_sPLT_tp from = entries + i; + png_const_sPLT_tp from = entries + i; png_uint_32 length; length = png_strlen(from->name) + 1; to->name = (png_charp)png_malloc_warn(png_ptr, (png_size_t)length); + if (to->name == NULL) { png_warning(png_ptr, - "Out of memory while processing sPLT chunk"); + "Out of memory while processing sPLT chunk"); continue; } + png_memcpy(to->name, from->name, length); to->entries = (png_sPLT_entryp)png_malloc_warn(png_ptr, (png_size_t)(from->nentries * png_sizeof(png_sPLT_entry))); + if (to->entries == NULL) { png_warning(png_ptr, - "Out of memory while processing sPLT chunk"); + "Out of memory while processing sPLT chunk"); png_free(png_ptr, to->name); to->name = NULL; continue; } + png_memcpy(to->entries, from->entries, from->nentries * png_sizeof(png_sPLT_entry)); + to->nentries = from->nentries; to->depth = from->depth; } @@ -942,7 +957,7 @@ png_set_sPLT(png_structp png_ptr, #ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED void PNGAPI png_set_unknown_chunks(png_structp png_ptr, - png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns) + png_infop info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns) { png_unknown_chunkp np; int i; @@ -951,8 +966,9 @@ png_set_unknown_chunks(png_structp png_ptr, return; np = (png_unknown_chunkp)png_malloc_warn(png_ptr, - (png_size_t)((info_ptr->unknown_chunks_num + num_unknowns) * - png_sizeof(png_unknown_chunk))); + (png_size_t)(info_ptr->unknown_chunks_num + num_unknowns) * + png_sizeof(png_unknown_chunk)); + if (np == NULL) { png_warning(png_ptr, @@ -961,34 +977,39 @@ png_set_unknown_chunks(png_structp png_ptr, } png_memcpy(np, info_ptr->unknown_chunks, - info_ptr->unknown_chunks_num * png_sizeof(png_unknown_chunk)); + (png_size_t)info_ptr->unknown_chunks_num * + png_sizeof(png_unknown_chunk)); + png_free(png_ptr, info_ptr->unknown_chunks); info_ptr->unknown_chunks = NULL; for (i = 0; i < num_unknowns; i++) { png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i; - png_unknown_chunkp from = unknowns + i; + png_const_unknown_chunkp from = unknowns + i; - png_memcpy((png_charp)to->name, (png_charp)from->name, - png_sizeof(from->name)); + png_memcpy(to->name, from->name, png_sizeof(from->name)); to->name[png_sizeof(to->name)-1] = '\0'; to->size = from->size; + /* Note our location in the read or write sequence */ to->location = (png_byte)(png_ptr->mode & 0xff); if (from->size == 0) to->data=NULL; + else { to->data = (png_bytep)png_malloc_warn(png_ptr, - (png_size_t)from->size); + (png_size_t)from->size); + if (to->data == NULL) { png_warning(png_ptr, - "Out of memory while processing unknown chunk"); + "Out of memory while processing unknown chunk"); to->size = 0; } + else png_memcpy(to->data, from->data, from->size); } @@ -998,12 +1019,13 @@ png_set_unknown_chunks(png_structp png_ptr, info_ptr->unknown_chunks_num += num_unknowns; info_ptr->free_me |= PNG_FREE_UNKN; } + void PNGAPI png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr, - int chunk, int location) + int chunk, int location) { if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk < - (int)info_ptr->unknown_chunks_num) + info_ptr->unknown_chunks_num) info_ptr->unknown_chunks[chunk].location = (png_byte)location; } #endif @@ -1011,46 +1033,54 @@ png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr, #ifdef PNG_MNG_FEATURES_SUPPORTED png_uint_32 PNGAPI -png_permit_mng_features(png_structp png_ptr, png_uint_32 mng_features) +png_permit_mng_features (png_structp png_ptr, png_uint_32 mng_features) { png_debug(1, "in png_permit_mng_features"); if (png_ptr == NULL) return (png_uint_32)0; + png_ptr->mng_features_permitted = - (png_byte)(mng_features & PNG_ALL_MNG_FEATURES); + (png_byte)(mng_features & PNG_ALL_MNG_FEATURES); + return (png_uint_32)png_ptr->mng_features_permitted; } #endif #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED void PNGAPI -png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_bytep - chunk_list, int num_chunks) +png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_const_bytep + chunk_list, int num_chunks) { png_bytep new_list, p; int i, old_num_chunks; if (png_ptr == NULL) return; + if (num_chunks == 0) { if (keep == PNG_HANDLE_CHUNK_ALWAYS || keep == PNG_HANDLE_CHUNK_IF_SAFE) png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_CHUNKS; + else png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS; if (keep == PNG_HANDLE_CHUNK_ALWAYS) png_ptr->flags |= PNG_FLAG_KEEP_UNSAFE_CHUNKS; + else png_ptr->flags &= ~PNG_FLAG_KEEP_UNSAFE_CHUNKS; + return; } + if (chunk_list == NULL) return; + old_num_chunks = png_ptr->num_chunk_list; new_list=(png_bytep)png_malloc(png_ptr, - (png_size_t) - (5*(num_chunks + old_num_chunks))); + (png_size_t)(5*(num_chunks + old_num_chunks))); + if (png_ptr->chunk_list != NULL) { png_memcpy(new_list, png_ptr->chunk_list, @@ -1058,10 +1088,13 @@ png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_bytep png_free(png_ptr, png_ptr->chunk_list); png_ptr->chunk_list=NULL; } + png_memcpy(new_list + 5*old_num_chunks, chunk_list, (png_size_t)(5*num_chunks)); + for (p = new_list + 5*old_num_chunks + 4, i = 0; inum_chunk_list = old_num_chunks + num_chunks; png_ptr->chunk_list = new_list; png_ptr->free_me |= PNG_FREE_LIST; @@ -1071,7 +1104,7 @@ png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_bytep #ifdef PNG_READ_USER_CHUNKS_SUPPORTED void PNGAPI png_set_read_user_chunk_fn(png_structp png_ptr, png_voidp user_chunk_ptr, - png_user_chunk_ptr read_user_chunk_fn) + png_user_chunk_ptr read_user_chunk_fn) { png_debug(1, "in png_set_read_user_chunk_fn"); @@ -1094,23 +1127,40 @@ png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers) if (info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers)) png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0); + info_ptr->row_pointers = row_pointers; + if (row_pointers) info_ptr->valid |= PNG_INFO_IDAT; } #endif void PNGAPI -png_set_compression_buffer_size(png_structp png_ptr, - png_size_t size) +png_set_compression_buffer_size(png_structp png_ptr, png_size_t size) { if (png_ptr == NULL) return; + png_free(png_ptr, png_ptr->zbuf); - png_ptr->zbuf_size = size; + + if (size > ZLIB_IO_MAX) + { + png_warning(png_ptr, "Attempt to set buffer size beyond max ignored"); + png_ptr->zbuf_size = ZLIB_IO_MAX; + size = ZLIB_IO_MAX; /* must fit */ + } + + else + png_ptr->zbuf_size = (uInt)size; + png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size); + + /* The following ensures a relatively safe failure if this gets called while + * the buffer is actually in use. + */ png_ptr->zstream.next_out = png_ptr->zbuf; - png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; + png_ptr->zstream.avail_out = 0; + png_ptr->zstream.avail_in = 0; } void PNGAPI @@ -1125,7 +1175,7 @@ png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask) #ifdef PNG_SET_USER_LIMITS_SUPPORTED /* This function was added to libpng 1.2.6 */ void PNGAPI -png_set_user_limits(png_structp png_ptr, png_uint_32 user_width_max, +png_set_user_limits (png_structp png_ptr, png_uint_32 user_width_max, png_uint_32 user_height_max) { /* Images with dimensions larger than these limits will be @@ -1134,13 +1184,14 @@ png_set_user_limits(png_structp png_ptr, png_uint_32 user_width_max, */ if (png_ptr == NULL) return; + png_ptr->user_width_max = user_width_max; png_ptr->user_height_max = user_height_max; } /* This function was added to libpng 1.4.0 */ void PNGAPI -png_set_chunk_cache_max(png_structp png_ptr, +png_set_chunk_cache_max (png_structp png_ptr, png_uint_32 user_chunk_cache_max) { if (png_ptr) @@ -1149,12 +1200,11 @@ png_set_chunk_cache_max(png_structp png_ptr, /* This function was added to libpng 1.4.1 */ void PNGAPI -png_set_chunk_malloc_max(png_structp png_ptr, - png_alloc_size_t user_chunk_malloc_max) +png_set_chunk_malloc_max (png_structp png_ptr, + png_alloc_size_t user_chunk_malloc_max) { - if (png_ptr) - png_ptr->user_chunk_malloc_max = - (png_size_t)user_chunk_malloc_max; + if (png_ptr) + png_ptr->user_chunk_malloc_max = user_chunk_malloc_max; } #endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */ @@ -1167,6 +1217,7 @@ png_set_benign_errors(png_structp png_ptr, int allowed) if (allowed) png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN; + else png_ptr->flags &= ~PNG_FLAG_BENIGN_ERRORS_WARN; } diff --git a/harbour/src/3rd/png/pngtrans.c b/harbour/src/3rd/png/pngtrans.c index 741daf45b7..1f4da17e44 100644 --- a/harbour/src/3rd/png/pngtrans.c +++ b/harbour/src/3rd/png/pngtrans.c @@ -1,8 +1,8 @@ /* pngtrans.c - transforms the data in a row (used by both readers and writers) * - * Last changed in libpng 1.4.2 [April 29, 2010] - * Copyright (c) 1998-2010 Glenn Randers-Pehrson + * Last changed in libpng 1.5.0 [January 6, 2011] + * Copyright (c) 1998-2011 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -11,11 +11,10 @@ * and license in png.h */ -#define PNG_NO_PEDANTIC_WARNINGS -#include "png.h" -#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) #include "pngpriv.h" +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) + #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) /* Turn on BGR-to-RGB mapping */ void PNGAPI @@ -25,6 +24,7 @@ png_set_bgr(png_structp png_ptr) if (png_ptr == NULL) return; + png_ptr->transformations |= PNG_BGR; } #endif @@ -38,6 +38,7 @@ png_set_swap(png_structp png_ptr) if (png_ptr == NULL) return; + if (png_ptr->bit_depth == 16) png_ptr->transformations |= PNG_SWAP_BYTES; } @@ -52,6 +53,7 @@ png_set_packing(png_structp png_ptr) if (png_ptr == NULL) return; + if (png_ptr->bit_depth < 8) { png_ptr->transformations |= PNG_PACK; @@ -69,6 +71,7 @@ png_set_packswap(png_structp png_ptr) if (png_ptr == NULL) return; + if (png_ptr->bit_depth < 8) png_ptr->transformations |= PNG_PACKSWAP; } @@ -76,12 +79,13 @@ png_set_packswap(png_structp png_ptr) #if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED) void PNGAPI -png_set_shift(png_structp png_ptr, png_color_8p true_bits) +png_set_shift(png_structp png_ptr, png_const_color_8p true_bits) { png_debug(1, "in png_set_shift"); if (png_ptr == NULL) return; + png_ptr->transformations |= PNG_SHIFT; png_ptr->shift = *true_bits; } @@ -117,10 +121,13 @@ png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc) if (png_ptr == NULL) return; + png_ptr->transformations |= PNG_FILLER; png_ptr->filler = (png_uint_16)filler; + if (filler_loc == PNG_FILLER_AFTER) png_ptr->flags |= PNG_FLAG_FILLER_AFTER; + else png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER; @@ -135,7 +142,7 @@ png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc) } /* Also I added this in libpng-1.0.2a (what happens when we expand - * a less-than-8-bit grayscale to GA? */ + * a less-than-8-bit grayscale to GA?) */ if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8) { @@ -151,6 +158,7 @@ png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc) if (png_ptr == NULL) return; + png_set_filler(png_ptr, filler, filler_loc); png_ptr->transformations |= PNG_ADD_ALPHA; } @@ -166,6 +174,7 @@ png_set_swap_alpha(png_structp png_ptr) if (png_ptr == NULL) return; + png_ptr->transformations |= PNG_SWAP_ALPHA; } #endif @@ -179,6 +188,7 @@ png_set_invert_alpha(png_structp png_ptr) if (png_ptr == NULL) return; + png_ptr->transformations |= PNG_INVERT_ALPHA; } #endif @@ -191,6 +201,7 @@ png_set_invert_mono(png_structp png_ptr) if (png_ptr == NULL) return; + png_ptr->transformations |= PNG_INVERT_MONO; } @@ -206,8 +217,8 @@ png_do_invert(png_row_infop row_info, png_bytep row) if (row_info->color_type == PNG_COLOR_TYPE_GRAY) { png_bytep rp = row; - png_uint_32 i; - png_uint_32 istop = row_info->rowbytes; + png_size_t i; + png_size_t istop = row_info->rowbytes; for (i = 0; i < istop; i++) { @@ -215,36 +226,41 @@ png_do_invert(png_row_infop row_info, png_bytep row) rp++; } } + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && row_info->bit_depth == 8) { png_bytep rp = row; - png_uint_32 i; - png_uint_32 istop = row_info->rowbytes; + png_size_t i; + png_size_t istop = row_info->rowbytes; - for (i = 0; i < istop; i+=2) + for (i = 0; i < istop; i += 2) { *rp = (png_byte)(~(*rp)); - rp+=2; + rp += 2; } } + +#ifdef PNG_16BIT_SUPPORTED else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && row_info->bit_depth == 16) { png_bytep rp = row; - png_uint_32 i; - png_uint_32 istop = row_info->rowbytes; + png_size_t i; + png_size_t istop = row_info->rowbytes; - for (i = 0; i < istop; i+=4) + for (i = 0; i < istop; i += 4) { *rp = (png_byte)(~(*rp)); - *(rp+1) = (png_byte)(~(*(rp+1))); - rp+=4; + *(rp + 1) = (png_byte)(~(*(rp + 1))); + rp += 4; } } +#endif } #endif +#ifdef PNG_16BIT_SUPPORTED #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) /* Swaps byte order on 16 bit depth images */ void /* PRIVATE */ @@ -252,8 +268,7 @@ png_do_swap(png_row_infop row_info, png_bytep row) { png_debug(1, "in png_do_swap"); - if ( - row_info->bit_depth == 16) + if (row_info->bit_depth == 16) { png_bytep rp = row; png_uint_32 i; @@ -268,6 +283,7 @@ png_do_swap(png_row_infop row_info, png_bytep row) } } #endif +#endif #if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED) static PNG_CONST png_byte onebppswaptable[256] = { @@ -381,19 +397,22 @@ png_do_packswap(png_row_infop row_info, png_bytep row) { png_debug(1, "in png_do_packswap"); - if ( - row_info->bit_depth < 8) + if (row_info->bit_depth < 8) { - png_bytep rp, end, table; + png_bytep rp; + png_const_bytep end, table; end = row + row_info->rowbytes; if (row_info->bit_depth == 1) - table = (png_bytep)onebppswaptable; + table = onebppswaptable; + else if (row_info->bit_depth == 2) - table = (png_bytep)twobppswaptable; + table = twobppswaptable; + else if (row_info->bit_depth == 4) - table = (png_bytep)fourbppswaptable; + table = fourbppswaptable; + else return; @@ -412,9 +431,9 @@ png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags) png_debug(1, "in png_do_strip_filler"); { - png_bytep sp=row; - png_bytep dp=row; - png_uint_32 row_width=row_info->width; + png_bytep sp = row; + png_bytep dp = row; + png_uint_32 row_width = row_info->width; png_uint_32 i; if ((row_info->color_type == PNG_COLOR_TYPE_RGB || @@ -427,7 +446,7 @@ png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags) /* This converts from RGBX or RGBA to RGB */ if (flags & PNG_FLAG_FILLER_AFTER) { - dp+=3; sp+=4; + dp += 3; sp += 4; for (i = 1; i < row_width; i++) { *dp++ = *sp++; @@ -436,6 +455,7 @@ png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags) sp++; } } + /* This converts from XRGB or ARGB to RGB */ else { @@ -450,6 +470,7 @@ png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags) row_info->pixel_depth = 24; row_info->rowbytes = row_width * 3; } + else /* if (row_info->bit_depth == 16) */ { if (flags & PNG_FLAG_FILLER_AFTER) @@ -473,6 +494,7 @@ png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags) sp += 2; } } + else { /* This converts from XXRRGGBB or AARRGGBB to RRGGBB */ @@ -484,7 +506,7 @@ png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags) dp += 6; */ - sp+=2; + sp += 2; *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp++; @@ -493,11 +515,13 @@ png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags) *dp++ = *sp++; } } + row_info->pixel_depth = 48; row_info->rowbytes = row_width * 6; } row_info->channels = 3; } + else if ((row_info->color_type == PNG_COLOR_TYPE_GRAY || (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && (flags & PNG_FLAG_STRIP_ALPHA))) && @@ -505,27 +529,30 @@ png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags) { if (row_info->bit_depth == 8) { - /* This converts from GX or GA to G */ if (flags & PNG_FLAG_FILLER_AFTER) { + /* This converts from GX or GA to G */ for (i = 0; i < row_width; i++) { *dp++ = *sp++; sp++; } } - /* This converts from XG or AG to G */ + else { + /* This converts from XG or AG to G */ for (i = 0; i < row_width; i++) { sp++; *dp++ = *sp++; } } + row_info->pixel_depth = 8; row_info->rowbytes = row_width; } + else /* if (row_info->bit_depth == 16) */ { if (flags & PNG_FLAG_FILLER_AFTER) @@ -539,6 +566,7 @@ png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags) sp += 2; } } + else { /* This converts from XXGG or AAGG to GG */ @@ -549,13 +577,16 @@ png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags) *dp++ = *sp++; } } + row_info->pixel_depth = 16; row_info->rowbytes = row_width * 2; } row_info->channels = 1; } + if (flags & PNG_FLAG_STRIP_ALPHA) - row_info->color_type &= ~PNG_COLOR_MASK_ALPHA; + row_info->color_type = (png_byte)(row_info->color_type & + ~PNG_COLOR_MASK_ALPHA); } } #endif @@ -567,8 +598,7 @@ png_do_bgr(png_row_infop row_info, png_bytep row) { png_debug(1, "in png_do_bgr"); - if ( - (row_info->color_type & PNG_COLOR_MASK_COLOR)) + if ((row_info->color_type & PNG_COLOR_MASK_COLOR)) { png_uint_32 row_width = row_info->width; if (row_info->bit_depth == 8) @@ -585,6 +615,7 @@ png_do_bgr(png_row_infop row_info, png_bytep row) *(rp + 2) = save; } } + else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) { png_bytep rp; @@ -598,6 +629,8 @@ png_do_bgr(png_row_infop row_info, png_bytep row) } } } + +#ifdef PNG_16BIT_SUPPORTED else if (row_info->bit_depth == 16) { if (row_info->color_type == PNG_COLOR_TYPE_RGB) @@ -615,6 +648,7 @@ png_do_bgr(png_row_infop row_info, png_bytep row) *(rp + 5) = save; } } + else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) { png_bytep rp; @@ -631,6 +665,7 @@ png_do_bgr(png_row_infop row_info, png_bytep row) } } } +#endif } } #endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */ @@ -666,6 +701,7 @@ png_get_user_transform_ptr(png_structp png_ptr) { if (png_ptr == NULL) return (NULL); + #ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED return ((png_voidp)png_ptr->user_transform_ptr); #else diff --git a/harbour/src/3rd/png/pngwio.c b/harbour/src/3rd/png/pngwio.c index 513a71a062..95ffb3429f 100644 --- a/harbour/src/3rd/png/pngwio.c +++ b/harbour/src/3rd/png/pngwio.c @@ -1,8 +1,8 @@ /* pngwio.c - functions for data output * - * Last changed in libpng 1.4.0 [January 3, 2010] - * Copyright (c) 1998-2010 Glenn Randers-Pehrson + * Last changed in libpng 1.5.0 [January 6, 2011] + * Copyright (c) 1998-2011 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -18,11 +18,10 @@ * them at run time with png_set_write_fn(...). */ -#define PNG_NO_PEDANTIC_WARNINGS -#include "png.h" -#ifdef PNG_WRITE_SUPPORTED #include "pngpriv.h" +#ifdef PNG_WRITE_SUPPORTED + /* Write the data to whatever output you are using. The default routine * writes to a file pointer. Note that this routine sometimes gets called * with very small lengths, so you should implement some kind of simple @@ -31,10 +30,12 @@ */ void /* PRIVATE */ -png_write_data(png_structp png_ptr, png_bytep data, png_size_t length) +png_write_data(png_structp png_ptr, png_const_bytep data, png_size_t length) { + /* NOTE: write_data_fn must not change the buffer! */ if (png_ptr->write_data_fn != NULL ) - (*(png_ptr->write_data_fn))(png_ptr, data, length); + (*(png_ptr->write_data_fn))(png_ptr, (png_bytep)data, length); + else png_error(png_ptr, "Call to NULL write function"); } @@ -46,14 +47,16 @@ png_write_data(png_structp png_ptr, png_bytep data, png_size_t length) * than changing the library. */ #ifndef USE_FAR_KEYWORD -void PNGAPI +void PNGCBAPI png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) { - png_uint_32 check; + png_size_t check; if (png_ptr == NULL) return; + check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr)); + if (check != length) png_error(png_ptr, "Write Error"); } @@ -66,7 +69,7 @@ png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) #define NEAR_BUF_SIZE 1024 #define MIN(a,b) (a <= b ? a : b) -void PNGAPI +void PNGCBAPI png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) { png_uint_32 check; @@ -75,24 +78,29 @@ png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) if (png_ptr == NULL) return; + /* Check if data really is near. If so, use usual code. */ near_data = (png_byte *)CVT_PTR_NOCHECK(data); io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr); + if ((png_bytep)near_data == data) { check = fwrite(near_data, 1, length, io_ptr); } + else { png_byte buf[NEAR_BUF_SIZE]; png_size_t written, remaining, err; check = 0; remaining = length; + do { written = MIN(NEAR_BUF_SIZE, remaining); png_memcpy(buf, data, written); /* Copy far buffer to near buffer */ err = fwrite(buf, 1, written, io_ptr); + if (err != written) break; @@ -104,6 +112,7 @@ png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) } while (remaining != 0); } + if (check != length) png_error(png_ptr, "Write Error"); } @@ -123,17 +132,19 @@ png_flush(png_structp png_ptr) (*(png_ptr->output_flush_fn))(png_ptr); } -#ifdef PNG_STDIO_SUPPORTED -void PNGAPI +# ifdef PNG_STDIO_SUPPORTED +void PNGCBAPI png_default_flush(png_structp png_ptr) { png_FILE_p io_ptr; + if (png_ptr == NULL) return; + io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr)); fflush(io_ptr); } -#endif +# endif #endif /* This function allows the application to supply new output functions for @@ -167,7 +178,7 @@ png_default_flush(png_structp png_ptr) */ void PNGAPI png_set_write_fn(png_structp png_ptr, png_voidp io_ptr, - png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn) + png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn) { if (png_ptr == NULL) return; @@ -185,30 +196,32 @@ png_set_write_fn(png_structp png_ptr, png_voidp io_ptr, #endif #ifdef PNG_WRITE_FLUSH_SUPPORTED -#ifdef PNG_STDIO_SUPPORTED +# ifdef PNG_STDIO_SUPPORTED + if (output_flush_fn != NULL) png_ptr->output_flush_fn = output_flush_fn; else png_ptr->output_flush_fn = png_default_flush; -#else + +# else png_ptr->output_flush_fn = output_flush_fn; -#endif +# endif #endif /* PNG_WRITE_FLUSH_SUPPORTED */ /* It is an error to read while writing a png file */ if (png_ptr->read_data_fn != NULL) { png_ptr->read_data_fn = NULL; + png_warning(png_ptr, - "Attempted to set both read_data_fn and write_data_fn in"); - png_warning(png_ptr, - "the same structure. Resetting read_data_fn to NULL"); + "Can't set both read_data_fn and write_data_fn in the" + " same structure"); } } #ifdef USE_FAR_KEYWORD -#ifdef _MSC_VER +# ifdef _MSC_VER void *png_far_to_near(png_structp png_ptr, png_voidp ptr, int check) { void *near_ptr; @@ -236,6 +249,6 @@ void *png_far_to_near(png_structp png_ptr, png_voidp ptr, int check) return(near_ptr); } -# endif -# endif +# endif +#endif #endif /* PNG_WRITE_SUPPORTED */ diff --git a/harbour/src/3rd/png/pngwrite.c b/harbour/src/3rd/png/pngwrite.c index 0252051989..c3922f09d1 100644 --- a/harbour/src/3rd/png/pngwrite.c +++ b/harbour/src/3rd/png/pngwrite.c @@ -1,8 +1,8 @@ /* pngwrite.c - general routines to write a PNG file * - * Last changed in libpng 1.4.0 [January 3, 2010] - * Copyright (c) 1998-2010 Glenn Randers-Pehrson + * Last changed in libpng 1.5.0 [January 6, 2011] + * Copyright (c) 1998-2011 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -11,12 +11,10 @@ * and license in png.h */ -/* Get internal access to png.h */ -#define PNG_NO_PEDANTIC_WARNINGS -#include "png.h" -#ifdef PNG_WRITE_SUPPORTED #include "pngpriv.h" +#ifdef PNG_WRITE_SUPPORTED + /* Writes all the PNG information. This is the suggested way to use the * library. If you have a new chunk to add, make a function to write it, * and put it in the correct location here. If you want the chunk written @@ -33,50 +31,46 @@ png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr) if (png_ptr == NULL || info_ptr == NULL) return; + if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE)) { /* Write PNG signature */ png_write_sig(png_ptr); + #ifdef PNG_MNG_FEATURES_SUPPORTED if ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) && \ - (png_ptr->mng_features_permitted)) + (png_ptr->mng_features_permitted)) { png_warning(png_ptr, "MNG features are not allowed in a PNG datastream"); png_ptr->mng_features_permitted = 0; } #endif + /* Write IHDR information. */ png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height, - info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type, - info_ptr->filter_type, + info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type, + info_ptr->filter_type, #ifdef PNG_WRITE_INTERLACING_SUPPORTED - info_ptr->interlace_type); + info_ptr->interlace_type); #else - 0); + 0); #endif /* The rest of these check to see if the valid field has the appropriate * flag set, and if it does, writes the chunk. */ #ifdef PNG_WRITE_gAMA_SUPPORTED if (info_ptr->valid & PNG_INFO_gAMA) - { -# ifdef PNG_FLOATING_POINT_SUPPORTED - png_write_gAMA(png_ptr, info_ptr->gamma); -#else -#ifdef PNG_FIXED_POINT_SUPPORTED - png_write_gAMA_fixed(png_ptr, info_ptr->int_gamma); -# endif -#endif - } + png_write_gAMA_fixed(png_ptr, info_ptr->gamma); #endif #ifdef PNG_WRITE_sRGB_SUPPORTED if (info_ptr->valid & PNG_INFO_sRGB) png_write_sRGB(png_ptr, (int)info_ptr->srgb_intent); #endif + #ifdef PNG_WRITE_iCCP_SUPPORTED if (info_ptr->valid & PNG_INFO_iCCP) png_write_iCCP(png_ptr, info_ptr->iccp_name, PNG_COMPRESSION_TYPE_BASE, - info_ptr->iccp_profile, (int)info_ptr->iccp_proflen); + (png_charp)info_ptr->iccp_profile, (int)info_ptr->iccp_proflen); #endif #ifdef PNG_WRITE_sBIT_SUPPORTED if (info_ptr->valid & PNG_INFO_sBIT) @@ -84,24 +78,13 @@ png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr) #endif #ifdef PNG_WRITE_cHRM_SUPPORTED if (info_ptr->valid & PNG_INFO_cHRM) - { -#ifdef PNG_FLOATING_POINT_SUPPORTED - png_write_cHRM(png_ptr, - info_ptr->x_white, info_ptr->y_white, - info_ptr->x_red, info_ptr->y_red, - info_ptr->x_green, info_ptr->y_green, - info_ptr->x_blue, info_ptr->y_blue); -#else -# ifdef PNG_FIXED_POINT_SUPPORTED png_write_cHRM_fixed(png_ptr, - info_ptr->int_x_white, info_ptr->int_y_white, - info_ptr->int_x_red, info_ptr->int_y_red, - info_ptr->int_x_green, info_ptr->int_y_green, - info_ptr->int_x_blue, info_ptr->int_y_blue); -# endif -#endif - } + info_ptr->x_white, info_ptr->y_white, + info_ptr->x_red, info_ptr->y_red, + info_ptr->x_green, info_ptr->y_green, + info_ptr->x_blue, info_ptr->y_blue); #endif + #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED if (info_ptr->unknown_chunks_num) { @@ -114,14 +97,16 @@ png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr) up++) { int keep = png_handle_as_unknown(png_ptr, up->name); + if (keep != PNG_HANDLE_CHUNK_NEVER && - up->location && !(up->location & PNG_HAVE_PLTE) && - !(up->location & PNG_HAVE_IDAT) && - ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || - (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) + up->location && !(up->location & PNG_HAVE_PLTE) && + !(up->location & PNG_HAVE_IDAT) && + ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || + (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) { if (up->size == 0) png_warning(png_ptr, "Writing zero-length unknown chunk"); + png_write_chunk(png_ptr, up->name, up->data, up->size); } } @@ -147,7 +132,8 @@ png_write_info(png_structp png_ptr, png_infop info_ptr) if (info_ptr->valid & PNG_INFO_PLTE) png_write_PLTE(png_ptr, info_ptr->palette, - (png_uint_32)info_ptr->num_palette); + (png_uint_32)info_ptr->num_palette); + else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) png_error(png_ptr, "Valid palette required for paletted images"); @@ -157,59 +143,51 @@ png_write_info(png_structp png_ptr, png_infop info_ptr) #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED /* Invert the alpha channel (in tRNS) */ if ((png_ptr->transformations & PNG_INVERT_ALPHA) && - info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { int j; for (j = 0; j<(int)info_ptr->num_trans; j++) - info_ptr->trans_alpha[j] = (png_byte)(255 - info_ptr->trans_alpha[j]); + info_ptr->trans_alpha[j] = + (png_byte)(255 - info_ptr->trans_alpha[j]); } #endif png_write_tRNS(png_ptr, info_ptr->trans_alpha, &(info_ptr->trans_color), - info_ptr->num_trans, info_ptr->color_type); + info_ptr->num_trans, info_ptr->color_type); } #endif #ifdef PNG_WRITE_bKGD_SUPPORTED if (info_ptr->valid & PNG_INFO_bKGD) png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type); #endif + #ifdef PNG_WRITE_hIST_SUPPORTED if (info_ptr->valid & PNG_INFO_hIST) png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette); #endif + #ifdef PNG_WRITE_oFFs_SUPPORTED if (info_ptr->valid & PNG_INFO_oFFs) png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset, - info_ptr->offset_unit_type); + info_ptr->offset_unit_type); #endif + #ifdef PNG_WRITE_pCAL_SUPPORTED if (info_ptr->valid & PNG_INFO_pCAL) png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0, - info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams, - info_ptr->pcal_units, info_ptr->pcal_params); + info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams, + info_ptr->pcal_units, info_ptr->pcal_params); #endif -#ifdef PNG_sCAL_SUPPORTED - if (info_ptr->valid & PNG_INFO_sCAL) #ifdef PNG_WRITE_sCAL_SUPPORTED -#if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_STDIO_SUPPORTED) - png_write_sCAL(png_ptr, (int)info_ptr->scal_unit, - info_ptr->scal_pixel_width, info_ptr->scal_pixel_height); -#else /* !FLOATING_POINT */ -#ifdef PNG_FIXED_POINT_SUPPORTED + if (info_ptr->valid & PNG_INFO_sCAL) png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit, info_ptr->scal_s_width, info_ptr->scal_s_height); -#endif /* FIXED_POINT */ -#endif /* FLOATING_POINT */ -#else /* !WRITE_sCAL */ - png_warning(png_ptr, - "png_write_sCAL not supported; sCAL chunk not written"); -#endif /* WRITE_sCAL */ #endif /* sCAL */ #ifdef PNG_WRITE_pHYs_SUPPORTED if (info_ptr->valid & PNG_INFO_pHYs) png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit, - info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type); + info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type); #endif /* pHYs */ #ifdef PNG_WRITE_tIME_SUPPORTED @@ -222,8 +200,8 @@ png_write_info(png_structp png_ptr, png_infop info_ptr) #ifdef 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); + for (i = 0; i < (int)info_ptr->splt_palettes_num; i++) + png_write_sPLT(png_ptr, info_ptr->splt_palettes + i); #endif /* sPLT */ #ifdef PNG_WRITE_TEXT_SUPPORTED @@ -231,45 +209,47 @@ png_write_info(png_structp png_ptr, png_infop info_ptr) for (i = 0; i < info_ptr->num_text; i++) { png_debug2(2, "Writing header text chunk %d, type %d", i, - info_ptr->text[i].compression); + info_ptr->text[i].compression); /* An internationalized chunk? */ if (info_ptr->text[i].compression > 0) { #ifdef PNG_WRITE_iTXt_SUPPORTED - /* Write international chunk */ - png_write_iTXt(png_ptr, - info_ptr->text[i].compression, - info_ptr->text[i].key, - info_ptr->text[i].lang, - info_ptr->text[i].lang_key, - info_ptr->text[i].text); + /* Write international chunk */ + png_write_iTXt(png_ptr, + info_ptr->text[i].compression, + info_ptr->text[i].key, + info_ptr->text[i].lang, + info_ptr->text[i].lang_key, + info_ptr->text[i].text); #else png_warning(png_ptr, "Unable to write international text"); #endif /* Mark this chunk as written */ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; } + /* If we want a compressed text chunk */ else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_zTXt) { #ifdef PNG_WRITE_zTXt_SUPPORTED /* Write compressed chunk */ png_write_zTXt(png_ptr, info_ptr->text[i].key, - info_ptr->text[i].text, 0, - info_ptr->text[i].compression); + info_ptr->text[i].text, 0, + info_ptr->text[i].compression); #else png_warning(png_ptr, "Unable to write compressed text"); #endif /* Mark this chunk as written */ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; } + else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) { #ifdef PNG_WRITE_tEXt_SUPPORTED /* Write uncompressed chunk */ png_write_tEXt(png_ptr, info_ptr->text[i].key, - info_ptr->text[i].text, - 0); + info_ptr->text[i].text, + 0); /* Mark this chunk as written */ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; #else @@ -293,10 +273,10 @@ png_write_info(png_structp png_ptr, png_infop info_ptr) { int keep = png_handle_as_unknown(png_ptr, up->name); if (keep != PNG_HANDLE_CHUNK_NEVER && - up->location && (up->location & PNG_HAVE_PLTE) && - !(up->location & PNG_HAVE_IDAT) && - ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || - (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) + up->location && (up->location & PNG_HAVE_PLTE) && + !(up->location & PNG_HAVE_IDAT) && + ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || + (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) { png_write_chunk(png_ptr, up->name, up->data, up->size); } @@ -317,6 +297,7 @@ png_write_end(png_structp png_ptr, png_infop info_ptr) if (png_ptr == NULL) return; + if (!(png_ptr->mode & PNG_HAVE_IDAT)) png_error(png_ptr, "No IDATs written into file"); @@ -329,8 +310,9 @@ png_write_end(png_structp png_ptr, png_infop info_ptr) #ifdef PNG_WRITE_tIME_SUPPORTED /* Check to see if user has supplied a time chunk */ if ((info_ptr->valid & PNG_INFO_tIME) && - !(png_ptr->mode & PNG_WROTE_tIME)) + !(png_ptr->mode & PNG_WROTE_tIME)) png_write_tIME(png_ptr, &(info_ptr->mod_time)); + #endif #ifdef PNG_WRITE_TEXT_SUPPORTED /* Loop through comment chunks */ @@ -344,36 +326,38 @@ png_write_end(png_structp png_ptr, png_infop info_ptr) #ifdef PNG_WRITE_iTXt_SUPPORTED /* Write international chunk */ png_write_iTXt(png_ptr, - info_ptr->text[i].compression, - info_ptr->text[i].key, - info_ptr->text[i].lang, - info_ptr->text[i].lang_key, - info_ptr->text[i].text); + info_ptr->text[i].compression, + info_ptr->text[i].key, + info_ptr->text[i].lang, + info_ptr->text[i].lang_key, + info_ptr->text[i].text); #else png_warning(png_ptr, "Unable to write international text"); #endif /* Mark this chunk as written */ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; } + else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt) { #ifdef PNG_WRITE_zTXt_SUPPORTED /* Write compressed chunk */ png_write_zTXt(png_ptr, info_ptr->text[i].key, - info_ptr->text[i].text, 0, - info_ptr->text[i].compression); + info_ptr->text[i].text, 0, + info_ptr->text[i].compression); #else png_warning(png_ptr, "Unable to write compressed text"); #endif /* Mark this chunk as written */ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR; } + else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) { #ifdef PNG_WRITE_tEXt_SUPPORTED /* Write uncompressed chunk */ png_write_tEXt(png_ptr, info_ptr->text[i].key, - info_ptr->text[i].text, 0); + info_ptr->text[i].text, 0); #else png_warning(png_ptr, "Unable to write uncompressed text"); #endif @@ -396,9 +380,9 @@ png_write_end(png_structp png_ptr, png_infop info_ptr) { int keep = png_handle_as_unknown(png_ptr, up->name); if (keep != PNG_HANDLE_CHUNK_NEVER && - up->location && (up->location & PNG_AFTER_IDAT) && - ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || - (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) + up->location && (up->location & PNG_AFTER_IDAT) && + ((up->name[3] & 0x20) || keep == PNG_HANDLE_CHUNK_ALWAYS || + (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS))) { png_write_chunk(png_ptr, up->name, up->data, up->size); } @@ -428,7 +412,7 @@ png_write_end(png_structp png_ptr, png_infop info_ptr) #ifdef PNG_CONVERT_tIME_SUPPORTED /* "tm" structure is not supported on WindowsCE */ void PNGAPI -png_convert_from_struct_tm(png_timep ptime, struct tm FAR * ttime) +png_convert_from_struct_tm(png_timep ptime, PNG_CONST struct tm FAR * ttime) { png_debug(1, "in png_convert_from_struct_tm"); @@ -453,20 +437,22 @@ png_convert_from_time_t(png_timep ptime, time_t ttime) #endif /* Initialize png_ptr structure, and allocate any memory needed */ -png_structp PNGAPI -png_create_write_struct(png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn) +PNG_FUNCTION(png_structp,PNGAPI +png_create_write_struct,(png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED) { #ifdef PNG_USER_MEM_SUPPORTED return (png_create_write_struct_2(user_png_ver, error_ptr, error_fn, - warn_fn, NULL, NULL, NULL)); + warn_fn, NULL, NULL, NULL)); } /* Alternate initialize png_ptr structure, and allocate any memory needed */ -png_structp PNGAPI -png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, - png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, - png_malloc_ptr malloc_fn, png_free_ptr free_fn) +static void png_reset_filter_heuristics(png_structp png_ptr); /* forward decl */ + +PNG_FUNCTION(png_structp,PNGAPI +png_create_write_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr, + png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr, + png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED) { #endif /* PNG_USER_MEM_SUPPORTED */ volatile int png_cleanup_needed = 0; @@ -476,7 +462,7 @@ png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, png_structp png_ptr; #ifdef PNG_SETJMP_SUPPORTED #ifdef USE_FAR_KEYWORD - jmp_buf jmpbuf; + jmp_buf png_jmpbuf; #endif #endif int i; @@ -485,7 +471,7 @@ png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, #ifdef PNG_USER_MEM_SUPPORTED png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG, - (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr); + (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr); #else png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); #endif /* PNG_USER_MEM_SUPPORTED */ @@ -503,12 +489,12 @@ png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, encounter a png_error() will longjmp here. Since the jmpbuf is then meaningless we abort instead of returning. */ #ifdef USE_FAR_KEYWORD - if (setjmp(jmpbuf)) + if (setjmp(png_jmpbuf)) #else if (setjmp(png_jmpbuf(png_ptr))) /* sets longjmp to match setjmp */ #endif #ifdef USE_FAR_KEYWORD - png_memcpy(png_jmpbuf(png_ptr), jmpbuf, png_sizeof(jmp_buf)); + png_memcpy(png_jmpbuf(png_ptr), png_jmpbuf, png_sizeof(jmp_buf)); #endif PNG_ABORT(); #endif @@ -539,38 +525,40 @@ png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) || (user_png_ver[0] == '0' && user_png_ver[2] < '9')) { -#ifdef PNG_STDIO_SUPPORTED +#ifdef PNG_CONSOLE_IO_SUPPORTED char msg[80]; + if (user_png_ver) { - png_snprintf(msg, 80, - "Application was compiled with png.h from libpng-%.20s", - user_png_ver); - png_warning(png_ptr, msg); - } - png_snprintf(msg, 80, - "Application is running with png.c from libpng-%.20s", - png_libpng_ver); - png_warning(png_ptr, msg); + png_snprintf2(msg, 80, + "Application built with libpng-%.20s" + " but running with %.20s", + user_png_ver, + png_libpng_ver); + png_warning(png_ptr, msg); + } +#else + png_warning(png_ptr, + "Incompatible libpng version in application and library"); #endif #ifdef PNG_ERROR_NUMBERS_SUPPORTED png_ptr->flags = 0; #endif - png_warning(png_ptr, - "Incompatible libpng version in application and library"); png_cleanup_needed = 1; } } /* Initialize zbuf - compression buffer */ png_ptr->zbuf_size = PNG_ZBUF_SIZE; + if (!png_cleanup_needed) { png_ptr->zbuf = (png_bytep)png_malloc_warn(png_ptr, - png_ptr->zbuf_size); + png_ptr->zbuf_size); if (png_ptr->zbuf == NULL) png_cleanup_needed = 1; } + if (png_cleanup_needed) { /* Clean up PNG structure and deallocate any memory. */ @@ -578,7 +566,7 @@ png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, png_ptr->zbuf = NULL; #ifdef PNG_USER_MEM_SUPPORTED png_destroy_struct_2((png_voidp)png_ptr, - (png_free_ptr)free_fn, (png_voidp)mem_ptr); + (png_free_ptr)free_fn, (png_voidp)mem_ptr); #else png_destroy_struct((png_voidp)png_ptr); #endif @@ -588,8 +576,7 @@ png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, png_set_write_fn(png_ptr, NULL, NULL, NULL); #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED - png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_DEFAULT, - 1, NULL, NULL); + png_reset_filter_heuristics(png_ptr); #endif return (png_ptr); @@ -603,7 +590,7 @@ png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, */ void PNGAPI png_write_rows(png_structp png_ptr, png_bytepp row, - png_uint_32 num_rows) + png_uint_32 num_rows) { png_uint_32 i; /* row counter */ png_bytepp rp; /* row pointer */ @@ -656,12 +643,12 @@ png_write_image(png_structp png_ptr, png_bytepp image) /* Called by user to write a row of image data */ void PNGAPI -png_write_row(png_structp png_ptr, png_bytep row) +png_write_row(png_structp png_ptr, png_const_bytep row) { if (png_ptr == NULL) return; - png_debug2(1, "in png_write_row (row %ld, pass %d)", + png_debug2(1, "in png_write_row (row %u, pass %d)", png_ptr->row_number, png_ptr->pass); /* Initialize transformations and other stuff if first time */ @@ -670,13 +657,14 @@ png_write_row(png_structp png_ptr, png_bytep row) /* Make sure we wrote the header info */ if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE)) png_error(png_ptr, - "png_write_info was never called before png_write_row"); + "png_write_info was never called before png_write_row"); /* Check for transforms that have been set but were defined out */ #if !defined(PNG_WRITE_INVERT_SUPPORTED) && defined(PNG_READ_INVERT_SUPPORTED) if (png_ptr->transformations & PNG_INVERT_MONO) png_warning(png_ptr, "PNG_WRITE_INVERT_SUPPORTED is not defined"); #endif + #if !defined(PNG_WRITE_FILLER_SUPPORTED) && defined(PNG_READ_FILLER_SUPPORTED) if (png_ptr->transformations & PNG_FILLER) png_warning(png_ptr, "PNG_WRITE_FILLER_SUPPORTED is not defined"); @@ -687,18 +675,22 @@ png_write_row(png_structp png_ptr, png_bytep row) png_warning(png_ptr, "PNG_WRITE_PACKSWAP_SUPPORTED is not defined"); #endif + #if !defined(PNG_WRITE_PACK_SUPPORTED) && defined(PNG_READ_PACK_SUPPORTED) if (png_ptr->transformations & PNG_PACK) png_warning(png_ptr, "PNG_WRITE_PACK_SUPPORTED is not defined"); #endif + #if !defined(PNG_WRITE_SHIFT_SUPPORTED) && defined(PNG_READ_SHIFT_SUPPORTED) if (png_ptr->transformations & PNG_SHIFT) png_warning(png_ptr, "PNG_WRITE_SHIFT_SUPPORTED is not defined"); #endif + #if !defined(PNG_WRITE_BGR_SUPPORTED) && defined(PNG_READ_BGR_SUPPORTED) if (png_ptr->transformations & PNG_BGR) png_warning(png_ptr, "PNG_WRITE_BGR_SUPPORTED is not defined"); #endif + #if !defined(PNG_WRITE_SWAP_SUPPORTED) && defined(PNG_READ_SWAP_SUPPORTED) if (png_ptr->transformations & PNG_SWAP_BYTES) png_warning(png_ptr, "PNG_WRITE_SWAP_SUPPORTED is not defined"); @@ -720,6 +712,7 @@ png_write_row(png_structp png_ptr, png_bytep row) return; } break; + case 1: if ((png_ptr->row_number & 0x07) || png_ptr->width < 5) { @@ -727,6 +720,7 @@ png_write_row(png_structp png_ptr, png_bytep row) return; } break; + case 2: if ((png_ptr->row_number & 0x07) != 4) { @@ -734,6 +728,7 @@ png_write_row(png_structp png_ptr, png_bytep row) return; } break; + case 3: if ((png_ptr->row_number & 0x03) || png_ptr->width < 3) { @@ -741,6 +736,7 @@ png_write_row(png_structp png_ptr, png_bytep row) return; } break; + case 4: if ((png_ptr->row_number & 0x03) != 2) { @@ -748,6 +744,7 @@ png_write_row(png_structp png_ptr, png_bytep row) return; } break; + case 5: if ((png_ptr->row_number & 0x01) || png_ptr->width < 2) { @@ -755,6 +752,7 @@ png_write_row(png_structp png_ptr, png_bytep row) return; } break; + case 6: if (!(png_ptr->row_number & 0x01)) { @@ -762,6 +760,9 @@ png_write_row(png_structp png_ptr, png_bytep row) return; } break; + + default: /* error: ignore it */ + break; } } #endif @@ -778,11 +779,11 @@ png_write_row(png_structp png_ptr, png_bytep row) png_ptr->row_info.width); png_debug1(3, "row_info->color_type = %d", png_ptr->row_info.color_type); - png_debug1(3, "row_info->width = %lu", png_ptr->row_info.width); + png_debug1(3, "row_info->width = %u", png_ptr->row_info.width); png_debug1(3, "row_info->channels = %d", png_ptr->row_info.channels); png_debug1(3, "row_info->bit_depth = %d", png_ptr->row_info.bit_depth); png_debug1(3, "row_info->pixel_depth = %d", png_ptr->row_info.pixel_depth); - png_debug1(3, "row_info->rowbytes = %lu", png_ptr->row_info.rowbytes); + png_debug1(3, "row_info->rowbytes = %u", png_ptr->row_info.rowbytes); /* Copy user's row into buffer, leaving room for filter byte. */ png_memcpy(png_ptr->row_buf + 1, row, png_ptr->row_info.rowbytes); @@ -790,10 +791,10 @@ png_write_row(png_structp png_ptr, png_bytep row) #ifdef PNG_WRITE_INTERLACING_SUPPORTED /* Handle interlacing */ if (png_ptr->interlaced && png_ptr->pass < 6 && - (png_ptr->transformations & PNG_INTERLACE)) + (png_ptr->transformations & PNG_INTERLACE)) { png_do_write_interlace(&(png_ptr->row_info), - png_ptr->row_buf + 1, png_ptr->pass); + png_ptr->row_buf + 1, png_ptr->pass); /* This should always get caught above, but still ... */ if (!(png_ptr->row_info.width)) { @@ -818,7 +819,7 @@ png_write_row(png_structp png_ptr, png_bytep row) * 5. The color_type is RGB or RGBA */ if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && - (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) + (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) { /* Intrapixel differencing */ png_do_write_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1); @@ -841,6 +842,7 @@ png_set_flush(png_structp png_ptr, int nrows) if (png_ptr == NULL) return; + png_ptr->flush_dist = (nrows < 0 ? 0 : nrows); } @@ -854,6 +856,7 @@ png_write_flush(png_structp png_ptr) if (png_ptr == NULL) return; + /* We have already written out all of the data */ if (png_ptr->row_number >= png_ptr->num_rows) return; @@ -871,6 +874,7 @@ png_write_flush(png_structp png_ptr) { if (png_ptr->zstream.msg != NULL) png_error(png_ptr, png_ptr->zstream.msg); + else png_error(png_ptr, "zlib error"); } @@ -878,20 +882,19 @@ png_write_flush(png_structp png_ptr) if (!(png_ptr->zstream.avail_out)) { /* Write the IDAT and reset the zlib output buffer */ - png_write_IDAT(png_ptr, png_ptr->zbuf, - png_ptr->zbuf_size); + png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); png_ptr->zstream.next_out = png_ptr->zbuf; png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; wrote_IDAT = 1; } - } while(wrote_IDAT == 1); + } while (wrote_IDAT == 1); /* If there is any data left to be output, write it into a new IDAT */ if (png_ptr->zbuf_size != png_ptr->zstream.avail_out) { /* Write the IDAT and reset the zlib output buffer */ png_write_IDAT(png_ptr, png_ptr->zbuf, - png_ptr->zbuf_size - png_ptr->zstream.avail_out); + png_ptr->zbuf_size - png_ptr->zstream.avail_out); png_ptr->zstream.next_out = png_ptr->zbuf; png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; } @@ -937,20 +940,20 @@ png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr) { if (png_ptr != NULL) { - png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); + png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - if (png_ptr->num_chunk_list) - { - png_free(png_ptr, png_ptr->chunk_list); - png_ptr->num_chunk_list = 0; - } + if (png_ptr->num_chunk_list) + { + png_free(png_ptr, png_ptr->chunk_list); + png_ptr->num_chunk_list = 0; + } #endif } #ifdef PNG_USER_MEM_SUPPORTED png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn, - (png_voidp)mem_ptr); + (png_voidp)mem_ptr); #else png_destroy_struct((png_voidp)info_ptr); #endif @@ -962,7 +965,7 @@ png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr) png_write_destroy(png_ptr); #ifdef PNG_USER_MEM_SUPPORTED png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn, - (png_voidp)mem_ptr); + (png_voidp)mem_ptr); #else png_destroy_struct((png_voidp)png_ptr); #endif @@ -1006,16 +1009,15 @@ png_write_destroy(png_structp png_ptr) #endif #ifdef 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); + /* Use this to save a little code space, it doesn't free the filter_costs */ + png_reset_filter_heuristics(png_ptr); png_free(png_ptr, png_ptr->filter_costs); png_free(png_ptr, png_ptr->inv_filter_costs); #endif #ifdef PNG_SETJMP_SUPPORTED /* Reset structure */ - png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof(jmp_buf)); + png_memcpy(tmp_jmp, png_ptr->png_jmpbuf, png_sizeof(jmp_buf)); #endif error_fn = png_ptr->error_fn; @@ -1035,7 +1037,7 @@ png_write_destroy(png_structp png_ptr) #endif #ifdef PNG_SETJMP_SUPPORTED - png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof(jmp_buf)); + png_memcpy(png_ptr->png_jmpbuf, tmp_jmp, png_sizeof(jmp_buf)); #endif } @@ -1047,10 +1049,12 @@ png_set_filter(png_structp png_ptr, int method, int filters) if (png_ptr == NULL) return; + #ifdef PNG_MNG_FEATURES_SUPPORTED if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && - (method == PNG_INTRAPIXEL_DIFFERENCING)) - method = PNG_FILTER_TYPE_BASE; + (method == PNG_INTRAPIXEL_DIFFERENCING)) + method = PNG_FILTER_TYPE_BASE; + #endif if (method == PNG_FILTER_TYPE_BASE) { @@ -1062,19 +1066,26 @@ png_set_filter(png_structp png_ptr, int method, int filters) case 7: png_warning(png_ptr, "Unknown row filter for method 0"); #endif /* PNG_WRITE_FILTER_SUPPORTED */ case PNG_FILTER_VALUE_NONE: - png_ptr->do_filter = PNG_FILTER_NONE; break; + png_ptr->do_filter = PNG_FILTER_NONE; break; + #ifdef PNG_WRITE_FILTER_SUPPORTED case PNG_FILTER_VALUE_SUB: - png_ptr->do_filter = PNG_FILTER_SUB; break; + png_ptr->do_filter = PNG_FILTER_SUB; break; + case PNG_FILTER_VALUE_UP: - png_ptr->do_filter = PNG_FILTER_UP; break; + png_ptr->do_filter = PNG_FILTER_UP; break; + case PNG_FILTER_VALUE_AVG: - png_ptr->do_filter = PNG_FILTER_AVG; break; + png_ptr->do_filter = PNG_FILTER_AVG; break; + case PNG_FILTER_VALUE_PAETH: - png_ptr->do_filter = PNG_FILTER_PAETH; break; - default: png_ptr->do_filter = (png_byte)filters; break; + png_ptr->do_filter = PNG_FILTER_PAETH; break; + + default: + png_ptr->do_filter = (png_byte)filters; break; #else - default: png_warning(png_ptr, "Unknown row filter for method 0"); + default: + png_warning(png_ptr, "Unknown row filter for method 0"); #endif /* PNG_WRITE_FILTER_SUPPORTED */ } @@ -1093,7 +1104,7 @@ png_set_filter(png_structp png_ptr, int method, int filters) if ((png_ptr->do_filter & PNG_FILTER_SUB) && png_ptr->sub_row == NULL) { png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, - (png_ptr->rowbytes + 1)); + (png_ptr->rowbytes + 1)); png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB; } @@ -1102,12 +1113,14 @@ png_set_filter(png_structp png_ptr, int method, int filters) if (png_ptr->prev_row == NULL) { png_warning(png_ptr, "Can't add Up filter after starting"); - png_ptr->do_filter &= ~PNG_FILTER_UP; + png_ptr->do_filter = (png_byte)(png_ptr->do_filter & + ~PNG_FILTER_UP); } + else { png_ptr->up_row = (png_bytep)png_malloc(png_ptr, - (png_ptr->rowbytes + 1)); + (png_ptr->rowbytes + 1)); png_ptr->up_row[0] = PNG_FILTER_VALUE_UP; } } @@ -1117,12 +1130,14 @@ png_set_filter(png_structp png_ptr, int method, int filters) if (png_ptr->prev_row == NULL) { png_warning(png_ptr, "Can't add Average filter after starting"); - png_ptr->do_filter &= ~PNG_FILTER_AVG; + png_ptr->do_filter = (png_byte)(png_ptr->do_filter & + ~PNG_FILTER_AVG); } + else { png_ptr->avg_row = (png_bytep)png_malloc(png_ptr, - (png_ptr->rowbytes + 1)); + (png_ptr->rowbytes + 1)); png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG; } } @@ -1135,10 +1150,11 @@ png_set_filter(png_structp png_ptr, int method, int filters) png_warning(png_ptr, "Can't add Paeth filter after starting"); png_ptr->do_filter &= (png_byte)(~PNG_FILTER_PAETH); } + else { png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr, - (png_ptr->rowbytes + 1)); + (png_ptr->rowbytes + 1)); png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH; } } @@ -1160,123 +1176,242 @@ png_set_filter(png_structp png_ptr, int method, int filters) * better compression. */ #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* GRR 970116 */ -void PNGAPI -png_set_filter_heuristics(png_structp png_ptr, int heuristic_method, - int num_weights, png_doublep filter_weights, - png_doublep filter_costs) +/* Conveneince reset API. */ +static void +png_reset_filter_heuristics(png_structp png_ptr) { - int i; + /* Clear out any old values in the 'weights' - this must be done because if + * the app calls set_filter_heuristics multiple times with different + * 'num_weights' values we would otherwise potentially have wrong sized + * arrays. + */ + png_ptr->num_prev_filters = 0; + png_ptr->heuristic_method = PNG_FILTER_HEURISTIC_UNWEIGHTED; + if (png_ptr->prev_filters != NULL) + { + png_bytep old = png_ptr->prev_filters; + png_ptr->prev_filters = NULL; + png_free(png_ptr, old); + } + if (png_ptr->filter_weights != NULL) + { + png_uint_16p old = png_ptr->filter_weights; + png_ptr->filter_weights = NULL; + png_free(png_ptr, old); + } - png_debug(1, "in png_set_filter_heuristics"); + if (png_ptr->inv_filter_weights != NULL) + { + png_uint_16p old = png_ptr->inv_filter_weights; + png_ptr->inv_filter_weights = NULL; + png_free(png_ptr, old); + } + /* Leave the filter_costs - this array is fixed size. */ +} + +static int +png_init_filter_heuristics(png_structp png_ptr, int heuristic_method, + int num_weights) +{ if (png_ptr == NULL) - return; - if (heuristic_method >= PNG_FILTER_HEURISTIC_LAST) - { - png_warning(png_ptr, "Unknown filter heuristic method"); - return; - } + return 0; - if (heuristic_method == PNG_FILTER_HEURISTIC_DEFAULT) - { - heuristic_method = PNG_FILTER_HEURISTIC_UNWEIGHTED; - } + /* Clear out the arrays */ + png_reset_filter_heuristics(png_ptr); - if (num_weights < 0 || filter_weights == NULL || - heuristic_method == PNG_FILTER_HEURISTIC_UNWEIGHTED) + /* Check arguments; the 'reset' function makes the correct settings for the + * unweighted case, but we must handle the weight case by initializing the + * arrays for the caller. + */ + if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) { - num_weights = 0; - } + int i; - png_ptr->num_prev_filters = (png_byte)num_weights; - png_ptr->heuristic_method = (png_byte)heuristic_method; - - if (num_weights > 0) - { - if (png_ptr->prev_filters == NULL) + if (num_weights > 0) { png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr, - (png_uint_32)(png_sizeof(png_byte) * num_weights)); + (png_uint_32)(png_sizeof(png_byte) * num_weights)); /* To make sure that the weighting starts out fairly */ for (i = 0; i < num_weights; i++) { png_ptr->prev_filters[i] = 255; } - } - if (png_ptr->filter_weights == NULL) - { png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr, - (png_uint_32)(png_sizeof(png_uint_16) * num_weights)); + (png_uint_32)(png_sizeof(png_uint_16) * num_weights)); png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr, - (png_uint_32)(png_sizeof(png_uint_16) * num_weights)); + (png_uint_32)(png_sizeof(png_uint_16) * num_weights)); + for (i = 0; i < num_weights; i++) { png_ptr->inv_filter_weights[i] = png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR; } + + /* Safe to set this now */ + png_ptr->num_prev_filters = (png_byte)num_weights; } - for (i = 0; i < num_weights; i++) + /* If, in the future, there are other filter methods, this would + * need to be based on png_ptr->filter. + */ + if (png_ptr->filter_costs == NULL) { - if (filter_weights[i] < 0.0) - { - png_ptr->inv_filter_weights[i] = - png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR; - } - else - { - png_ptr->inv_filter_weights[i] = - (png_uint_16)((double)PNG_WEIGHT_FACTOR*filter_weights[i]+0.5); - png_ptr->filter_weights[i] = - (png_uint_16)((double)PNG_WEIGHT_FACTOR/filter_weights[i]+0.5); - } + png_ptr->filter_costs = (png_uint_16p)png_malloc(png_ptr, + (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST)); + + png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr, + (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST)); } - } - - /* If, in the future, there are other filter methods, this would - * need to be based on png_ptr->filter. - */ - if (png_ptr->filter_costs == NULL) - { - png_ptr->filter_costs = (png_uint_16p)png_malloc(png_ptr, - (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST)); - - png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr, - (png_uint_32)(png_sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST)); for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) { png_ptr->inv_filter_costs[i] = png_ptr->filter_costs[i] = PNG_COST_FACTOR; } - } - /* Here is where we set the relative costs of the different filters. We - * should take the desired compression level into account when setting - * the costs, so that Paeth, for instance, has a high relative cost at low - * compression levels, while it has a lower relative cost at higher - * compression settings. The filter types are in order of increasing - * relative cost, so it would be possible to do this with an algorithm. - */ - for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) + /* All the arrays are inited, safe to set this: */ + png_ptr->heuristic_method = PNG_FILTER_HEURISTIC_WEIGHTED; + + /* Return the 'ok' code. */ + return 1; + } + else if (heuristic_method == PNG_FILTER_HEURISTIC_DEFAULT || + heuristic_method == PNG_FILTER_HEURISTIC_UNWEIGHTED) { - if (filter_costs == NULL || filter_costs[i] < 0.0) + return 1; + } + else + { + png_warning(png_ptr, "Unknown filter heuristic method"); + return 0; + } +} + +/* Provide floating and fixed point APIs */ +#ifdef PNG_FLOATING_POINT_SUPPORTED +void PNGAPI +png_set_filter_heuristics(png_structp png_ptr, int heuristic_method, + int num_weights, png_const_doublep filter_weights, + png_const_doublep filter_costs) +{ + png_debug(1, "in png_set_filter_heuristics"); + + /* The internal API allocates all the arrays and ensures that the elements of + * those arrays are set to the default value. + */ + if (!png_init_filter_heuristics(png_ptr, heuristic_method, num_weights)) + return; + + /* If using the weighted method copy in the weights. */ + if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + int i; + for (i = 0; i < num_weights; i++) { - png_ptr->inv_filter_costs[i] = - png_ptr->filter_costs[i] = PNG_COST_FACTOR; + if (filter_weights[i] <= 0.0) + { + png_ptr->inv_filter_weights[i] = + png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR; + } + + else + { + png_ptr->inv_filter_weights[i] = + (png_uint_16)(PNG_WEIGHT_FACTOR*filter_weights[i]+.5); + + png_ptr->filter_weights[i] = + (png_uint_16)(PNG_WEIGHT_FACTOR/filter_weights[i]+.5); + } } - else if (filter_costs[i] >= 1.0) + + /* Here is where we set the relative costs of the different filters. We + * should take the desired compression level into account when setting + * the costs, so that Paeth, for instance, has a high relative cost at low + * compression levels, while it has a lower relative cost at higher + * compression settings. The filter types are in order of increasing + * relative cost, so it would be possible to do this with an algorithm. + */ + for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) if (filter_costs[i] >= 1.0) { png_ptr->inv_filter_costs[i] = - (png_uint_16)((double)PNG_COST_FACTOR / filter_costs[i] + 0.5); + (png_uint_16)(PNG_COST_FACTOR / filter_costs[i] + .5); + png_ptr->filter_costs[i] = - (png_uint_16)((double)PNG_COST_FACTOR * filter_costs[i] + 0.5); + (png_uint_16)(PNG_COST_FACTOR * filter_costs[i] + .5); } } } +#endif /* FLOATING_POINT */ + +#ifdef PNG_FIXED_POINT_SUPPORTED +void PNGAPI +png_set_filter_heuristics_fixed(png_structp png_ptr, int heuristic_method, + int num_weights, png_const_fixed_point_p filter_weights, + png_const_fixed_point_p filter_costs) +{ + png_debug(1, "in png_set_filter_heuristics_fixed"); + + /* The internal API allocates all the arrays and ensures that the elements of + * those arrays are set to the default value. + */ + if (!png_init_filter_heuristics(png_ptr, heuristic_method, num_weights)) + return; + + /* If using the weighted method copy in the weights. */ + if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED) + { + int i; + for (i = 0; i < num_weights; i++) + { + if (filter_weights[i] <= 0) + { + png_ptr->inv_filter_weights[i] = + png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR; + } + + else + { + png_ptr->inv_filter_weights[i] = (png_uint_16) + ((PNG_WEIGHT_FACTOR*filter_weights[i]+PNG_FP_HALF)/PNG_FP_1); + + png_ptr->filter_weights[i] = (png_uint_16)((PNG_WEIGHT_FACTOR* + PNG_FP_1+(filter_weights[i]/2))/filter_weights[i]); + } + } + + /* Here is where we set the relative costs of the different filters. We + * should take the desired compression level into account when setting + * the costs, so that Paeth, for instance, has a high relative cost at low + * compression levels, while it has a lower relative cost at higher + * compression settings. The filter types are in order of increasing + * relative cost, so it would be possible to do this with an algorithm. + */ + for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) + if (filter_costs[i] >= PNG_FP_1) + { + png_uint_32 tmp; + + /* Use a 32 bit unsigned temporary here because otherwise the + * intermediate value will be a 32 bit *signed* integer (ANSI rules) + * and this will get the wrong answer on division. + */ + tmp = PNG_COST_FACTOR*PNG_FP_1 + (filter_costs[i]/2); + tmp /= filter_costs[i]; + + png_ptr->inv_filter_costs[i] = (png_uint_16)tmp; + + tmp = PNG_COST_FACTOR * filter_costs[i] + PNG_FP_HALF; + tmp /= PNG_FP_1; + + png_ptr->filter_costs[i] = (png_uint_16)tmp; + } + } +} +#endif /* FIXED_POINT */ #endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */ void PNGAPI @@ -1286,6 +1421,7 @@ png_set_compression_level(png_structp png_ptr, int level) if (png_ptr == NULL) return; + png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_LEVEL; png_ptr->zlib_level = level; } @@ -1297,6 +1433,7 @@ png_set_compression_mem_level(png_structp png_ptr, int mem_level) if (png_ptr == NULL) return; + png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL; png_ptr->zlib_mem_level = mem_level; } @@ -1308,6 +1445,7 @@ png_set_compression_strategy(png_structp png_ptr, int strategy) if (png_ptr == NULL) return; + png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY; png_ptr->zlib_strategy = strategy; } @@ -1317,17 +1455,21 @@ png_set_compression_window_bits(png_structp png_ptr, int window_bits) { if (png_ptr == NULL) return; + if (window_bits > 15) png_warning(png_ptr, "Only compression windows <= 32k supported by PNG"); + else if (window_bits < 8) png_warning(png_ptr, "Only compression windows >= 256 supported by PNG"); + #ifndef WBITS_8_OK /* Avoid libpng bug with 256-byte windows */ if (window_bits == 8) - { - png_warning(png_ptr, "Compression window is being reset to 512"); - window_bits = 9; - } + { + png_warning(png_ptr, "Compression window is being reset to 512"); + window_bits = 9; + } + #endif png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS; png_ptr->zlib_window_bits = window_bits; @@ -1340,8 +1482,10 @@ png_set_compression_method(png_structp png_ptr, int method) if (png_ptr == NULL) return; + if (method != 8) png_warning(png_ptr, "Only compression method 8 is supported by PNG"); + png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_METHOD; png_ptr->zlib_method = method; } @@ -1351,18 +1495,20 @@ png_set_write_status_fn(png_structp png_ptr, png_write_status_ptr write_row_fn) { if (png_ptr == NULL) return; + png_ptr->write_row_fn = write_row_fn; } #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED void PNGAPI png_set_write_user_transform_fn(png_structp png_ptr, png_user_transform_ptr - write_user_transform_fn) + write_user_transform_fn) { png_debug(1, "in png_set_write_user_transform_fn"); if (png_ptr == NULL) return; + png_ptr->transformations |= PNG_USER_TRANSFORM; png_ptr->write_user_transform_fn = write_user_transform_fn; } @@ -1372,7 +1518,7 @@ png_set_write_user_transform_fn(png_structp png_ptr, png_user_transform_ptr #ifdef PNG_INFO_IMAGE_SUPPORTED void PNGAPI png_write_png(png_structp png_ptr, png_infop info_ptr, - int transforms, voidp params) + int transforms, voidp params) { if (png_ptr == NULL || info_ptr == NULL) return; @@ -1393,7 +1539,7 @@ png_write_png(png_structp png_ptr, png_infop info_ptr, * as appropriate to correctly scale the image. */ if ((transforms & PNG_TRANSFORM_SHIFT) - && (info_ptr->valid & PNG_INFO_sBIT)) + && (info_ptr->valid & PNG_INFO_sBIT)) png_set_shift(png_ptr, &info_ptr->sig_bit); #endif @@ -1413,6 +1559,7 @@ png_write_png(png_structp png_ptr, png_infop info_ptr, /* Pack XRGB/RGBX/ARGB/RGBA into * RGB (4 channels -> 3 channels) */ if (transforms & PNG_TRANSFORM_STRIP_FILLER_AFTER) png_set_filler(png_ptr, 0, PNG_FILLER_AFTER); + else if (transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE) png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); #endif @@ -1450,8 +1597,8 @@ png_write_png(png_structp png_ptr, png_infop info_ptr, /* It is REQUIRED to call this to finish writing the rest of the file */ png_write_end(png_ptr, info_ptr); - transforms = transforms; /* Quiet compiler warnings */ - params = params; + PNG_UNUSED(transforms) /* Quiet compiler warnings */ + PNG_UNUSED(params) } #endif #endif /* PNG_WRITE_SUPPORTED */ diff --git a/harbour/src/3rd/png/pngwtran.c b/harbour/src/3rd/png/pngwtran.c index 2925a93377..115ca37212 100644 --- a/harbour/src/3rd/png/pngwtran.c +++ b/harbour/src/3rd/png/pngwtran.c @@ -1,8 +1,8 @@ /* pngwtran.c - transforms the data in a row for PNG writers * - * Last changed in libpng 1.4.1 [February 25, 2010] - * Copyright (c) 1998-2010 Glenn Randers-Pehrson + * Last changed in libpng 1.5.0 [January 6, 2011] + * Copyright (c) 1998-2011 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -11,11 +11,10 @@ * and license in png.h */ -#define PNG_NO_PEDANTIC_WARNINGS -#include "png.h" -#ifdef PNG_WRITE_SUPPORTED #include "pngpriv.h" +#ifdef PNG_WRITE_SUPPORTED + /* Transform the data according to the user's wishes. The order of * transformations is significant. */ @@ -30,53 +29,62 @@ png_do_write_transformations(png_structp png_ptr) #ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED if (png_ptr->transformations & PNG_USER_TRANSFORM) if (png_ptr->write_user_transform_fn != NULL) - (*(png_ptr->write_user_transform_fn)) /* User write transform + (*(png_ptr->write_user_transform_fn)) /* User write transform function */ - (png_ptr, /* png_ptr */ - &(png_ptr->row_info), /* row_info: */ - /* png_uint_32 width; width of row */ - /* png_uint_32 rowbytes; number of bytes in row */ - /* png_byte color_type; color type of pixels */ - /* png_byte bit_depth; bit depth of samples */ - /* png_byte channels; number of channels (1-4) */ - /* png_byte pixel_depth; bits per pixel (depth*channels) */ - png_ptr->row_buf + 1); /* start of pixel data for row */ + (png_ptr, /* png_ptr */ + &(png_ptr->row_info), /* row_info: */ + /* png_uint_32 width; width of row */ + /* png_size_t rowbytes; number of bytes in row */ + /* png_byte color_type; color type of pixels */ + /* png_byte bit_depth; bit depth of samples */ + /* png_byte channels; number of channels (1-4) */ + /* png_byte pixel_depth; bits per pixel (depth*channels) */ + png_ptr->row_buf + 1); /* start of pixel data for row */ #endif + #ifdef PNG_WRITE_FILLER_SUPPORTED if (png_ptr->transformations & PNG_FILLER) png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1, - png_ptr->flags); + png_ptr->flags); #endif + #ifdef PNG_WRITE_PACKSWAP_SUPPORTED if (png_ptr->transformations & PNG_PACKSWAP) png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1); #endif + #ifdef PNG_WRITE_PACK_SUPPORTED if (png_ptr->transformations & PNG_PACK) png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1, - (png_uint_32)png_ptr->bit_depth); + (png_uint_32)png_ptr->bit_depth); #endif + #ifdef PNG_WRITE_SWAP_SUPPORTED if (png_ptr->transformations & PNG_SWAP_BYTES) png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1); #endif + #ifdef PNG_WRITE_SHIFT_SUPPORTED if (png_ptr->transformations & PNG_SHIFT) png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1, - &(png_ptr->shift)); + &(png_ptr->shift)); #endif + #ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED if (png_ptr->transformations & PNG_SWAP_ALPHA) png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); #endif + #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED if (png_ptr->transformations & PNG_INVERT_ALPHA) png_do_write_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1); #endif + #ifdef PNG_WRITE_BGR_SUPPORTED if (png_ptr->transformations & PNG_BGR) png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1); #endif + #ifdef PNG_WRITE_INVERT_SUPPORTED if (png_ptr->transformations & PNG_INVERT_MONO) png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1); @@ -114,9 +122,12 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth) { if (*sp != 0) v |= mask; + sp++; + if (mask > 1) mask >>= 1; + else { mask = 0x80; @@ -125,10 +136,13 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth) v = 0; } } + if (mask != 0x80) *dp = (png_byte)v; + break; } + case 2: { png_bytep sp, dp; @@ -140,12 +154,14 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth) dp = row; shift = 6; v = 0; + for (i = 0; i < row_width; i++) { png_byte value; value = (png_byte)(*sp & 0x03); v |= (value << shift); + if (shift == 0) { shift = 6; @@ -153,14 +169,19 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth) dp++; v = 0; } + else shift -= 2; + sp++; } + if (shift != 6) *dp = (png_byte)v; + break; } + case 4: { png_bytep sp, dp; @@ -172,6 +193,7 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth) dp = row; shift = 4; v = 0; + for (i = 0; i < row_width; i++) { png_byte value; @@ -186,23 +208,27 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth) dp++; v = 0; } + else shift -= 4; sp++; } + if (shift != 4) *dp = (png_byte)v; + break; } default: break; } + row_info->bit_depth = (png_byte)bit_depth; row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels); row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, - row_info->width); + row_info->width); } } #endif @@ -216,12 +242,12 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth) * data to 0 to 15. */ void /* PRIVATE */ -png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth) +png_do_shift(png_row_infop row_info, png_bytep row, + png_const_color_8p bit_depth) { png_debug(1, "in png_do_shift"); - if ( - row_info->color_type != PNG_COLOR_TYPE_PALETTE) + if (row_info->color_type != PNG_COLOR_TYPE_PALETTE) { int shift_start[4], shift_dec[4]; int channels = 0; @@ -231,19 +257,23 @@ png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth) shift_start[channels] = row_info->bit_depth - bit_depth->red; shift_dec[channels] = bit_depth->red; channels++; + shift_start[channels] = row_info->bit_depth - bit_depth->green; shift_dec[channels] = bit_depth->green; channels++; + shift_start[channels] = row_info->bit_depth - bit_depth->blue; shift_dec[channels] = bit_depth->blue; channels++; } + else { shift_start[channels] = row_info->bit_depth - bit_depth->gray; shift_dec[channels] = bit_depth->gray; channels++; } + if (row_info->color_type & PNG_COLOR_MASK_ALPHA) { shift_start[channels] = row_info->bit_depth - bit_depth->alpha; @@ -255,14 +285,16 @@ png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth) if (row_info->bit_depth < 8) { png_bytep bp = row; - png_uint_32 i; + png_size_t i; png_byte mask; - png_uint_32 row_bytes = row_info->rowbytes; + png_size_t row_bytes = row_info->rowbytes; if (bit_depth->gray == 1 && row_info->bit_depth == 2) mask = 0x55; + else if (row_info->bit_depth == 4 && bit_depth->gray == 3) mask = 0x11; + else mask = 0xff; @@ -273,15 +305,18 @@ png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth) v = *bp; *bp = 0; + for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0]) { if (j > 0) *bp |= (png_byte)((v << j) & 0xff); + else *bp |= (png_byte)((v >> (-j)) & mask); } } } + else if (row_info->bit_depth == 8) { png_bytep bp = row; @@ -297,15 +332,18 @@ png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth) v = *bp; *bp = 0; + for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) { if (j > 0) *bp |= (png_byte)((v << j) & 0xff); + else *bp |= (png_byte)((v >> (-j)) & 0xff); } } } + else { png_bytep bp; @@ -320,10 +358,12 @@ png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth) v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1)); value = 0; + for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c]) { if (j > 0) value |= (png_uint_16)((v << j) & (png_uint_16)0xffff); + else value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff); } @@ -344,12 +384,13 @@ png_do_write_swap_alpha(png_row_infop row_info, png_bytep row) { if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) { - /* This converts from ARGB to RGBA */ if (row_info->bit_depth == 8) { + /* This converts from ARGB to RGBA */ png_bytep sp, dp; png_uint_32 i; png_uint_32 row_width = row_info->width; + for (i = 0, sp = dp = row; i < row_width; i++) { png_byte save = *(sp++); @@ -359,9 +400,11 @@ png_do_write_swap_alpha(png_row_infop row_info, png_bytep row) *(dp++) = save; } } - /* This converts from AARRGGBB to RRGGBBAA */ + +#ifdef PNG_WRITE_16BIT_SUPPORTED else { + /* This converts from AARRGGBB to RRGGBBAA */ png_bytep sp, dp; png_uint_32 i; png_uint_32 row_width = row_info->width; @@ -381,12 +424,14 @@ png_do_write_swap_alpha(png_row_infop row_info, png_bytep row) *(dp++) = save[1]; } } +#endif /* PNG_WRITE_16BIT_SUPPORTED */ } + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { - /* This converts from AG to GA */ if (row_info->bit_depth == 8) { + /* This converts from AG to GA */ png_bytep sp, dp; png_uint_32 i; png_uint_32 row_width = row_info->width; @@ -398,9 +443,11 @@ png_do_write_swap_alpha(png_row_infop row_info, png_bytep row) *(dp++) = save; } } - /* This converts from AAGG to GGAA */ + +#ifdef PNG_WRITE_16BIT_SUPPORTED else { + /* This converts from AAGG to GGAA */ png_bytep sp, dp; png_uint_32 i; png_uint_32 row_width = row_info->width; @@ -416,6 +463,7 @@ png_do_write_swap_alpha(png_row_infop row_info, png_bytep row) *(dp++) = save[1]; } } +#endif /* PNG_WRITE_16BIT_SUPPORTED */ } } } @@ -430,12 +478,13 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row) { if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) { - /* This inverts the alpha channel in RGBA */ if (row_info->bit_depth == 8) { + /* This inverts the alpha channel in RGBA */ png_bytep sp, dp; png_uint_32 i; png_uint_32 row_width = row_info->width; + for (i = 0, sp = dp = row; i < row_width; i++) { /* Does nothing @@ -447,9 +496,11 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row) *(dp++) = (png_byte)(255 - *(sp++)); } } - /* This inverts the alpha channel in RRGGBBAA */ + +#ifdef PNG_WRITE_16BIT_SUPPORTED else { + /* This inverts the alpha channel in RRGGBBAA */ png_bytep sp, dp; png_uint_32 i; png_uint_32 row_width = row_info->width; @@ -469,12 +520,14 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row) *(dp++) = (png_byte)(255 - *(sp++)); } } +#endif /* PNG_WRITE_16BIT_SUPPORTED */ } + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { - /* This inverts the alpha channel in GA */ if (row_info->bit_depth == 8) { + /* This inverts the alpha channel in GA */ png_bytep sp, dp; png_uint_32 i; png_uint_32 row_width = row_info->width; @@ -485,9 +538,11 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row) *(dp++) = (png_byte)(255 - *(sp++)); } } - /* This inverts the alpha channel in GGAA */ + +#ifdef PNG_WRITE_16BIT_SUPPORTED else { + /* This inverts the alpha channel in GGAA */ png_bytep sp, dp; png_uint_32 i; png_uint_32 row_width = row_info->width; @@ -503,6 +558,7 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row) *(dp++) = (png_byte)(255 - *(sp++)); } } +#endif /* PNG_WRITE_16BIT_SUPPORTED */ } } } @@ -515,8 +571,7 @@ png_do_write_intrapixel(png_row_infop row_info, png_bytep row) { png_debug(1, "in png_do_write_intrapixel"); - if ( - (row_info->color_type & PNG_COLOR_MASK_COLOR)) + if ((row_info->color_type & PNG_COLOR_MASK_COLOR)) { int bytes_per_pixel; png_uint_32 row_width = row_info->width; @@ -527,17 +582,21 @@ png_do_write_intrapixel(png_row_infop row_info, png_bytep row) if (row_info->color_type == PNG_COLOR_TYPE_RGB) bytes_per_pixel = 3; + else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) bytes_per_pixel = 4; + else return; for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) { - *(rp) = (png_byte)((*rp - *(rp+1))&0xff); - *(rp+2) = (png_byte)((*(rp+2) - *(rp+1))&0xff); + *(rp) = (png_byte)((*rp - *(rp + 1)) & 0xff); + *(rp + 2) = (png_byte)((*(rp + 2) - *(rp + 1)) & 0xff); } } + +#ifdef PNG_WRITE_16BIT_SUPPORTED else if (row_info->bit_depth == 16) { png_bytep rp; @@ -545,24 +604,27 @@ png_do_write_intrapixel(png_row_infop row_info, png_bytep row) if (row_info->color_type == PNG_COLOR_TYPE_RGB) bytes_per_pixel = 6; + else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA) bytes_per_pixel = 8; + else return; for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel) { - png_uint_32 s0 = (*(rp ) << 8) | *(rp+1); - png_uint_32 s1 = (*(rp+2) << 8) | *(rp+3); - png_uint_32 s2 = (*(rp+4) << 8) | *(rp+5); + png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1); + png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3); + png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5); png_uint_32 red = (png_uint_32)((s0 - s1) & 0xffffL); png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL); - *(rp ) = (png_byte)((red >> 8) & 0xff); - *(rp+1) = (png_byte)(red & 0xff); - *(rp+4) = (png_byte)((blue >> 8) & 0xff); - *(rp+5) = (png_byte)(blue & 0xff); + *(rp ) = (png_byte)((red >> 8) & 0xff); + *(rp + 1) = (png_byte)(red & 0xff); + *(rp + 4) = (png_byte)((blue >> 8) & 0xff); + *(rp + 5) = (png_byte)(blue & 0xff); } } +#endif /* PNG_WRITE_16BIT_SUPPORTED */ } } #endif /* PNG_MNG_FEATURES_SUPPORTED */ diff --git a/harbour/src/3rd/png/pngwutil.c b/harbour/src/3rd/png/pngwutil.c index 8f7c7c24df..2c35785aa1 100644 --- a/harbour/src/3rd/png/pngwutil.c +++ b/harbour/src/3rd/png/pngwutil.c @@ -1,8 +1,8 @@ /* pngwutil.c - utilities to write a PNG file * - * Last changed in libpng 1.4.1 [February 25, 2010] - * Copyright (c) 1998-2010 Glenn Randers-Pehrson + * Last changed in libpng 1.5.0 [January 6, 2011] + * Copyright (c) 1998-2011 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * @@ -11,11 +11,11 @@ * and license in png.h */ -#define PNG_NO_PEDANTIC_WARNINGS -#include "png.h" -#ifdef PNG_WRITE_SUPPORTED #include "pngpriv.h" +#ifdef PNG_WRITE_SUPPORTED + +#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED /* Place a 32-bit number into a buffer in PNG byte order. We work * with unsigned numbers for convenience, although one supported * ancillary chunk uses signed (two's complement) numbers. @@ -32,7 +32,9 @@ png_save_uint_32(png_bytep buf, png_uint_32 i) #ifdef PNG_SAVE_INT_32_SUPPORTED /* The png_save_int_32 function assumes integers are stored in two's * complement format. If this isn't the case, then this routine needs to - * be modified to write data in two's complement format. + * be modified to write data in two's complement format. Note that, + * the following works correctly even if png_int_32 has more than 32 bits + * (compare the more complex code required on read for sign extention.) */ void PNGAPI png_save_int_32(png_bytep buf, png_int_32 i) @@ -54,6 +56,7 @@ png_save_uint_16(png_bytep buf, unsigned int i) buf[0] = (png_byte)((i >> 8) & 0xff); buf[1] = (png_byte)(i & 0xff); } +#endif /* Simple function to write the signature. If we have already written * the magic bytes of the signature, or more likely, the PNG stream is @@ -74,6 +77,7 @@ png_write_sig(png_structp png_ptr) /* Write the rest of the 8 byte signature */ png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes], (png_size_t)(8 - png_ptr->sig_bytes)); + if (png_ptr->sig_bytes < 3) png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE; } @@ -88,11 +92,12 @@ png_write_sig(png_structp png_ptr) * functions instead. */ void PNGAPI -png_write_chunk(png_structp png_ptr, png_bytep chunk_name, - png_bytep data, png_size_t length) +png_write_chunk(png_structp png_ptr, png_const_bytep chunk_name, + png_const_bytep data, png_size_t length) { if (png_ptr == NULL) return; + png_write_chunk_start(png_ptr, chunk_name, (png_uint_32)length); png_write_chunk_data(png_ptr, data, (png_size_t)length); png_write_chunk_end(png_ptr); @@ -103,8 +108,8 @@ png_write_chunk(png_structp png_ptr, png_bytep chunk_name, * passing in png_write_chunk_data(). */ void PNGAPI -png_write_chunk_start(png_structp png_ptr, png_bytep chunk_name, - png_uint_32 length) +png_write_chunk_start(png_structp png_ptr, png_const_bytep chunk_name, + png_uint_32 length) { png_byte buf[8]; @@ -125,10 +130,13 @@ png_write_chunk_start(png_structp png_ptr, png_bytep chunk_name, png_save_uint_32(buf, length); png_memcpy(buf + 4, chunk_name, 4); png_write_data(png_ptr, buf, (png_size_t)8); + /* Put the chunk name into png_ptr->chunk_name */ png_memcpy(png_ptr->chunk_name, chunk_name, 4); + /* Reset the crc and run it over the chunk name */ png_reset_crc(png_ptr); + png_calculate_crc(png_ptr, chunk_name, 4); #ifdef PNG_IO_STATE_SUPPORTED @@ -145,14 +153,17 @@ png_write_chunk_start(png_structp png_ptr, png_bytep chunk_name, * given to png_write_chunk_start(). */ void PNGAPI -png_write_chunk_data(png_structp png_ptr, png_bytep data, png_size_t length) +png_write_chunk_data(png_structp png_ptr, png_const_bytep data, + png_size_t length) { /* Write the data, and run the CRC over it */ if (png_ptr == NULL) return; + if (data != NULL && length > 0) { png_write_data(png_ptr, data, length); + /* Update the CRC after writing the data, * in case that the user I/O routine alters it. */ @@ -190,18 +201,18 @@ png_write_chunk_end(png_structp png_ptr) 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 */ + png_const_bytep input; /* The uncompressed input data */ + png_size_t input_len; /* Its length */ + int num_output_ptr; /* Number of output pointers used */ + int max_output_ptr; /* Size of output_ptr */ + png_bytep *output_ptr; /* Array of pointers to output */ } compression_state; /* Compress given text into storage in the png_ptr structure */ static int /* PRIVATE */ png_text_compress(png_structp png_ptr, - png_charp text, png_size_t text_len, int compression, - compression_state *comp) + png_const_charp text, png_size_t text_len, int compression, + compression_state *comp) { int ret; @@ -214,14 +225,14 @@ png_text_compress(png_structp png_ptr, /* 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((int)text_len); + comp->input = (png_const_bytep)text; + comp->input_len = text_len; + return((int)text_len); } if (compression >= PNG_TEXT_COMPRESSION_LAST) { -#ifdef PNG_STDIO_SUPPORTED +#ifdef PNG_CONSOLE_IO_SUPPORTED char msg[50]; png_snprintf(msg, 50, "Unknown compression type %d", compression); png_warning(png_ptr, msg); @@ -258,14 +269,17 @@ png_text_compress(png_structp png_ptr, { /* 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)) { @@ -278,28 +292,33 @@ png_text_compress(png_structp png_ptr, comp->max_output_ptr = comp->num_output_ptr + 4; if (comp->output_ptr != NULL) { - png_charpp old_ptr; + png_bytepp old_ptr; old_ptr = comp->output_ptr; - comp->output_ptr = (png_charpp)png_malloc(png_ptr, - (png_alloc_size_t) - (comp->max_output_ptr * png_sizeof(png_charpp))); + + comp->output_ptr = (png_bytepp)png_malloc(png_ptr, + (png_alloc_size_t) + (comp->max_output_ptr * png_sizeof(png_charpp))); + png_memcpy(comp->output_ptr, old_ptr, old_max - * png_sizeof(png_charp)); + * png_sizeof(png_charp)); + png_free(png_ptr, old_ptr); } else - comp->output_ptr = (png_charpp)png_malloc(png_ptr, - (png_alloc_size_t) - (comp->max_output_ptr * png_sizeof(png_charp))); + comp->output_ptr = (png_bytepp)png_malloc(png_ptr, + (png_alloc_size_t) + (comp->max_output_ptr * png_sizeof(png_charp))); } /* Save the data */ comp->output_ptr[comp->num_output_ptr] = - (png_charp)png_malloc(png_ptr, - (png_alloc_size_t)png_ptr->zbuf_size); + (png_bytep)png_malloc(png_ptr, + (png_alloc_size_t)png_ptr->zbuf_size); + png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf, - png_ptr->zbuf_size); + png_ptr->zbuf_size); + comp->num_output_ptr++; /* and reset the buffer */ @@ -329,29 +348,35 @@ png_text_compress(png_structp png_ptr, comp->max_output_ptr = comp->num_output_ptr + 4; if (comp->output_ptr != NULL) { - png_charpp old_ptr; + png_bytepp old_ptr; old_ptr = comp->output_ptr; + /* This could be optimized to realloc() */ - comp->output_ptr = (png_charpp)png_malloc(png_ptr, - (png_alloc_size_t)(comp->max_output_ptr * - png_sizeof(png_charp))); + comp->output_ptr = (png_bytepp)png_malloc(png_ptr, + (png_alloc_size_t)(comp->max_output_ptr * + png_sizeof(png_charp))); + png_memcpy(comp->output_ptr, old_ptr, - old_max * png_sizeof(png_charp)); + old_max * png_sizeof(png_charp)); + png_free(png_ptr, old_ptr); } + else - comp->output_ptr = (png_charpp)png_malloc(png_ptr, - (png_alloc_size_t)(comp->max_output_ptr * - png_sizeof(png_charp))); + comp->output_ptr = (png_bytepp)png_malloc(png_ptr, + (png_alloc_size_t)(comp->max_output_ptr * + png_sizeof(png_charp))); } /* Save the data */ comp->output_ptr[comp->num_output_ptr] = - (png_charp)png_malloc(png_ptr, - (png_alloc_size_t)png_ptr->zbuf_size); + (png_bytep)png_malloc(png_ptr, + (png_alloc_size_t)png_ptr->zbuf_size); + png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf, - png_ptr->zbuf_size); + png_ptr->zbuf_size); + comp->num_output_ptr++; /* and reset the buffer pointers */ @@ -364,6 +389,7 @@ png_text_compress(png_structp png_ptr, /* 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"); } @@ -371,6 +397,7 @@ png_text_compress(png_structp png_ptr, /* 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; @@ -386,24 +413,27 @@ png_write_compressed_data_out(png_structp png_ptr, compression_state *comp) /* Handle the no-compression case */ if (comp->input) { - png_write_chunk_data(png_ptr, (png_bytep)comp->input, - (png_size_t)comp->input_len); + png_write_chunk_data(png_ptr, 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_size_t)png_ptr->zbuf_size); + png_write_chunk_data(png_ptr, comp->output_ptr[i], + (png_size_t)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_size_t)(png_ptr->zbuf_size - png_ptr->zstream.avail_out)); + (png_size_t)(png_ptr->zbuf_size - png_ptr->zstream.avail_out)); /* Reset zlib for another zTXt/iTXt or image data */ deflateReset(&png_ptr->zstream); @@ -417,8 +447,8 @@ png_write_compressed_data_out(png_structp png_ptr, compression_state *comp) */ void /* PRIVATE */ 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) + int bit_depth, int color_type, int compression_type, int filter_type, + int interlace_type) { PNG_IHDR; int ret; @@ -437,36 +467,61 @@ png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height, case 2: case 4: case 8: - case 16: png_ptr->channels = 1; break; - default: png_error(png_ptr, - "Invalid bit depth for grayscale image"); +#ifdef PNG_WRITE_16BIT_SUPPORTED + case 16: +#endif + png_ptr->channels = 1; break; + + default: + png_error(png_ptr, + "Invalid bit depth for grayscale image"); } break; + case PNG_COLOR_TYPE_RGB: +#ifdef PNG_WRITE_16BIT_SUPPORTED if (bit_depth != 8 && bit_depth != 16) +#else + if (bit_depth != 8) +#endif png_error(png_ptr, "Invalid bit depth for RGB image"); + png_ptr->channels = 3; break; + case PNG_COLOR_TYPE_PALETTE: switch (bit_depth) { case 1: case 2: case 4: - case 8: png_ptr->channels = 1; break; - default: png_error(png_ptr, "Invalid bit depth for paletted image"); + case 8: + png_ptr->channels = 1; + break; + + default: + png_error(png_ptr, "Invalid bit depth for paletted image"); } break; + case PNG_COLOR_TYPE_GRAY_ALPHA: if (bit_depth != 8 && bit_depth != 16) png_error(png_ptr, "Invalid bit depth for grayscale+alpha image"); + png_ptr->channels = 2; break; + case PNG_COLOR_TYPE_RGB_ALPHA: +#ifdef PNG_WRITE_16BIT_SUPPORTED if (bit_depth != 8 && bit_depth != 16) +#else + if (bit_depth != 8) +#endif png_error(png_ptr, "Invalid bit depth for RGBA image"); + png_ptr->channels = 4; break; + default: png_error(png_ptr, "Invalid image color type specified"); } @@ -488,13 +543,13 @@ png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height, */ if ( #ifdef PNG_MNG_FEATURES_SUPPORTED - !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && - ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) && - (color_type == PNG_COLOR_TYPE_RGB || - color_type == PNG_COLOR_TYPE_RGB_ALPHA) && - (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) && + !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && + ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) && + (color_type == PNG_COLOR_TYPE_RGB || + color_type == PNG_COLOR_TYPE_RGB_ALPHA) && + (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) && #endif - filter_type != PNG_FILTER_TYPE_BASE) + filter_type != PNG_FILTER_TYPE_BASE) { png_warning(png_ptr, "Invalid filter type specified"); filter_type = PNG_FILTER_TYPE_BASE; @@ -502,7 +557,7 @@ png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height, #ifdef PNG_WRITE_INTERLACING_SUPPORTED if (interlace_type != PNG_INTERLACE_NONE && - interlace_type != PNG_INTERLACE_ADAM7) + interlace_type != PNG_INTERLACE_ADAM7) { png_warning(png_ptr, "Invalid interlace type specified"); interlace_type = PNG_INTERLACE_ADAM7; @@ -539,52 +594,70 @@ 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_bytep)png_IHDR, buf, (png_size_t)13); + png_write_chunk(png_ptr, png_IHDR, buf, (png_size_t)13); /* Initialize zlib with PNG info */ png_ptr->zstream.zalloc = png_zalloc; png_ptr->zstream.zfree = png_zfree; png_ptr->zstream.opaque = (voidpf)png_ptr; + if (!(png_ptr->do_filter)) { if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE || - png_ptr->bit_depth < 8) + png_ptr->bit_depth < 8) png_ptr->do_filter = PNG_FILTER_NONE; + else png_ptr->do_filter = PNG_ALL_FILTERS; } + if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY)) { if (png_ptr->do_filter != PNG_FILTER_NONE) png_ptr->zlib_strategy = Z_FILTERED; + else png_ptr->zlib_strategy = Z_DEFAULT_STRATEGY; } + if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_LEVEL)) png_ptr->zlib_level = Z_DEFAULT_COMPRESSION; + if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL)) png_ptr->zlib_mem_level = 8; + if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS)) png_ptr->zlib_window_bits = 15; + if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_METHOD)) png_ptr->zlib_method = 8; + ret = deflateInit2(&png_ptr->zstream, png_ptr->zlib_level, - png_ptr->zlib_method, png_ptr->zlib_window_bits, - png_ptr->zlib_mem_level, png_ptr->zlib_strategy); + png_ptr->zlib_method, png_ptr->zlib_window_bits, + png_ptr->zlib_mem_level, png_ptr->zlib_strategy); + if (ret != Z_OK) { - if (ret == Z_VERSION_ERROR) png_error(png_ptr, - "zlib failed to initialize compressor -- version error"); - if (ret == Z_STREAM_ERROR) png_error(png_ptr, - "zlib failed to initialize compressor -- stream error"); - if (ret == Z_MEM_ERROR) png_error(png_ptr, - "zlib failed to initialize compressor -- mem error"); + if (ret == Z_VERSION_ERROR) + png_error(png_ptr, + "zlib failed to initialize compressor -- version error"); + + if (ret == Z_STREAM_ERROR) + png_error(png_ptr, + "zlib failed to initialize compressor -- stream error"); + + if (ret == Z_MEM_ERROR) + png_error(png_ptr, + "zlib failed to initialize compressor -- mem error"); + png_error(png_ptr, "zlib failed to initialize compressor"); } + png_ptr->zstream.next_out = png_ptr->zbuf; png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; - /* libpng is not interested in zstream.data_type */ - /* Set it to a predefined value, to avoid its evaluation inside zlib */ + /* libpng is not interested in zstream.data_type, so set it + * to a predefined value, to avoid its evaluation inside zlib + */ png_ptr->zstream.data_type = Z_BINARY; png_ptr->mode = PNG_HAVE_IHDR; @@ -595,45 +668,48 @@ png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height, * structure. */ void /* PRIVATE */ -png_write_PLTE(png_structp png_ptr, png_colorp palette, png_uint_32 num_pal) +png_write_PLTE(png_structp png_ptr, png_const_colorp palette, + png_uint_32 num_pal) { PNG_PLTE; png_uint_32 i; - png_colorp pal_ptr; + png_const_colorp pal_ptr; png_byte buf[3]; png_debug(1, "in png_write_PLTE"); if (( #ifdef PNG_MNG_FEATURES_SUPPORTED - !(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) && + !(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) && #endif - num_pal == 0) || num_pal > 256) + num_pal == 0) || num_pal > 256) { - if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) - { - png_error(png_ptr, "Invalid number of colors in palette"); - } - else - { - png_warning(png_ptr, "Invalid number of colors in palette"); - return; - } + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + png_error(png_ptr, "Invalid number of colors in palette"); + } + + else + { + png_warning(png_ptr, "Invalid number of colors in palette"); + return; + } } if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR)) { png_warning(png_ptr, - "Ignoring request to write a PLTE chunk in grayscale PNG"); + "Ignoring request to write a PLTE chunk in grayscale PNG"); + return; } png_ptr->num_palette = (png_uint_16)num_pal; png_debug1(3, "num_palette = %d", png_ptr->num_palette); - png_write_chunk_start(png_ptr, (png_bytep)png_PLTE, - (png_uint_32)(num_pal * 3)); + png_write_chunk_start(png_ptr, png_PLTE, (png_uint_32)(num_pal * 3)); #ifdef PNG_POINTER_INDEXING_SUPPORTED + for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++) { buf[0] = pal_ptr->red; @@ -641,11 +717,13 @@ png_write_PLTE(png_structp png_ptr, png_colorp palette, png_uint_32 num_pal) buf[2] = pal_ptr->blue; png_write_chunk_data(png_ptr, buf, (png_size_t)3); } + #else /* This is a little slower but some buggy compilers need to do this * instead */ pal_ptr=palette; + for (i = 0; i < num_pal; i++) { buf[0] = pal_ptr[i].red; @@ -653,6 +731,7 @@ png_write_PLTE(png_structp png_ptr, png_colorp palette, png_uint_32 num_pal) buf[2] = pal_ptr[i].blue; png_write_chunk_data(png_ptr, buf, (png_size_t)3); } + #endif png_write_chunk_end(png_ptr); png_ptr->mode |= PNG_HAVE_PLTE; @@ -683,31 +762,36 @@ png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length) png_ptr->height < 16384 && png_ptr->width < 16384) { png_uint_32 uncompressed_idat_size = png_ptr->height * - ((png_ptr->width * - png_ptr->channels * png_ptr->bit_depth + 15) >> 3); + ((png_ptr->width * + png_ptr->channels * png_ptr->bit_depth + 15) >> 3); unsigned int z_cinfo = z_cmf >> 4; unsigned int half_z_window_size = 1 << (z_cinfo + 7); while (uncompressed_idat_size <= half_z_window_size && - half_z_window_size >= 256) + half_z_window_size >= 256) { z_cinfo--; half_z_window_size >>= 1; } + z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4); - if (data[0] != (png_byte)z_cmf) + + if (data[0] != z_cmf) { + int tmp; data[0] = (png_byte)z_cmf; - data[1] &= 0xe0; - data[1] += (png_byte)(0x1f - ((z_cmf << 8) + data[1]) % 0x1f); + tmp = data[1] & 0xe0; + tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f; + data[1] = (png_byte)tmp; } } } + else png_error(png_ptr, - "Invalid zlib compression method or flags in IDAT"); + "Invalid zlib compression method or flags in IDAT"); } - png_write_chunk(png_ptr, (png_bytep)png_IDAT, data, length); + png_write_chunk(png_ptr, png_IDAT, data, length); png_ptr->mode |= PNG_HAVE_IDAT; } @@ -719,30 +803,12 @@ png_write_IEND(png_structp png_ptr) png_debug(1, "in png_write_IEND"); - png_write_chunk(png_ptr, (png_bytep)png_IEND, NULL, - (png_size_t)0); + png_write_chunk(png_ptr, png_IEND, NULL, (png_size_t)0); png_ptr->mode |= PNG_HAVE_IEND; } #ifdef PNG_WRITE_gAMA_SUPPORTED /* Write a gAMA chunk */ -#ifdef PNG_FLOATING_POINT_SUPPORTED -void /* PRIVATE */ -png_write_gAMA(png_structp png_ptr, double file_gamma) -{ - PNG_gAMA; - png_uint_32 igamma; - png_byte buf[4]; - - png_debug(1, "in png_write_gAMA"); - - /* file_gamma is saved in 1/100,000ths */ - igamma = (png_uint_32)(file_gamma * 100000.0 + 0.5); - png_save_uint_32(buf, igamma); - png_write_chunk(png_ptr, (png_bytep)png_gAMA, buf, (png_size_t)4); -} -#endif -#ifdef PNG_FIXED_POINT_SUPPORTED void /* PRIVATE */ png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma) { @@ -753,10 +819,9 @@ png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma) /* file_gamma is saved in 1/100,000ths */ png_save_uint_32(buf, (png_uint_32)file_gamma); - png_write_chunk(png_ptr, (png_bytep)png_gAMA, buf, (png_size_t)4); + png_write_chunk(png_ptr, png_gAMA, buf, (png_size_t)4); } #endif -#endif #ifdef PNG_WRITE_sRGB_SUPPORTED /* Write a sRGB chunk */ @@ -769,18 +834,19 @@ png_write_sRGB(png_structp png_ptr, int srgb_intent) png_debug(1, "in png_write_sRGB"); if (srgb_intent >= PNG_sRGB_INTENT_LAST) - png_warning(png_ptr, - "Invalid sRGB rendering intent specified"); + png_warning(png_ptr, + "Invalid sRGB rendering intent specified"); + buf[0]=(png_byte)srgb_intent; - png_write_chunk(png_ptr, (png_bytep)png_sRGB, buf, (png_size_t)1); + png_write_chunk(png_ptr, png_sRGB, buf, (png_size_t)1); } #endif #ifdef PNG_WRITE_iCCP_SUPPORTED /* Write an iCCP chunk */ void /* PRIVATE */ -png_write_iCCP(png_structp png_ptr, png_charp name, int compression_type, - png_charp profile, int profile_len) +png_write_iCCP(png_structp png_ptr, png_const_charp name, int compression_type, + png_const_charp profile, int profile_len) { PNG_iCCP; png_size_t name_len; @@ -796,8 +862,7 @@ png_write_iCCP(png_structp png_ptr, png_charp name, int compression_type, comp.input = NULL; comp.input_len = 0; - if ((name_len = png_check_keyword(png_ptr, name, - &new_name)) == 0) + if ((name_len = png_check_keyword(png_ptr, name, &new_name)) == 0) return; if (compression_type != PNG_COMPRESSION_TYPE_BASE) @@ -808,15 +873,16 @@ png_write_iCCP(png_structp png_ptr, png_charp name, int compression_type, if (profile_len > 3) embedded_profile_len = - ((*( (png_bytep)profile ))<<24) | - ((*( (png_bytep)profile + 1))<<16) | - ((*( (png_bytep)profile + 2))<< 8) | - ((*( (png_bytep)profile + 3)) ); + ((*( (png_const_bytep)profile ))<<24) | + ((*( (png_const_bytep)profile + 1))<<16) | + ((*( (png_const_bytep)profile + 2))<< 8) | + ((*( (png_const_bytep)profile + 3)) ); if (embedded_profile_len < 0) { png_warning(png_ptr, - "Embedded profile length in iCCP chunk is negative"); + "Embedded profile length in iCCP chunk is negative"); + png_free(png_ptr, new_name); return; } @@ -824,7 +890,8 @@ png_write_iCCP(png_structp png_ptr, png_charp name, int compression_type, if (profile_len < embedded_profile_len) { png_warning(png_ptr, - "Embedded profile length too large in iCCP chunk"); + "Embedded profile length too large in iCCP chunk"); + png_free(png_ptr, new_name); return; } @@ -832,20 +899,23 @@ png_write_iCCP(png_structp png_ptr, png_charp name, int compression_type, if (profile_len > embedded_profile_len) { png_warning(png_ptr, - "Truncating profile to actual length in iCCP chunk"); + "Truncating profile to actual length in iCCP chunk"); + profile_len = embedded_profile_len; } if (profile_len) profile_len = png_text_compress(png_ptr, profile, - (png_size_t)profile_len, PNG_COMPRESSION_TYPE_BASE, &comp); + (png_size_t)profile_len, PNG_COMPRESSION_TYPE_BASE, &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_start(png_ptr, png_iCCP, + (png_uint_32)(name_len + profile_len + 2)); + new_name[name_len + 1] = 0x00; + png_write_chunk_data(png_ptr, (png_bytep)new_name, - (png_size_t)(name_len + 2)); + (png_size_t)(name_len + 2)); if (profile_len) png_write_compressed_data_out(png_ptr, &comp); @@ -858,7 +928,7 @@ png_write_iCCP(png_structp png_ptr, png_charp name, int compression_type, #ifdef PNG_WRITE_sPLT_SUPPORTED /* Write a sPLT chunk */ void /* PRIVATE */ -png_write_sPLT(png_structp png_ptr, png_sPLT_tp spalette) +png_write_sPLT(png_structp png_ptr, png_const_sPLT_tp spalette) { PNG_sPLT; png_size_t name_len; @@ -877,11 +947,13 @@ png_write_sPLT(png_structp png_ptr, png_sPLT_tp spalette) 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 + 2 + palette_size)); + png_write_chunk_start(png_ptr, png_sPLT, + (png_uint_32)(name_len + 2 + palette_size)); + png_write_chunk_data(png_ptr, (png_bytep)new_name, - (png_size_t)(name_len + 1)); - png_write_chunk_data(png_ptr, (png_bytep)&spalette->depth, (png_size_t)1); + (png_size_t)(name_len + 1)); + + png_write_chunk_data(png_ptr, &spalette->depth, (png_size_t)1); /* Loop through each palette entry, writing appropriately */ #ifdef PNG_POINTER_INDEXING_SUPPORTED @@ -889,42 +961,46 @@ png_write_sPLT(png_structp png_ptr, png_sPLT_tp spalette) { 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); + 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_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, (png_size_t)entry_size); } #else ep=spalette->entries; - for (i=0; i>spalette->nentries; i++) + for (i = 0; i>spalette->nentries; i++) { if (spalette->depth == 8) { - entrybuf[0] = (png_byte)ep[i].red; - entrybuf[1] = (png_byte)ep[i].green; - entrybuf[2] = (png_byte)ep[i].blue; - entrybuf[3] = (png_byte)ep[i].alpha; - png_save_uint_16(entrybuf + 4, ep[i].frequency); + entrybuf[0] = (png_byte)ep[i].red; + entrybuf[1] = (png_byte)ep[i].green; + entrybuf[2] = (png_byte)ep[i].blue; + entrybuf[3] = (png_byte)ep[i].alpha; + png_save_uint_16(entrybuf + 4, ep[i].frequency); } + else { - png_save_uint_16(entrybuf + 0, ep[i].red); - png_save_uint_16(entrybuf + 2, ep[i].green); - png_save_uint_16(entrybuf + 4, ep[i].blue); - png_save_uint_16(entrybuf + 6, ep[i].alpha); - png_save_uint_16(entrybuf + 8, ep[i].frequency); + png_save_uint_16(entrybuf + 0, ep[i].red); + png_save_uint_16(entrybuf + 2, ep[i].green); + png_save_uint_16(entrybuf + 4, ep[i].blue); + png_save_uint_16(entrybuf + 6, ep[i].alpha); + png_save_uint_16(entrybuf + 8, ep[i].frequency); } + png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size); } #endif @@ -937,7 +1013,7 @@ png_write_sPLT(png_structp png_ptr, png_sPLT_tp spalette) #ifdef PNG_WRITE_sBIT_SUPPORTED /* Write the sBIT chunk */ void /* PRIVATE */ -png_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type) +png_write_sBIT(png_structp png_ptr, png_const_color_8p sbit, int color_type) { PNG_sBIT; png_byte buf[4]; @@ -951,7 +1027,8 @@ png_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type) png_byte maxbits; maxbits = (png_byte)(color_type==PNG_COLOR_TYPE_PALETTE ? 8 : - png_ptr->usr_bit_depth); + png_ptr->usr_bit_depth); + if (sbit->red == 0 || sbit->red > maxbits || sbit->green == 0 || sbit->green > maxbits || sbit->blue == 0 || sbit->blue > maxbits) @@ -959,11 +1036,13 @@ png_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type) png_warning(png_ptr, "Invalid sBIT depth specified"); return; } + buf[0] = sbit->red; buf[1] = sbit->green; buf[2] = sbit->blue; size = 3; } + else { if (sbit->gray == 0 || sbit->gray > png_ptr->usr_bit_depth) @@ -971,6 +1050,7 @@ png_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type) png_warning(png_ptr, "Invalid sBIT depth specified"); return; } + buf[0] = sbit->gray; size = 1; } @@ -982,67 +1062,21 @@ png_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type) png_warning(png_ptr, "Invalid sBIT depth specified"); return; } + buf[size++] = sbit->alpha; } - png_write_chunk(png_ptr, (png_bytep)png_sBIT, buf, size); + png_write_chunk(png_ptr, png_sBIT, buf, size); } #endif #ifdef PNG_WRITE_cHRM_SUPPORTED /* Write the cHRM chunk */ -#ifdef PNG_FLOATING_POINT_SUPPORTED -void /* PRIVATE */ -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) -{ - PNG_cHRM; - png_byte buf[32]; - - png_fixed_point int_white_x, int_white_y, int_red_x, int_red_y, - int_green_x, int_green_y, int_blue_x, int_blue_y; - - png_debug(1, "in png_write_cHRM"); - - int_white_x = (png_uint_32)(white_x * 100000.0 + 0.5); - int_white_y = (png_uint_32)(white_y * 100000.0 + 0.5); - int_red_x = (png_uint_32)(red_x * 100000.0 + 0.5); - int_red_y = (png_uint_32)(red_y * 100000.0 + 0.5); - int_green_x = (png_uint_32)(green_x * 100000.0 + 0.5); - int_green_y = (png_uint_32)(green_y * 100000.0 + 0.5); - int_blue_x = (png_uint_32)(blue_x * 100000.0 + 0.5); - int_blue_y = (png_uint_32)(blue_y * 100000.0 + 0.5); - -#ifdef PNG_CHECK_cHRM_SUPPORTED - if (png_check_cHRM_fixed(png_ptr, int_white_x, int_white_y, - int_red_x, int_red_y, int_green_x, int_green_y, int_blue_x, int_blue_y)) -#endif - { - /* Each value is saved in 1/100,000ths */ - - png_save_uint_32(buf, int_white_x); - png_save_uint_32(buf + 4, int_white_y); - - png_save_uint_32(buf + 8, int_red_x); - png_save_uint_32(buf + 12, int_red_y); - - png_save_uint_32(buf + 16, int_green_x); - png_save_uint_32(buf + 20, int_green_y); - - png_save_uint_32(buf + 24, int_blue_x); - png_save_uint_32(buf + 28, int_blue_y); - - png_write_chunk(png_ptr, (png_bytep)png_cHRM, buf, (png_size_t)32); - } -} -#endif -#ifdef PNG_FIXED_POINT_SUPPORTED void /* PRIVATE */ png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x, - png_fixed_point white_y, png_fixed_point red_x, png_fixed_point red_y, - png_fixed_point green_x, png_fixed_point green_y, png_fixed_point blue_x, - png_fixed_point blue_y) + png_fixed_point white_y, png_fixed_point red_x, png_fixed_point red_y, + png_fixed_point green_x, png_fixed_point green_y, png_fixed_point blue_x, + png_fixed_point blue_y) { PNG_cHRM; png_byte buf[32]; @@ -1052,7 +1086,7 @@ png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x, /* Each value is saved in 1/100,000ths */ #ifdef PNG_CHECK_cHRM_SUPPORTED if (png_check_cHRM_fixed(png_ptr, white_x, white_y, red_x, red_y, - green_x, green_y, blue_x, blue_y)) + green_x, green_y, blue_x, blue_y)) #endif { png_save_uint_32(buf, (png_uint_32)white_x); @@ -1067,17 +1101,16 @@ png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x, png_save_uint_32(buf + 24, (png_uint_32)blue_x); png_save_uint_32(buf + 28, (png_uint_32)blue_y); - png_write_chunk(png_ptr, (png_bytep)png_cHRM, buf, (png_size_t)32); + png_write_chunk(png_ptr, png_cHRM, buf, (png_size_t)32); } } #endif -#endif #ifdef PNG_WRITE_tRNS_SUPPORTED /* Write the tRNS chunk */ void /* PRIVATE */ -png_write_tRNS(png_structp png_ptr, png_bytep trans_alpha, png_color_16p tran, - int num_trans, int color_type) +png_write_tRNS(png_structp png_ptr, png_const_bytep trans_alpha, + png_const_color_16p tran, int num_trans, int color_type) { PNG_tRNS; png_byte buf[6]; @@ -1091,36 +1124,46 @@ png_write_tRNS(png_structp png_ptr, png_bytep trans_alpha, png_color_16p tran, png_warning(png_ptr, "Invalid number of transparent colors specified"); return; } + /* Write the chunk out as it is */ - png_write_chunk(png_ptr, (png_bytep)png_tRNS, trans_alpha, - (png_size_t)num_trans); + png_write_chunk(png_ptr, png_tRNS, trans_alpha, (png_size_t)num_trans); } + else if (color_type == PNG_COLOR_TYPE_GRAY) { /* One 16 bit value */ if (tran->gray >= (1 << png_ptr->bit_depth)) { png_warning(png_ptr, - "Ignoring attempt to write tRNS chunk out-of-range for bit_depth"); + "Ignoring attempt to write tRNS chunk out-of-range for bit_depth"); + return; } + png_save_uint_16(buf, tran->gray); - png_write_chunk(png_ptr, (png_bytep)png_tRNS, buf, (png_size_t)2); + png_write_chunk(png_ptr, png_tRNS, buf, (png_size_t)2); } + else if (color_type == PNG_COLOR_TYPE_RGB) { /* Three 16 bit values */ png_save_uint_16(buf, tran->red); png_save_uint_16(buf + 2, tran->green); png_save_uint_16(buf + 4, tran->blue); +#ifdef PNG_WRITE_16BIT_SUPPORTED if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4])) +#else + if (buf[0] | buf[2] | buf[4]) +#endif { png_warning(png_ptr, "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8"); return; } - png_write_chunk(png_ptr, (png_bytep)png_tRNS, buf, (png_size_t)6); + + png_write_chunk(png_ptr, png_tRNS, buf, (png_size_t)6); } + else { png_warning(png_ptr, "Can't write tRNS with an alpha channel"); @@ -1131,7 +1174,7 @@ png_write_tRNS(png_structp png_ptr, png_bytep trans_alpha, png_color_16p tran, #ifdef PNG_WRITE_bKGD_SUPPORTED /* Write the background chunk */ void /* PRIVATE */ -png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type) +png_write_bKGD(png_structp png_ptr, png_const_color_16p back, int color_type) { PNG_bKGD; png_byte buf[6]; @@ -1150,32 +1193,43 @@ png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type) png_warning(png_ptr, "Invalid background palette index"); return; } + buf[0] = back->index; - png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)1); + png_write_chunk(png_ptr, 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); +#ifdef PNG_WRITE_16BIT_SUPPORTED if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4])) +#else + if (buf[0] | buf[2] | buf[4]) +#endif { png_warning(png_ptr, - "Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8"); + "Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8"); + return; } - png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)6); + + png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)6); } + else { if (back->gray >= (1 << png_ptr->bit_depth)) { png_warning(png_ptr, - "Ignoring attempt to write bKGD chunk out-of-range for bit_depth"); + "Ignoring attempt to write bKGD chunk out-of-range for bit_depth"); + return; } + png_save_uint_16(buf, back->gray); - png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)2); + png_write_chunk(png_ptr, png_bKGD, buf, (png_size_t)2); } } #endif @@ -1183,7 +1237,7 @@ png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type) #ifdef PNG_WRITE_hIST_SUPPORTED /* Write the histogram */ void /* PRIVATE */ -png_write_hIST(png_structp png_ptr, png_uint_16p hist, int num_hist) +png_write_hIST(png_structp png_ptr, png_const_uint_16p hist, int num_hist) { PNG_hIST; int i; @@ -1194,18 +1248,20 @@ png_write_hIST(png_structp png_ptr, png_uint_16p hist, int num_hist) if (num_hist > (int)png_ptr->num_palette) { png_debug2(3, "num_hist = %d, num_palette = %d", num_hist, - png_ptr->num_palette); + png_ptr->num_palette); + png_warning(png_ptr, "Invalid number of histogram entries specified"); return; } - png_write_chunk_start(png_ptr, (png_bytep)png_hIST, - (png_uint_32)(num_hist * 2)); + png_write_chunk_start(png_ptr, png_hIST, (png_uint_32)(num_hist * 2)); + for (i = 0; i < num_hist; i++) { png_save_uint_16(buf, hist[i]); png_write_chunk_data(png_ptr, buf, (png_size_t)2); } + png_write_chunk_end(png_ptr); } #endif @@ -1223,9 +1279,10 @@ png_write_hIST(png_structp png_ptr, png_uint_16p hist, int num_hist) * static keywords without having to have duplicate copies of the strings. */ png_size_t /* PRIVATE */ -png_check_keyword(png_structp png_ptr, png_charp key, png_charpp new_key) +png_check_keyword(png_structp png_ptr, png_const_charp key, png_charpp new_key) { png_size_t key_len; + png_const_charp ikp; png_charp kp, dp; int kflag; int kwarn=0; @@ -1243,6 +1300,7 @@ png_check_keyword(png_structp png_ptr, png_charp key, png_charpp new_key) png_debug1(2, "Keyword to be checked is '%s'", key); *new_key = (png_charp)png_malloc_warn(png_ptr, (png_uint_32)(key_len + 2)); + if (*new_key == NULL) { png_warning(png_ptr, "Out of memory while procesing keyword"); @@ -1250,25 +1308,26 @@ png_check_keyword(png_structp png_ptr, png_charp key, png_charpp new_key) } /* Replace non-printing characters with a blank and print a warning */ - for (kp = key, dp = *new_key; *kp != '\0'; kp++, dp++) + for (ikp = key, dp = *new_key; *ikp != '\0'; ikp++, dp++) { - if ((png_byte)*kp < 0x20 || - ((png_byte)*kp > 0x7E && (png_byte)*kp < 0xA1)) + if ((png_byte)*ikp < 0x20 || + ((png_byte)*ikp > 0x7E && (png_byte)*ikp < 0xA1)) { -#ifdef PNG_STDIO_SUPPORTED +#ifdef PNG_CONSOLE_IO_SUPPORTED char msg[40]; png_snprintf(msg, 40, - "invalid keyword character 0x%02X", (png_byte)*kp); + "invalid keyword character 0x%02X", (png_byte)*ikp); png_warning(png_ptr, msg); #else png_warning(png_ptr, "invalid character in keyword"); #endif *dp = ' '; } + else { - *dp = *kp; + *dp = *ikp; } } *dp = '\0'; @@ -1309,11 +1368,13 @@ png_check_keyword(png_structp png_ptr, png_charp key, png_charpp new_key) *(dp++) = *kp; kflag = 1; } + else if (*kp == ' ') { key_len--; - kwarn=1; + kwarn = 1; } + else { *(dp++) = *kp; @@ -1344,8 +1405,8 @@ png_check_keyword(png_structp png_ptr, png_charp key, png_charpp new_key) #ifdef PNG_WRITE_tEXt_SUPPORTED /* Write a tEXt chunk */ void /* PRIVATE */ -png_write_tEXt(png_structp png_ptr, png_charp key, png_charp text, - png_size_t text_len) +png_write_tEXt(png_structp png_ptr, png_const_charp key, png_const_charp text, + png_size_t text_len) { PNG_tEXt; png_size_t key_len; @@ -1358,12 +1419,13 @@ png_write_tEXt(png_structp png_ptr, png_charp key, png_charp text, if (text == NULL || *text == '\0') text_len = 0; + else text_len = png_strlen(text); /* Make sure we include the 0 after the key */ - png_write_chunk_start(png_ptr, (png_bytep)png_tEXt, - (png_uint_32)(key_len + text_len + 1)); + png_write_chunk_start(png_ptr, 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 @@ -1371,9 +1433,11 @@ png_write_tEXt(png_structp png_ptr, png_charp key, png_charp text, * 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, - (png_size_t)(key_len + 1)); + (png_size_t)(key_len + 1)); + if (text_len) - png_write_chunk_data(png_ptr, (png_bytep)text, (png_size_t)text_len); + png_write_chunk_data(png_ptr, (png_const_bytep)text, + (png_size_t)text_len); png_write_chunk_end(png_ptr); png_free(png_ptr, new_key); @@ -1383,12 +1447,12 @@ png_write_tEXt(png_structp png_ptr, png_charp key, png_charp text, #ifdef PNG_WRITE_zTXt_SUPPORTED /* Write a compressed text chunk */ void /* PRIVATE */ -png_write_zTXt(png_structp png_ptr, png_charp key, png_charp text, - png_size_t text_len, int compression) +png_write_zTXt(png_structp png_ptr, png_const_charp key, png_const_charp text, + png_size_t text_len, int compression) { PNG_zTXt; png_size_t key_len; - char buf[1]; + png_byte buf; png_charp new_key; compression_state comp; @@ -1400,7 +1464,7 @@ png_write_zTXt(png_structp png_ptr, png_charp key, png_charp text, comp.input = NULL; comp.input_len = 0; - if ((key_len = png_check_keyword(png_ptr, key, &new_key))==0) + if ((key_len = png_check_keyword(png_ptr, key, &new_key)) == 0) { png_free(png_ptr, new_key); return; @@ -1420,16 +1484,20 @@ png_write_zTXt(png_structp png_ptr, png_charp key, png_charp text, &comp); /* Write start of chunk */ - png_write_chunk_start(png_ptr, (png_bytep)png_zTXt, - (png_uint_32)(key_len+text_len + 2)); + png_write_chunk_start(png_ptr, png_zTXt, + (png_uint_32)(key_len+text_len + 2)); + /* Write key */ png_write_chunk_data(png_ptr, (png_bytep)new_key, - (png_size_t)(key_len + 1)); + (png_size_t)(key_len + 1)); + png_free(png_ptr, new_key); - buf[0] = (png_byte)compression; + buf = (png_byte)compression; + /* Write compression */ - png_write_chunk_data(png_ptr, (png_bytep)buf, (png_size_t)1); + png_write_chunk_data(png_ptr, &buf, (png_size_t)1); + /* Write the compressed data */ png_write_compressed_data_out(png_ptr, &comp); @@ -1441,8 +1509,8 @@ png_write_zTXt(png_structp png_ptr, png_charp key, png_charp text, #ifdef PNG_WRITE_iTXt_SUPPORTED /* Write an iTXt chunk */ void /* PRIVATE */ -png_write_iTXt(png_structp png_ptr, int compression, png_charp key, - png_charp lang, png_charp lang_key, png_charp text) +png_write_iTXt(png_structp png_ptr, int compression, png_const_charp key, + png_const_charp lang, png_const_charp lang_key, png_const_charp text) { PNG_iTXt; png_size_t lang_len, key_len, lang_key_len, text_len; @@ -1458,10 +1526,10 @@ png_write_iTXt(png_structp png_ptr, int compression, png_charp key, comp.output_ptr = NULL; comp.input = NULL; - if ((key_len = png_check_keyword(png_ptr, key, &new_key))==0) + if ((key_len = png_check_keyword(png_ptr, key, &new_key)) == 0) return; - if ((lang_len = png_check_keyword(png_ptr, lang, &new_lang))==0) + if ((lang_len = png_check_keyword(png_ptr, lang, &new_lang)) == 0) { png_warning(png_ptr, "Empty language field in iTXt chunk"); new_lang = NULL; @@ -1470,24 +1538,26 @@ png_write_iTXt(png_structp png_ptr, int compression, png_charp key, if (lang_key == NULL) lang_key_len = 0; + else lang_key_len = png_strlen(lang_key); if (text == NULL) text_len = 0; + else text_len = png_strlen(text); /* Compute the compressed data; do it now for the length */ - text_len = png_text_compress(png_ptr, text, text_len, compression-2, - &comp); + text_len = png_text_compress(png_ptr, text, text_len, compression - 2, + &comp); /* Make sure we include the compression flag, the compression byte, - * and the NULs after the key, lang, and lang_key parts */ + * and the NULs after the key, lang, and lang_key parts + */ - png_write_chunk_start(png_ptr, (png_bytep)png_iTXt, - (png_uint_32)( + png_write_chunk_start(png_ptr, png_iTXt, (png_uint_32)( 5 /* comp byte, comp flag, terminators for key, lang and lang_key */ + key_len + lang_len @@ -1499,27 +1569,32 @@ png_write_iTXt(png_structp png_ptr, int compression, png_charp key, * 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, - (png_size_t)(key_len + 1)); + png_write_chunk_data(png_ptr, (png_bytep)new_key, (png_size_t)(key_len + 1)); /* Set the compression flag */ - if (compression == PNG_ITXT_COMPRESSION_NONE || \ + if (compression == PNG_ITXT_COMPRESSION_NONE || compression == PNG_TEXT_COMPRESSION_NONE) - cbuf[0] = 0; + cbuf[0] = 0; + else /* compression == PNG_ITXT_COMPRESSION_zTXt */ - cbuf[0] = 1; + cbuf[0] = 1; + /* Set the compression method */ cbuf[1] = 0; + png_write_chunk_data(png_ptr, cbuf, (png_size_t)2); cbuf[0] = 0; - png_write_chunk_data(png_ptr, (new_lang ? (png_bytep)new_lang : cbuf), - (png_size_t)(lang_len + 1)); - png_write_chunk_data(png_ptr, (lang_key ? (png_bytep)lang_key : cbuf), - (png_size_t)(lang_key_len + 1)); + png_write_chunk_data(png_ptr, (new_lang ? (png_const_bytep)new_lang : cbuf), + (png_size_t)(lang_len + 1)); + + png_write_chunk_data(png_ptr, (lang_key ? (png_const_bytep)lang_key : cbuf), + (png_size_t)(lang_key_len + 1)); + png_write_compressed_data_out(png_ptr, &comp); png_write_chunk_end(png_ptr); + png_free(png_ptr, new_key); png_free(png_ptr, new_lang); } @@ -1529,7 +1604,7 @@ png_write_iTXt(png_structp png_ptr, int compression, png_charp key, /* Write the oFFs chunk */ void /* PRIVATE */ png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset, - int unit_type) + int unit_type) { PNG_oFFs; png_byte buf[9]; @@ -1543,14 +1618,15 @@ png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset, png_save_int_32(buf + 4, y_offset); buf[8] = (png_byte)unit_type; - png_write_chunk(png_ptr, (png_bytep)png_oFFs, buf, (png_size_t)9); + png_write_chunk(png_ptr, png_oFFs, buf, (png_size_t)9); } #endif #ifdef PNG_WRITE_pCAL_SUPPORTED /* Write the pCAL chunk (described in the PNG extensions document) */ void /* PRIVATE */ 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) + png_int_32 X1, int type, int nparams, png_const_charp units, + png_charpp params) { PNG_pCAL; png_size_t purpose_len, units_len, total_len; @@ -1571,35 +1647,36 @@ png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0, total_len = purpose_len + units_len + 10; params_len = (png_uint_32p)png_malloc(png_ptr, - (png_alloc_size_t)(nparams * png_sizeof(png_uint_32))); + (png_alloc_size_t)(nparams * png_sizeof(png_uint_32))); /* Find the length of each parameter, making sure we don't count the - null terminator for the last parameter. */ + * null terminator for the last parameter. + */ for (i = 0; i < nparams; i++) { params_len[i] = png_strlen(params[i]) + (i == nparams - 1 ? 0 : 1); png_debug2(3, "pCAL parameter %d length = %lu", i, - (unsigned long) params_len[i]); + (unsigned long)params_len[i]); total_len += (png_size_t)params_len[i]; } png_debug1(3, "pCAL total length = %d", (int)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, - (png_size_t)purpose_len); + png_write_chunk_start(png_ptr, png_pCAL, (png_uint_32)total_len); + png_write_chunk_data(png_ptr, (png_const_bytep)new_purpose, + (png_size_t)purpose_len); png_save_int_32(buf, X0); png_save_int_32(buf + 4, X1); buf[8] = (png_byte)type; buf[9] = (png_byte)nparams; png_write_chunk_data(png_ptr, buf, (png_size_t)10); - png_write_chunk_data(png_ptr, (png_bytep)units, (png_size_t)units_len); + png_write_chunk_data(png_ptr, (png_const_bytep)units, (png_size_t)units_len); png_free(png_ptr, new_purpose); for (i = 0; i < nparams; i++) { - png_write_chunk_data(png_ptr, (png_bytep)params[i], - (png_size_t)params_len[i]); + png_write_chunk_data(png_ptr, (png_const_bytep)params[i], + (png_size_t)params_len[i]); } png_free(png_ptr, params_len); @@ -1609,30 +1686,9 @@ png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0, #ifdef PNG_WRITE_sCAL_SUPPORTED /* Write the sCAL chunk */ -#if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_STDIO_SUPPORTED) void /* PRIVATE */ -png_write_sCAL(png_structp png_ptr, int unit, double width, double height) -{ - PNG_sCAL; - char buf[64]; - png_size_t total_len; - - png_debug(1, "in png_write_sCAL"); - - buf[0] = (char)unit; - png_snprintf(buf + 1, 63, "%12.12e", width); - total_len = 1 + png_strlen(buf + 1) + 1; - png_snprintf(buf + total_len, 64-total_len, "%12.12e", height); - total_len += png_strlen(buf + total_len); - - png_debug1(3, "sCAL total length = %u", (unsigned int)total_len); - png_write_chunk(png_ptr, (png_bytep)png_sCAL, (png_bytep)buf, total_len); -} -#else -#ifdef PNG_FIXED_POINT_SUPPORTED -void /* PRIVATE */ -png_write_sCAL_s(png_structp png_ptr, int unit, png_charp width, - png_charp height) +png_write_sCAL_s(png_structp png_ptr, int unit, png_const_charp width, + png_const_charp height) { PNG_sCAL; png_byte buf[64]; @@ -1643,6 +1699,7 @@ png_write_sCAL_s(png_structp png_ptr, int unit, png_charp width, wlen = png_strlen(width); hlen = png_strlen(height); total_len = wlen + hlen + 2; + if (total_len > 64) { png_warning(png_ptr, "Can't write sCAL (buffer too small)"); @@ -1654,18 +1711,16 @@ png_write_sCAL_s(png_structp png_ptr, int unit, png_charp width, png_memcpy(buf + wlen + 2, height, hlen); /* Do NOT append the '\0' here */ png_debug1(3, "sCAL total length = %u", (unsigned int)total_len); - png_write_chunk(png_ptr, (png_bytep)png_sCAL, buf, total_len); + png_write_chunk(png_ptr, png_sCAL, buf, total_len); } #endif -#endif -#endif #ifdef PNG_WRITE_pHYs_SUPPORTED /* Write the pHYs chunk */ void /* PRIVATE */ png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit, - png_uint_32 y_pixels_per_unit, - int unit_type) + png_uint_32 y_pixels_per_unit, + int unit_type) { PNG_pHYs; png_byte buf[9]; @@ -1679,7 +1734,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_bytep)png_pHYs, buf, (png_size_t)9); + png_write_chunk(png_ptr, png_pHYs, buf, (png_size_t)9); } #endif @@ -1688,7 +1743,7 @@ png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit, * or png_convert_from_time_t(), or fill in the structure yourself. */ void /* PRIVATE */ -png_write_tIME(png_structp png_ptr, png_timep mod_time) +png_write_tIME(png_structp png_ptr, png_const_timep mod_time) { PNG_tIME; png_byte buf[7]; @@ -1710,7 +1765,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_bytep)png_tIME, buf, (png_size_t)7); + png_write_chunk(png_ptr, png_tIME, buf, (png_size_t)7); } #endif @@ -1739,19 +1794,20 @@ png_write_start_row(png_structp png_ptr) png_debug(1, "in png_write_start_row"); buf_size = (png_size_t)(PNG_ROWBYTES( - png_ptr->usr_channels*png_ptr->usr_bit_depth, png_ptr->width) + 1); + png_ptr->usr_channels*png_ptr->usr_bit_depth, png_ptr->width) + 1); /* Set up row buffer */ png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, - (png_alloc_size_t)buf_size); + (png_alloc_size_t)buf_size); + png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE; #ifdef PNG_WRITE_FILTER_SUPPORTED /* Set up filtering buffer, if using this filter */ if (png_ptr->do_filter & PNG_FILTER_SUB) { - png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, - (png_alloc_size_t)(png_ptr->rowbytes + 1)); + png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, png_ptr->rowbytes + 1); + png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB; } @@ -1760,26 +1816,29 @@ png_write_start_row(png_structp png_ptr) { /* Set up previous row buffer */ png_ptr->prev_row = (png_bytep)png_calloc(png_ptr, - (png_alloc_size_t)buf_size); + (png_alloc_size_t)buf_size); if (png_ptr->do_filter & PNG_FILTER_UP) { png_ptr->up_row = (png_bytep)png_malloc(png_ptr, - (png_size_t)(png_ptr->rowbytes + 1)); + png_ptr->rowbytes + 1); + png_ptr->up_row[0] = PNG_FILTER_VALUE_UP; } if (png_ptr->do_filter & PNG_FILTER_AVG) { png_ptr->avg_row = (png_bytep)png_malloc(png_ptr, - (png_alloc_size_t)(png_ptr->rowbytes + 1)); + png_ptr->rowbytes + 1); + png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG; } if (png_ptr->do_filter & PNG_FILTER_PAETH) { png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr, - (png_size_t)(png_ptr->rowbytes + 1)); + png_ptr->rowbytes + 1); + png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH; } } @@ -1792,22 +1851,26 @@ png_write_start_row(png_structp png_ptr) if (!(png_ptr->transformations & PNG_INTERLACE)) { png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - - png_pass_ystart[0]) / png_pass_yinc[0]; + png_pass_ystart[0]) / png_pass_yinc[0]; + png_ptr->usr_width = (png_ptr->width + png_pass_inc[0] - 1 - - png_pass_start[0]) / png_pass_inc[0]; + png_pass_start[0]) / png_pass_inc[0]; } + else { png_ptr->num_rows = png_ptr->height; png_ptr->usr_width = png_ptr->width; } } + else #endif { png_ptr->num_rows = png_ptr->height; png_ptr->usr_width = png_ptr->width; } + png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; png_ptr->zstream.next_out = png_ptr->zbuf; } @@ -1852,24 +1915,30 @@ png_write_finish_row(png_structp png_ptr) { png_ptr->pass++; } + else { /* Loop until we find a non-zero width or height pass */ do { png_ptr->pass++; + if (png_ptr->pass >= 7) break; + png_ptr->usr_width = (png_ptr->width + - png_pass_inc[png_ptr->pass] - 1 - - png_pass_start[png_ptr->pass]) / - png_pass_inc[png_ptr->pass]; + png_pass_inc[png_ptr->pass] - 1 - + png_pass_start[png_ptr->pass]) / + png_pass_inc[png_ptr->pass]; + png_ptr->num_rows = (png_ptr->height + - png_pass_yinc[png_ptr->pass] - 1 - - png_pass_ystart[png_ptr->pass]) / - png_pass_yinc[png_ptr->pass]; + png_pass_yinc[png_ptr->pass] - 1 - + png_pass_ystart[png_ptr->pass]) / + png_pass_yinc[png_ptr->pass]; + if (png_ptr->transformations & PNG_INTERLACE) break; + } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0); } @@ -1879,8 +1948,9 @@ png_write_finish_row(png_structp png_ptr) { if (png_ptr->prev_row != NULL) png_memset(png_ptr->prev_row, 0, - (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels* - png_ptr->usr_bit_depth, png_ptr->width)) + 1); + (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels* + png_ptr->usr_bit_depth, png_ptr->width)) + 1); + return; } } @@ -1892,6 +1962,7 @@ png_write_finish_row(png_structp png_ptr) { /* Tell the compressor we are done */ ret = deflate(&png_ptr->zstream, Z_FINISH); + /* Check for an error */ if (ret == Z_OK) { @@ -1903,10 +1974,12 @@ png_write_finish_row(png_structp png_ptr) png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; } } + else if (ret != Z_STREAM_END) { if (png_ptr->zstream.msg != NULL) png_error(png_ptr, png_ptr->zstream.msg); + else png_error(png_ptr, "zlib error"); } @@ -1916,7 +1989,7 @@ png_write_finish_row(png_structp png_ptr) if (png_ptr->zstream.avail_out < png_ptr->zbuf_size) { png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size - - png_ptr->zstream.avail_out); + png_ptr->zstream.avail_out); } deflateReset(&png_ptr->zstream); @@ -1963,6 +2036,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) dp = row; d = 0; shift = 7; + for (i = png_pass_start[pass]; i < row_width; i += png_pass_inc[pass]) { @@ -1976,14 +2050,17 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) *dp++ = (png_byte)d; d = 0; } + else shift--; } if (shift != 7) *dp = (png_byte)d; + break; } + case 2: { png_bytep sp; @@ -1997,6 +2074,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) dp = row; shift = 6; d = 0; + for (i = png_pass_start[pass]; i < row_width; i += png_pass_inc[pass]) { @@ -2010,13 +2088,16 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) *dp++ = (png_byte)d; d = 0; } + else shift -= 2; } if (shift != 6) - *dp = (png_byte)d; + *dp = (png_byte)d; + break; } + case 4: { png_bytep sp; @@ -2031,7 +2112,7 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) shift = 4; d = 0; for (i = png_pass_start[pass]; i < row_width; - i += png_pass_inc[pass]) + i += png_pass_inc[pass]) { sp = row + (png_size_t)(i >> 1); value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f; @@ -2043,13 +2124,16 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) *dp++ = (png_byte)d; d = 0; } + else shift -= 4; } if (shift != 4) *dp = (png_byte)d; + break; } + default: { png_bytep sp; @@ -2060,18 +2144,21 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) /* Start at the beginning */ dp = row; + /* Find out how many bytes each pixel takes up */ pixel_bytes = (row_info->pixel_depth >> 3); - /* Loop through the row, only looking at the pixels that - matter */ + + /* Loop through the row, only looking at the pixels that matter */ for (i = png_pass_start[pass]; i < row_width; i += png_pass_inc[pass]) { /* Find out where the original pixel is */ sp = row + (png_size_t)i * pixel_bytes; + /* Move the pixel */ if (dp != sp) png_memcpy(dp, sp, pixel_bytes); + /* Next pixel */ dp += pixel_bytes; } @@ -2080,11 +2167,12 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) } /* Set new row width */ row_info->width = (row_info->width + - png_pass_inc[pass] - 1 - - png_pass_start[pass]) / - png_pass_inc[pass]; - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, - row_info->width); + png_pass_inc[pass] - 1 - + png_pass_start[pass]) / + png_pass_inc[pass]; + + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, + row_info->width); } } #endif @@ -2105,7 +2193,7 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) png_bytep prev_row, row_buf; png_uint_32 mins, bpp; png_byte filter_to_do = png_ptr->do_filter; - png_uint_32 row_bytes = row_info->rowbytes; + png_size_t row_bytes = row_info->rowbytes; #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED int num_p_filters = (int)png_ptr->num_prev_filters; #endif @@ -2115,8 +2203,8 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) #ifndef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED if (png_ptr->row_number == 0 && filter_to_do == PNG_ALL_FILTERS) { - /* These will never be selected so we need not test them. */ - filter_to_do &= ~(PNG_FILTER_UP | PNG_FILTER_PAETH); + /* These will never be selected so we need not test them. */ + filter_to_do &= ~(PNG_FILTER_UP | PNG_FILTER_PAETH); } #endif @@ -2142,11 +2230,14 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) * computationally expensive). * * GRR 980525: consider also + * * (1) minimum sum of absolute differences from running average (i.e., * keep running sum of non-absolute differences & count of bytes) * [track dispersion, too? restart average if dispersion too large?] + * * (1b) minimum sum of absolute differences from sliding average, probably * with window size <= deflate window (usually 32K) + * * (2) minimum sum of squared differences from zero or running average * (i.e., ~ root-mean-square approach) */ @@ -2155,12 +2246,11 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) /* We don't need to test the 'no filter' case if this is the only filter * that has been chosen, as it doesn't actually do anything to the data. */ - if ((filter_to_do & PNG_FILTER_NONE) && - filter_to_do != PNG_FILTER_NONE) + if ((filter_to_do & PNG_FILTER_NONE) && filter_to_do != PNG_FILTER_NONE) { png_bytep rp; png_uint_32 sum = 0; - png_uint_32 i; + png_size_t i; int v; for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++) @@ -2183,9 +2273,10 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE) { sumlo = (sumlo * png_ptr->filter_weights[j]) >> - PNG_WEIGHT_SHIFT; + PNG_WEIGHT_SHIFT; + sumhi = (sumhi * png_ptr->filter_weights[j]) >> - PNG_WEIGHT_SHIFT; + PNG_WEIGHT_SHIFT; } } @@ -2194,12 +2285,14 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) * it has the minimum possible computational cost - none). */ sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >> - PNG_COST_SHIFT; + PNG_COST_SHIFT; + sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >> - PNG_COST_SHIFT; + PNG_COST_SHIFT; if (sumhi > PNG_HIMASK) sum = PNG_MAXSUM; + else sum = (sumhi << PNG_HISHIFT) + sumlo; } @@ -2212,17 +2305,20 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) /* It's the only filter so no testing is needed */ { png_bytep rp, lp, dp; - png_uint_32 i; + png_size_t i; + for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp; i++, rp++, dp++) { *dp = *rp; } + for (lp = row_buf + 1; i < row_bytes; i++, rp++, lp++, dp++) { *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff); } + best_row = png_ptr->sub_row; } @@ -2230,7 +2326,7 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) { png_bytep rp, dp, lp; png_uint_32 sum = 0, lmins = mins; - png_uint_32 i; + png_size_t i; int v; #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED @@ -2250,19 +2346,22 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB) { lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> - PNG_WEIGHT_SHIFT; + PNG_WEIGHT_SHIFT; + lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> - PNG_WEIGHT_SHIFT; + PNG_WEIGHT_SHIFT; } } lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> - PNG_COST_SHIFT; + PNG_COST_SHIFT; + lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> - PNG_COST_SHIFT; + PNG_COST_SHIFT; if (lmhi > PNG_HIMASK) lmins = PNG_MAXSUM; + else lmins = (lmhi << PNG_HISHIFT) + lmlo; } @@ -2275,6 +2374,7 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) sum += (v < 128) ? v : 256 - v; } + for (lp = row_buf + 1; i < row_bytes; i++, rp++, lp++, dp++) { @@ -2299,19 +2399,22 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB) { sumlo = (sumlo * png_ptr->inv_filter_weights[j]) >> - PNG_WEIGHT_SHIFT; + PNG_WEIGHT_SHIFT; + sumhi = (sumhi * png_ptr->inv_filter_weights[j]) >> - PNG_WEIGHT_SHIFT; + PNG_WEIGHT_SHIFT; } } sumlo = (sumlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> - PNG_COST_SHIFT; + PNG_COST_SHIFT; + sumhi = (sumhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >> - PNG_COST_SHIFT; + PNG_COST_SHIFT; if (sumhi > PNG_HIMASK) sum = PNG_MAXSUM; + else sum = (sumhi << PNG_HISHIFT) + sumlo; } @@ -2328,14 +2431,15 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) if (filter_to_do == PNG_FILTER_UP) { png_bytep rp, dp, pp; - png_uint_32 i; + png_size_t i; for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1, - pp = prev_row + 1; i < row_bytes; - i++, rp++, pp++, dp++) + pp = prev_row + 1; i < row_bytes; + i++, rp++, pp++, dp++) { *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff); } + best_row = png_ptr->up_row; } @@ -2343,7 +2447,7 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) { png_bytep rp, dp, pp; png_uint_32 sum = 0, lmins = mins; - png_uint_32 i; + png_size_t i; int v; @@ -2360,26 +2464,29 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP) { lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> - PNG_WEIGHT_SHIFT; + PNG_WEIGHT_SHIFT; + lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> - PNG_WEIGHT_SHIFT; + PNG_WEIGHT_SHIFT; } } lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >> - PNG_COST_SHIFT; + PNG_COST_SHIFT; + lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >> - PNG_COST_SHIFT; + PNG_COST_SHIFT; if (lmhi > PNG_HIMASK) lmins = PNG_MAXSUM; + else lmins = (lmhi << PNG_HISHIFT) + lmlo; } #endif for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1, - pp = prev_row + 1; i < row_bytes; i++) + pp = prev_row + 1; i < row_bytes; i++) { v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff); @@ -2402,19 +2509,22 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP) { sumlo = (sumlo * png_ptr->filter_weights[j]) >> - PNG_WEIGHT_SHIFT; + PNG_WEIGHT_SHIFT; + sumhi = (sumhi * png_ptr->filter_weights[j]) >> - PNG_WEIGHT_SHIFT; + PNG_WEIGHT_SHIFT; } } sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >> - PNG_COST_SHIFT; + PNG_COST_SHIFT; + sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >> - PNG_COST_SHIFT; + PNG_COST_SHIFT; if (sumhi > PNG_HIMASK) sum = PNG_MAXSUM; + else sum = (sumhi << PNG_HISHIFT) + sumlo; } @@ -2432,11 +2542,13 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) { png_bytep rp, dp, pp, lp; png_uint_32 i; + for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1, pp = prev_row + 1; i < bpp; i++) { *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff); } + for (lp = row_buf + 1; i < row_bytes; i++) { *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) @@ -2449,7 +2561,7 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) { png_bytep rp, dp, pp, lp; png_uint_32 sum = 0, lmins = mins; - png_uint_32 i; + png_size_t i; int v; #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED @@ -2465,19 +2577,22 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_AVG) { lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> - PNG_WEIGHT_SHIFT; + PNG_WEIGHT_SHIFT; + lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> - PNG_WEIGHT_SHIFT; + PNG_WEIGHT_SHIFT; } } lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >> - PNG_COST_SHIFT; + PNG_COST_SHIFT; + lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >> - PNG_COST_SHIFT; + PNG_COST_SHIFT; if (lmhi > PNG_HIMASK) lmins = PNG_MAXSUM; + else lmins = (lmhi << PNG_HISHIFT) + lmlo; } @@ -2490,10 +2605,11 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) sum += (v < 128) ? v : 256 - v; } + for (lp = row_buf + 1; i < row_bytes; i++) { v = *dp++ = - (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) & 0xff); + (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) & 0xff); sum += (v < 128) ? v : 256 - v; @@ -2514,19 +2630,22 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE) { sumlo = (sumlo * png_ptr->filter_weights[j]) >> - PNG_WEIGHT_SHIFT; + PNG_WEIGHT_SHIFT; + sumhi = (sumhi * png_ptr->filter_weights[j]) >> - PNG_WEIGHT_SHIFT; + PNG_WEIGHT_SHIFT; } } sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >> - PNG_COST_SHIFT; + PNG_COST_SHIFT; + sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >> - PNG_COST_SHIFT; + PNG_COST_SHIFT; if (sumhi > PNG_HIMASK) sum = PNG_MAXSUM; + else sum = (sumhi << PNG_HISHIFT) + sumlo; } @@ -2543,9 +2662,10 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) if (filter_to_do == PNG_FILTER_PAETH) { png_bytep rp, dp, pp, cp, lp; - png_uint_32 i; + png_size_t i; + for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1, - pp = prev_row + 1; i < bpp; i++) + pp = prev_row + 1; i < bpp; i++) { *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff); } @@ -2582,7 +2702,7 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) { png_bytep rp, dp, pp, cp, lp; png_uint_32 sum = 0, lmins = mins; - png_uint_32 i; + png_size_t i; int v; #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED @@ -2598,26 +2718,29 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH) { lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >> - PNG_WEIGHT_SHIFT; + PNG_WEIGHT_SHIFT; + lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >> - PNG_WEIGHT_SHIFT; + PNG_WEIGHT_SHIFT; } } lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >> - PNG_COST_SHIFT; + PNG_COST_SHIFT; + lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >> - PNG_COST_SHIFT; + PNG_COST_SHIFT; if (lmhi > PNG_HIMASK) lmins = PNG_MAXSUM; + else lmins = (lmhi << PNG_HISHIFT) + lmlo; } #endif for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1, - pp = prev_row + 1; i < bpp; i++) + pp = prev_row + 1; i < bpp; i++) { v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff); @@ -2650,10 +2773,13 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) pa = abs(p - a); pb = abs(p - b); pc = abs(p - c); + if (pa <= pb && pa <= pc) p = a; + else if (pb <= pc) p = b; + else p = c; #endif /* PNG_SLOW_PAETH */ @@ -2679,19 +2805,22 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH) { sumlo = (sumlo * png_ptr->filter_weights[j]) >> - PNG_WEIGHT_SHIFT; + PNG_WEIGHT_SHIFT; + sumhi = (sumhi * png_ptr->filter_weights[j]) >> - PNG_WEIGHT_SHIFT; + PNG_WEIGHT_SHIFT; } } sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >> - PNG_COST_SHIFT; + PNG_COST_SHIFT; + sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >> - PNG_COST_SHIFT; + PNG_COST_SHIFT; if (sumhi > PNG_HIMASK) sum = PNG_MAXSUM; + else sum = (sumhi << PNG_HISHIFT) + sumlo; } @@ -2713,10 +2842,12 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) if (png_ptr->num_prev_filters > 0) { int j; + for (j = 1; j < num_p_filters; j++) { png_ptr->prev_filters[j] = png_ptr->prev_filters[j - 1]; } + png_ptr->prev_filters[j] = best_row[0]; } #endif @@ -2728,25 +2859,54 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) void /* PRIVATE */ png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row) { + png_size_t avail; + png_debug(1, "in png_write_filtered_row"); png_debug1(2, "filter = %d", filtered_row[0]); /* Set up the zlib input buffer */ png_ptr->zstream.next_in = filtered_row; - png_ptr->zstream.avail_in = (uInt)png_ptr->row_info.rowbytes + 1; + png_ptr->zstream.avail_in = 0; + avail = png_ptr->row_info.rowbytes + 1; /* Repeat until we have compressed all the data */ do { int ret; /* Return of zlib */ + /* Record the number of bytes available - zlib supports at least 65535 + * bytes at one step, depending on the size of the zlib type 'uInt', the + * maximum size zlib can write at once is ZLIB_IO_MAX (from pngpriv.h). + * Use this because on 16 bit systems 'rowbytes' can be up to 65536 (i.e. + * one more than 16 bits) and, in this case 'rowbytes+1' can overflow a + * uInt. ZLIB_IO_MAX can be safely reduced to cause zlib to be called + * with smaller chunks of data. + */ + if (png_ptr->zstream.avail_in == 0) + { + if (avail > ZLIB_IO_MAX) + { + png_ptr->zstream.avail_in = ZLIB_IO_MAX; + avail -= ZLIB_IO_MAX; + } + + else + { + /* So this will fit in the available uInt space: */ + png_ptr->zstream.avail_in = (uInt)avail; + avail = 0; + } + } + /* Compress the data */ ret = deflate(&png_ptr->zstream, Z_NO_FLUSH); + /* Check for compression errors */ if (ret != Z_OK) { if (png_ptr->zstream.msg != NULL) png_error(png_ptr, png_ptr->zstream.msg); + else png_error(png_ptr, "zlib error"); } @@ -2760,7 +2920,7 @@ png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row) png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; } /* Repeat until all data has been compressed */ - } while (png_ptr->zstream.avail_in); + } while (avail > 0 || png_ptr->zstream.avail_in > 0); /* Swap the current and previous rows */ if (png_ptr->prev_row != NULL)