diff --git a/3rdparty/wxWidgets/build/msw/wx_core_2008.vcproj b/3rdparty/wxWidgets/build/msw/wx_core_2008.vcproj index 1be4120fe5..e22b32bb3e 100644 --- a/3rdparty/wxWidgets/build/msw/wx_core_2008.vcproj +++ b/3rdparty/wxWidgets/build/msw/wx_core_2008.vcproj @@ -4270,40 +4270,6 @@ /> - - - - - - - - - - - @@ -4644,40 +4610,6 @@ /> - - - - - - - - - - - diff --git a/3rdparty/wxWidgets/src/png/LICENSE b/3rdparty/wxWidgets/src/png/LICENSE new file mode 100644 index 0000000000..97d066c2d2 --- /dev/null +++ b/3rdparty/wxWidgets/src/png/LICENSE @@ -0,0 +1,111 @@ + +This copy of the libpng notices is provided for your convenience. In case of +any discrepancy between this copy and the notices in the file png.h that is +included in the libpng distribution, the latter shall prevail. + +COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: + +If you modify libpng you may insert additional notices immediately following +this sentence. + +This code is released under the libpng license. + +libpng versions 1.2.6, August 15, 2004, through 1.2.39, August 13, 2009, are +Copyright (c) 2004, 2006-2009 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 + + Cosmin Truta + +libpng versions 1.0.7, July 1, 2000, through 1.2.5 - October 3, 2002, are +Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are +distributed according to the same disclaimer and license as libpng-1.0.6 +with the following individuals added to the list of Contributing Authors + + Simon-Pierre Cadieux + Eric S. Raymond + Gilles Vollant + +and with the following additions to the disclaimer: + + There is no warranty against interference with your enjoyment of the + library or against infringement. There is no warranty that our + efforts or the library will fulfill any of your particular purposes + or needs. This library is provided with all faults, and the entire + risk of satisfactory quality, performance, accuracy, and effort is with + the user. + +libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are +Copyright (c) 1998, 1999 Glenn Randers-Pehrson, and are +distributed according to the same disclaimer and license as libpng-0.96, +with the following individuals added to the list of Contributing Authors: + + Tom Lane + Glenn Randers-Pehrson + Willem van Schaik + +libpng versions 0.89, June 1996, through 0.96, May 1997, are +Copyright (c) 1996, 1997 Andreas Dilger +Distributed according to the same disclaimer and license as libpng-0.88, +with the following individuals added to the list of Contributing Authors: + + John Bowler + Kevin Bracey + Sam Bushell + Magnus Holmgren + Greg Roelofs + Tom Tanner + +libpng versions 0.5, May 1995, through 0.88, January 1996, are +Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc. + +For the purposes of this copyright and license, "Contributing Authors" +is defined as the following set of individuals: + + Andreas Dilger + Dave Martindale + Guy Eric Schalnat + Paul Schmidt + Tim Wegner + +The PNG Reference Library is supplied "AS IS". The Contributing Authors +and Group 42, Inc. disclaim all warranties, expressed or implied, +including, without limitation, the warranties of merchantability and of +fitness for any purpose. The Contributing Authors and Group 42, Inc. +assume no liability for direct, indirect, incidental, special, exemplary, +or consequential damages, which may result from the use of the PNG +Reference Library, even if advised of the possibility of such damage. + +Permission is hereby granted to use, copy, modify, and distribute this +source code, or portions hereof, for any purpose, without fee, subject +to the following restrictions: + +1. The origin of this source code must not be misrepresented. + +2. Altered versions must be plainly marked as such and must not + be misrepresented as being the original source. + +3. This Copyright notice may not be removed or altered from any + source or altered source distribution. + +The Contributing Authors and Group 42, Inc. specifically permit, without +fee, and encourage the use of this source code as a component to +supporting the PNG file format in commercial products. If you use this +source code in a product, acknowledgment is not required but would be +appreciated. + + +A "png_get_copyright" function is available, for convenient use in "about" +boxes and the like: + + printf("%s",png_get_copyright(NULL)); + +Also, the PNG logo (in PNG format, of course) is supplied in the +files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31). + +Libpng is OSI Certified Open Source Software. OSI Certified Open Source is a +certification mark of the Open Source Initiative. + +Glenn Randers-Pehrson +glennrp at users.sourceforge.net +August 13, 2009 diff --git a/3rdparty/wxWidgets/src/png/png.c b/3rdparty/wxWidgets/src/png/png.c index a0332b9abc..c1f3e3e8d3 100644 --- a/3rdparty/wxWidgets/src/png/png.c +++ b/3rdparty/wxWidgets/src/png/png.c @@ -1,11 +1,14 @@ /* png.c - location for general purpose libpng functions * - * libpng version 1.2.7 - September 12, 2004 - * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2004 Glenn Randers-Pehrson + * Last changed in libpng 1.2.39 [August 13, 2009] + * Copyright (c) 1998-2009 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. + * For conditions of distribution and use, see the disclaimer + * and license in png.h */ #define PNG_INTERNAL @@ -13,18 +16,21 @@ #include "png.h" /* Generate a compiler error if there is an old png.h in the search path. */ -typedef version_1_2_7 Your_png_h_is_not_version_1_2_7; +typedef version_1_2_39 Your_png_h_is_not_version_1_2_39; /* Version information for C files. This had better match the version * string defined in png.h. */ #ifdef PNG_USE_GLOBAL_ARRAYS /* png_libpng_ver was changed to a function in version 1.0.5c */ -const char png_libpng_ver[18] = PNG_LIBPNG_VER_STRING; +PNG_CONST char png_libpng_ver[18] = PNG_LIBPNG_VER_STRING; + +#ifdef PNG_READ_SUPPORTED /* png_sig was changed to a function in version 1.0.5c */ /* Place to hold the signature string for a PNG file. */ -const png_byte FARDATA png_sig[8] = {137, 80, 78, 71, 13, 10, 26, 10}; +PNG_CONST png_byte FARDATA png_sig[8] = {137, 80, 78, 71, 13, 10, 26, 10}; +#endif /* PNG_READ_SUPPORTED */ /* Invoke global declarations for constant strings for known chunk types */ PNG_IHDR; @@ -49,38 +55,35 @@ PNG_tIME; PNG_tRNS; PNG_zTXt; -/* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ +#ifdef PNG_READ_SUPPORTED +/* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ -/* start of interlace block */ -const int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; +/* Start of interlace block */ +PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; -/* offset to next interlace block */ -const int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; +/* Offset to next interlace block */ +PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; -/* start of interlace block in the y direction */ -const int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; +/* Start of interlace block in the y direction */ +PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; -/* offset to next interlace block in the y direction */ -const int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; - -/* width of interlace block (used in assembler routines only) */ -#ifdef PNG_HAVE_ASSEMBLER_COMBINE_ROW -const int FARDATA png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; -#endif +/* Offset to next interlace block in the y direction */ +PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; /* Height of interlace block. This is not currently used - if you need * it, uncomment it here and in png.h -const int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1}; +PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1}; */ /* Mask to determine which pixels are valid in a pass */ -const int FARDATA png_pass_mask[] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff}; +PNG_CONST int FARDATA png_pass_mask[] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff}; /* Mask to determine which pixels to overwrite while displaying */ -const int FARDATA png_pass_dsp_mask[] +PNG_CONST int FARDATA png_pass_dsp_mask[] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff}; -#endif +#endif /* PNG_READ_SUPPORTED */ +#endif /* PNG_USE_GLOBAL_ARRAYS */ /* 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 @@ -88,10 +91,13 @@ const int FARDATA png_pass_dsp_mask[] * or write any of the magic bytes before it starts on the IHDR. */ +#ifdef PNG_READ_SUPPORTED void PNGAPI png_set_sig_bytes(png_structp png_ptr, int num_bytes) { - png_debug(1, "in png_set_sig_bytes\n"); + if (png_ptr == NULL) + return; + png_debug(1, "in png_set_sig_bytes"); if (num_bytes > 8) png_error(png_ptr, "Too many bytes for PNG signature."); @@ -113,10 +119,10 @@ png_sig_cmp(png_bytep sig, png_size_t start, png_size_t num_to_check) if (num_to_check > 8) num_to_check = 8; else if (num_to_check < 1) - return (0); + return (-1); if (start > 7) - return (0); + return (-1); if (start + num_to_check > 8) num_to_check = 8 - start; @@ -124,32 +130,38 @@ png_sig_cmp(png_bytep sig, png_size_t start, png_size_t num_to_check) return ((int)(png_memcmp(&sig[start], &png_signature[start], num_to_check))); } +#if defined(PNG_1_0_X) || defined(PNG_1_2_X) /* (Obsolete) function to check signature bytes. It does not allow one * to check a partial signature. This function might be removed in the - * future - use png_sig_cmp(). Returns true (nonzero) if the file is a PNG. + * future - use png_sig_cmp(). Returns true (nonzero) if the file is PNG. */ int PNGAPI png_check_sig(png_bytep sig, int num) { return ((int)!png_sig_cmp(sig, (png_size_t)0, (png_size_t)num)); } +#endif +#endif /* PNG_READ_SUPPORTED */ +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) /* Function to allocate memory for zlib and clear it to 0. */ #ifdef PNG_1_0_X voidpf PNGAPI #else -voidpf /* private */ +voidpf /* PRIVATE */ #endif png_zalloc(voidpf png_ptr, uInt items, uInt size) { png_voidp ptr; - png_structp p=(png_struct*)png_ptr; + png_structp p=(png_structp)png_ptr; png_uint_32 save_flags=p->flags; png_uint_32 num_bytes; + if (png_ptr == NULL) + return (NULL); if (items > PNG_UINT_32_MAX/size) { - png_warning (png_ptr, "Potential overflow in png_zalloc()"); + png_warning (p, "Potential overflow in png_zalloc()"); return (NULL); } num_bytes = (png_uint_32)items * size; @@ -176,11 +188,11 @@ png_zalloc(voidpf png_ptr, uInt items, uInt size) return ((voidpf)ptr); } -/* function to free memory for zlib */ +/* Function to free memory for zlib */ #ifdef PNG_1_0_X void PNGAPI #else -void /* private */ +void /* PRIVATE */ #endif png_zfree(voidpf png_ptr, voidpf ptr) { @@ -233,8 +245,9 @@ png_create_info_struct(png_structp png_ptr) { png_infop info_ptr; - png_debug(1, "in png_create_info_struct\n"); - if(png_ptr == NULL) return (NULL); + png_debug(1, "in png_create_info_struct"); + if (png_ptr == NULL) + return (NULL); #ifdef PNG_USER_MEM_SUPPORTED info_ptr = (png_infop)png_create_struct_2(PNG_STRUCT_INFO, png_ptr->malloc_fn, png_ptr->mem_ptr); @@ -256,8 +269,10 @@ void PNGAPI png_destroy_info_struct(png_structp png_ptr, png_infopp info_ptr_ptr) { png_infop info_ptr = NULL; + if (png_ptr == NULL) + return; - png_debug(1, "in png_destroy_info_struct\n"); + png_debug(1, "in png_destroy_info_struct"); if (info_ptr_ptr != NULL) info_ptr = *info_ptr_ptr; @@ -279,6 +294,7 @@ png_destroy_info_struct(png_structp png_ptr, png_infopp info_ptr_ptr) * and applications using it are urged to use png_create_info_struct() * instead. */ +#if defined(PNG_1_0_X) || defined(PNG_1_2_X) #undef png_info_init void PNGAPI png_info_init(png_infop info_ptr) @@ -286,23 +302,27 @@ png_info_init(png_infop info_ptr) /* We only come here via pre-1.0.12-compiled applications */ png_info_init_3(&info_ptr, 0); } +#endif void PNGAPI png_info_init_3(png_infopp ptr_ptr, png_size_t png_info_struct_size) { png_infop info_ptr = *ptr_ptr; - png_debug(1, "in png_info_init_3\n"); + if (info_ptr == NULL) + return; - if(png_sizeof(png_info) > png_info_struct_size) - { - png_destroy_struct(info_ptr); - info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO); - *ptr_ptr = info_ptr; - } + png_debug(1, "in png_info_init_3"); - /* set everything to 0 */ - png_memset(info_ptr, 0, png_sizeof (png_info)); + if (png_sizeof(png_info) > png_info_struct_size) + { + png_destroy_struct(info_ptr); + info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO); + *ptr_ptr = info_ptr; + } + + /* Set everything to 0 */ + png_memset(info_ptr, 0, png_sizeof(png_info)); } #ifdef PNG_FREE_ME_SUPPORTED @@ -310,12 +330,12 @@ void PNGAPI png_data_freer(png_structp png_ptr, png_infop info_ptr, int freer, png_uint_32 mask) { - png_debug(1, "in png_data_freer\n"); + png_debug(1, "in png_data_freer"); if (png_ptr == NULL || info_ptr == NULL) return; - if(freer == PNG_DESTROY_WILL_FREE_DATA) + if (freer == PNG_DESTROY_WILL_FREE_DATA) info_ptr->free_me |= mask; - else if(freer == PNG_USER_WILL_FREE_DATA) + else if (freer == PNG_USER_WILL_FREE_DATA) info_ptr->free_me &= ~mask; else png_warning(png_ptr, @@ -327,244 +347,250 @@ void PNGAPI png_free_data(png_structp png_ptr, png_infop info_ptr, png_uint_32 mask, int num) { - png_debug(1, "in png_free_data\n"); + png_debug(1, "in png_free_data"); if (png_ptr == NULL || info_ptr == NULL) return; #if defined(PNG_TEXT_SUPPORTED) -/* free text item num or (if num == -1) all text items */ + /* Free text item num or (if num == -1) all text items */ #ifdef PNG_FREE_ME_SUPPORTED -if ((mask & PNG_FREE_TEXT) & info_ptr->free_me) + if ((mask & PNG_FREE_TEXT) & info_ptr->free_me) #else -if (mask & PNG_FREE_TEXT) + if (mask & PNG_FREE_TEXT) #endif -{ - if (num != -1) { - if (info_ptr->text && info_ptr->text[num].key) - { - png_free(png_ptr, info_ptr->text[num].key); - info_ptr->text[num].key = NULL; - } + if (num != -1) + { + if (info_ptr->text && info_ptr->text[num].key) + { + png_free(png_ptr, info_ptr->text[num].key); + info_ptr->text[num].key = NULL; + } + } + else + { + int i; + for (i = 0; i < info_ptr->num_text; i++) + png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, i); + png_free(png_ptr, info_ptr->text); + info_ptr->text = NULL; + info_ptr->num_text=0; + } } - else - { - int i; - for (i = 0; i < info_ptr->num_text; i++) - png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, i); - png_free(png_ptr, info_ptr->text); - info_ptr->text = NULL; - info_ptr->num_text=0; - } -} #endif #if defined(PNG_tRNS_SUPPORTED) -/* free any tRNS entry */ + /* Free any tRNS entry */ #ifdef PNG_FREE_ME_SUPPORTED -if ((mask & PNG_FREE_TRNS) & info_ptr->free_me) + if ((mask & PNG_FREE_TRNS) & info_ptr->free_me) #else -if ((mask & PNG_FREE_TRNS) && (png_ptr->flags & PNG_FLAG_FREE_TRNS)) + if ((mask & PNG_FREE_TRNS) && (png_ptr->flags & PNG_FLAG_FREE_TRNS)) #endif -{ - png_free(png_ptr, info_ptr->trans); - info_ptr->valid &= ~PNG_INFO_tRNS; + { + png_free(png_ptr, info_ptr->trans); + info_ptr->trans = NULL; + info_ptr->valid &= ~PNG_INFO_tRNS; #ifndef PNG_FREE_ME_SUPPORTED - png_ptr->flags &= ~PNG_FLAG_FREE_TRNS; + png_ptr->flags &= ~PNG_FLAG_FREE_TRNS; #endif - info_ptr->trans = NULL; -} + } #endif #if defined(PNG_sCAL_SUPPORTED) -/* free any sCAL entry */ + /* Free any sCAL entry */ #ifdef PNG_FREE_ME_SUPPORTED -if ((mask & PNG_FREE_SCAL) & info_ptr->free_me) + if ((mask & PNG_FREE_SCAL) & info_ptr->free_me) #else -if (mask & PNG_FREE_SCAL) + if (mask & PNG_FREE_SCAL) #endif -{ + { #if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) - png_free(png_ptr, info_ptr->scal_s_width); - png_free(png_ptr, info_ptr->scal_s_height); - info_ptr->scal_s_width = NULL; - info_ptr->scal_s_height = NULL; + png_free(png_ptr, info_ptr->scal_s_width); + png_free(png_ptr, info_ptr->scal_s_height); + info_ptr->scal_s_width = NULL; + info_ptr->scal_s_height = NULL; #endif - info_ptr->valid &= ~PNG_INFO_sCAL; -} + info_ptr->valid &= ~PNG_INFO_sCAL; + } #endif #if defined(PNG_pCAL_SUPPORTED) -/* free any pCAL entry */ + /* Free any pCAL entry */ #ifdef PNG_FREE_ME_SUPPORTED -if ((mask & PNG_FREE_PCAL) & info_ptr->free_me) + if ((mask & PNG_FREE_PCAL) & info_ptr->free_me) #else -if (mask & PNG_FREE_PCAL) + if (mask & PNG_FREE_PCAL) #endif -{ - png_free(png_ptr, info_ptr->pcal_purpose); - png_free(png_ptr, info_ptr->pcal_units); - info_ptr->pcal_purpose = NULL; - info_ptr->pcal_units = NULL; - if (info_ptr->pcal_params != NULL) - { - int i; - for (i = 0; i < (int)info_ptr->pcal_nparams; i++) - { - png_free(png_ptr, info_ptr->pcal_params[i]); - info_ptr->pcal_params[i]=NULL; - } - png_free(png_ptr, info_ptr->pcal_params); - info_ptr->pcal_params = NULL; - } - info_ptr->valid &= ~PNG_INFO_pCAL; -} + { + png_free(png_ptr, info_ptr->pcal_purpose); + png_free(png_ptr, info_ptr->pcal_units); + info_ptr->pcal_purpose = NULL; + info_ptr->pcal_units = NULL; + if (info_ptr->pcal_params != NULL) + { + int i; + for (i = 0; i < (int)info_ptr->pcal_nparams; i++) + { + png_free(png_ptr, info_ptr->pcal_params[i]); + info_ptr->pcal_params[i]=NULL; + } + png_free(png_ptr, info_ptr->pcal_params); + info_ptr->pcal_params = NULL; + } + info_ptr->valid &= ~PNG_INFO_pCAL; + } #endif #if defined(PNG_iCCP_SUPPORTED) -/* free any iCCP entry */ + /* Free any iCCP entry */ #ifdef PNG_FREE_ME_SUPPORTED -if ((mask & PNG_FREE_ICCP) & info_ptr->free_me) + if ((mask & PNG_FREE_ICCP) & info_ptr->free_me) #else -if (mask & PNG_FREE_ICCP) + if (mask & PNG_FREE_ICCP) #endif -{ - png_free(png_ptr, info_ptr->iccp_name); - png_free(png_ptr, info_ptr->iccp_profile); - info_ptr->iccp_name = NULL; - info_ptr->iccp_profile = NULL; - info_ptr->valid &= ~PNG_INFO_iCCP; -} + { + png_free(png_ptr, info_ptr->iccp_name); + png_free(png_ptr, info_ptr->iccp_profile); + info_ptr->iccp_name = NULL; + info_ptr->iccp_profile = NULL; + info_ptr->valid &= ~PNG_INFO_iCCP; + } #endif #if defined(PNG_sPLT_SUPPORTED) -/* free a given sPLT entry, or (if num == -1) all sPLT entries */ + /* Free a given sPLT entry, or (if num == -1) all sPLT entries */ #ifdef PNG_FREE_ME_SUPPORTED -if ((mask & PNG_FREE_SPLT) & info_ptr->free_me) + if ((mask & PNG_FREE_SPLT) & info_ptr->free_me) #else -if (mask & PNG_FREE_SPLT) + if (mask & PNG_FREE_SPLT) #endif -{ - if (num != -1) { - if(info_ptr->splt_palettes) + if (num != -1) { - png_free(png_ptr, info_ptr->splt_palettes[num].name); - png_free(png_ptr, info_ptr->splt_palettes[num].entries); - info_ptr->splt_palettes[num].name = NULL; - info_ptr->splt_palettes[num].entries = NULL; + if (info_ptr->splt_palettes) + { + png_free(png_ptr, info_ptr->splt_palettes[num].name); + png_free(png_ptr, info_ptr->splt_palettes[num].entries); + info_ptr->splt_palettes[num].name = NULL; + info_ptr->splt_palettes[num].entries = NULL; + } + } + else + { + if (info_ptr->splt_palettes_num) + { + int i; + for (i = 0; i < (int)info_ptr->splt_palettes_num; i++) + png_free_data(png_ptr, info_ptr, PNG_FREE_SPLT, i); + + png_free(png_ptr, info_ptr->splt_palettes); + info_ptr->splt_palettes = NULL; + info_ptr->splt_palettes_num = 0; + } + info_ptr->valid &= ~PNG_INFO_sPLT; } } - else - { - if(info_ptr->splt_palettes_num) - { - int i; - for (i = 0; i < (int)info_ptr->splt_palettes_num; i++) - png_free_data(png_ptr, info_ptr, PNG_FREE_SPLT, i); - - png_free(png_ptr, info_ptr->splt_palettes); - info_ptr->splt_palettes = NULL; - info_ptr->splt_palettes_num = 0; - } - info_ptr->valid &= ~PNG_INFO_sPLT; - } -} #endif #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) + if (png_ptr->unknown_chunk.data) + { + png_free(png_ptr, png_ptr->unknown_chunk.data); + png_ptr->unknown_chunk.data = NULL; + } + #ifdef PNG_FREE_ME_SUPPORTED -if ((mask & PNG_FREE_UNKN) & info_ptr->free_me) + if ((mask & PNG_FREE_UNKN) & info_ptr->free_me) #else -if (mask & PNG_FREE_UNKN) + if (mask & PNG_FREE_UNKN) #endif -{ - if (num != -1) { - if(info_ptr->unknown_chunks) - { - png_free(png_ptr, info_ptr->unknown_chunks[num].data); - info_ptr->unknown_chunks[num].data = NULL; - } - } - else - { - int i; + if (num != -1) + { + if (info_ptr->unknown_chunks) + { + png_free(png_ptr, info_ptr->unknown_chunks[num].data); + 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++) - png_free_data(png_ptr, info_ptr, PNG_FREE_UNKN, i); + if (info_ptr->unknown_chunks_num) + { + for (i = 0; i < (int)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); - info_ptr->unknown_chunks = NULL; - info_ptr->unknown_chunks_num = 0; - } + png_free(png_ptr, info_ptr->unknown_chunks); + info_ptr->unknown_chunks = NULL; + info_ptr->unknown_chunks_num = 0; + } + } } -} #endif #if defined(PNG_hIST_SUPPORTED) -/* free any hIST entry */ + /* Free any hIST entry */ #ifdef PNG_FREE_ME_SUPPORTED -if ((mask & PNG_FREE_HIST) & info_ptr->free_me) + if ((mask & PNG_FREE_HIST) & info_ptr->free_me) #else -if ((mask & PNG_FREE_HIST) && (png_ptr->flags & PNG_FLAG_FREE_HIST)) + if ((mask & PNG_FREE_HIST) && (png_ptr->flags & PNG_FLAG_FREE_HIST)) #endif -{ - png_free(png_ptr, info_ptr->hist); - info_ptr->hist = NULL; - info_ptr->valid &= ~PNG_INFO_hIST; + { + png_free(png_ptr, info_ptr->hist); + info_ptr->hist = NULL; + info_ptr->valid &= ~PNG_INFO_hIST; #ifndef PNG_FREE_ME_SUPPORTED - png_ptr->flags &= ~PNG_FLAG_FREE_HIST; + png_ptr->flags &= ~PNG_FLAG_FREE_HIST; #endif -} + } #endif -/* free any PLTE entry that was internally allocated */ + /* Free any PLTE entry that was internally allocated */ #ifdef PNG_FREE_ME_SUPPORTED -if ((mask & PNG_FREE_PLTE) & info_ptr->free_me) + if ((mask & PNG_FREE_PLTE) & info_ptr->free_me) #else -if ((mask & PNG_FREE_PLTE) && (png_ptr->flags & PNG_FLAG_FREE_PLTE)) + if ((mask & PNG_FREE_PLTE) && (png_ptr->flags & PNG_FLAG_FREE_PLTE)) #endif -{ - png_zfree(png_ptr, info_ptr->palette); - info_ptr->palette = NULL; - info_ptr->valid &= ~PNG_INFO_PLTE; + { + png_zfree(png_ptr, info_ptr->palette); + info_ptr->palette = NULL; + info_ptr->valid &= ~PNG_INFO_PLTE; #ifndef PNG_FREE_ME_SUPPORTED - png_ptr->flags &= ~PNG_FLAG_FREE_PLTE; + png_ptr->flags &= ~PNG_FLAG_FREE_PLTE; #endif - info_ptr->num_palette = 0; -} + info_ptr->num_palette = 0; + } #if defined(PNG_INFO_IMAGE_SUPPORTED) -/* free any image bits attached to the info structure */ + /* Free any image bits attached to the info structure */ #ifdef PNG_FREE_ME_SUPPORTED -if ((mask & PNG_FREE_ROWS) & info_ptr->free_me) + if ((mask & PNG_FREE_ROWS) & info_ptr->free_me) #else -if (mask & PNG_FREE_ROWS) + if (mask & PNG_FREE_ROWS) #endif -{ - if(info_ptr->row_pointers) - { - int row; - for (row = 0; row < (int)info_ptr->height; row++) - { - png_free(png_ptr, info_ptr->row_pointers[row]); - info_ptr->row_pointers[row]=NULL; - } - png_free(png_ptr, info_ptr->row_pointers); - info_ptr->row_pointers=NULL; - } - info_ptr->valid &= ~PNG_INFO_IDAT; -} + { + if (info_ptr->row_pointers) + { + int row; + for (row = 0; row < (int)info_ptr->height; row++) + { + png_free(png_ptr, info_ptr->row_pointers[row]); + info_ptr->row_pointers[row]=NULL; + } + png_free(png_ptr, info_ptr->row_pointers); + info_ptr->row_pointers=NULL; + } + info_ptr->valid &= ~PNG_INFO_IDAT; + } #endif #ifdef PNG_FREE_ME_SUPPORTED - if(num == -1) - info_ptr->free_me &= ~mask; + if (num == -1) + info_ptr->free_me &= ~mask; else - info_ptr->free_me &= ~(mask & ~PNG_FREE_MUL); + info_ptr->free_me &= ~(mask & ~PNG_FREE_MUL); #endif } @@ -575,21 +601,22 @@ if (mask & PNG_FREE_ROWS) void /* PRIVATE */ png_info_destroy(png_structp png_ptr, png_infop info_ptr) { - png_debug(1, "in png_info_destroy\n"); + png_debug(1, "in png_info_destroy"); png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); -#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) +#if defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED) if (png_ptr->num_chunk_list) { - png_free(png_ptr, png_ptr->chunk_list); - png_ptr->chunk_list=NULL; - png_ptr->num_chunk_list=0; + png_free(png_ptr, png_ptr->chunk_list); + png_ptr->chunk_list=NULL; + png_ptr->num_chunk_list = 0; } #endif png_info_init_3(&info_ptr, png_sizeof(png_info)); } +#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ /* This function returns a pointer to the io_ptr associated with the user * functions. The application should free any memory associated with this @@ -598,9 +625,12 @@ png_info_destroy(png_structp png_ptr, png_infop info_ptr) png_voidp PNGAPI 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) #if !defined(PNG_NO_STDIO) /* 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() @@ -611,7 +641,9 @@ png_get_io_ptr(png_structp png_ptr) void PNGAPI png_init_io(png_structp png_ptr, png_FILE_p fp) { - png_debug(1, "in png_init_io\n"); + png_debug(1, "in png_init_io"); + if (png_ptr == NULL) + return; png_ptr->io_ptr = (png_voidp)fp; } #endif @@ -627,6 +659,8 @@ png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime) {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; + 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* @@ -647,7 +681,7 @@ png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime) #ifdef USE_FAR_KEYWORD { char near_time_buf[29]; - sprintf(near_time_buf, "%d %s %d %02d:%02d:%02d +0000", + png_snprintf6(near_time_buf, 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); @@ -655,7 +689,7 @@ png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime) 29*png_sizeof(char)); } #else - sprintf(png_ptr->time_buffer, "%d %s %d %02d:%02d:%02d +0000", + 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); @@ -665,24 +699,16 @@ png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime) } #endif /* PNG_TIME_RFC1123_SUPPORTED */ -#if 0 -/* Signature string for a PNG file. */ -png_bytep PNGAPI -png_sig_bytes(void) -{ - return ((png_bytep)"\211\120\116\107\015\012\032\012"); -} -#endif +#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ png_charp PNGAPI png_get_copyright(png_structp png_ptr) { - if (&png_ptr != NULL) /* silence compiler warning about unused png_ptr */ - return ((png_charp) "\n libpng version 1.2.7 - September 12, 2004\n\ - Copyright (c) 1998-2004 Glenn Randers-Pehrson\n\ + png_ptr = png_ptr; /* Silence compiler warning about unused png_ptr */ + return ((png_charp) "\n libpng version 1.2.39 - August 13, 2009\n\ + Copyright (c) 1998-2009 Glenn Randers-Pehrson\n\ Copyright (c) 1996-1997 Andreas Dilger\n\ Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.\n"); - return ((png_charp) ""); } /* The following return the library version as a short string in the @@ -697,42 +723,44 @@ png_charp PNGAPI png_get_libpng_ver(png_structp png_ptr) { /* Version of *.c files used when building libpng */ - if (&png_ptr != NULL) /* silence compiler warning about unused png_ptr */ - return ((png_charp) PNG_LIBPNG_VER_STRING); - return ((png_charp) ""); + png_ptr = png_ptr; /* Silence compiler warning about unused png_ptr */ + return ((png_charp) PNG_LIBPNG_VER_STRING); } png_charp PNGAPI png_get_header_ver(png_structp png_ptr) { /* Version of *.h files used when building libpng */ - if (&png_ptr != NULL) /* silence compiler warning about unused png_ptr */ - return ((png_charp) PNG_LIBPNG_VER_STRING); - return ((png_charp) ""); + png_ptr = png_ptr; /* Silence compiler warning about unused png_ptr */ + return ((png_charp) PNG_LIBPNG_VER_STRING); } png_charp PNGAPI png_get_header_version(png_structp png_ptr) { /* Returns longer string containing both version and date */ - if (&png_ptr != NULL) /* silence compiler warning about unused png_ptr */ - return ((png_charp) PNG_HEADER_VERSION_STRING); - return ((png_charp) ""); + png_ptr = png_ptr; /* Silence compiler warning about unused png_ptr */ + return ((png_charp) PNG_HEADER_VERSION_STRING +#ifndef PNG_READ_SUPPORTED + " (NO READ SUPPORT)" +#endif + "\n"); } +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED int PNGAPI png_handle_as_unknown(png_structp png_ptr, png_bytep chunk_name) { - /* check chunk_name and return "keep" value if it's on the list, else 0 */ + /* 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) + 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) + 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 ((int)*(p + 4)); return 0; } #endif @@ -741,8 +769,11 @@ png_handle_as_unknown(png_structp png_ptr, png_bytep chunk_name) int PNGAPI png_reset_zstream(png_structp png_ptr) { + if (png_ptr == NULL) + return Z_STREAM_ERROR; return (inflateReset(&png_ptr->zstream)); } +#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ /* This function was added to libpng-1.0.7 */ png_uint_32 PNGAPI @@ -753,74 +784,143 @@ png_access_version_number(void) } +#if defined(PNG_READ_SUPPORTED) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) #if !defined(PNG_1_0_X) -#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) - /* GRR: could add this: && defined(PNG_MMX_CODE_SUPPORTED) */ -/* this INTERNAL function was added to libpng 1.2.0 */ -void /* PRIVATE */ -png_init_mmx_flags (png_structp png_ptr) -{ - png_ptr->mmx_rowbytes_threshold = 0; - png_ptr->mmx_bitdepth_threshold = 0; - -# if (defined(PNG_USE_PNGVCRD) || defined(PNG_USE_PNGGCCRD)) - - png_ptr->asm_flags |= PNG_ASM_FLAG_MMX_SUPPORT_COMPILED; - - if (png_mmx_support() > 0) { - png_ptr->asm_flags |= PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU -# ifdef PNG_HAVE_ASSEMBLER_COMBINE_ROW - | PNG_ASM_FLAG_MMX_READ_COMBINE_ROW -# endif -# ifdef PNG_HAVE_ASSEMBLER_READ_INTERLACE - | PNG_ASM_FLAG_MMX_READ_INTERLACE -# endif -# ifndef PNG_HAVE_ASSEMBLER_READ_FILTER_ROW - ; -# else - | PNG_ASM_FLAG_MMX_READ_FILTER_SUB - | PNG_ASM_FLAG_MMX_READ_FILTER_UP - | PNG_ASM_FLAG_MMX_READ_FILTER_AVG - | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ; - - png_ptr->mmx_rowbytes_threshold = PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT; - png_ptr->mmx_bitdepth_threshold = PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT; -# endif - } else { - png_ptr->asm_flags &= ~( PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU - | PNG_MMX_READ_FLAGS - | PNG_MMX_WRITE_FLAGS ); - } - -# else /* !((PNGVCRD || PNGGCCRD) && PNG_ASSEMBLER_CODE_SUPPORTED)) */ - - /* clear all MMX flags; no support is compiled in */ - png_ptr->asm_flags &= ~( PNG_MMX_FLAGS ); - -# endif /* ?(PNGVCRD || PNGGCCRD) */ -} - -#endif /* !(PNG_ASSEMBLER_CODE_SUPPORTED) */ - -/* this function was added to libpng 1.2.0 */ -#if !defined(PNG_USE_PNGGCCRD) && \ - !(defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_USE_PNGVCRD)) +/* This function was added to libpng 1.2.0 */ int PNGAPI png_mmx_support(void) { + /* Obsolete, to be removed from libpng-1.4.0 */ return -1; } -#endif #endif /* PNG_1_0_X */ +#endif /* PNG_READ_SUPPORTED && PNG_ASSEMBLER_CODE_SUPPORTED */ +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) #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 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); + 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 */ + +/* Added at libpng version 1.2.34 and 1.4.0 (moved from pngset.c) */ +#if defined(PNG_cHRM_SUPPORTED) +#if !defined(PNG_NO_CHECK_cHRM) + +/* + * 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; +} + +int /* PRIVATE */ +png_check_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) +{ + int ret = 1; + unsigned long xy_hi,xy_lo,yx_hi,yx_lo; + + png_debug(1, "in function png_check_cHRM_fixed"); + if (png_ptr == NULL) + return 0; + + if (white_x < 0 || white_y <= 0 || + red_x < 0 || red_y < 0 || + green_x < 0 || green_y < 0 || + blue_x < 0 || blue_y < 0) + { + png_warning(png_ptr, + "Ignoring attempt to set negative chromaticity value"); + 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 ) + { + png_warning(png_ptr, + "Ignoring attempt to set chromaticity value exceeding 21474.83"); + ret = 0; + } + if (white_x > 100000L - white_y) + { + 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"); + ret = 0; + } + + png_64bit_product(green_x - red_x, blue_y - red_y, &xy_hi, &xy_lo); + png_64bit_product(green_y - red_y, blue_x - red_x, &yx_hi, &yx_lo); + + if (xy_hi == yx_hi && xy_lo == yx_lo) + { + png_warning(png_ptr, + "Ignoring attempt to set cHRM RGB triangle with zero area"); + ret = 0; + } + + return ret; +} +#endif /* NO_PNG_CHECK_cHRM */ +#endif /* PNG_cHRM_SUPPORTED */ +#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */ diff --git a/3rdparty/wxWidgets/src/png/png.h b/3rdparty/wxWidgets/src/png/png.h index b57acb4141..f6330be318 100644 --- a/3rdparty/wxWidgets/src/png/png.h +++ b/3rdparty/wxWidgets/src/png/png.h @@ -1,14 +1,16 @@ /* png.h - header file for PNG reference library * - * libpng version 1.2.7 - September 12, 2004 - * Copyright (c) 1998-2004 Glenn Randers-Pehrson + * libpng version 1.2.39 - August 13, 2009 + * Copyright (c) 1998-2009 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.2.7 - September 12, 2004: Glenn + * libpng versions 0.97, January 1998, through 1.2.39 - August 13, 2009: Glenn * See also "Contributing Authors", below. * * Note about libpng version numbers: @@ -102,10 +104,143 @@ * 1.0.16 10 10016 10.so.0.1.0.16 * 1.2.6 13 10206 12.so.0.1.2.6 * 1.2.7beta1-2 13 10207 12.so.0.1.2.7beta1-2 - * 1.0.17rc1 10 10017 12.so.0.1.0.17rc1 + * 1.0.17rc1 10 10017 10.so.0.1.0.17rc1 * 1.2.7rc1 13 10207 12.so.0.1.2.7rc1 - * 1.0.17 10 10017 12.so.0.1.0.17 + * 1.0.17 10 10017 10.so.0.1.0.17 * 1.2.7 13 10207 12.so.0.1.2.7 + * 1.2.8beta1-5 13 10208 12.so.0.1.2.8beta1-5 + * 1.0.18rc1-5 10 10018 10.so.0.1.0.18rc1-5 + * 1.2.8rc1-5 13 10208 12.so.0.1.2.8rc1-5 + * 1.0.18 10 10018 10.so.0.1.0.18 + * 1.2.8 13 10208 12.so.0.1.2.8 + * 1.2.9beta1-3 13 10209 12.so.0.1.2.9beta1-3 + * 1.2.9beta4-11 13 10209 12.so.0.9[.0] + * 1.2.9rc1 13 10209 12.so.0.9[.0] + * 1.2.9 13 10209 12.so.0.9[.0] + * 1.2.10beta1-8 13 10210 12.so.0.10[.0] + * 1.2.10rc1-3 13 10210 12.so.0.10[.0] + * 1.2.10 13 10210 12.so.0.10[.0] + * 1.2.11beta1-4 13 10211 12.so.0.11[.0] + * 1.0.19rc1-5 10 10019 10.so.0.19[.0] + * 1.2.11rc1-5 13 10211 12.so.0.11[.0] + * 1.0.19 10 10019 10.so.0.19[.0] + * 1.2.11 13 10211 12.so.0.11[.0] + * 1.0.20 10 10020 10.so.0.20[.0] + * 1.2.12 13 10212 12.so.0.12[.0] + * 1.2.13beta1 13 10213 12.so.0.13[.0] + * 1.0.21 10 10021 10.so.0.21[.0] + * 1.2.13 13 10213 12.so.0.13[.0] + * 1.2.14beta1-2 13 10214 12.so.0.14[.0] + * 1.0.22rc1 10 10022 10.so.0.22[.0] + * 1.2.14rc1 13 10214 12.so.0.14[.0] + * 1.0.22 10 10022 10.so.0.22[.0] + * 1.2.14 13 10214 12.so.0.14[.0] + * 1.2.15beta1-6 13 10215 12.so.0.15[.0] + * 1.0.23rc1-5 10 10023 10.so.0.23[.0] + * 1.2.15rc1-5 13 10215 12.so.0.15[.0] + * 1.0.23 10 10023 10.so.0.23[.0] + * 1.2.15 13 10215 12.so.0.15[.0] + * 1.2.16beta1-2 13 10216 12.so.0.16[.0] + * 1.2.16rc1 13 10216 12.so.0.16[.0] + * 1.0.24 10 10024 10.so.0.24[.0] + * 1.2.16 13 10216 12.so.0.16[.0] + * 1.2.17beta1-2 13 10217 12.so.0.17[.0] + * 1.0.25rc1 10 10025 10.so.0.25[.0] + * 1.2.17rc1-3 13 10217 12.so.0.17[.0] + * 1.0.25 10 10025 10.so.0.25[.0] + * 1.2.17 13 10217 12.so.0.17[.0] + * 1.0.26 10 10026 10.so.0.26[.0] + * 1.2.18 13 10218 12.so.0.18[.0] + * 1.2.19beta1-31 13 10219 12.so.0.19[.0] + * 1.0.27rc1-6 10 10027 10.so.0.27[.0] + * 1.2.19rc1-6 13 10219 12.so.0.19[.0] + * 1.0.27 10 10027 10.so.0.27[.0] + * 1.2.19 13 10219 12.so.0.19[.0] + * 1.2.20beta01-04 13 10220 12.so.0.20[.0] + * 1.0.28rc1-6 10 10028 10.so.0.28[.0] + * 1.2.20rc1-6 13 10220 12.so.0.20[.0] + * 1.0.28 10 10028 10.so.0.28[.0] + * 1.2.20 13 10220 12.so.0.20[.0] + * 1.2.21beta1-2 13 10221 12.so.0.21[.0] + * 1.2.21rc1-3 13 10221 12.so.0.21[.0] + * 1.0.29 10 10029 10.so.0.29[.0] + * 1.2.21 13 10221 12.so.0.21[.0] + * 1.2.22beta1-4 13 10222 12.so.0.22[.0] + * 1.0.30rc1 10 10030 10.so.0.30[.0] + * 1.2.22rc1 13 10222 12.so.0.22[.0] + * 1.0.30 10 10030 10.so.0.30[.0] + * 1.2.22 13 10222 12.so.0.22[.0] + * 1.2.23beta01-05 13 10223 12.so.0.23[.0] + * 1.2.23rc01 13 10223 12.so.0.23[.0] + * 1.2.23 13 10223 12.so.0.23[.0] + * 1.2.24beta01-02 13 10224 12.so.0.24[.0] + * 1.2.24rc01 13 10224 12.so.0.24[.0] + * 1.2.24 13 10224 12.so.0.24[.0] + * 1.2.25beta01-06 13 10225 12.so.0.25[.0] + * 1.2.25rc01-02 13 10225 12.so.0.25[.0] + * 1.0.31 10 10031 10.so.0.31[.0] + * 1.2.25 13 10225 12.so.0.25[.0] + * 1.2.26beta01-06 13 10226 12.so.0.26[.0] + * 1.2.26rc01 13 10226 12.so.0.26[.0] + * 1.2.26 13 10226 12.so.0.26[.0] + * 1.0.32 10 10032 10.so.0.32[.0] + * 1.2.27beta01-06 13 10227 12.so.0.27[.0] + * 1.2.27rc01 13 10227 12.so.0.27[.0] + * 1.0.33 10 10033 10.so.0.33[.0] + * 1.2.27 13 10227 12.so.0.27[.0] + * 1.0.34 10 10034 10.so.0.34[.0] + * 1.2.28 13 10228 12.so.0.28[.0] + * 1.2.29beta01-03 13 10229 12.so.0.29[.0] + * 1.2.29rc01 13 10229 12.so.0.29[.0] + * 1.0.35 10 10035 10.so.0.35[.0] + * 1.2.29 13 10229 12.so.0.29[.0] + * 1.0.37 10 10037 10.so.0.37[.0] + * 1.2.30beta01-04 13 10230 12.so.0.30[.0] + * 1.0.38rc01-08 10 10038 10.so.0.38[.0] + * 1.2.30rc01-08 13 10230 12.so.0.30[.0] + * 1.0.38 10 10038 10.so.0.38[.0] + * 1.2.30 13 10230 12.so.0.30[.0] + * 1.0.39rc01-03 10 10039 10.so.0.39[.0] + * 1.2.31rc01-03 13 10231 12.so.0.31[.0] + * 1.0.39 10 10039 10.so.0.39[.0] + * 1.2.31 13 10231 12.so.0.31[.0] + * 1.2.32beta01-02 13 10232 12.so.0.32[.0] + * 1.0.40rc01 10 10040 10.so.0.40[.0] + * 1.2.32rc01 13 10232 12.so.0.32[.0] + * 1.0.40 10 10040 10.so.0.40[.0] + * 1.2.32 13 10232 12.so.0.32[.0] + * 1.2.33beta01-02 13 10233 12.so.0.33[.0] + * 1.2.33rc01-02 13 10233 12.so.0.33[.0] + * 1.0.41rc01 10 10041 10.so.0.41[.0] + * 1.2.33 13 10233 12.so.0.33[.0] + * 1.0.41 10 10041 10.so.0.41[.0] + * 1.2.34beta01-07 13 10234 12.so.0.34[.0] + * 1.0.42rc01 10 10042 10.so.0.42[.0] + * 1.2.34rc01 13 10234 12.so.0.34[.0] + * 1.0.42 10 10042 10.so.0.42[.0] + * 1.2.34 13 10234 12.so.0.34[.0] + * 1.2.35beta01-03 13 10235 12.so.0.35[.0] + * 1.0.43rc01-02 10 10043 10.so.0.43[.0] + * 1.2.35rc01-02 13 10235 12.so.0.35[.0] + * 1.0.43 10 10043 10.so.0.43[.0] + * 1.2.35 13 10235 12.so.0.35[.0] + * 1.2.36beta01-05 13 10236 12.so.0.36[.0] + * 1.2.36rc01 13 10236 12.so.0.36[.0] + * 1.0.44 10 10044 10.so.0.44[.0] + * 1.2.36 13 10236 12.so.0.36[.0] + * 1.2.37beta01-03 13 10237 12.so.0.37[.0] + * 1.2.37rc01 13 10237 12.so.0.37[.0] + * 1.2.37 13 10237 12.so.0.37[.0] + * 1.2.45 10 10045 12.so.0.45[.0] + * 1.0.46 10 10046 10.so.0.46[.0] + * 1.2.38beta01 13 10238 12.so.0.38[.0] + * 1.2.38rc01-03 13 10238 12.so.0.38[.0] + * 1.0.47 10 10047 10.so.0.47[.0] + * 1.2.38 13 10238 12.so.0.38[.0] + * 1.2.39beta01-05 13 10239 12.so.0.39[.0] + * 1.2.39rc01 13 10239 12.so.0.39[.0] + * 1.0.48 10 10048 10.so.0.48[.0] + * 1.2.39 13 10239 12.so.0.39[.0] * * Henceforth the source version will match the shared-library major * and minor numbers; the shared-library major version number will be @@ -115,7 +250,7 @@ * 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". + * release number plus "betaNN" or "rcNN". * * Binary incompatibility exists only when applications make direct access * to the info_ptr or png_ptr members through png.h, and the compiled @@ -135,8 +270,10 @@ * If you modify libpng you may insert additional notices immediately following * this sentence. * - * libpng versions 1.2.6, August 15, 2004, through 1.2.7, September 12, 2004, are - * Copyright (c) 2004 Glenn Randers-Pehrson, and are + * This code is released under the libpng license. + * + * libpng versions 1.2.6, August 15, 2004, through 1.2.39, August 13, 2009, are + * Copyright (c) 2004, 2006-2009 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: * @@ -247,13 +384,13 @@ * Y2K compliance in libpng: * ========================= * - * September 12, 2004 + * August 13, 2009 * * Since the PNG Development group is an ad-hoc body, we can't make * an official declaration. * * This is your unofficial assurance that libpng from version 0.71 and - * upward through 1.2.7 are Y2K compliant. It is my belief that earlier + * upward through 1.2.39 are Y2K compliant. It is my belief that earlier * versions were also Y2K compliant. * * Libpng only has three year fields. One is a 2-byte unsigned integer @@ -309,45 +446,83 @@ */ /* Version information for png.h - this should match the version in png.c */ -#define PNG_LIBPNG_VER_STRING "1.2.7" +#define PNG_LIBPNG_VER_STRING "1.2.39" #define PNG_HEADER_VERSION_STRING \ - " libpng version 1.2.7 - September 12, 2004 (header)\n" + " libpng version 1.2.39 - August 13, 2009\n" #define PNG_LIBPNG_VER_SONUM 0 -#define PNG_LIBPNG_VER_DLLNUM %DLLNUM% +#define PNG_LIBPNG_VER_DLLNUM 13 /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */ #define PNG_LIBPNG_VER_MAJOR 1 #define PNG_LIBPNG_VER_MINOR 2 -#define PNG_LIBPNG_VER_RELEASE 7 +#define PNG_LIBPNG_VER_RELEASE 39 /* This should match the numeric part of the final component of - * PNG_LIBPNG_VER_STRING, omitting any leading zero: */ + * PNG_LIBPNG_VER_STRING, omitting any leading zero: + */ -#define PNG_LIBPNG_VER_BUILD 3 +#define PNG_LIBPNG_VER_BUILD 0 +/* Release Status */ #define PNG_LIBPNG_BUILD_ALPHA 1 #define PNG_LIBPNG_BUILD_BETA 2 #define PNG_LIBPNG_BUILD_RC 3 #define PNG_LIBPNG_BUILD_STABLE 4 -#define PNG_LIBPNG_BUILD_TYPEMASK 7 -#define PNG_LIBPNG_BUILD_PATCH 8 /* Can be OR'ed with STABLE only */ -#define PNG_LIBPNG_BUILD_TYPE 3 +#define PNG_LIBPNG_BUILD_RELEASE_STATUS_MASK 7 + +/* Release-Specific Flags */ +#define PNG_LIBPNG_BUILD_PATCH 8 /* Can be OR'ed with + PNG_LIBPNG_BUILD_STABLE only */ +#define PNG_LIBPNG_BUILD_PRIVATE 16 /* Cannot be OR'ed with + PNG_LIBPNG_BUILD_SPECIAL */ +#define PNG_LIBPNG_BUILD_SPECIAL 32 /* Cannot be OR'ed with + PNG_LIBPNG_BUILD_PRIVATE */ + +#define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_STABLE /* Careful here. At one time, Guy wanted to use 082, but that would be octal. * We must not include leading zeros. * Versions 0.7 through 1.0.0 were in the range 0 to 100 here (only * version 1.0.0 was mis-numbered 100 instead of 10000). From - * version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release */ -#define PNG_LIBPNG_VER 10207 /* 1.2.7 */ + * version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release + */ +#define PNG_LIBPNG_VER 10239 /* 1.2.39 */ #ifndef PNG_VERSION_INFO_ONLY - /* include the compression library's header */ #include "zlib.h" +#endif /* include all user configurable info, including optional assembler routines */ #include "pngconf.h" +/* + * Added at libpng-1.2.8 */ +/* Ref MSDN: Private as priority over Special + * VS_FF_PRIVATEBUILD File *was not* built using standard release + * procedures. If this value is given, the StringFileInfo block must + * contain a PrivateBuild string. + * + * VS_FF_SPECIALBUILD File *was* built by the original company using + * standard release procedures but is a variation of the standard + * file of the same version number. If this value is given, the + * StringFileInfo block must contain a SpecialBuild string. + */ + +#if defined(PNG_USER_PRIVATEBUILD) +# define PNG_LIBPNG_BUILD_TYPE \ + (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_PRIVATE) +#else +# if defined(PNG_LIBPNG_SPECIALBUILD) +# define PNG_LIBPNG_BUILD_TYPE \ + (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_SPECIAL) +# else +# define PNG_LIBPNG_BUILD_TYPE (PNG_LIBPNG_BUILD_BASE_TYPE) +# endif +#endif + +#ifndef PNG_VERSION_INFO_ONLY + /* Inhibit C++ name-mangling for libpng functions but not for system calls. */ #ifdef __cplusplus extern "C" { @@ -393,13 +568,13 @@ extern "C" { #define png_write_status_ptr_NULL NULL #endif -/* variables declared in png.c - only it needs to define PNG_NO_EXTERN */ +/* 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. */ #ifdef PNG_USE_GLOBAL_ARRAYS -PNG_EXPORT_VAR (const char) png_libpng_ver[18]; +PNG_EXPORT_VAR (PNG_CONST char) png_libpng_ver[18]; /* need room for 99.99.99beta99z */ #else #define png_libpng_ver png_get_header_ver(NULL) @@ -408,17 +583,14 @@ PNG_EXPORT_VAR (const char) png_libpng_ver[18]; #ifdef PNG_USE_GLOBAL_ARRAYS /* This was removed in version 1.0.5c */ /* Structures to facilitate easy interlacing. See png.c for more details */ -PNG_EXPORT_VAR (const int FARDATA) png_pass_start[7]; -PNG_EXPORT_VAR (const int FARDATA) png_pass_inc[7]; -PNG_EXPORT_VAR (const int FARDATA) png_pass_ystart[7]; -PNG_EXPORT_VAR (const int FARDATA) png_pass_yinc[7]; -PNG_EXPORT_VAR (const int FARDATA) png_pass_mask[7]; -PNG_EXPORT_VAR (const int FARDATA) png_pass_dsp_mask[7]; -#ifdef PNG_HAVE_ASSEMBLER_COMBINE_ROW -PNG_EXPORT_VAR (const int FARDATA) png_pass_width[7]; -#endif +PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_start[7]; +PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_inc[7]; +PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_ystart[7]; +PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_yinc[7]; +PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_mask[7]; +PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_dsp_mask[7]; /* This isn't currently used. If you need it, see png.c for more details. -PNG_EXPORT_VAR (const int FARDATA) png_pass_height[7]; +PNG_EXPORT_VAR (PNG_CONST int FARDATA) png_pass_height[7]; */ #endif @@ -522,7 +694,8 @@ typedef png_text FAR * FAR * png_textpp; #endif /* Supported compression types for text in PNG files (tEXt, and zTXt). - * The values of the PNG_TEXT_COMPRESSION_ defines should NOT be changed. */ + * The values of the PNG_TEXT_COMPRESSION_ defines should NOT be changed. + */ #define PNG_TEXT_COMPRESSION_NONE_WR -3 #define PNG_TEXT_COMPRESSION_zTXt_WR -2 #define PNG_TEXT_COMPRESSION_NONE -1 @@ -549,15 +722,17 @@ typedef struct png_time_struct typedef png_time FAR * png_timep; typedef png_time FAR * FAR * png_timepp; -#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) +#if defined(PNG_UNKNOWN_CHUNKS_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 * know about their semantics. */ +#define PNG_CHUNK_NAME_LENGTH 5 typedef struct png_unknown_chunk_t { - png_byte name[5]; + png_byte name[PNG_CHUNK_NAME_LENGTH]; png_byte *data; png_size_t size; @@ -783,8 +958,9 @@ defined(PNG_READ_BACKGROUND_SUPPORTED) png_uint_32 free_me; /* flags items libpng is responsible for freeing */ #endif -#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) - /* storage for unknown chunks that the library doesn't recognize. */ +#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_size_t unknown_chunks_num; #endif @@ -799,7 +975,7 @@ defined(PNG_READ_BACKGROUND_SUPPORTED) #endif #if defined(PNG_sPLT_SUPPORTED) - /* data on sPLT chunks (there may be more than one). */ + /* Data on sPLT chunks (there may be more than one). */ png_sPLT_tp splt_palettes; png_uint_32 splt_palettes_num; #endif @@ -851,10 +1027,12 @@ typedef png_info FAR * FAR * png_infopp; /* Maximum positive integer used in PNG is (2^31)-1 */ #define PNG_UINT_31_MAX ((png_uint_32)0x7fffffffL) -#define PNG_UINT_32_MAX (~((png_uint_32)0)) -#define PNG_SIZE_MAX (~((png_size_t)0)) +#define PNG_UINT_32_MAX ((png_uint_32)(-1)) +#define PNG_SIZE_MAX ((png_size_t)(-1)) +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) /* PNG_MAX_UINT is deprecated; use PNG_UINT_31_MAX instead. */ #define PNG_MAX_UINT PNG_UINT_31_MAX +#endif /* These describe the color_type field in png_info. */ /* color type masks */ @@ -1012,7 +1190,10 @@ typedef void (PNGAPI *png_unknown_chunk_ptr) PNGARG((png_structp)); #define PNG_TRANSFORM_SWAP_ALPHA 0x0100 /* read and write */ #define PNG_TRANSFORM_SWAP_ENDIAN 0x0200 /* read and write */ #define PNG_TRANSFORM_INVERT_ALPHA 0x0400 /* read and write */ -#define PNG_TRANSFORM_STRIP_FILLER 0x0800 /* WRITE only */ +#define PNG_TRANSFORM_STRIP_FILLER 0x0800 /* WRITE only, deprecated */ +/* Added to libpng-1.2.34 */ +#define PNG_TRANSFORM_STRIP_FILLER_BEFORE 0x0800 /* WRITE only */ +#define PNG_TRANSFORM_STRIP_FILLER_AFTER 0x1000 /* WRITE only */ /* Flags for MNG supported features */ #define PNG_FLAG_MNG_EMPTY_PLTE 0x01 @@ -1082,10 +1263,12 @@ struct png_struct_def png_uint_32 row_number; /* current row in interlace pass */ png_bytep prev_row; /* buffer to save previous (unfiltered) row */ png_bytep row_buf; /* buffer to save current (unfiltered) row */ +#ifndef PNG_NO_WRITE_FILTER png_bytep sub_row; /* buffer to save "sub" row when filtering */ png_bytep up_row; /* buffer to save "up" row when filtering */ png_bytep avg_row; /* buffer to save "avg" row when filtering */ png_bytep paeth_row; /* buffer to save "Paeth" row when filtering */ +#endif png_row_info row_info; /* used for transformation routines */ png_uint_32 idat_size; /* current IDAT size for read */ @@ -1127,7 +1310,7 @@ struct png_struct_def #endif /* PNG_bKGD_SUPPORTED */ #if defined(PNG_WRITE_FLUSH_SUPPORTED) - png_flush_ptr output_flush_fn;/* Function for flushing output */ + png_flush_ptr output_flush_fn; /* Function for flushing output */ png_uint_32 flush_dist; /* how many rows apart to flush, 0 - no flush */ png_uint_32 flush_rows; /* number of rows written since last flush */ #endif @@ -1187,8 +1370,7 @@ struct png_struct_def png_size_t current_text_left; /* how much text left to read in input */ png_charp current_text; /* current text chunk buffer */ png_charp current_text_ptr; /* current location in current_text */ -# endif /* PNG_PROGRESSIVE_READ_SUPPORTED && PNG_TEXT_SUPPORTED */ - +# endif /* PNG_TEXT_SUPPORTED */ #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ #if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__) @@ -1226,7 +1408,7 @@ struct png_struct_def /* New members added in libpng-1.0.6 */ #ifdef PNG_FREE_ME_SUPPORTED - png_uint_32 free_me; /* flags items libpng is responsible for freeing */ + png_uint_32 free_me; /* flags items libpng is responsible for freeing */ #endif #if defined(PNG_USER_CHUNKS_SUPPORTED) @@ -1234,7 +1416,7 @@ struct png_struct_def png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */ #endif -#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED int num_chunk_list; png_bytep chunk_list; #endif @@ -1270,35 +1452,39 @@ struct png_struct_def png_byte filter_type; #endif -#if defined(PNG_1_0_X) || (defined(PNG_DEBUG) && defined(PNG_USE_PNGGCCRD)) +#if defined(PNG_1_0_X) /* New member added in libpng-1.0.10, ifdef'ed out in 1.2.0 */ png_uint_32 row_buf_size; #endif /* New members added in libpng-1.2.0 */ -#if !defined(PNG_1_0_X) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) +# if !defined(PNG_1_0_X) +# if defined(PNG_MMX_CODE_SUPPORTED) png_byte mmx_bitdepth_threshold; png_uint_32 mmx_rowbytes_threshold; +# endif png_uint_32 asm_flags; +# endif #endif /* 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; /* user supplied struct for mem functions */ - png_malloc_ptr malloc_fn; /* function for allocating memory */ - png_free_ptr free_fn; /* function for freeing memory */ + png_voidp mem_ptr; /* user supplied struct for mem functions */ + png_malloc_ptr malloc_fn; /* function for allocating memory */ + png_free_ptr free_fn; /* function for freeing memory */ #endif /* New member added in libpng-1.0.13 and 1.2.0 */ - png_bytep big_row_buf; /* buffer to save current (unfiltered) row */ + png_bytep big_row_buf; /* buffer to save current (unfiltered) row */ #if defined(PNG_READ_DITHER_SUPPORTED) /* The following three members were added at version 1.0.14 and 1.2.4 */ - png_bytep dither_sort; /* working sort array */ - png_bytep index_to_palette; /* where the original index currently is */ - /* in the palette */ - png_bytep palette_to_index; /* which original index points to this */ - /* palette color */ + png_bytep dither_sort; /* working sort array */ + png_bytep index_to_palette; /* where the original index currently is */ + /* in the palette */ + png_bytep palette_to_index; /* which original index points to this */ + /* palette color */ #endif /* New members added in libpng-1.0.16 and 1.2.6 */ @@ -1309,13 +1495,25 @@ struct png_struct_def png_uint_32 user_height_max; #endif +/* New member added in libpng-1.0.25 and 1.2.17 */ +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) + /* Storage for unknown chunk that the library doesn't recognize. */ + png_unknown_chunk unknown_chunk; +#endif + +/* New members added in libpng-1.2.26 */ + png_uint_32 old_big_row_buf_size, old_prev_row_size; + +/* New member added in libpng-1.2.30 */ + png_charp chunkdata; /* buffer for reading chunk data */ + }; /* 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_2_7; +typedef png_structp version_1_2_39; typedef png_struct FAR * FAR * png_structpp; @@ -1401,11 +1599,14 @@ extern PNG_EXPORT(void,png_write_chunk_end) PNGARG((png_structp png_ptr)); extern PNG_EXPORT(png_infop,png_create_info_struct) PNGARG((png_structp png_ptr)); +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) /* Initialize the info structure (old interface - DEPRECATED) */ extern PNG_EXPORT(void,png_info_init) PNGARG((png_infop info_ptr)); #undef png_info_init #define png_info_init(info_ptr) png_info_init_3(&info_ptr,\ png_sizeof(png_info)); +#endif + extern PNG_EXPORT(void,png_info_init_3) PNGARG((png_infopp info_ptr, png_size_t png_info_struct_size)); @@ -1416,7 +1617,7 @@ extern PNG_EXPORT(void,png_write_info) PNGARG((png_structp png_ptr, png_infop info_ptr)); #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED -/* read the information before the actual image data. */ +/* Read the information before the actual image data. */ extern PNG_EXPORT(void,png_read_info) PNGARG((png_structp png_ptr, png_infop info_ptr)); #endif @@ -1429,11 +1630,11 @@ extern PNG_EXPORT(png_charp,png_convert_to_rfc1123) #if !defined(_WIN32_WCE) /* "time.h" functions are not supported on WindowsCE */ #if defined(PNG_WRITE_tIME_SUPPORTED) -/* convert from a struct tm to png_time */ +/* Convert from a struct tm to png_time */ extern PNG_EXPORT(void,png_convert_from_struct_tm) PNGARG((png_timep ptime, struct tm FAR * ttime)); -/* convert from time_t to png_time. Uses gmtime() */ +/* Convert from time_t to png_time. Uses gmtime() */ extern PNG_EXPORT(void,png_convert_from_time_t) PNGARG((png_timep ptime, time_t ttime)); #endif /* PNG_WRITE_tIME_SUPPORTED */ @@ -1442,9 +1643,16 @@ extern PNG_EXPORT(void,png_convert_from_time_t) PNGARG((png_timep ptime, #if defined(PNG_READ_EXPAND_SUPPORTED) /* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */ extern PNG_EXPORT(void,png_set_expand) PNGARG((png_structp png_ptr)); -extern PNG_EXPORT(void,png_set_gray_1_2_4_to_8) PNGARG((png_structp png_ptr)); +#if !defined(PNG_1_0_X) +extern PNG_EXPORT(void,png_set_expand_gray_1_2_4_to_8) PNGARG((png_structp + png_ptr)); +#endif extern PNG_EXPORT(void,png_set_palette_to_rgb) PNGARG((png_structp png_ptr)); extern PNG_EXPORT(void,png_set_tRNS_to_alpha) PNGARG((png_structp png_ptr)); +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +/* Deprecated */ +extern PNG_EXPORT(void,png_set_gray_1_2_4_to_8) PNGARG((png_structp png_ptr)); +#endif #endif #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) @@ -1546,7 +1754,7 @@ extern PNG_EXPORT(void,png_set_background) PNGARG((png_structp png_ptr, #endif #if defined(PNG_READ_16_TO_8_SUPPORTED) -/* strip the second byte of information from a 16-bit depth file. */ +/* Strip the second byte of information from a 16-bit depth file. */ extern PNG_EXPORT(void,png_set_strip_16) PNGARG((png_structp png_ptr)); #endif @@ -1565,6 +1773,7 @@ extern PNG_EXPORT(void,png_set_gamma) PNGARG((png_structp png_ptr, #endif #endif +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) #if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \ defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) /* Permit or disallow empty PLTE (0: not permitted, 1: permitted) */ @@ -1572,6 +1781,7 @@ extern PNG_EXPORT(void,png_set_gamma) PNGARG((png_structp png_ptr, extern PNG_EXPORT(void,png_permit_empty_plte) PNGARG((png_structp png_ptr, int empty_plte_permitted)); #endif +#endif #if defined(PNG_WRITE_FLUSH_SUPPORTED) /* Set how many lines between output flushes - 0 for no flushing */ @@ -1580,74 +1790,74 @@ extern PNG_EXPORT(void,png_set_flush) PNGARG((png_structp png_ptr, int nrows)); extern PNG_EXPORT(void,png_write_flush) PNGARG((png_structp png_ptr)); #endif -/* optional update palette with requested transformations */ +/* Optional update palette with requested transformations */ extern PNG_EXPORT(void,png_start_read_image) PNGARG((png_structp png_ptr)); -/* optional call to update the users info structure */ +/* Optional call to update the users info structure */ extern PNG_EXPORT(void,png_read_update_info) PNGARG((png_structp png_ptr, png_infop info_ptr)); #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED -/* read one or more rows of image data. */ +/* Read one or more rows of image data. */ extern PNG_EXPORT(void,png_read_rows) PNGARG((png_structp png_ptr, png_bytepp row, png_bytepp display_row, png_uint_32 num_rows)); #endif #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED -/* read a row of data. */ +/* Read a row of data. */ extern PNG_EXPORT(void,png_read_row) PNGARG((png_structp png_ptr, png_bytep row, png_bytep display_row)); #endif #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED -/* read the whole image into memory at once. */ +/* Read the whole image into memory at once. */ extern PNG_EXPORT(void,png_read_image) PNGARG((png_structp png_ptr, png_bytepp image)); #endif -/* write a row of image data */ +/* Write a row of image data */ extern PNG_EXPORT(void,png_write_row) PNGARG((png_structp png_ptr, png_bytep row)); -/* write a few rows of image data */ +/* Write a few rows of image data */ extern PNG_EXPORT(void,png_write_rows) PNGARG((png_structp png_ptr, png_bytepp row, png_uint_32 num_rows)); -/* write the image data */ +/* Write the image data */ extern PNG_EXPORT(void,png_write_image) PNGARG((png_structp png_ptr, png_bytepp image)); -/* writes the end of the PNG file. */ +/* Writes the end of the PNG file. */ extern PNG_EXPORT(void,png_write_end) PNGARG((png_structp png_ptr, png_infop info_ptr)); #ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED -/* read the end of the PNG file. */ +/* Read the end of the PNG file. */ extern PNG_EXPORT(void,png_read_end) PNGARG((png_structp png_ptr, png_infop info_ptr)); #endif -/* free any memory associated with the png_info_struct */ +/* Free any memory associated with the png_info_struct */ extern PNG_EXPORT(void,png_destroy_info_struct) PNGARG((png_structp png_ptr, png_infopp info_ptr_ptr)); -/* free any memory associated with the png_struct and the png_info_structs */ +/* Free any memory associated with the png_struct and the png_info_structs */ extern PNG_EXPORT(void,png_destroy_read_struct) PNGARG((png_structpp png_ptr_ptr, png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr)); -/* free all memory used by the read (old method - NOT DLL EXPORTED) */ +/* Free all memory used by the read (old method - NOT DLL EXPORTED) */ extern void png_read_destroy PNGARG((png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr)); -/* free any memory associated with the png_struct and the png_info_structs */ +/* Free any memory associated with the png_struct and the png_info_structs */ extern PNG_EXPORT(void,png_destroy_write_struct) PNGARG((png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)); -/* free any memory used in png_ptr struct (old method - NOT DLL EXPORTED) */ +/* Free any memory used in png_ptr struct (old method - NOT DLL EXPORTED) */ extern void png_write_destroy PNGARG((png_structp png_ptr)); -/* set the libpng method of handling chunk CRC errors */ +/* Set the libpng method of handling chunk CRC errors */ extern PNG_EXPORT(void,png_set_crc_action) PNGARG((png_structp png_ptr, int crit_action, int ancil_action)); @@ -1675,7 +1885,7 @@ extern PNG_EXPORT(void,png_set_crc_action) PNGARG((png_structp png_ptr, * header file (zlib.h) for an explination of the compression functions. */ -/* set the filtering method(s) used by libpng. Currently, the only valid +/* Set the filtering method(s) used by libpng. Currently, the only valid * value for "method" is 0. */ extern PNG_EXPORT(void,png_set_filter) PNGARG((png_structp png_ptr, int method, @@ -1803,6 +2013,11 @@ extern PNG_EXPORT(png_voidp,png_get_error_ptr) PNGARG((png_structp png_ptr)); * If buffered output is not used, then output_flush_fn can be set to NULL. * If PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time * output_flush_fn will be ignored (and thus can be NULL). + * It is probably a mistake to use NULL for output_flush_fn if + * write_data_fn is not also NULL unless you have built libpng with + * PNG_WRITE_FLUSH_SUPPORTED undefined, because in this case libpng's + * default flush function, which uses the standard *FILE structure, will + * be used. */ extern 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)); @@ -1867,11 +2082,11 @@ extern PNG_EXPORT(void,png_set_progressive_read_fn) PNGARG((png_structp png_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 */ +/* Returns the user pointer associated with the push read functions */ extern PNG_EXPORT(png_voidp,png_get_progressive_ptr) PNGARG((png_structp png_ptr)); -/* function to be called when data becomes available */ +/* Function to be called when data becomes available */ extern PNG_EXPORT(void,png_process_data) PNGARG((png_structp png_ptr, png_infop info_ptr, png_bytep buffer, png_size_t buffer_size)); @@ -1893,7 +2108,7 @@ extern PNG_EXPORT(png_voidp,png_malloc_warn) PNGARG((png_structp png_ptr, png_uint_32 size)); #endif -/* frees a pointer allocated by png_malloc() */ +/* Frees a pointer allocated by png_malloc() */ extern PNG_EXPORT(void,png_free) PNGARG((png_structp png_ptr, png_voidp ptr)); #if defined(PNG_1_0_X) @@ -1910,11 +2125,12 @@ extern PNG_EXPORT(void,png_free_data) PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 free_me, int num)); #ifdef PNG_FREE_ME_SUPPORTED /* Reassign responsibility for freeing existing data, whether allocated - * by libpng or by the application */ + * by libpng or by the application + */ extern PNG_EXPORT(void,png_data_freer) PNGARG((png_structp png_ptr, png_infop info_ptr, int freer, png_uint_32 mask)); #endif -/* assignments for png_data_freer */ +/* Assignments for png_data_freer */ #define PNG_DESTROY_WILL_FREE_DATA 1 #define PNG_SET_WILL_FREE_DATA 1 #define PNG_USER_WILL_FREE_DATA 2 @@ -1951,6 +2167,7 @@ extern void *png_far_to_near PNGARG((png_structp png_ptr,png_voidp ptr, int check)); #endif /* USE_FAR_KEYWORD */ +#ifndef PNG_NO_ERROR_TEXT /* Fatal error in PNG image of libpng - can't continue */ extern PNG_EXPORT(void,png_error) PNGARG((png_structp png_ptr, png_const_charp error_message)); @@ -1958,14 +2175,22 @@ extern PNG_EXPORT(void,png_error) PNGARG((png_structp png_ptr, /* The same, but the chunk name is prepended to the error string. */ extern PNG_EXPORT(void,png_chunk_error) PNGARG((png_structp png_ptr, png_const_charp error_message)); +#else +/* Fatal error in PNG image of libpng - can't continue */ +extern PNG_EXPORT(void,png_err) PNGARG((png_structp png_ptr)); +#endif +#ifndef PNG_NO_WARNINGS /* Non-fatal error in libpng. Can continue, but may have a problem. */ extern PNG_EXPORT(void,png_warning) PNGARG((png_structp png_ptr, png_const_charp warning_message)); +#ifdef PNG_READ_SUPPORTED /* Non-fatal error in libpng, chunk name is prepended to message. */ extern PNG_EXPORT(void,png_chunk_warning) PNGARG((png_structp png_ptr, png_const_charp warning_message)); +#endif /* PNG_READ_SUPPORTED */ +#endif /* PNG_NO_WARNINGS */ /* The png_set_ functions are for storing values in the png_info_struct. * Similarly, the png_get_ calls are used to read values from the @@ -1989,11 +2214,13 @@ png_infop info_ptr)); #if defined(PNG_INFO_IMAGE_SUPPORTED) /* Returns row_pointers, which is an array of pointers to scanlines that was -returned from png_read_png(). */ + * returned from png_read_png(). + */ extern PNG_EXPORT(png_bytepp,png_get_rows) PNGARG((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(). */ + * by png_write_png(). + */ extern PNG_EXPORT(void,png_set_rows) PNGARG((png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers)); #endif @@ -2286,25 +2513,30 @@ extern PNG_EXPORT(png_uint_32,png_get_sCAL_s) PNGARG((png_structp png_ptr, #ifdef PNG_FLOATING_POINT_SUPPORTED extern PNG_EXPORT(void,png_set_sCAL) PNGARG((png_structp png_ptr, png_infop info_ptr, int unit, double width, double height)); -#endif +#else #ifdef PNG_FIXED_POINT_SUPPORTED extern 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 */ -#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) -/* provide a list of chunks and how they are to be handled, if the built-in +#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 listed will be handled in the default manner. The IHDR and IEND chunks must not be listed. - keep = 0: follow default behavour + keep = 0: follow default behaviour = 1: do not keep = 2: keep only if safe-to-copy = 3: keep even if unsafe-to-copy */ extern 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)); +#endif +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) extern PNG_EXPORT(void, png_set_unknown_chunks) PNGARG((png_structp png_ptr, png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns)); extern PNG_EXPORT(void, png_set_unknown_chunk_location) @@ -2312,14 +2544,11 @@ extern PNG_EXPORT(void, png_set_unknown_chunk_location) extern PNG_EXPORT(png_uint_32,png_get_unknown_chunks) PNGARG((png_structp png_ptr, png_infop info_ptr, png_unknown_chunkpp entries)); #endif -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -PNG_EXPORT(int,png_handle_as_unknown) PNGARG((png_structp png_ptr, png_bytep - chunk_name)); -#endif /* Png_free_data() will turn off the "valid" flag for anything it frees. - If you need to turn it off for a chunk that your application has freed, - you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK); */ + * 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); + */ extern PNG_EXPORT(void, png_set_invalid) PNGARG((png_structp png_ptr, png_infop info_ptr, int mask)); @@ -2345,34 +2574,90 @@ extern PNG_EXPORT(void, png_write_png) PNGARG((png_structp png_ptr, #if !defined(PNG_DEBUG_FILE) && defined(_MSC_VER) #include #if (PNG_DEBUG > 1) -#define png_debug(l,m) _RPT0(_CRT_WARN,m) -#define png_debug1(l,m,p1) _RPT1(_CRT_WARN,m,p1) -#define png_debug2(l,m,p1,p2) _RPT2(_CRT_WARN,m,p1,p2) +#ifndef _DEBUG +# define _DEBUG +#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) -#define png_debug(l,m) \ -{ \ - int num_tabs=l; \ - fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \ - (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":"")))); \ -} -#define png_debug1(l,m,p1) \ -{ \ - int num_tabs=l; \ - fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \ - (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1); \ -} -#define png_debug2(l,m,p1,p2) \ -{ \ - int num_tabs=l; \ - fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \ - (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1,p2); \ -} +/* Note: ["%s"m PNG_STRING_NEWLINE] probably does not work on non-ISO + * compilers. + */ +# 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) */ + #endif /* _MSC_VER */ #endif /* (PNG_DEBUG > 0) */ #endif /* PNG_DEBUG */ @@ -2386,8 +2671,6 @@ extern PNG_EXPORT(void, png_write_png) PNGARG((png_structp png_ptr, #define png_debug2(l, m, p1, p2) #endif -extern PNG_EXPORT(png_bytep,png_sig_bytes) PNGARG((void)); - extern PNG_EXPORT(png_charp,png_get_copyright) PNGARG((png_structp png_ptr)); extern PNG_EXPORT(png_charp,png_get_header_ver) PNGARG((png_structp png_ptr)); extern PNG_EXPORT(png_charp,png_get_header_version) PNGARG((png_structp png_ptr)); @@ -2406,6 +2689,7 @@ extern PNG_EXPORT(png_uint_32,png_permit_mng_features) PNGARG((png_structp /* Added to version 1.2.0 */ #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) +#if defined(PNG_MMX_CODE_SUPPORTED) #define PNG_ASM_FLAG_MMX_SUPPORT_COMPILED 0x01 /* not user-settable */ #define PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU 0x02 /* not user-settable */ #define PNG_ASM_FLAG_MMX_READ_COMBINE_ROW 0x04 @@ -2431,6 +2715,7 @@ extern PNG_EXPORT(png_uint_32,png_permit_mng_features) PNGARG((png_structp #define PNG_SELECT_READ 1 #define PNG_SELECT_WRITE 2 +#endif /* PNG_MMX_CODE_SUPPORTED */ #if !defined(PNG_1_0_X) /* pngget.c */ @@ -2463,21 +2748,21 @@ extern PNG_EXPORT(void,png_set_mmx_thresholds) png_uint_32 mmx_rowbytes_threshold)); #endif /* PNG_1_0_X */ -#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ #if !defined(PNG_1_0_X) /* png.c, pnggccrd.c, or pngvcrd.c */ extern PNG_EXPORT(int,png_mmx_support) PNGARG((void)); +#endif /* PNG_1_0_X */ +#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ /* Strip the prepended error numbers ("#nnn ") from error and warning - * messages before passing them to the error or warning handler. */ + * messages before passing them to the error or warning handler. + */ #ifdef PNG_ERROR_NUMBERS_SUPPORTED extern PNG_EXPORT(void,png_set_strip_error_numbers) PNGARG((png_structp png_ptr, png_uint_32 strip_mode)); #endif -#endif /* PNG_1_0_X */ - /* Added at libpng-1.2.6 */ #ifdef PNG_SET_USER_LIMITS_SUPPORTED extern PNG_EXPORT(void,png_set_user_limits) PNGARG((png_structp @@ -2488,7 +2773,10 @@ extern PNG_EXPORT(png_uint_32,png_get_user_height_max) PNGARG((png_structp png_ptr)); #endif -/* Maintainer: Put new public prototypes here ^, in libpng.3, and project defs */ + +/* Maintainer: Put new public prototypes here ^, in libpng.3, and in + * project defs + */ #ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED /* With these routines we avoid an integer divide, which will be slower on @@ -2517,7 +2805,7 @@ extern PNG_EXPORT(png_uint_32,png_get_user_height_max) PNGARG((png_structp (png_uint_32)(alpha)) + (png_uint_32)32768L); \ (composite) = (png_uint_16)((temp + (temp >> 16)) >> 16); } -#else /* standard method using integer division */ +#else /* Standard method using integer division */ # define png_composite(composite, fg, alpha, bg) \ (composite) = (png_byte)(((png_uint_16)(fg) * (png_uint_16)(alpha) + \ @@ -2531,22 +2819,65 @@ extern PNG_EXPORT(png_uint_32,png_get_user_height_max) PNGARG((png_structp #endif /* PNG_READ_COMPOSITE_NODIV_SUPPORTED */ +/* Inline macros to do direct reads of bytes from the input buffer. These + * require that you are using an architecture that uses PNG byte ordering + * (MSB first) and supports unaligned data storage. I think that PowerPC + * in big-endian mode and 680x0 are the only ones that will support this. + * The x86 line of processors definitely do not. The png_get_int_32() + * routine also assumes we are using two's complement format for negative + * values, which is almost certainly true. + */ +#if defined(PNG_READ_BIG_ENDIAN_SUPPORTED) +# define png_get_uint_32(buf) ( *((png_uint_32p) (buf))) +# define png_get_uint_16(buf) ( *((png_uint_16p) (buf))) +# define png_get_int_32(buf) ( *((png_int_32p) (buf))) +#else +extern PNG_EXPORT(png_uint_32,png_get_uint_32) PNGARG((png_bytep buf)); +extern PNG_EXPORT(png_uint_16,png_get_uint_16) PNGARG((png_bytep buf)); +extern PNG_EXPORT(png_int_32,png_get_int_32) PNGARG((png_bytep buf)); +#endif /* !PNG_READ_BIG_ENDIAN_SUPPORTED */ +extern PNG_EXPORT(png_uint_32,png_get_uint_31) + PNGARG((png_structp png_ptr, png_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). + */ +extern PNG_EXPORT(void,png_save_uint_32) + PNGARG((png_bytep buf, png_uint_32 i)); +extern PNG_EXPORT(void,png_save_int_32) + PNGARG((png_bytep buf, png_int_32 i)); + +/* Place a 16-bit number into a buffer in PNG byte order. + * The parameter is declared unsigned int, not png_uint_16, + * just to avoid potential problems on pre-ANSI C compilers. + */ +extern PNG_EXPORT(void,png_save_uint_16) + PNGARG((png_bytep buf, unsigned int i)); +/* No png_save_int_16 -- may be added if there's a real need for it. */ + +/* ************************************************************************* */ + /* These next functions are used internally in the code. They generally * shouldn't be used unless you are writing code to add or replace some * functionality in libpng. More information about most functions can * be found in the files where the functions are located. */ -#if defined(PNG_INTERNAL) -/* Various modes of operation. Note that after an init, mode is set to - * zero automatically when the structure is created. +/* Various modes of operation, that are visible to applications because + * they are used for unknown chunk location. */ #define PNG_HAVE_IHDR 0x01 #define PNG_HAVE_PLTE 0x02 #define PNG_HAVE_IDAT 0x04 -#define PNG_AFTER_IDAT 0x08 +#define PNG_AFTER_IDAT 0x08 /* Have complete zlib datastream */ #define PNG_HAVE_IEND 0x10 + +#if defined(PNG_INTERNAL) + +/* More modes of operation. Note that after an init, mode is set to + * zero automatically when the structure is created. + */ #define PNG_HAVE_gAMA 0x20 #define PNG_HAVE_cHRM 0x40 #define PNG_HAVE_sRGB 0x80 @@ -2555,8 +2886,9 @@ extern PNG_EXPORT(png_uint_32,png_get_user_height_max) PNGARG((png_structp #define PNG_WROTE_INFO_BEFORE_PLTE 0x400 #define PNG_BACKGROUND_IS_GRAY 0x800 #define PNG_HAVE_PNG_SIGNATURE 0x1000 +#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */ -/* flags for the transformations the PNG library does on the image data */ +/* Flags for the transformations the PNG library does on the image data */ #define PNG_BGR 0x0001 #define PNG_INTERLACE 0x0002 #define PNG_PACK 0x0004 @@ -2581,9 +2913,16 @@ extern PNG_EXPORT(png_uint_32,png_get_user_height_max) PNGARG((png_structp #define PNG_RGB_TO_GRAY_ERR 0x200000L #define PNG_RGB_TO_GRAY_WARN 0x400000L #define PNG_RGB_TO_GRAY 0x600000L /* two bits, RGB_TO_GRAY_ERR|WARN */ + /* 0x800000L Unused */ #define PNG_ADD_ALPHA 0x1000000L /* Added to libpng-1.2.7 */ +#define PNG_EXPAND_tRNS 0x2000000L /* Added to libpng-1.2.9 */ + /* 0x4000000L unused */ + /* 0x8000000L unused */ + /* 0x10000000L unused */ + /* 0x20000000L unused */ + /* 0x40000000L unused */ -/* flags for png_create_struct */ +/* Flags for png_create_struct */ #define PNG_STRUCT_PNG 0x0001 #define PNG_STRUCT_INFO 0x0002 @@ -2593,7 +2932,7 @@ extern PNG_EXPORT(png_uint_32,png_get_user_height_max) PNGARG((png_structp #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 */ +/* Flags for the png_ptr->flags rather than declaring a byte for each one */ #define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x0001 #define PNG_FLAG_ZLIB_CUSTOM_LEVEL 0x0002 #define PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL 0x0004 @@ -2615,6 +2954,16 @@ extern PNG_EXPORT(png_uint_32,png_get_user_height_max) PNGARG((png_structp #define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000L #define PNG_FLAG_STRIP_ERROR_TEXT 0x80000L #define PNG_FLAG_MALLOC_NULL_MEM_OK 0x100000L +#define PNG_FLAG_ADD_ALPHA 0x200000L /* Added to libpng-1.2.8 */ +#define PNG_FLAG_STRIP_ALPHA 0x400000L /* Added to libpng-1.2.8 */ + /* 0x800000L unused */ + /* 0x1000000L unused */ + /* 0x2000000L unused */ + /* 0x4000000L unused */ + /* 0x8000000L unused */ + /* 0x10000000L unused */ + /* 0x20000000L unused */ + /* 0x40000000L unused */ #define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \ PNG_FLAG_CRC_ANCILLARY_NOWARN) @@ -2625,7 +2974,7 @@ extern PNG_EXPORT(png_uint_32,png_get_user_height_max) PNGARG((png_structp #define PNG_FLAG_CRC_MASK (PNG_FLAG_CRC_ANCILLARY_MASK | \ PNG_FLAG_CRC_CRITICAL_MASK) -/* save typing and make code easier to understand */ +/* Save typing and make code easier to understand */ #define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \ abs((int)((c1).green) - (int)((c2).green)) + \ @@ -2638,19 +2987,19 @@ extern PNG_EXPORT(png_uint_32,png_get_user_height_max) PNGARG((png_structp (( ((width) * ((png_uint_32)(pixel_bits))) + 7) >> 3) ) /* PNG_OUT_OF_RANGE returns true if value is outside the range - ideal-delta..ideal+delta. Each argument is evaluated twice. - "ideal" and "delta" should be constants, normally simple - integers, "value" a variable. Added to libpng-1.2.6 JB */ + * ideal-delta..ideal+delta. Each argument is evaluated twice. + * "ideal" and "delta" should be constants, normally simple + * 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) ) -/* variables declared in png.c - only it needs to define PNG_NO_EXTERN */ +/* Variables declared in png.c - only it needs to define PNG_NO_EXTERN */ #if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN) /* place to hold the signature string for a PNG file. */ #ifdef PNG_USE_GLOBAL_ARRAYS - PNG_EXPORT_VAR (const png_byte FARDATA) png_sig[8]; + PNG_EXPORT_VAR (PNG_CONST png_byte FARDATA) png_sig[8]; #else -#define png_sig png_sig_bytes(NULL) #endif #endif /* PNG_NO_EXTERN */ @@ -2658,80 +3007,53 @@ extern PNG_EXPORT(png_uint_32,png_get_user_height_max) PNGARG((png_structp * define the name here, and add an invocation of the macro in png.c and * wherever it's needed. */ -#define PNG_IHDR const png_byte png_IHDR[5] = { 73, 72, 68, 82, '\0'} -#define PNG_IDAT const png_byte png_IDAT[5] = { 73, 68, 65, 84, '\0'} -#define PNG_IEND const png_byte png_IEND[5] = { 73, 69, 78, 68, '\0'} -#define PNG_PLTE const png_byte png_PLTE[5] = { 80, 76, 84, 69, '\0'} -#define PNG_bKGD const png_byte png_bKGD[5] = { 98, 75, 71, 68, '\0'} -#define PNG_cHRM const png_byte png_cHRM[5] = { 99, 72, 82, 77, '\0'} -#define PNG_gAMA const png_byte png_gAMA[5] = {103, 65, 77, 65, '\0'} -#define PNG_hIST const png_byte png_hIST[5] = {104, 73, 83, 84, '\0'} -#define PNG_iCCP const png_byte png_iCCP[5] = {105, 67, 67, 80, '\0'} -#define PNG_iTXt const png_byte png_iTXt[5] = {105, 84, 88, 116, '\0'} -#define PNG_oFFs const png_byte png_oFFs[5] = {111, 70, 70, 115, '\0'} -#define PNG_pCAL const png_byte png_pCAL[5] = {112, 67, 65, 76, '\0'} -#define PNG_sCAL const png_byte png_sCAL[5] = {115, 67, 65, 76, '\0'} -#define PNG_pHYs const png_byte png_pHYs[5] = {112, 72, 89, 115, '\0'} -#define PNG_sBIT const png_byte png_sBIT[5] = {115, 66, 73, 84, '\0'} -#define PNG_sPLT const png_byte png_sPLT[5] = {115, 80, 76, 84, '\0'} -#define PNG_sRGB const png_byte png_sRGB[5] = {115, 82, 71, 66, '\0'} -#define PNG_tEXt const png_byte png_tEXt[5] = {116, 69, 88, 116, '\0'} -#define PNG_tIME const png_byte png_tIME[5] = {116, 73, 77, 69, '\0'} -#define PNG_tRNS const png_byte png_tRNS[5] = {116, 82, 78, 83, '\0'} -#define PNG_zTXt const png_byte png_zTXt[5] = {122, 84, 88, 116, '\0'} +#define PNG_IHDR png_byte png_IHDR[5] = { 73, 72, 68, 82, '\0'} +#define PNG_IDAT png_byte png_IDAT[5] = { 73, 68, 65, 84, '\0'} +#define PNG_IEND png_byte png_IEND[5] = { 73, 69, 78, 68, '\0'} +#define PNG_PLTE png_byte png_PLTE[5] = { 80, 76, 84, 69, '\0'} +#define PNG_bKGD png_byte png_bKGD[5] = { 98, 75, 71, 68, '\0'} +#define PNG_cHRM png_byte png_cHRM[5] = { 99, 72, 82, 77, '\0'} +#define PNG_gAMA png_byte png_gAMA[5] = {103, 65, 77, 65, '\0'} +#define PNG_hIST png_byte png_hIST[5] = {104, 73, 83, 84, '\0'} +#define PNG_iCCP png_byte png_iCCP[5] = {105, 67, 67, 80, '\0'} +#define PNG_iTXt png_byte png_iTXt[5] = {105, 84, 88, 116, '\0'} +#define PNG_oFFs png_byte png_oFFs[5] = {111, 70, 70, 115, '\0'} +#define PNG_pCAL png_byte png_pCAL[5] = {112, 67, 65, 76, '\0'} +#define PNG_sCAL png_byte png_sCAL[5] = {115, 67, 65, 76, '\0'} +#define PNG_pHYs png_byte png_pHYs[5] = {112, 72, 89, 115, '\0'} +#define PNG_sBIT png_byte png_sBIT[5] = {115, 66, 73, 84, '\0'} +#define PNG_sPLT png_byte png_sPLT[5] = {115, 80, 76, 84, '\0'} +#define PNG_sRGB png_byte png_sRGB[5] = {115, 82, 71, 66, '\0'} +#define PNG_tEXt png_byte png_tEXt[5] = {116, 69, 88, 116, '\0'} +#define PNG_tIME png_byte png_tIME[5] = {116, 73, 77, 69, '\0'} +#define PNG_tRNS png_byte png_tRNS[5] = {116, 82, 78, 83, '\0'} +#define PNG_zTXt png_byte png_zTXt[5] = {122, 84, 88, 116, '\0'} #ifdef PNG_USE_GLOBAL_ARRAYS -PNG_EXPORT_VAR (const png_byte FARDATA) png_IHDR[5]; -PNG_EXPORT_VAR (const png_byte FARDATA) png_IDAT[5]; -PNG_EXPORT_VAR (const png_byte FARDATA) png_IEND[5]; -PNG_EXPORT_VAR (const png_byte FARDATA) png_PLTE[5]; -PNG_EXPORT_VAR (const png_byte FARDATA) png_bKGD[5]; -PNG_EXPORT_VAR (const png_byte FARDATA) png_cHRM[5]; -PNG_EXPORT_VAR (const png_byte FARDATA) png_gAMA[5]; -PNG_EXPORT_VAR (const png_byte FARDATA) png_hIST[5]; -PNG_EXPORT_VAR (const png_byte FARDATA) png_iCCP[5]; -PNG_EXPORT_VAR (const png_byte FARDATA) png_iTXt[5]; -PNG_EXPORT_VAR (const png_byte FARDATA) png_oFFs[5]; -PNG_EXPORT_VAR (const png_byte FARDATA) png_pCAL[5]; -PNG_EXPORT_VAR (const png_byte FARDATA) png_sCAL[5]; -PNG_EXPORT_VAR (const png_byte FARDATA) png_pHYs[5]; -PNG_EXPORT_VAR (const png_byte FARDATA) png_sBIT[5]; -PNG_EXPORT_VAR (const png_byte FARDATA) png_sPLT[5]; -PNG_EXPORT_VAR (const png_byte FARDATA) png_sRGB[5]; -PNG_EXPORT_VAR (const png_byte FARDATA) png_tEXt[5]; -PNG_EXPORT_VAR (const png_byte FARDATA) png_tIME[5]; -PNG_EXPORT_VAR (const png_byte FARDATA) png_tRNS[5]; -PNG_EXPORT_VAR (const png_byte FARDATA) png_zTXt[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_IHDR[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_IDAT[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_IEND[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_PLTE[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_bKGD[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_cHRM[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_gAMA[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_hIST[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_iCCP[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_iTXt[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_oFFs[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_pCAL[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_sCAL[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_pHYs[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_sBIT[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_sPLT[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_sRGB[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_tEXt[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_tIME[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_tRNS[5]; +PNG_EXPORT_VAR (png_byte FARDATA) png_zTXt[5]; #endif /* PNG_USE_GLOBAL_ARRAYS */ - -/* Inline macros to do direct reads of bytes from the input buffer. These - * require that you are using an architecture that uses PNG byte ordering - * (MSB first) and supports unaligned data storage. I think that PowerPC - * in big-endian mode and 680x0 are the only ones that will support this. - * The x86 line of processors definitely do not. The png_get_int_32() - * routine also assumes we are using two's complement format for negative - * values, which is almost certainly true. - */ -#if defined(PNG_READ_BIG_ENDIAN_SUPPORTED) -# if defined(PNG_pCAL_SUPPORTED) || defined(PNG_oFFs_SUPPORTED) -# define png_get_int_32(buf) ( *((png_int_32p) (buf))) -# endif -# define png_get_uint_32(buf) ( *((png_uint_32p) (buf))) -# define png_get_uint_16(buf) ( *((png_uint_16p) (buf))) -#else -# if defined(PNG_pCAL_SUPPORTED) || defined(PNG_oFFs_SUPPORTED) -PNG_EXTERN png_int_32 png_get_int_32 PNGARG((png_bytep buf)); -# endif -PNG_EXTERN png_uint_32 png_get_uint_32 PNGARG((png_bytep buf)); -PNG_EXTERN png_uint_16 png_get_uint_16 PNGARG((png_bytep buf)); -#endif /* !PNG_READ_BIG_ENDIAN_SUPPORTED */ -/* RN: This define is blatent hack to get png to (hopefully) - link on OSX 10.2 and earlier versions of 10.3 due to an - Apple linking bug introduced in 10.2 */ -#define png_get_uint_31 wxpng_get_uint_31 -PNG_EXTERN png_uint_32 png_get_uint_31 PNGARG((png_structp png_ptr, - png_bytep buf)); +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) /* Initialize png_ptr struct for reading, and allocate any other memory. * (old interface - DEPRECATED - use png_create_read_struct instead). */ @@ -2739,12 +3061,17 @@ extern PNG_EXPORT(void,png_read_init) PNGARG((png_structp png_ptr)); #undef png_read_init #define png_read_init(png_ptr) png_read_init_3(&png_ptr, \ PNG_LIBPNG_VER_STRING, png_sizeof(png_struct)); +#endif + extern PNG_EXPORT(void,png_read_init_3) PNGARG((png_structpp ptr_ptr, png_const_charp user_png_ver, png_size_t png_struct_size)); +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) extern PNG_EXPORT(void,png_read_init_2) PNGARG((png_structp png_ptr, png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t png_info_size)); +#endif +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) /* Initialize png_ptr struct for writing, and allocate any other memory. * (old interface - DEPRECATED - use png_create_write_struct instead). */ @@ -2752,6 +3079,8 @@ extern PNG_EXPORT(void,png_write_init) PNGARG((png_structp png_ptr)); #undef png_write_init #define png_write_init(png_ptr) png_write_init_3(&png_ptr, \ PNG_LIBPNG_VER_STRING, png_sizeof(png_struct)); +#endif + extern PNG_EXPORT(void,png_write_init_3) PNGARG((png_structpp ptr_ptr, png_const_charp user_png_ver, png_size_t png_struct_size)); extern PNG_EXPORT(void,png_write_init_2) PNGARG((png_structp png_ptr, @@ -2786,7 +3115,8 @@ PNG_EXTERN void png_zfree PNGARG((voidpf png_ptr, voidpf ptr)); #endif /* Next four functions are used internally as callbacks. PNGAPI is required - * but not PNG_EXPORT. PNGAPI added at libpng version 1.2.3. */ + * but not PNG_EXPORT. PNGAPI added at libpng version 1.2.3. + */ PNG_EXTERN void PNGAPI png_default_read_data PNGARG((png_structp png_ptr, png_bytep data, png_size_t length)); @@ -2829,8 +3159,8 @@ PNG_EXTERN void png_crc_read PNGARG((png_structp png_ptr, png_bytep buf, /* 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 png_charp png_decompress_chunk PNGARG((png_structp png_ptr, - int comp_type, png_charp chunkdata, png_size_t chunklength, +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)); #endif @@ -2851,27 +3181,10 @@ PNG_EXTERN void png_calculate_crc PNGARG((png_structp png_ptr, png_bytep ptr, PNG_EXTERN void png_flush PNGARG((png_structp png_ptr)); #endif - -/* Place a 32-bit number into a buffer in PNG byte order (big-endian). - * The only currently known PNG chunks that use signed numbers are - * the ancillary extension chunks, oFFs and pCAL. - */ -PNG_EXTERN void png_save_uint_32 PNGARG((png_bytep buf, png_uint_32 i)); - -#if defined(PNG_WRITE_pCAL_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED) -PNG_EXTERN void png_save_int_32 PNGARG((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, - * just to avoid potential problems on pre-ANSI C compilers. - */ -PNG_EXTERN void png_save_uint_16 PNGARG((png_bytep buf, unsigned int i)); - -/* simple function to write the signature */ +/* Simple function to write the signature */ PNG_EXTERN void png_write_sig PNGARG((png_structp png_ptr)); -/* write various chunks */ +/* Write various chunks */ /* Write the IHDR chunk, and update the png_struct with the necessary * information. @@ -3023,12 +3336,12 @@ PNG_EXTERN void png_write_start_row PNGARG((png_structp png_ptr)); PNG_EXTERN void png_build_gamma_table PNGARG((png_structp png_ptr)); #endif -/* combine a row of data, dealing with alpha, etc. if requested */ +/* 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)); #if defined(PNG_READ_INTERLACING_SUPPORTED) -/* expand an interlaced row */ +/* 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)); @@ -3039,12 +3352,12 @@ PNG_EXTERN void png_do_read_interlace PNGARG((png_structp png_ptr)); /* GRR TO DO (2.0 or whenever): simplify other internal calling interfaces */ #if defined(PNG_WRITE_INTERLACING_SUPPORTED) -/* grab pixels out of a row for an interlaced pass */ +/* 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)); #endif -/* unfilter a row */ +/* 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)); @@ -3055,16 +3368,16 @@ PNG_EXTERN void png_write_find_filter PNGARG((png_structp png_ptr, /* Write out the filtered row. */ PNG_EXTERN void png_write_filtered_row PNGARG((png_structp png_ptr, png_bytep filtered_row)); -/* finish a row while reading, dealing with interlacing passes, etc. */ +/* Finish a row while reading, dealing with interlacing passes, etc. */ PNG_EXTERN void png_read_finish_row PNGARG((png_structp png_ptr)); -/* initialize the row buffers, etc. */ +/* Initialize the row buffers, etc. */ PNG_EXTERN void png_read_start_row PNGARG((png_structp png_ptr)); -/* optional call to update the users info structure */ +/* Optional call to update the users info structure */ PNG_EXTERN void png_read_transform_info PNGARG((png_structp png_ptr, png_infop info_ptr)); -/* these are the functions that do the transformations */ +/* These are the functions that do the transformations */ #if defined(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)); @@ -3186,7 +3499,7 @@ PNG_EXTERN void png_do_expand PNGARG((png_row_infop row_info, * then calls the appropriate callback for the chunk if it is valid. */ -/* decode the IHDR chunk */ +/* Decode the IHDR chunk */ PNG_EXTERN void png_handle_IHDR PNGARG((png_structp png_ptr, png_infop info_ptr, png_uint_32 length)); PNG_EXTERN void png_handle_PLTE PNGARG((png_structp png_ptr, png_infop info_ptr, @@ -3285,7 +3598,7 @@ PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr, PNG_EXTERN void png_check_chunk_name PNGARG((png_structp png_ptr, png_bytep chunk_name)); -/* handle the transformations for reading and writing */ +/* Handle the transformations for reading and writing */ PNG_EXTERN void png_do_read_transformations PNGARG((png_structp png_ptr)); PNG_EXTERN void png_do_write_transformations PNGARG((png_structp png_ptr)); @@ -3348,9 +3661,54 @@ PNG_EXTERN void png_do_write_intrapixel PNGARG((png_row_infop row_info, #endif #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) +#if defined(PNG_MMX_CODE_SUPPORTED) /* png.c */ /* PRIVATE */ PNG_EXTERN void png_init_mmx_flags PNGARG((png_structp png_ptr)); #endif +#endif + +#if defined(PNG_INCH_CONVERSIONS) && defined(PNG_FLOATING_POINT_SUPPORTED) +PNG_EXTERN png_uint_32 png_get_pixels_per_inch PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +PNG_EXTERN png_uint_32 png_get_x_pixels_per_inch PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +PNG_EXTERN png_uint_32 png_get_y_pixels_per_inch PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +PNG_EXTERN float png_get_x_offset_inches PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +PNG_EXTERN float png_get_y_offset_inches PNGARG((png_structp png_ptr, +png_infop info_ptr)); + +#if defined(PNG_pHYs_SUPPORTED) +PNG_EXTERN 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 */ + +/* Read the chunk header (length + type name) */ +PNG_EXTERN png_uint_32 png_read_chunk_header PNGARG((png_structp png_ptr)); + +/* Added at libpng version 1.2.34 */ +#if defined(PNG_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)); +#endif + +#if defined(PNG_cHRM_SUPPORTED) +#if !defined(PNG_NO_CHECK_cHRM) +/* Added at libpng version 1.2.34 */ +PNG_EXTERN void png_64bit_product (long v1, long v2, unsigned long *hi_product, + unsigned long *lo_product); +#endif +#endif + /* Maintainer: Put new private prototypes here ^ and in libpngpf.3 */ #endif /* PNG_INTERNAL */ @@ -3360,5 +3718,5 @@ PNG_EXTERN void png_init_mmx_flags PNGARG((png_structp png_ptr)); #endif #endif /* PNG_VERSION_INFO_ONLY */ -/* do not put anything past this line */ +/* Do not put anything past this line */ #endif /* PNG_H */ diff --git a/3rdparty/wxWidgets/src/png/pngconf.h b/3rdparty/wxWidgets/src/png/pngconf.h index 867e0a8668..35523d85eb 100644 --- a/3rdparty/wxWidgets/src/png/pngconf.h +++ b/3rdparty/wxWidgets/src/png/pngconf.h @@ -1,11 +1,14 @@ /* pngconf.h - machine configurable file for libpng * - * libpng version 1.2.7 - September 12, 2004 - * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2004 Glenn Randers-Pehrson + * libpng version 1.2.39 - August 13, 2009 + * Copyright (c) 1998-2009 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. + * For conditions of distribution and use, see the disclaimer + * and license in png.h */ /* Any machine specific code is near the front of this file, so if you @@ -17,10 +20,72 @@ #ifndef PNGCONF_H #define PNGCONF_H +#define PNG_1_2_X + +/* + * 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 +# ifndef PNG_USER_PRIVATEBUILD +# define PNG_USER_PRIVATEBUILD +# endif #include "pngusr.h" #endif +/* PNG_CONFIGURE_LIBPNG is set by the "configure" script. */ +#ifdef PNG_CONFIGURE_LIBPNG +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#endif + +/* + * Added at libpng-1.2.8 + * + * If you create a private DLL you need to define in "pngusr.h" the followings: + * #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 "libpng13gx.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__ */ + +#ifndef PNG_VERSION_INFO_ONLY + +/* End of material added to libpng-1.2.8 */ + +/* Added at libpng-1.2.19, removed at libpng-1.2.20 because it caused trouble + Restored at libpng-1.2.21 */ +#if !defined(PNG_NO_WARN_UNINITIALIZED_ROW) && \ + !defined(PNG_WARN_UNINITIALIZED_ROW) +# define PNG_WARN_UNINITIALIZED_ROW 1 +#endif +/* End of material added at libpng-1.2.19/1.2.21 */ + /* 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 @@ -171,6 +236,8 @@ # include /* Console I/O functions are not supported on WindowsCE */ # define PNG_NO_CONSOLE_IO + /* abort() may not be supported on some/all Windows CE platforms */ +# define PNG_ABORT() exit(-1) # ifdef PNG_DEBUG # undef PNG_DEBUG # endif @@ -222,6 +289,7 @@ # define PNGARG(arglist) arglist #endif /* _NO_PROTO */ + #endif /* OF */ #endif /* PNGARG */ @@ -232,7 +300,7 @@ */ #ifndef MACOS # if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \ - defined(THINK_C) || (defined(__SC__) && !defined(__DMC__))|| defined(TARGET_OS_MAC) + defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC) # define MACOS # endif #endif @@ -249,28 +317,38 @@ #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. + * + * 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. */ -# 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. - */ - __png.h__ already includes setjmp.h; - __dont__ include it again.; -# endif -# endif /* __linux__ */ +# 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 */ /* include setjmp.h for error handling */ # include # ifdef __linux__ # ifdef PNG_SAVE_BSD_SOURCE -# define _BSD_SOURCE +# ifndef _BSD_SOURCE +# define _BSD_SOURCE +# endif # undef PNG_SAVE_BSD_SOURCE # endif # endif /* __linux__ */ @@ -409,21 +487,33 @@ */ /* The size of the png_text structure changed in libpng-1.0.6 when - * iTXt is supported. It is turned off by default, to support old apps - * that malloc the png_text structure instead of calling png_set_text() - * and letting libpng malloc it. It will be turned on by default in - * libpng-1.3.0. + * 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 + * will be turned on by default in libpng-1.4.0. */ -#ifndef PNG_iTXt_SUPPORTED -# if !defined(PNG_READ_iTXt_SUPPORTED) && !defined(PNG_NO_READ_iTXt) +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) +# ifndef PNG_NO_iTXt_SUPPORTED +# define PNG_NO_iTXt_SUPPORTED +# endif +# ifndef PNG_NO_READ_iTXt # define PNG_NO_READ_iTXt # endif -# if !defined(PNG_WRITE_iTXt_SUPPORTED) && !defined(PNG_NO_WRITE_iTXt) +# ifndef PNG_NO_WRITE_iTXt # define PNG_NO_WRITE_iTXt # endif #endif +#if !defined(PNG_NO_iTXt_SUPPORTED) +# if !defined(PNG_READ_iTXt_SUPPORTED) && !defined(PNG_NO_READ_iTXt) +# define PNG_READ_iTXt +# endif +# if !defined(PNG_WRITE_iTXt_SUPPORTED) && !defined(PNG_NO_WRITE_iTXt) +# define PNG_WRITE_iTXt +# endif +#endif + /* The following support, added after version 1.0.0, can be turned off here en * masse by defining PNG_LEGACY_SUPPORTED in case you need binary compatibility * with old applications that require the length of png_struct and png_info @@ -434,6 +524,7 @@ # define PNG_NO_FREE_ME # define PNG_NO_READ_UNKNOWN_CHUNKS # define PNG_NO_WRITE_UNKNOWN_CHUNKS +# define PNG_NO_HANDLE_AS_UNKNOWN # define PNG_NO_READ_USER_CHUNKS # define PNG_NO_READ_iCCP # define PNG_NO_WRITE_iCCP @@ -463,7 +554,7 @@ # define PNG_FREE_ME_SUPPORTED #endif -#if defined(PNG_READ_SUPPORTED) +#ifdef PNG_READ_SUPPORTED #if !defined(PNG_READ_TRANSFORMS_NOT_SUPPORTED) && \ !defined(PNG_NO_READ_TRANSFORMS) @@ -528,28 +619,30 @@ #endif /* PNG_READ_TRANSFORMS_SUPPORTED */ #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 line: */ + !defined(PNG_PROGRESSIVE_READ_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 line: */ -#define PNG_READ_INTERLACING_SUPPORTED /* required for PNG-compliant decoders */ +#define PNG_READ_INTERLACING_SUPPORTED /* required in PNG-compliant decoders */ #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 */ +# define PNG_READ_COMPOSITE_NODIV_SUPPORTED /* well tested on Intel, SGI */ # endif #endif +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) /* Deprecated, will be removed from version 2.0.0. Use PNG_MNG_FEATURES_SUPPORTED instead. */ #ifndef PNG_NO_READ_EMPTY_PLTE # define PNG_READ_EMPTY_PLTE_SUPPORTED #endif +#endif #endif /* PNG_READ_SUPPORTED */ -#if defined(PNG_WRITE_SUPPORTED) +#ifdef PNG_WRITE_SUPPORTED # if !defined(PNG_WRITE_TRANSFORMS_NOT_SUPPORTED) && \ !defined(PNG_NO_WRITE_TRANSFORMS) @@ -589,11 +682,15 @@ # endif #endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */ +#if !defined(PNG_NO_WRITE_INTERLACING_SUPPORTED) && \ + !defined(PNG_WRITE_INTERLACING_SUPPORTED) #define PNG_WRITE_INTERLACING_SUPPORTED /* not required for PNG-compliant encoders, but can cause trouble if left undefined */ +#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 @@ -602,10 +699,12 @@ # define PNG_WRITE_FLUSH_SUPPORTED #endif +#if defined(PNG_1_0_X) || defined (PNG_1_2_X) /* Deprecated, see PNG_MNG_FEATURES_SUPPORTED, above */ #ifndef PNG_NO_WRITE_EMPTY_PLTE # define PNG_WRITE_EMPTY_PLTE_SUPPORTED #endif +#endif #endif /* PNG_WRITE_SUPPORTED */ @@ -647,21 +746,46 @@ #endif /* PNG_ASSEMBLER_CODE was enabled by default in version 1.2.0 - even when PNG_USE_PNGVCRD or PNG_USE_PNGGCCRD is not defined */ + * and removed from version 1.2.20. The following will be removed + * from libpng-1.4.0 +*/ + +#if defined(PNG_READ_SUPPORTED) && !defined(PNG_NO_OPTIMIZED_CODE) +# ifndef PNG_OPTIMIZED_CODE_SUPPORTED +# define PNG_OPTIMIZED_CODE_SUPPORTED +# endif +#endif + #if defined(PNG_READ_SUPPORTED) && !defined(PNG_NO_ASSEMBLER_CODE) # ifndef PNG_ASSEMBLER_CODE_SUPPORTED # define PNG_ASSEMBLER_CODE_SUPPORTED # endif + +# if defined(__GNUC__) && defined(__x86_64__) && (__GNUC__ < 4) + /* work around 64-bit gcc compiler bugs in gcc-3.x */ +# if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE) +# define PNG_NO_MMX_CODE +# endif +# endif + +# if defined(__APPLE__) +# if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE) +# define PNG_NO_MMX_CODE +# endif +# endif + +# if (defined(__MWERKS__) && ((__MWERKS__ < 0x0900) || macintosh)) +# if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE) +# define PNG_NO_MMX_CODE +# endif +# endif + # if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE) # define PNG_MMX_CODE_SUPPORTED # endif -#endif -/* If you are sure that you don't need thread safety and you are compiling - with PNG_USE_PNGCCRD for an MMX application, you can define this for - faster execution. See pnggccrd.c. -#define PNG_THREAD_UNSAFE_OK -*/ +#endif +/* end of obsolete code to be removed from libpng-1.4.0 */ #if !defined(PNG_1_0_X) #if !defined(PNG_NO_USER_MEM) && !defined(PNG_USER_MEM_SUPPORTED) @@ -688,6 +812,11 @@ # define PNG_USER_HEIGHT_MAX 1000000L #endif +/* Added at libpng-1.2.34 and 1.4.0 */ +#ifndef PNG_STRING_NEWLINE +#define PNG_STRING_NEWLINE "\n" +#endif + /* These are currently experimental features, define them if you want */ /* very little testing */ @@ -815,14 +944,22 @@ # 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 # define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED # ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED # define PNG_UNKNOWN_CHUNKS_SUPPORTED # endif -# ifndef PNG_NO_HANDLE_AS_UNKNOWN -# define PNG_HANDLE_AS_UNKNOWN_SUPPORTED -# endif #endif #if !defined(PNG_NO_READ_USER_CHUNKS) && \ defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) @@ -835,17 +972,14 @@ # undef PNG_NO_HANDLE_AS_UNKNOWN # endif #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 + +#ifndef PNG_NO_HANDLE_AS_UNKNOWN +# ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED +# define PNG_HANDLE_AS_UNKNOWN_SUPPORTED +# endif #endif -#endif /* PNG_READ_ANCILLARY_CHUNKS_SUPPORTED */ - +#ifdef PNG_WRITE_SUPPORTED #ifdef PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED #ifdef PNG_NO_WRITE_TEXT @@ -957,17 +1091,6 @@ # define PNG_zTXt_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 -# ifndef PNG_NO_HANDLE_AS_UNKNOWN -# ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED -# define PNG_HANDLE_AS_UNKNOWN_SUPPORTED -# endif -# endif -#endif #if defined(PNG_WRITE_iTXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \ defined(PNG_WRITE_zTXt_SUPPORTED) # define PNG_WRITE_TEXT_SUPPORTED @@ -978,6 +1101,20 @@ #endif /* PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED */ +#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. @@ -1013,10 +1150,10 @@ typedef unsigned char png_byte; change (I'm not sure if you will or not, so I thought I'd be safe) */ #ifdef PNG_SIZE_T typedef PNG_SIZE_T png_size_t; -# define png_sizeof(x) png_convert_size(sizeof (x)) +# define png_sizeof(x) png_convert_size(sizeof(x)) #else typedef size_t png_size_t; -# define png_sizeof(x) sizeof (x) +# define png_sizeof(x) sizeof(x) #endif /* The following is needed for medium model support. It cannot be in the @@ -1121,6 +1258,9 @@ typedef double FAR * FAR * png_doublepp; /* Pointers to pointers to pointers; i.e., pointer to array */ typedef char FAR * FAR * FAR * png_charppp; +#if defined(PNG_1_0_X) || defined(PNG_1_2_X) +/* SPC - Is this stuff deprecated? */ +/* It'll be removed as of libpng-1.4.0 - GR-P */ /* libpng typedefs for types in zlib. If zlib changes * or another compression library is used, then change these. * Eliminates need to change all the source files. @@ -1128,6 +1268,7 @@ typedef char FAR * FAR * FAR * png_charppp; typedef charf * png_zcharp; typedef charf * FAR * png_zcharpp; typedef z_stream FAR * png_zstreamp; +#endif /* (PNG_1_0_X) || defined(PNG_1_2_X) */ /* * Define PNG_BUILD_DLL if the module being built is a Windows @@ -1179,20 +1320,17 @@ typedef z_stream FAR * png_zstreamp; * but might be required for some pre-1.0.5c applications. */ #if !defined(PNG_USE_LOCAL_ARRAYS) && !defined(PNG_USE_GLOBAL_ARRAYS) -# if defined(PNG_NO_GLOBAL_ARRAYS) || (defined(__GNUC__) && defined(PNG_DLL)) +# if defined(PNG_NO_GLOBAL_ARRAYS) || \ + (defined(__GNUC__) && defined(PNG_DLL)) || defined(_MSC_VER) # define PNG_USE_LOCAL_ARRAYS # else # define PNG_USE_GLOBAL_ARRAYS # endif #endif -#if defined(__CYGWIN__) || defined(__WINE__) +#if defined(__CYGWIN__) # undef PNGAPI -# if defined(__WINE__) -# define PNGAPI -# else -# define PNGAPI __cdecl -# endif +# define PNGAPI __cdecl # undef PNG_IMPEXP # define PNG_IMPEXP #endif @@ -1268,21 +1406,7 @@ typedef z_stream FAR * png_zstreamp; # else # if 0 /* ... other platforms, with other meanings */ # endif -# endif -#endif - -#if defined(__VISAGECPP__) -/* I don't compile with this _System linkage for wxWidgets */ -# ifdef PNGAPI -# undef PNGAPI -# endif -# define PNGAPI _Optlink -# define PNG_IMPEXP -# define PNG_USE_LOCAL_ARRAYS -# ifdef PNG_USE_GLOBAL_ARRAYS -# undef PNG_USE_GLOBAL_ARRAYS -# endif -extern const char png_libpng_ver[18]; +# endif #endif #ifndef PNGAPI @@ -1292,6 +1416,17 @@ extern const char png_libpng_ver[18]; # define PNG_IMPEXP #endif +#ifdef PNG_BUILDSYMS +# ifndef PNG_EXPORT +# define PNG_EXPORT(type,symbol) PNG_FUNCTION_EXPORT symbol END +# endif +# ifdef PNG_USE_GLOBAL_ARRAYS +# ifndef PNG_EXPORT_VAR +# define PNG_EXPORT_VAR(type) PNG_DATA_EXPORT +# endif +# endif +#endif + #ifndef PNG_EXPORT # define PNG_EXPORT(type,symbol) PNG_IMPEXP type PNGAPI symbol #endif @@ -1323,8 +1458,7 @@ extern const char png_libpng_ver[18]; # 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_snprintf _fsnprintf /* Added to v 1.2.19 */ # define png_strlen _fstrlen # define png_memcmp _fmemcmp /* SJT: added */ # define png_memcpy _fmemcpy @@ -1332,8 +1466,27 @@ extern const char png_libpng_ver[18]; #else /* use the usual functions */ # 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 */ +# 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) sprintf(s1,fmt,x1) +# define png_snprintf2(s1,n,fmt,x1,x2) sprintf(s1,fmt,x1,x2) +# define png_snprintf6(s1,n,fmt,x1,x2,x3,x4,x5,x6) \ + sprintf(s1,fmt,x1,x2,x3,x4,x5,x6) +# endif # define png_strlen strlen # define png_memcmp memcmp /* SJT: added */ # define png_memcpy memcpy @@ -1349,46 +1502,7 @@ extern const char png_libpng_ver[18]; # define PNG_ZBUF_SIZE 65536L #endif -#ifdef PNG_READ_SUPPORTED -/* Prior to libpng-1.0.9, this block was in pngasmrd.h */ -#if defined(PNG_INTERNAL) - -/* These are the default thresholds before the MMX code kicks in; if either - * rowbytes or bitdepth is below the threshold, plain C code is used. These - * can be overridden at runtime via the png_set_mmx_thresholds() call in - * libpng 1.2.0 and later. The values below were chosen by Intel. - */ - -#ifndef PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT -# define PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT 128 /* >= */ -#endif -#ifndef PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT -# define PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT 9 /* >= */ -#endif - -/* Set this in the makefile for VC++ on Pentium, not here. */ -/* Platform must be Pentium. Makefile must assemble and load pngvcrd.c . - * MMX will be detected at run time and used if present. - */ -#ifdef PNG_USE_PNGVCRD -# define PNG_HAVE_ASSEMBLER_COMBINE_ROW -# define PNG_HAVE_ASSEMBLER_READ_INTERLACE -# define PNG_HAVE_ASSEMBLER_READ_FILTER_ROW -#endif - -/* Set this in the makefile for gcc/as on Pentium, not here. */ -/* Platform must be Pentium. Makefile must assemble and load pnggccrd.c . - * MMX will be detected at run time and used if present. - */ -#ifdef PNG_USE_PNGGCCRD -# define PNG_HAVE_ASSEMBLER_COMBINE_ROW -# define PNG_HAVE_ASSEMBLER_READ_INTERLACE -# define PNG_HAVE_ASSEMBLER_READ_FILTER_ROW -#endif -/* - see pnggccrd.c for info about what is currently enabled */ - -#endif /* PNG_INTERNAL */ -#endif /* PNG_READ_SUPPORTED */ +/* Added at libpng-1.2.8 */ +#endif /* PNG_VERSION_INFO_ONLY */ #endif /* PNGCONF_H */ - diff --git a/3rdparty/wxWidgets/src/png/pngerror.c b/3rdparty/wxWidgets/src/png/pngerror.c index fda078ef58..d68416b384 100644 --- a/3rdparty/wxWidgets/src/png/pngerror.c +++ b/3rdparty/wxWidgets/src/png/pngerror.c @@ -1,12 +1,15 @@ /* pngerror.c - stub functions for i/o and memory allocation * - * libpng version 1.2.7 - September 12, 2004 - * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2004 Glenn Randers-Pehrson + * Last changed in libpng 1.2.37 [June 4, 2009] + * Copyright (c) 1998-2009 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. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * * This file provides a location for all error handling. Users who * need special error handling are expected to write replacement functions * and use png_set_error_fn() to use those functions. See the instructions @@ -15,51 +18,60 @@ #define PNG_INTERNAL #include "png.h" +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) static void /* PRIVATE */ png_default_error PNGARG((png_structp png_ptr, png_const_charp error_message)); +#ifndef PNG_NO_WARNINGS static void /* PRIVATE */ png_default_warning PNGARG((png_structp png_ptr, png_const_charp warning_message)); +#endif /* PNG_NO_WARNINGS */ /* This function is called whenever there is a fatal error. This function * should not be changed. If there is a need to handle errors differently, * you should supply a replacement error function and use png_set_error_fn() * to replace the error function at run-time. */ +#ifndef PNG_NO_ERROR_TEXT void PNGAPI png_error(png_structp png_ptr, png_const_charp error_message) { #ifdef PNG_ERROR_NUMBERS_SUPPORTED char msg[16]; - if (png_ptr->flags&(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) + if (png_ptr != NULL) { - if (*error_message == '#') + if (png_ptr->flags& + (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) { - 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; iflags&PNG_FLAG_STRIP_ERROR_TEXT) - { - msg[0]='0'; - msg[1]='\0'; - error_message=msg; - } + if (*error_message == '#') + { + /* 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; + } + } } } #endif @@ -70,7 +82,20 @@ png_error(png_structp png_ptr, png_const_charp error_message) use the default handler, which will not return. */ png_default_error(png_ptr, error_message); } +#else +void PNGAPI +png_err(png_structp png_ptr) +{ + if (png_ptr != NULL && png_ptr->error_fn != NULL) + (*(png_ptr->error_fn))(png_ptr, '\0'); + /* If the custom handler doesn't exist, or if it returns, + use the default handler, which will not return. */ + png_default_error(png_ptr, '\0'); +} +#endif /* PNG_NO_ERROR_TEXT */ + +#ifndef PNG_NO_WARNINGS /* This function is called whenever there is a non-fatal error. This function * should not be changed. If there is a need to handle warnings differently, * you should supply a replacement warning function and use @@ -80,22 +105,28 @@ void PNGAPI png_warning(png_structp png_ptr, png_const_charp warning_message) { int offset = 0; -#ifdef PNG_ERROR_NUMBERS_SUPPORTED - if (png_ptr->flags&(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) -#endif + if (png_ptr != NULL) { - if (*warning_message == '#') +#ifdef PNG_ERROR_NUMBERS_SUPPORTED + if (png_ptr->flags& + (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) +#endif { - for (offset=1; offset<15; offset++) - if (*(warning_message+offset) == ' ') - break; + if (*warning_message == '#') + { + 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); + (*(png_ptr->warning_fn))(png_ptr, warning_message + offset); else - png_default_warning(png_ptr, warning_message+offset); + png_default_warning(png_ptr, warning_message + offset); } +#endif /* PNG_NO_WARNINGS */ + /* These utilities are used internally to build an error message that relates * to the current chunk. The chunk name comes from png_ptr->chunk_name, @@ -109,6 +140,9 @@ static PNG_CONST char png_digit[16] = { 'A', 'B', 'C', 'D', 'E', 'F' }; +#define PNG_MAX_ERROR_TEXT 64 + +#if !defined(PNG_NO_WARNINGS) || !defined(PNG_NO_ERROR_TEXT) static void /* PRIVATE */ png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp error_message) @@ -117,7 +151,7 @@ png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp while (iin < 4) { - int c = png_ptr->chunk_name[iin++]; + int c = png_ptr->chunk_name[iin++]; if (isnonalpha(c)) { buffer[iout++] = '['; @@ -132,31 +166,47 @@ png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp } if (error_message == NULL) - buffer[iout] = 0; + buffer[iout] = '\0'; else { buffer[iout++] = ':'; buffer[iout++] = ' '; - png_strncpy(buffer+iout, error_message, 63); - buffer[iout+63] = 0; + png_memcpy(buffer + iout, error_message, PNG_MAX_ERROR_TEXT); + buffer[iout + PNG_MAX_ERROR_TEXT - 1] = '\0'; } } +#ifdef PNG_READ_SUPPORTED void PNGAPI png_chunk_error(png_structp png_ptr, png_const_charp error_message) { - char msg[18+64]; - png_format_buffer(png_ptr, msg, error_message); - png_error(png_ptr, msg); + char msg[18+PNG_MAX_ERROR_TEXT]; + if (png_ptr == NULL) + png_error(png_ptr, error_message); + else + { + png_format_buffer(png_ptr, msg, error_message); + png_error(png_ptr, msg); + } } +#endif /* PNG_READ_SUPPORTED */ +#endif /* !defined(PNG_NO_WARNINGS) || !defined(PNG_NO_ERROR_TEXT) */ +#ifndef PNG_NO_WARNINGS void PNGAPI png_chunk_warning(png_structp png_ptr, png_const_charp warning_message) { - char msg[18+64]; - png_format_buffer(png_ptr, msg, warning_message); - png_warning(png_ptr, msg); + char msg[18+PNG_MAX_ERROR_TEXT]; + if (png_ptr == NULL) + png_warning(png_ptr, warning_message); + else + { + png_format_buffer(png_ptr, msg, warning_message); + png_warning(png_ptr, msg); + } } +#endif /* PNG_NO_WARNINGS */ + /* This is the default error handling function. Note that replacements for * this function MUST NOT RETURN, or the program will likely crash. This @@ -170,50 +220,59 @@ png_default_error(png_structp png_ptr, png_const_charp error_message) #ifdef PNG_ERROR_NUMBERS_SUPPORTED if (*error_message == '#') { + /* Strip "#nnnn " from beginning of error message. */ int offset; char error_number[16]; - for (offset=0; offset<15; offset++) + for (offset = 0; offset<15; offset++) { - error_number[offset] = *(error_message+offset+1); - if (*(error_message+offset) == ' ') + error_number[offset] = error_message[offset + 1]; + if (error_message[offset] == ' ') break; } - if((offset > 1) && (offset < 15)) + if ((offset > 1) && (offset < 15)) { - error_number[offset-1]='\0'; - fprintf(stderr, "libpng error no. %s: %s\n", error_number, - error_message+offset); + 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\n", error_message,offset); + { + fprintf(stderr, "libpng error: %s, offset=%d", + error_message, offset); + fprintf(stderr, PNG_STRING_NEWLINE); + } } else #endif - fprintf(stderr, "libpng error: %s\n", error_message); + { + fprintf(stderr, "libpng error: %s", error_message); + fprintf(stderr, PNG_STRING_NEWLINE); + } #endif #ifdef PNG_SETJMP_SUPPORTED + if (png_ptr) + { # ifdef USE_FAR_KEYWORD { jmp_buf jmpbuf; - png_memcpy(jmpbuf,png_ptr->jmpbuf,png_sizeof(jmp_buf)); + png_memcpy(jmpbuf, png_ptr->jmpbuf, png_sizeof(jmp_buf)); longjmp(jmpbuf, 1); } # else longjmp(png_ptr->jmpbuf, 1); -# endif +# endif + } #else - /* make compiler happy */ ; - if (png_ptr) PNG_ABORT(); #endif #ifdef PNG_NO_CONSOLE_IO - /* make compiler happy */ ; - if (&error_message != NULL) - return; + error_message = error_message; /* Make compiler happy */ #endif } +#ifndef PNG_NO_WARNINGS /* This function is called when there is a warning, but the library thinks * it can continue anyway. Replacement functions don't have to do anything * here if you don't want them to. In the default configuration, png_ptr is @@ -228,33 +287,38 @@ png_default_warning(png_structp png_ptr, png_const_charp warning_message) { int offset; char warning_number[16]; - for (offset=0; offset<15; offset++) + for (offset = 0; offset < 15; offset++) { - warning_number[offset]=*(warning_message+offset+1); - if (*(warning_message+offset) == ' ') + warning_number[offset] = warning_message[offset + 1]; + if (warning_message[offset] == ' ') break; } - if((offset > 1) && (offset < 15)) + if ((offset > 1) && (offset < 15)) { - warning_number[offset-1]='\0'; - fprintf(stderr, "libpng warning no. %s: %s\n", warning_number, - warning_message+offset); + 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\n", warning_message); + { + fprintf(stderr, "libpng warning: %s", + warning_message); + fprintf(stderr, PNG_STRING_NEWLINE); + } } else # endif - fprintf(stderr, "libpng warning: %s\n", warning_message); + { + fprintf(stderr, "libpng warning: %s", warning_message); + fprintf(stderr, PNG_STRING_NEWLINE); + } #else - /* make compiler happy */ ; - if (warning_message) - return; + warning_message = warning_message; /* Make compiler happy */ #endif - /* make compiler happy */ ; - if (png_ptr) - return; + png_ptr = png_ptr; /* Make compiler happy */ } +#endif /* PNG_NO_WARNINGS */ /* This function is called when the application wants to use another method * of handling errors and warnings. Note that the error function MUST NOT @@ -265,6 +329,8 @@ void PNGAPI png_set_error_fn(png_structp png_ptr, png_voidp error_ptr, 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; @@ -278,6 +344,8 @@ png_set_error_fn(png_structp png_ptr, png_voidp error_ptr, png_voidp PNGAPI png_get_error_ptr(png_structp png_ptr) { + if (png_ptr == NULL) + return NULL; return ((png_voidp)png_ptr->error_ptr); } @@ -286,10 +354,11 @@ png_get_error_ptr(png_structp png_ptr) void PNGAPI png_set_strip_error_numbers(png_structp png_ptr, png_uint_32 strip_mode) { - if(png_ptr != NULL) + if (png_ptr != NULL) { png_ptr->flags &= ((~(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode); } } #endif +#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ diff --git a/3rdparty/wxWidgets/src/png/pnggccrd.c b/3rdparty/wxWidgets/src/png/pnggccrd.c deleted file mode 100644 index 27c716a2c0..0000000000 --- a/3rdparty/wxWidgets/src/png/pnggccrd.c +++ /dev/null @@ -1,5408 +0,0 @@ -/* pnggccrd.c - mixed C/assembler version of utilities to read a PNG file - * - * For Intel x86 CPU (Pentium-MMX or later) and GNU C compiler. - * - * See http://www.intel.com/drg/pentiumII/appnotes/916/916.htm - * and http://www.intel.com/drg/pentiumII/appnotes/923/923.htm - * for Intel's performance analysis of the MMX vs. non-MMX code. - * - * libpng version 1.2.7 - September 12, 2004 - * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2004 Glenn Randers-Pehrson - * Copyright (c) 1998, Intel Corporation - * - * Based on MSVC code contributed by Nirav Chhatrapati, Intel Corp., 1998. - * Interface to libpng contributed by Gilles Vollant, 1999. - * GNU C port by Greg Roelofs, 1999-2001. - * - * Lines 2350-4300 converted in place with intel2gas 1.3.1: - * - * intel2gas -mdI pnggccrd.c.partially-msvc -o pnggccrd.c - * - * and then cleaned up by hand. See http://hermes.terminal.at/intel2gas/ . - * - * NOTE: A sufficiently recent version of GNU as (or as.exe under DOS/Windows) - * is required to assemble the newer MMX instructions such as movq. - * For djgpp, see - * - * ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/bnu281b.zip - * - * (or a later version in the same directory). For Linux, check your - * distribution's web site(s) or try these links: - * - * http://rufus.w3.org/linux/RPM/binutils.html - * http://www.debian.org/Packages/stable/devel/binutils.html - * ftp://ftp.slackware.com/pub/linux/slackware/slackware/slakware/d1/ - * binutils.tgz - * - * For other platforms, see the main GNU site: - * - * ftp://ftp.gnu.org/pub/gnu/binutils/ - * - * Version 2.5.2l.15 is definitely too old... - */ - -/* - * TEMPORARY PORTING NOTES AND CHANGELOG (mostly by Greg Roelofs) - * ===================================== - * - * 19991006: - * - fixed sign error in post-MMX cleanup code (16- & 32-bit cases) - * - * 19991007: - * - additional optimizations (possible or definite): - * x [DONE] write MMX code for 64-bit case (pixel_bytes == 8) [not tested] - * - write MMX code for 48-bit case (pixel_bytes == 6) - * - figure out what's up with 24-bit case (pixel_bytes == 3): - * why subtract 8 from width_mmx in the pass 4/5 case? - * (only width_mmx case) (near line 1606) - * x [DONE] replace pixel_bytes within each block with the true - * constant value (or are compilers smart enough to do that?) - * - rewrite all MMX interlacing code so it's aligned with - * the *beginning* of the row buffer, not the end. This - * would not only allow one to eliminate half of the memory - * writes for odd passes (that is, pass == odd), it may also - * eliminate some unaligned-data-access exceptions (assuming - * there's a penalty for not aligning 64-bit accesses on - * 64-bit boundaries). The only catch is that the "leftover" - * pixel(s) at the end of the row would have to be saved, - * but there are enough unused MMX registers in every case, - * so this is not a problem. A further benefit is that the - * post-MMX cleanup code (C code) in at least some of the - * cases could be done within the assembler block. - * x [DONE] the "v3 v2 v1 v0 v7 v6 v5 v4" comments are confusing, - * inconsistent, and don't match the MMX Programmer's Reference - * Manual conventions anyway. They should be changed to - * "b7 b6 b5 b4 b3 b2 b1 b0," where b0 indicates the byte that - * was lowest in memory (e.g., corresponding to a left pixel) - * and b7 is the byte that was highest (e.g., a right pixel). - * - * 19991016: - * - Brennan's Guide notwithstanding, gcc under Linux does *not* - * want globals prefixed by underscores when referencing them-- - * i.e., if the variable is const4, then refer to it as const4, - * not _const4. This seems to be a djgpp-specific requirement. - * Also, such variables apparently *must* be declared outside - * of functions; neither static nor automatic variables work if - * defined within the scope of a single function, but both - * static and truly global (multi-module) variables work fine. - * - * 19991023: - * - fixed png_combine_row() non-MMX replication bug (odd passes only?) - * - switched from string-concatenation-with-macros to cleaner method of - * renaming global variables for djgpp--i.e., always use prefixes in - * inlined assembler code (== strings) and conditionally rename the - * variables, not the other way around. Hence _const4, _mask8_0, etc. - * - * 19991024: - * - fixed mmxsupport()/png_do_read_interlace() first-row bug - * This one was severely weird: even though mmxsupport() doesn't touch - * ebx (where "row" pointer was stored), it nevertheless managed to zero - * the register (even in static/non-fPIC code--see below), which in turn - * caused png_do_read_interlace() to return prematurely on the first row of - * interlaced images (i.e., without expanding the interlaced pixels). - * Inspection of the generated assembly code didn't turn up any clues, - * although it did point at a minor optimization (i.e., get rid of - * mmx_supported_local variable and just use eax). Possibly the CPUID - * instruction is more destructive than it looks? (Not yet checked.) - * - "info gcc" was next to useless, so compared fPIC and non-fPIC assembly - * listings... Apparently register spillage has to do with ebx, since - * it's used to index the global offset table. Commenting it out of the - * input-reg lists in png_combine_row() eliminated compiler barfage, so - * ifdef'd with __PIC__ macro: if defined, use a global for unmask - * - * 19991107: - * - verified CPUID clobberage: 12-char string constant ("GenuineIntel", - * "AuthenticAMD", etc.) placed in ebx:ecx:edx. Still need to polish. - * - * 19991120: - * - made "diff" variable (now "_dif") global to simplify conversion of - * filtering routines (running out of regs, sigh). "diff" is still used - * in interlacing routines, however. - * - fixed up both versions of mmxsupport() (ORIG_THAT_USED_TO_CLOBBER_EBX - * macro determines which is used); original not yet tested. - * - * 20000213: - * - when compiling with gcc, be sure to use -fomit-frame-pointer - * - * 20000319: - * - fixed a register-name typo in png_do_read_interlace(), default (MMX) case, - * pass == 4 or 5, that caused visible corruption of interlaced images - * - * 20000623: - * - Various problems were reported with gcc 2.95.2 in the Cygwin environment, - * many of the form "forbidden register 0 (ax) was spilled for class AREG." - * This is explained at http://gcc.gnu.org/fom_serv/cache/23.html, and - * Chuck Wilson supplied a patch involving dummy output registers. See - * http://sourceforge.net/bugs/?func=detailbug&bug_id=108741&group_id=5624 - * for the original (anonymous) SourceForge bug report. - * - * 20000706: - * - Chuck Wilson passed along these remaining gcc 2.95.2 errors: - * pnggccrd.c: In function `png_combine_row': - * pnggccrd.c:525: more than 10 operands in `asm' - * pnggccrd.c:669: more than 10 operands in `asm' - * pnggccrd.c:828: more than 10 operands in `asm' - * pnggccrd.c:994: more than 10 operands in `asm' - * pnggccrd.c:1177: more than 10 operands in `asm' - * They are all the same problem and can be worked around by using the - * global _unmask variable unconditionally, not just in the -fPIC case. - * Reportedly earlier versions of gcc also have the problem with more than - * 10 operands; they just don't report it. Much strangeness ensues, etc. - * - * 20000729: - * - enabled png_read_filter_row_mmx_up() (shortest remaining unconverted - * MMX routine); began converting png_read_filter_row_mmx_sub() - * - to finish remaining sections: - * - clean up indentation and comments - * - preload local variables - * - add output and input regs (order of former determines numerical - * mapping of latter) - * - avoid all usage of ebx (including bx, bh, bl) register [20000823] - * - remove "$" from addressing of Shift and Mask variables [20000823] - * - * 20000731: - * - global union vars causing segfaults in png_read_filter_row_mmx_sub()? - * - * 20000822: - * - ARGH, stupid png_read_filter_row_mmx_sub() segfault only happens with - * shared-library (-fPIC) version! Code works just fine as part of static - * library. Damn damn damn damn damn, should have tested that sooner. - * ebx is getting clobbered again (explicitly this time); need to save it - * on stack or rewrite asm code to avoid using it altogether. Blargh! - * - * 20000823: - * - first section was trickiest; all remaining sections have ebx -> edx now. - * (-fPIC works again.) Also added missing underscores to various Shift* - * and *Mask* globals and got rid of leading "$" signs. - * - * 20000826: - * - added visual separators to help navigate microscopic printed copies - * (http://pobox.com/~newt/code/gpr-latest.zip, mode 10); started working - * on png_read_filter_row_mmx_avg() - * - * 20000828: - * - finished png_read_filter_row_mmx_avg(): only Paeth left! (930 lines...) - * What the hell, did png_read_filter_row_mmx_paeth(), too. Comments not - * cleaned up/shortened in either routine, but functionality is complete - * and seems to be working fine. - * - * 20000829: - * - ahhh, figured out last(?) bit of gcc/gas asm-fu: if register is listed - * as an input reg (with dummy output variables, etc.), then it *cannot* - * also appear in the clobber list or gcc 2.95.2 will barf. The solution - * is simple enough... - * - * 20000914: - * - bug in png_read_filter_row_mmx_avg(): 16-bit grayscale not handled - * correctly (but 48-bit RGB just fine) - * - * 20000916: - * - fixed bug in png_read_filter_row_mmx_avg(), bpp == 2 case; three errors: - * - "_ShiftBpp.use = 24;" should have been "_ShiftBpp.use = 16;" - * - "_ShiftRem.use = 40;" should have been "_ShiftRem.use = 48;" - * - "psllq _ShiftRem, %%mm2" should have been "psrlq _ShiftRem, %%mm2" - * - * 20010101: - * - added new png_init_mmx_flags() function (here only because it needs to - * call mmxsupport(), which should probably become global png_mmxsupport()); - * modified other MMX routines to run conditionally (png_ptr->asm_flags) - * - * 20010103: - * - renamed mmxsupport() to png_mmx_support(), with auto-set of mmx_supported, - * and made it public; moved png_init_mmx_flags() to png.c as internal func - * - * 20010104: - * - removed dependency on png_read_filter_row_c() (C code already duplicated - * within MMX version of png_read_filter_row()) so no longer necessary to - * compile it into pngrutil.o - * - * 20010310: - * - fixed buffer-overrun bug in png_combine_row() C code (non-MMX) - * - * 20020304: - * - eliminated incorrect use of width_mmx in pixel_bytes == 8 case - * - * 20040724: - * - more tinkering with clobber list at lines 4529 and 5033, to get - * it to compile on gcc-3.4. - * - * STILL TO DO: - * - test png_do_read_interlace() 64-bit case (pixel_bytes == 8) - * - write MMX code for 48-bit case (pixel_bytes == 6) - * - figure out what's up with 24-bit case (pixel_bytes == 3): - * why subtract 8 from width_mmx in the pass 4/5 case? - * (only width_mmx case) (near line 1606) - * - rewrite all MMX interlacing code so it's aligned with beginning - * of the row buffer, not the end (see 19991007 for details) - * x pick one version of mmxsupport() and get rid of the other - * - add error messages to any remaining bogus default cases - * - enable pixel_depth == 8 cases in png_read_filter_row()? (test speed) - * x add support for runtime enable/disable/query of various MMX routines - */ - -#define PNG_INTERNAL -#include "png.h" - -#if defined(PNG_USE_PNGGCCRD) - -int PNGAPI png_mmx_support(void); - -#ifdef PNG_USE_LOCAL_ARRAYS -static const int FARDATA png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; -static const int FARDATA png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; -static const int FARDATA png_pass_width[7] = {8, 4, 4, 2, 2, 1, 1}; -#endif - -#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) -/* djgpp, Win32, and Cygwin add their own underscores to global variables, - * so define them without: */ -#if defined(__DJGPP__) || defined(WIN32) || defined(__CYGWIN__) -# define _mmx_supported mmx_supported -# define _const4 const4 -# define _const6 const6 -# define _mask8_0 mask8_0 -# define _mask16_1 mask16_1 -# define _mask16_0 mask16_0 -# define _mask24_2 mask24_2 -# define _mask24_1 mask24_1 -# define _mask24_0 mask24_0 -# define _mask32_3 mask32_3 -# define _mask32_2 mask32_2 -# define _mask32_1 mask32_1 -# define _mask32_0 mask32_0 -# define _mask48_5 mask48_5 -# define _mask48_4 mask48_4 -# define _mask48_3 mask48_3 -# define _mask48_2 mask48_2 -# define _mask48_1 mask48_1 -# define _mask48_0 mask48_0 -# define _LBCarryMask LBCarryMask -# define _HBClearMask HBClearMask -# define _ActiveMask ActiveMask -# define _ActiveMask2 ActiveMask2 -# define _ActiveMaskEnd ActiveMaskEnd -# define _ShiftBpp ShiftBpp -# define _ShiftRem ShiftRem -#ifdef PNG_THREAD_UNSAFE_OK -# define _unmask unmask -# define _FullLength FullLength -# define _MMXLength MMXLength -# define _dif dif -# define _patemp patemp -# define _pbtemp pbtemp -# define _pctemp pctemp -#endif -#endif - - -/* These constants are used in the inlined MMX assembly code. - Ignore gcc's "At top level: defined but not used" warnings. */ - -/* GRR 20000706: originally _unmask was needed only when compiling with -fPIC, - * since that case uses the %ebx register for indexing the Global Offset Table - * and there were no other registers available. But gcc 2.95 and later emit - * "more than 10 operands in `asm'" errors when %ebx is used to preload unmask - * in the non-PIC case, so we'll just use the global unconditionally now. - */ -#ifdef PNG_THREAD_UNSAFE_OK -static int _unmask; -#endif - -static unsigned long long _mask8_0 = 0x0102040810204080LL; - -static unsigned long long _mask16_1 = 0x0101020204040808LL; -static unsigned long long _mask16_0 = 0x1010202040408080LL; - -static unsigned long long _mask24_2 = 0x0101010202020404LL; -static unsigned long long _mask24_1 = 0x0408080810101020LL; -static unsigned long long _mask24_0 = 0x2020404040808080LL; - -static unsigned long long _mask32_3 = 0x0101010102020202LL; -static unsigned long long _mask32_2 = 0x0404040408080808LL; -static unsigned long long _mask32_1 = 0x1010101020202020LL; -static unsigned long long _mask32_0 = 0x4040404080808080LL; - -static unsigned long long _mask48_5 = 0x0101010101010202LL; -static unsigned long long _mask48_4 = 0x0202020204040404LL; -static unsigned long long _mask48_3 = 0x0404080808080808LL; -static unsigned long long _mask48_2 = 0x1010101010102020LL; -static unsigned long long _mask48_1 = 0x2020202040404040LL; -static unsigned long long _mask48_0 = 0x4040808080808080LL; - -static unsigned long long _const4 = 0x0000000000FFFFFFLL; -/* static unsigned long long _const5 = 0x000000FFFFFF0000LL; */ /* NOT USED */ -static unsigned long long _const6 = 0x00000000000000FFLL; - -/* These are used in the row-filter routines and should/would be local */ -/* variables if not for gcc addressing limitations. */ -/* WARNING: Their presence probably defeats the thread safety of libpng. */ - -#ifdef PNG_THREAD_UNSAFE_OK -static png_uint_32 _FullLength; -static png_uint_32 _MMXLength; -static int _dif; -static int _patemp; /* temp variables for Paeth routine */ -static int _pbtemp; -static int _pctemp; -#endif - -void /* PRIVATE */ -png_squelch_warnings(void) -{ -#ifdef PNG_THREAD_UNSAFE_OK - _dif = _dif; - _patemp = _patemp; - _pbtemp = _pbtemp; - _pctemp = _pctemp; - _MMXLength = _MMXLength; -#endif - _const4 = _const4; - _const6 = _const6; - _mask8_0 = _mask8_0; - _mask16_1 = _mask16_1; - _mask16_0 = _mask16_0; - _mask24_2 = _mask24_2; - _mask24_1 = _mask24_1; - _mask24_0 = _mask24_0; - _mask32_3 = _mask32_3; - _mask32_2 = _mask32_2; - _mask32_1 = _mask32_1; - _mask32_0 = _mask32_0; - _mask48_5 = _mask48_5; - _mask48_4 = _mask48_4; - _mask48_3 = _mask48_3; - _mask48_2 = _mask48_2; - _mask48_1 = _mask48_1; - _mask48_0 = _mask48_0; -} -#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ - - -static int _mmx_supported = 2; - -/*===========================================================================*/ -/* */ -/* P N G _ C O M B I N E _ R O W */ -/* */ -/*===========================================================================*/ - -#if defined(PNG_HAVE_ASSEMBLER_COMBINE_ROW) - -#define BPP2 2 -#define BPP3 3 /* bytes per pixel (a.k.a. pixel_bytes) */ -#define BPP4 4 -#define BPP6 6 /* (defined only to help avoid cut-and-paste errors) */ -#define BPP8 8 - -/* Combines the row recently read in with the previous 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. */ - -/* Use this routine for the x86 platform - it uses a faster MMX routine - if the machine supports MMX. */ - -void /* PRIVATE */ -png_combine_row(png_structp png_ptr, png_bytep row, int mask) -{ - png_debug(1, "in png_combine_row (pnggccrd.c)\n"); - -#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) - if (_mmx_supported == 2) { -#if !defined(PNG_1_0_X) - /* this should have happened in png_init_mmx_flags() already */ - png_warning(png_ptr, "asm_flags may not have been initialized"); -#endif - png_mmx_support(); - } -#endif - - if (mask == 0xff) - { - png_debug(2,"mask == 0xff: doing single png_memcpy()\n"); - png_memcpy(row, png_ptr->row_buf + 1, - (png_size_t)PNG_ROWBYTES(png_ptr->row_info.pixel_depth,png_ptr->width)); - } - else /* (png_combine_row() is never called with mask == 0) */ - { - switch (png_ptr->row_info.pixel_depth) - { - case 1: /* png_ptr->row_info.pixel_depth */ - { - png_bytep sp; - png_bytep dp; - int s_inc, s_start, s_end; - int m; - int shift; - png_uint_32 i; - - sp = png_ptr->row_buf + 1; - dp = row; - m = 0x80; -#if defined(PNG_READ_PACKSWAP_SUPPORTED) - if (png_ptr->transformations & PNG_PACKSWAP) - { - s_start = 0; - s_end = 7; - s_inc = 1; - } - else -#endif - { - s_start = 7; - s_end = 0; - s_inc = -1; - } - - shift = s_start; - - for (i = 0; i < png_ptr->width; i++) - { - if (m & mask) - { - int value; - - value = (*sp >> shift) & 0x1; - *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff); - *dp |= (png_byte)(value << shift); - } - - if (shift == s_end) - { - shift = s_start; - sp++; - dp++; - } - else - shift += s_inc; - - if (m == 1) - m = 0x80; - else - m >>= 1; - } - break; - } - - case 2: /* png_ptr->row_info.pixel_depth */ - { - png_bytep sp; - png_bytep dp; - int s_start, s_end, s_inc; - int m; - int shift; - png_uint_32 i; - int value; - - sp = png_ptr->row_buf + 1; - dp = row; - m = 0x80; -#if defined(PNG_READ_PACKSWAP_SUPPORTED) - if (png_ptr->transformations & PNG_PACKSWAP) - { - s_start = 0; - s_end = 6; - s_inc = 2; - } - else -#endif - { - s_start = 6; - s_end = 0; - s_inc = -2; - } - - shift = s_start; - - for (i = 0; i < png_ptr->width; i++) - { - if (m & mask) - { - value = (*sp >> shift) & 0x3; - *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); - *dp |= (png_byte)(value << shift); - } - - if (shift == s_end) - { - shift = s_start; - sp++; - dp++; - } - else - shift += s_inc; - if (m == 1) - m = 0x80; - else - m >>= 1; - } - break; - } - - case 4: /* png_ptr->row_info.pixel_depth */ - { - png_bytep sp; - png_bytep dp; - int s_start, s_end, s_inc; - int m; - int shift; - png_uint_32 i; - int value; - - sp = png_ptr->row_buf + 1; - dp = row; - m = 0x80; -#if defined(PNG_READ_PACKSWAP_SUPPORTED) - if (png_ptr->transformations & PNG_PACKSWAP) - { - s_start = 0; - s_end = 4; - s_inc = 4; - } - else -#endif - { - s_start = 4; - s_end = 0; - s_inc = -4; - } - shift = s_start; - - for (i = 0; i < png_ptr->width; i++) - { - if (m & mask) - { - value = (*sp >> shift) & 0xf; - *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); - *dp |= (png_byte)(value << shift); - } - - if (shift == s_end) - { - shift = s_start; - sp++; - dp++; - } - else - shift += s_inc; - if (m == 1) - m = 0x80; - else - m >>= 1; - } - break; - } - - case 8: /* png_ptr->row_info.pixel_depth */ - { - png_bytep srcptr; - png_bytep dstptr; - -#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) -#if !defined(PNG_1_0_X) - if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) - /* && _mmx_supported */ ) -#else - if (_mmx_supported) -#endif - { - png_uint_32 len; - int diff; - int dummy_value_a; /* fix 'forbidden register spilled' error */ - int dummy_value_d; - int dummy_value_c; - int dummy_value_S; - int dummy_value_D; - _unmask = ~mask; /* global variable for -fPIC version */ - srcptr = png_ptr->row_buf + 1; - dstptr = row; - len = png_ptr->width &~7; /* reduce to multiple of 8 */ - diff = (int) (png_ptr->width & 7); /* amount lost */ - - __asm__ __volatile__ ( - "movd _unmask, %%mm7 \n\t" /* load bit pattern */ - "psubb %%mm6, %%mm6 \n\t" /* zero mm6 */ - "punpcklbw %%mm7, %%mm7 \n\t" - "punpcklwd %%mm7, %%mm7 \n\t" - "punpckldq %%mm7, %%mm7 \n\t" /* fill reg with 8 masks */ - - "movq _mask8_0, %%mm0 \n\t" - "pand %%mm7, %%mm0 \n\t" /* nonzero if keep byte */ - "pcmpeqb %%mm6, %%mm0 \n\t" /* zeros->1s, v versa */ - -/* preload "movl len, %%ecx \n\t" // load length of line */ -/* preload "movl srcptr, %%esi \n\t" // load source */ -/* preload "movl dstptr, %%edi \n\t" // load dest */ - - "cmpl $0, %%ecx \n\t" /* len == 0 ? */ - "je mainloop8end \n\t" - - "mainloop8: \n\t" - "movq (%%esi), %%mm4 \n\t" /* *srcptr */ - "pand %%mm0, %%mm4 \n\t" - "movq %%mm0, %%mm6 \n\t" - "pandn (%%edi), %%mm6 \n\t" /* *dstptr */ - "por %%mm6, %%mm4 \n\t" - "movq %%mm4, (%%edi) \n\t" - "addl $8, %%esi \n\t" /* inc by 8 bytes processed */ - "addl $8, %%edi \n\t" - "subl $8, %%ecx \n\t" /* dec by 8 pixels processed */ - "ja mainloop8 \n\t" - - "mainloop8end: \n\t" -/* preload "movl diff, %%ecx \n\t" // (diff is in eax) */ - "movl %%eax, %%ecx \n\t" - "cmpl $0, %%ecx \n\t" - "jz end8 \n\t" -/* preload "movl mask, %%edx \n\t" */ - "sall $24, %%edx \n\t" /* make low byte, high byte */ - - "secondloop8: \n\t" - "sall %%edx \n\t" /* move high bit to CF */ - "jnc skip8 \n\t" /* if CF = 0 */ - "movb (%%esi), %%al \n\t" - "movb %%al, (%%edi) \n\t" - - "skip8: \n\t" - "incl %%esi \n\t" - "incl %%edi \n\t" - "decl %%ecx \n\t" - "jnz secondloop8 \n\t" - - "end8: \n\t" - "EMMS \n\t" /* DONE */ - - : "=a" (dummy_value_a), /* output regs (dummy) */ - "=d" (dummy_value_d), - "=c" (dummy_value_c), - "=S" (dummy_value_S), - "=D" (dummy_value_D) - - : "3" (srcptr), /* esi // input regs */ - "4" (dstptr), /* edi */ - "0" (diff), /* eax */ -/* was (unmask) "b" RESERVED // ebx // Global Offset Table idx */ - "2" (len), /* ecx */ - "1" (mask) /* edx */ - -#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ - : "%mm0", "%mm4", "%mm6", "%mm7" /* clobber list */ -#endif - ); - } - else /* mmx _not supported - Use modified C routine */ -#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ - { - register png_uint_32 i; - png_uint_32 initial_val = png_pass_start[png_ptr->pass]; - /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */ - register int stride = png_pass_inc[png_ptr->pass]; - /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */ - register int rep_bytes = png_pass_width[png_ptr->pass]; - /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */ - png_uint_32 len = png_ptr->width &~7; /* reduce to mult. of 8 */ - int diff = (int) (png_ptr->width & 7); /* amount lost */ - register png_uint_32 final_val = len; /* GRR bugfix */ - - srcptr = png_ptr->row_buf + 1 + initial_val; - dstptr = row + initial_val; - - for (i = initial_val; i < final_val; i += stride) - { - png_memcpy(dstptr, srcptr, rep_bytes); - srcptr += stride; - dstptr += stride; - } - if (diff) /* number of leftover pixels: 3 for pngtest */ - { - final_val+=diff /* *BPP1 */ ; - for (; i < final_val; i += stride) - { - if (rep_bytes > (int)(final_val-i)) - rep_bytes = (int)(final_val-i); - png_memcpy(dstptr, srcptr, rep_bytes); - srcptr += stride; - dstptr += stride; - } - } - - } /* end of else (_mmx_supported) */ - - break; - } /* end 8 bpp */ - - case 16: /* png_ptr->row_info.pixel_depth */ - { - png_bytep srcptr; - png_bytep dstptr; - -#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) -#if !defined(PNG_1_0_X) - if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) - /* && _mmx_supported */ ) -#else - if (_mmx_supported) -#endif - { - png_uint_32 len; - int diff; - int dummy_value_a; /* fix 'forbidden register spilled' error */ - int dummy_value_d; - int dummy_value_c; - int dummy_value_S; - int dummy_value_D; - _unmask = ~mask; /* global variable for -fPIC version */ - srcptr = png_ptr->row_buf + 1; - dstptr = row; - len = png_ptr->width &~7; /* reduce to multiple of 8 */ - diff = (int) (png_ptr->width & 7); /* amount lost // */ - - __asm__ __volatile__ ( - "movd _unmask, %%mm7 \n\t" /* load bit pattern */ - "psubb %%mm6, %%mm6 \n\t" /* zero mm6 */ - "punpcklbw %%mm7, %%mm7 \n\t" - "punpcklwd %%mm7, %%mm7 \n\t" - "punpckldq %%mm7, %%mm7 \n\t" /* fill reg with 8 masks */ - - "movq _mask16_0, %%mm0 \n\t" - "movq _mask16_1, %%mm1 \n\t" - - "pand %%mm7, %%mm0 \n\t" - "pand %%mm7, %%mm1 \n\t" - - "pcmpeqb %%mm6, %%mm0 \n\t" - "pcmpeqb %%mm6, %%mm1 \n\t" - -/* preload "movl len, %%ecx \n\t" // load length of line */ -/* preload "movl srcptr, %%esi \n\t" // load source */ -/* preload "movl dstptr, %%edi \n\t" // load dest */ - - "cmpl $0, %%ecx \n\t" - "jz mainloop16end \n\t" - - "mainloop16: \n\t" - "movq (%%esi), %%mm4 \n\t" - "pand %%mm0, %%mm4 \n\t" - "movq %%mm0, %%mm6 \n\t" - "movq (%%edi), %%mm7 \n\t" - "pandn %%mm7, %%mm6 \n\t" - "por %%mm6, %%mm4 \n\t" - "movq %%mm4, (%%edi) \n\t" - - "movq 8(%%esi), %%mm5 \n\t" - "pand %%mm1, %%mm5 \n\t" - "movq %%mm1, %%mm7 \n\t" - "movq 8(%%edi), %%mm6 \n\t" - "pandn %%mm6, %%mm7 \n\t" - "por %%mm7, %%mm5 \n\t" - "movq %%mm5, 8(%%edi) \n\t" - - "addl $16, %%esi \n\t" /* inc by 16 bytes processed */ - "addl $16, %%edi \n\t" - "subl $8, %%ecx \n\t" /* dec by 8 pixels processed */ - "ja mainloop16 \n\t" - - "mainloop16end: \n\t" -/* preload "movl diff, %%ecx \n\t" // (diff is in eax) */ - "movl %%eax, %%ecx \n\t" - "cmpl $0, %%ecx \n\t" - "jz end16 \n\t" -/* preload "movl mask, %%edx \n\t" */ - "sall $24, %%edx \n\t" /* make low byte, high byte */ - - "secondloop16: \n\t" - "sall %%edx \n\t" /* move high bit to CF */ - "jnc skip16 \n\t" /* if CF = 0 */ - "movw (%%esi), %%ax \n\t" - "movw %%ax, (%%edi) \n\t" - - "skip16: \n\t" - "addl $2, %%esi \n\t" - "addl $2, %%edi \n\t" - "decl %%ecx \n\t" - "jnz secondloop16 \n\t" - - "end16: \n\t" - "EMMS \n\t" /* DONE */ - - : "=a" (dummy_value_a), /* output regs (dummy) */ - "=c" (dummy_value_c), - "=d" (dummy_value_d), - "=S" (dummy_value_S), - "=D" (dummy_value_D) - - : "0" (diff), /* eax // input regs */ -/* was (unmask) " " RESERVED // ebx // Global Offset Table idx */ - "1" (len), /* ecx */ - "2" (mask), /* edx */ - "3" (srcptr), /* esi */ - "4" (dstptr) /* edi */ - -#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ - : "%mm0", "%mm1", "%mm4" /* clobber list */ - , "%mm5", "%mm6", "%mm7" -#endif - ); - } - else /* mmx _not supported - Use modified C routine */ -#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ - { - register png_uint_32 i; - png_uint_32 initial_val = BPP2 * png_pass_start[png_ptr->pass]; - /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */ - register int stride = BPP2 * png_pass_inc[png_ptr->pass]; - /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */ - register int rep_bytes = BPP2 * png_pass_width[png_ptr->pass]; - /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */ - png_uint_32 len = png_ptr->width &~7; /* reduce to mult. of 8 */ - int diff = (int) (png_ptr->width & 7); /* amount lost */ - register png_uint_32 final_val = BPP2 * len; /* GRR bugfix */ - - srcptr = png_ptr->row_buf + 1 + initial_val; - dstptr = row + initial_val; - - for (i = initial_val; i < final_val; i += stride) - { - png_memcpy(dstptr, srcptr, rep_bytes); - srcptr += stride; - dstptr += stride; - } - if (diff) /* number of leftover pixels: 3 for pngtest */ - { - final_val+=diff*BPP2; - for (; i < final_val; i += stride) - { - if (rep_bytes > (int)(final_val-i)) - rep_bytes = (int)(final_val-i); - png_memcpy(dstptr, srcptr, rep_bytes); - srcptr += stride; - dstptr += stride; - } - } - } /* end of else (_mmx_supported) */ - - break; - } /* end 16 bpp */ - - case 24: /* png_ptr->row_info.pixel_depth */ - { - png_bytep srcptr; - png_bytep dstptr; - -#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) -#if !defined(PNG_1_0_X) - if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) - /* && _mmx_supported */ ) -#else - if (_mmx_supported) -#endif - { - png_uint_32 len; - int diff; - int dummy_value_a; /* fix 'forbidden register spilled' error */ - int dummy_value_d; - int dummy_value_c; - int dummy_value_S; - int dummy_value_D; - _unmask = ~mask; /* global variable for -fPIC version */ - srcptr = png_ptr->row_buf + 1; - dstptr = row; - len = png_ptr->width &~7; /* reduce to multiple of 8 */ - diff = (int) (png_ptr->width & 7); /* amount lost // */ - - __asm__ __volatile__ ( - "movd _unmask, %%mm7 \n\t" /* load bit pattern */ - "psubb %%mm6, %%mm6 \n\t" /* zero mm6 */ - "punpcklbw %%mm7, %%mm7 \n\t" - "punpcklwd %%mm7, %%mm7 \n\t" - "punpckldq %%mm7, %%mm7 \n\t" /* fill reg with 8 masks */ - - "movq _mask24_0, %%mm0 \n\t" - "movq _mask24_1, %%mm1 \n\t" - "movq _mask24_2, %%mm2 \n\t" - - "pand %%mm7, %%mm0 \n\t" - "pand %%mm7, %%mm1 \n\t" - "pand %%mm7, %%mm2 \n\t" - - "pcmpeqb %%mm6, %%mm0 \n\t" - "pcmpeqb %%mm6, %%mm1 \n\t" - "pcmpeqb %%mm6, %%mm2 \n\t" - -/* preload "movl len, %%ecx \n\t" // load length of line */ -/* preload "movl srcptr, %%esi \n\t" // load source */ -/* preload "movl dstptr, %%edi \n\t" // load dest */ - - "cmpl $0, %%ecx \n\t" - "jz mainloop24end \n\t" - - "mainloop24: \n\t" - "movq (%%esi), %%mm4 \n\t" - "pand %%mm0, %%mm4 \n\t" - "movq %%mm0, %%mm6 \n\t" - "movq (%%edi), %%mm7 \n\t" - "pandn %%mm7, %%mm6 \n\t" - "por %%mm6, %%mm4 \n\t" - "movq %%mm4, (%%edi) \n\t" - - "movq 8(%%esi), %%mm5 \n\t" - "pand %%mm1, %%mm5 \n\t" - "movq %%mm1, %%mm7 \n\t" - "movq 8(%%edi), %%mm6 \n\t" - "pandn %%mm6, %%mm7 \n\t" - "por %%mm7, %%mm5 \n\t" - "movq %%mm5, 8(%%edi) \n\t" - - "movq 16(%%esi), %%mm6 \n\t" - "pand %%mm2, %%mm6 \n\t" - "movq %%mm2, %%mm4 \n\t" - "movq 16(%%edi), %%mm7 \n\t" - "pandn %%mm7, %%mm4 \n\t" - "por %%mm4, %%mm6 \n\t" - "movq %%mm6, 16(%%edi) \n\t" - - "addl $24, %%esi \n\t" /* inc by 24 bytes processed */ - "addl $24, %%edi \n\t" - "subl $8, %%ecx \n\t" /* dec by 8 pixels processed */ - - "ja mainloop24 \n\t" - - "mainloop24end: \n\t" -/* preload "movl diff, %%ecx \n\t" // (diff is in eax) */ - "movl %%eax, %%ecx \n\t" - "cmpl $0, %%ecx \n\t" - "jz end24 \n\t" -/* preload "movl mask, %%edx \n\t" */ - "sall $24, %%edx \n\t" /* make low byte, high byte */ - - "secondloop24: \n\t" - "sall %%edx \n\t" /* move high bit to CF */ - "jnc skip24 \n\t" /* if CF = 0 */ - "movw (%%esi), %%ax \n\t" - "movw %%ax, (%%edi) \n\t" - "xorl %%eax, %%eax \n\t" - "movb 2(%%esi), %%al \n\t" - "movb %%al, 2(%%edi) \n\t" - - "skip24: \n\t" - "addl $3, %%esi \n\t" - "addl $3, %%edi \n\t" - "decl %%ecx \n\t" - "jnz secondloop24 \n\t" - - "end24: \n\t" - "EMMS \n\t" /* DONE */ - - : "=a" (dummy_value_a), /* output regs (dummy) */ - "=d" (dummy_value_d), - "=c" (dummy_value_c), - "=S" (dummy_value_S), - "=D" (dummy_value_D) - - : "3" (srcptr), /* esi // input regs */ - "4" (dstptr), /* edi */ - "0" (diff), /* eax */ -/* was (unmask) "b" RESERVED // ebx // Global Offset Table idx */ - "2" (len), /* ecx */ - "1" (mask) /* edx */ - -#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ - : "%mm0", "%mm1", "%mm2" /* clobber list */ - , "%mm4", "%mm5", "%mm6", "%mm7" -#endif - ); - } - else /* mmx _not supported - Use modified C routine */ -#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ - { - register png_uint_32 i; - png_uint_32 initial_val = BPP3 * png_pass_start[png_ptr->pass]; - /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */ - register int stride = BPP3 * png_pass_inc[png_ptr->pass]; - /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */ - register int rep_bytes = BPP3 * png_pass_width[png_ptr->pass]; - /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */ - png_uint_32 len = png_ptr->width &~7; /* reduce to mult. of 8 */ - int diff = (int) (png_ptr->width & 7); /* amount lost */ - register png_uint_32 final_val = BPP3 * len; /* GRR bugfix */ - - srcptr = png_ptr->row_buf + 1 + initial_val; - dstptr = row + initial_val; - - for (i = initial_val; i < final_val; i += stride) - { - png_memcpy(dstptr, srcptr, rep_bytes); - srcptr += stride; - dstptr += stride; - } - if (diff) /* number of leftover pixels: 3 for pngtest */ - { - final_val+=diff*BPP3; - for (; i < final_val; i += stride) - { - if (rep_bytes > (int)(final_val-i)) - rep_bytes = (int)(final_val-i); - png_memcpy(dstptr, srcptr, rep_bytes); - srcptr += stride; - dstptr += stride; - } - } - } /* end of else (_mmx_supported) */ - - break; - } /* end 24 bpp */ - - case 32: /* png_ptr->row_info.pixel_depth */ - { - png_bytep srcptr; - png_bytep dstptr; - -#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) -#if !defined(PNG_1_0_X) - if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) - /* && _mmx_supported */ ) -#else - if (_mmx_supported) -#endif - { - png_uint_32 len; - int diff; - int dummy_value_a; /* fix 'forbidden register spilled' error */ - int dummy_value_d; - int dummy_value_c; - int dummy_value_S; - int dummy_value_D; - _unmask = ~mask; /* global variable for -fPIC version */ - srcptr = png_ptr->row_buf + 1; - dstptr = row; - len = png_ptr->width &~7; /* reduce to multiple of 8 */ - diff = (int) (png_ptr->width & 7); /* amount lost // */ - - __asm__ __volatile__ ( - "movd _unmask, %%mm7 \n\t" /* load bit pattern */ - "psubb %%mm6, %%mm6 \n\t" /* zero mm6 */ - "punpcklbw %%mm7, %%mm7 \n\t" - "punpcklwd %%mm7, %%mm7 \n\t" - "punpckldq %%mm7, %%mm7 \n\t" /* fill reg with 8 masks */ - - "movq _mask32_0, %%mm0 \n\t" - "movq _mask32_1, %%mm1 \n\t" - "movq _mask32_2, %%mm2 \n\t" - "movq _mask32_3, %%mm3 \n\t" - - "pand %%mm7, %%mm0 \n\t" - "pand %%mm7, %%mm1 \n\t" - "pand %%mm7, %%mm2 \n\t" - "pand %%mm7, %%mm3 \n\t" - - "pcmpeqb %%mm6, %%mm0 \n\t" - "pcmpeqb %%mm6, %%mm1 \n\t" - "pcmpeqb %%mm6, %%mm2 \n\t" - "pcmpeqb %%mm6, %%mm3 \n\t" - -/* preload "movl len, %%ecx \n\t" // load length of line */ -/* preload "movl srcptr, %%esi \n\t" // load source */ -/* preload "movl dstptr, %%edi \n\t" // load dest */ - - "cmpl $0, %%ecx \n\t" /* lcr */ - "jz mainloop32end \n\t" - - "mainloop32: \n\t" - "movq (%%esi), %%mm4 \n\t" - "pand %%mm0, %%mm4 \n\t" - "movq %%mm0, %%mm6 \n\t" - "movq (%%edi), %%mm7 \n\t" - "pandn %%mm7, %%mm6 \n\t" - "por %%mm6, %%mm4 \n\t" - "movq %%mm4, (%%edi) \n\t" - - "movq 8(%%esi), %%mm5 \n\t" - "pand %%mm1, %%mm5 \n\t" - "movq %%mm1, %%mm7 \n\t" - "movq 8(%%edi), %%mm6 \n\t" - "pandn %%mm6, %%mm7 \n\t" - "por %%mm7, %%mm5 \n\t" - "movq %%mm5, 8(%%edi) \n\t" - - "movq 16(%%esi), %%mm6 \n\t" - "pand %%mm2, %%mm6 \n\t" - "movq %%mm2, %%mm4 \n\t" - "movq 16(%%edi), %%mm7 \n\t" - "pandn %%mm7, %%mm4 \n\t" - "por %%mm4, %%mm6 \n\t" - "movq %%mm6, 16(%%edi) \n\t" - - "movq 24(%%esi), %%mm7 \n\t" - "pand %%mm3, %%mm7 \n\t" - "movq %%mm3, %%mm5 \n\t" - "movq 24(%%edi), %%mm4 \n\t" - "pandn %%mm4, %%mm5 \n\t" - "por %%mm5, %%mm7 \n\t" - "movq %%mm7, 24(%%edi) \n\t" - - "addl $32, %%esi \n\t" /* inc by 32 bytes processed */ - "addl $32, %%edi \n\t" - "subl $8, %%ecx \n\t" /* dec by 8 pixels processed */ - "ja mainloop32 \n\t" - - "mainloop32end: \n\t" -/* preload "movl diff, %%ecx \n\t" // (diff is in eax) */ - "movl %%eax, %%ecx \n\t" - "cmpl $0, %%ecx \n\t" - "jz end32 \n\t" -/* preload "movl mask, %%edx \n\t" */ - "sall $24, %%edx \n\t" /* low byte => high byte */ - - "secondloop32: \n\t" - "sall %%edx \n\t" /* move high bit to CF */ - "jnc skip32 \n\t" /* if CF = 0 */ - "movl (%%esi), %%eax \n\t" - "movl %%eax, (%%edi) \n\t" - - "skip32: \n\t" - "addl $4, %%esi \n\t" - "addl $4, %%edi \n\t" - "decl %%ecx \n\t" - "jnz secondloop32 \n\t" - - "end32: \n\t" - "EMMS \n\t" /* DONE */ - - : "=a" (dummy_value_a), /* output regs (dummy) */ - "=d" (dummy_value_d), - "=c" (dummy_value_c), - "=S" (dummy_value_S), - "=D" (dummy_value_D) - - : "3" (srcptr), /* esi // input regs */ - "4" (dstptr), /* edi */ - "0" (diff), /* eax */ -/* was (unmask) "b" RESERVED // ebx // Global Offset Table idx */ - "2" (len), /* ecx */ - "1" (mask) /* edx */ - -#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ - : "%mm0", "%mm1", "%mm2", "%mm3" /* clobber list */ - , "%mm4", "%mm5", "%mm6", "%mm7" -#endif - ); - } - else /* mmx _not supported - Use modified C routine */ -#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ - { - register png_uint_32 i; - png_uint_32 initial_val = BPP4 * png_pass_start[png_ptr->pass]; - /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */ - register int stride = BPP4 * png_pass_inc[png_ptr->pass]; - /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */ - register int rep_bytes = BPP4 * png_pass_width[png_ptr->pass]; - /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */ - png_uint_32 len = png_ptr->width &~7; /* reduce to mult. of 8 */ - int diff = (int) (png_ptr->width & 7); /* amount lost */ - register png_uint_32 final_val = BPP4 * len; /* GRR bugfix */ - - srcptr = png_ptr->row_buf + 1 + initial_val; - dstptr = row + initial_val; - - for (i = initial_val; i < final_val; i += stride) - { - png_memcpy(dstptr, srcptr, rep_bytes); - srcptr += stride; - dstptr += stride; - } - if (diff) /* number of leftover pixels: 3 for pngtest */ - { - final_val+=diff*BPP4; - for (; i < final_val; i += stride) - { - if (rep_bytes > (int)(final_val-i)) - rep_bytes = (int)(final_val-i); - png_memcpy(dstptr, srcptr, rep_bytes); - srcptr += stride; - dstptr += stride; - } - } - } /* end of else (_mmx_supported) */ - - break; - } /* end 32 bpp */ - - case 48: /* png_ptr->row_info.pixel_depth */ - { - png_bytep srcptr; - png_bytep dstptr; - -#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) -#if !defined(PNG_1_0_X) - if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) - /* && _mmx_supported */ ) -#else - if (_mmx_supported) -#endif - { - png_uint_32 len; - int diff; - int dummy_value_a; /* fix 'forbidden register spilled' error */ - int dummy_value_d; - int dummy_value_c; - int dummy_value_S; - int dummy_value_D; - _unmask = ~mask; /* global variable for -fPIC version */ - srcptr = png_ptr->row_buf + 1; - dstptr = row; - len = png_ptr->width &~7; /* reduce to multiple of 8 */ - diff = (int) (png_ptr->width & 7); /* amount lost // */ - - __asm__ __volatile__ ( - "movd _unmask, %%mm7 \n\t" /* load bit pattern */ - "psubb %%mm6, %%mm6 \n\t" /* zero mm6 */ - "punpcklbw %%mm7, %%mm7 \n\t" - "punpcklwd %%mm7, %%mm7 \n\t" - "punpckldq %%mm7, %%mm7 \n\t" /* fill reg with 8 masks */ - - "movq _mask48_0, %%mm0 \n\t" - "movq _mask48_1, %%mm1 \n\t" - "movq _mask48_2, %%mm2 \n\t" - "movq _mask48_3, %%mm3 \n\t" - "movq _mask48_4, %%mm4 \n\t" - "movq _mask48_5, %%mm5 \n\t" - - "pand %%mm7, %%mm0 \n\t" - "pand %%mm7, %%mm1 \n\t" - "pand %%mm7, %%mm2 \n\t" - "pand %%mm7, %%mm3 \n\t" - "pand %%mm7, %%mm4 \n\t" - "pand %%mm7, %%mm5 \n\t" - - "pcmpeqb %%mm6, %%mm0 \n\t" - "pcmpeqb %%mm6, %%mm1 \n\t" - "pcmpeqb %%mm6, %%mm2 \n\t" - "pcmpeqb %%mm6, %%mm3 \n\t" - "pcmpeqb %%mm6, %%mm4 \n\t" - "pcmpeqb %%mm6, %%mm5 \n\t" - -/* preload "movl len, %%ecx \n\t" // load length of line */ -/* preload "movl srcptr, %%esi \n\t" // load source */ -/* preload "movl dstptr, %%edi \n\t" // load dest */ - - "cmpl $0, %%ecx \n\t" - "jz mainloop48end \n\t" - - "mainloop48: \n\t" - "movq (%%esi), %%mm7 \n\t" - "pand %%mm0, %%mm7 \n\t" - "movq %%mm0, %%mm6 \n\t" - "pandn (%%edi), %%mm6 \n\t" - "por %%mm6, %%mm7 \n\t" - "movq %%mm7, (%%edi) \n\t" - - "movq 8(%%esi), %%mm6 \n\t" - "pand %%mm1, %%mm6 \n\t" - "movq %%mm1, %%mm7 \n\t" - "pandn 8(%%edi), %%mm7 \n\t" - "por %%mm7, %%mm6 \n\t" - "movq %%mm6, 8(%%edi) \n\t" - - "movq 16(%%esi), %%mm6 \n\t" - "pand %%mm2, %%mm6 \n\t" - "movq %%mm2, %%mm7 \n\t" - "pandn 16(%%edi), %%mm7 \n\t" - "por %%mm7, %%mm6 \n\t" - "movq %%mm6, 16(%%edi) \n\t" - - "movq 24(%%esi), %%mm7 \n\t" - "pand %%mm3, %%mm7 \n\t" - "movq %%mm3, %%mm6 \n\t" - "pandn 24(%%edi), %%mm6 \n\t" - "por %%mm6, %%mm7 \n\t" - "movq %%mm7, 24(%%edi) \n\t" - - "movq 32(%%esi), %%mm6 \n\t" - "pand %%mm4, %%mm6 \n\t" - "movq %%mm4, %%mm7 \n\t" - "pandn 32(%%edi), %%mm7 \n\t" - "por %%mm7, %%mm6 \n\t" - "movq %%mm6, 32(%%edi) \n\t" - - "movq 40(%%esi), %%mm7 \n\t" - "pand %%mm5, %%mm7 \n\t" - "movq %%mm5, %%mm6 \n\t" - "pandn 40(%%edi), %%mm6 \n\t" - "por %%mm6, %%mm7 \n\t" - "movq %%mm7, 40(%%edi) \n\t" - - "addl $48, %%esi \n\t" /* inc by 48 bytes processed */ - "addl $48, %%edi \n\t" - "subl $8, %%ecx \n\t" /* dec by 8 pixels processed */ - - "ja mainloop48 \n\t" - - "mainloop48end: \n\t" -/* preload "movl diff, %%ecx \n\t" // (diff is in eax) */ - "movl %%eax, %%ecx \n\t" - "cmpl $0, %%ecx \n\t" - "jz end48 \n\t" -/* preload "movl mask, %%edx \n\t" */ - "sall $24, %%edx \n\t" /* make low byte, high byte */ - - "secondloop48: \n\t" - "sall %%edx \n\t" /* move high bit to CF */ - "jnc skip48 \n\t" /* if CF = 0 */ - "movl (%%esi), %%eax \n\t" - "movl %%eax, (%%edi) \n\t" - - "skip48: \n\t" - "addl $4, %%esi \n\t" - "addl $4, %%edi \n\t" - "decl %%ecx \n\t" - "jnz secondloop48 \n\t" - - "end48: \n\t" - "EMMS \n\t" /* DONE */ - - : "=a" (dummy_value_a), /* output regs (dummy) */ - "=d" (dummy_value_d), - "=c" (dummy_value_c), - "=S" (dummy_value_S), - "=D" (dummy_value_D) - - : "3" (srcptr), /* esi // input regs */ - "4" (dstptr), /* edi */ - "0" (diff), /* eax */ -/* was (unmask) "b" RESERVED // ebx // Global Offset Table idx */ - "2" (len), /* ecx */ - "1" (mask) /* edx */ - -#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ - : "%mm0", "%mm1", "%mm2", "%mm3" /* clobber list */ - , "%mm4", "%mm5", "%mm6", "%mm7" -#endif - ); - } - else /* mmx _not supported - Use modified C routine */ -#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ - { - register png_uint_32 i; - png_uint_32 initial_val = BPP6 * png_pass_start[png_ptr->pass]; - /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */ - register int stride = BPP6 * png_pass_inc[png_ptr->pass]; - /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */ - register int rep_bytes = BPP6 * png_pass_width[png_ptr->pass]; - /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */ - png_uint_32 len = png_ptr->width &~7; /* reduce to mult. of 8 */ - int diff = (int) (png_ptr->width & 7); /* amount lost */ - register png_uint_32 final_val = BPP6 * len; /* GRR bugfix */ - - srcptr = png_ptr->row_buf + 1 + initial_val; - dstptr = row + initial_val; - - for (i = initial_val; i < final_val; i += stride) - { - png_memcpy(dstptr, srcptr, rep_bytes); - srcptr += stride; - dstptr += stride; - } - if (diff) /* number of leftover pixels: 3 for pngtest */ - { - final_val+=diff*BPP6; - for (; i < final_val; i += stride) - { - if (rep_bytes > (int)(final_val-i)) - rep_bytes = (int)(final_val-i); - png_memcpy(dstptr, srcptr, rep_bytes); - srcptr += stride; - dstptr += stride; - } - } - } /* end of else (_mmx_supported) */ - - break; - } /* end 48 bpp */ - - case 64: /* png_ptr->row_info.pixel_depth */ - { - png_bytep srcptr; - png_bytep dstptr; - register png_uint_32 i; - png_uint_32 initial_val = BPP8 * png_pass_start[png_ptr->pass]; - /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */ - register int stride = BPP8 * png_pass_inc[png_ptr->pass]; - /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */ - register int rep_bytes = BPP8 * png_pass_width[png_ptr->pass]; - /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */ - png_uint_32 len = png_ptr->width &~7; /* reduce to mult. of 8 */ - int diff = (int) (png_ptr->width & 7); /* amount lost */ - register png_uint_32 final_val = BPP8 * len; /* GRR bugfix */ - - srcptr = png_ptr->row_buf + 1 + initial_val; - dstptr = row + initial_val; - - for (i = initial_val; i < final_val; i += stride) - { - png_memcpy(dstptr, srcptr, rep_bytes); - srcptr += stride; - dstptr += stride; - } - if (diff) /* number of leftover pixels: 3 for pngtest */ - { - final_val+=diff*BPP8; - for (; i < final_val; i += stride) - { - if (rep_bytes > (int)(final_val-i)) - rep_bytes = (int)(final_val-i); - png_memcpy(dstptr, srcptr, rep_bytes); - srcptr += stride; - dstptr += stride; - } - } - - break; - } /* end 64 bpp */ - - default: /* png_ptr->row_info.pixel_depth != 1,2,4,8,16,24,32,48,64 */ - { - /* this should never happen */ - png_warning(png_ptr, "Invalid row_info.pixel_depth in pnggccrd"); - break; - } - } /* end switch (png_ptr->row_info.pixel_depth) */ - - } /* end if (non-trivial mask) */ - -} /* end png_combine_row() */ - -#endif /* PNG_HAVE_ASSEMBLER_COMBINE_ROW */ - - - - -/*===========================================================================*/ -/* */ -/* P N G _ D O _ R E A D _ I N T E R L A C E */ -/* */ -/*===========================================================================*/ - -#if defined(PNG_READ_INTERLACING_SUPPORTED) -#if defined(PNG_HAVE_ASSEMBLER_READ_INTERLACE) - -/* png_do_read_interlace() is called after any 16-bit to 8-bit conversion - * has taken place. [GRR: what other steps come before and/or after?] - */ - -void /* PRIVATE */ -png_do_read_interlace(png_structp png_ptr) -{ - png_row_infop row_info = &(png_ptr->row_info); - png_bytep row = png_ptr->row_buf + 1; - int pass = png_ptr->pass; -#if defined(PNG_READ_PACKSWAP_SUPPORTED) - png_uint_32 transformations = png_ptr->transformations; -#endif - - png_debug(1, "in png_do_read_interlace (pnggccrd.c)\n"); - -#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) - if (_mmx_supported == 2) { -#if !defined(PNG_1_0_X) - /* this should have happened in png_init_mmx_flags() already */ - png_warning(png_ptr, "asm_flags may not have been initialized"); -#endif - png_mmx_support(); - } -#endif - - if (row != NULL && row_info != NULL) - { - png_uint_32 final_width; - - final_width = row_info->width * png_pass_inc[pass]; - - switch (row_info->pixel_depth) - { - case 1: - { - png_bytep sp, dp; - int sshift, dshift; - int s_start, s_end, s_inc; - png_byte v; - png_uint_32 i; - int j; - - sp = row + (png_size_t)((row_info->width - 1) >> 3); - dp = row + (png_size_t)((final_width - 1) >> 3); -#if defined(PNG_READ_PACKSWAP_SUPPORTED) - if (transformations & PNG_PACKSWAP) - { - sshift = (int)((row_info->width + 7) & 7); - dshift = (int)((final_width + 7) & 7); - s_start = 7; - s_end = 0; - s_inc = -1; - } - else -#endif - { - sshift = 7 - (int)((row_info->width + 7) & 7); - dshift = 7 - (int)((final_width + 7) & 7); - s_start = 0; - s_end = 7; - s_inc = 1; - } - - for (i = row_info->width; i; i--) - { - v = (png_byte)((*sp >> sshift) & 0x1); - for (j = 0; j < png_pass_inc[pass]; j++) - { - *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, dp; - int sshift, dshift; - int s_start, s_end, s_inc; - png_uint_32 i; - - sp = row + (png_size_t)((row_info->width - 1) >> 2); - dp = row + (png_size_t)((final_width - 1) >> 2); -#if defined(PNG_READ_PACKSWAP_SUPPORTED) - if (transformations & PNG_PACKSWAP) - { - sshift = (png_size_t)(((row_info->width + 3) & 3) << 1); - dshift = (png_size_t)(((final_width + 3) & 3) << 1); - s_start = 6; - s_end = 0; - s_inc = -2; - } - else -#endif - { - sshift = (png_size_t)((3 - ((row_info->width + 3) & 3)) << 1); - dshift = (png_size_t)((3 - ((final_width + 3) & 3)) << 1); - s_start = 0; - s_end = 6; - s_inc = 2; - } - - for (i = row_info->width; i; i--) - { - png_byte v; - int j; - - v = (png_byte)((*sp >> sshift) & 0x3); - for (j = 0; j < png_pass_inc[pass]; j++) - { - *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, dp; - int sshift, dshift; - int s_start, s_end, s_inc; - png_uint_32 i; - - sp = row + (png_size_t)((row_info->width - 1) >> 1); - dp = row + (png_size_t)((final_width - 1) >> 1); -#if defined(PNG_READ_PACKSWAP_SUPPORTED) - if (transformations & PNG_PACKSWAP) - { - sshift = (png_size_t)(((row_info->width + 1) & 1) << 2); - dshift = (png_size_t)(((final_width + 1) & 1) << 2); - s_start = 4; - s_end = 0; - s_inc = -4; - } - else -#endif - { - sshift = (png_size_t)((1 - ((row_info->width + 1) & 1)) << 2); - dshift = (png_size_t)((1 - ((final_width + 1) & 1)) << 2); - s_start = 0; - s_end = 4; - s_inc = 4; - } - - for (i = row_info->width; i; i--) - { - png_byte v; - int j; - - v = (png_byte)((*sp >> sshift) & 0xf); - for (j = 0; j < png_pass_inc[pass]; j++) - { - *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; - } - break; - } - - /*====================================================================*/ - - default: /* 8-bit or larger (this is where the routine is modified) */ - { -#if 0 -/* static unsigned long long _const4 = 0x0000000000FFFFFFLL; no good */ -/* static unsigned long long const4 = 0x0000000000FFFFFFLL; no good */ -/* unsigned long long _const4 = 0x0000000000FFFFFFLL; no good */ -/* unsigned long long const4 = 0x0000000000FFFFFFLL; no good */ -#endif - png_bytep sptr, dp; - png_uint_32 i; - png_size_t pixel_bytes; - int width = (int)row_info->width; - - pixel_bytes = (row_info->pixel_depth >> 3); - - /* point sptr at the last pixel in the pre-expanded row: */ - sptr = row + (width - 1) * pixel_bytes; - - /* point dp at the last pixel position in the expanded row: */ - dp = row + (final_width - 1) * pixel_bytes; - - /* New code by Nirav Chhatrapati - Intel Corporation */ - -#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) -#if !defined(PNG_1_0_X) - if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_INTERLACE) - /* && _mmx_supported */ ) -#else - if (_mmx_supported) -#endif - { - //-------------------------------------------------------------- - if (pixel_bytes == 3) - { - if (((pass == 0) || (pass == 1)) && width) - { - int dummy_value_c; /* fix 'forbidden register spilled' */ - int dummy_value_S; - int dummy_value_D; - - __asm__ __volatile__ ( - "subl $21, %%edi \n\t" - /* (png_pass_inc[pass] - 1)*pixel_bytes */ - - ".loop3_pass0: \n\t" - "movd (%%esi), %%mm0 \n\t" /* x x x x x 2 1 0 */ - "pand _const4, %%mm0 \n\t" /* z z z z z 2 1 0 */ - "movq %%mm0, %%mm1 \n\t" /* z z z z z 2 1 0 */ - "psllq $16, %%mm0 \n\t" /* z z z 2 1 0 z z */ - "movq %%mm0, %%mm2 \n\t" /* z z z 2 1 0 z z */ - "psllq $24, %%mm0 \n\t" /* 2 1 0 z z z z z */ - "psrlq $8, %%mm1 \n\t" /* z z z z z z 2 1 */ - "por %%mm2, %%mm0 \n\t" /* 2 1 0 2 1 0 z z */ - "por %%mm1, %%mm0 \n\t" /* 2 1 0 2 1 0 2 1 */ - "movq %%mm0, %%mm3 \n\t" /* 2 1 0 2 1 0 2 1 */ - "psllq $16, %%mm0 \n\t" /* 0 2 1 0 2 1 z z */ - "movq %%mm3, %%mm4 \n\t" /* 2 1 0 2 1 0 2 1 */ - "punpckhdq %%mm0, %%mm3 \n\t" /* 0 2 1 0 2 1 0 2 */ - "movq %%mm4, 16(%%edi) \n\t" - "psrlq $32, %%mm0 \n\t" /* z z z z 0 2 1 0 */ - "movq %%mm3, 8(%%edi) \n\t" - "punpckldq %%mm4, %%mm0 \n\t" /* 1 0 2 1 0 2 1 0 */ - "subl $3, %%esi \n\t" - "movq %%mm0, (%%edi) \n\t" - "subl $24, %%edi \n\t" - "decl %%ecx \n\t" - "jnz .loop3_pass0 \n\t" - "EMMS \n\t" /* DONE */ - - : "=c" (dummy_value_c), /* output regs (dummy) */ - "=S" (dummy_value_S), - "=D" (dummy_value_D) - - : "1" (sptr), // esi // input regs - "2" (dp), // edi - "0" (width), // ecx - "rim" (_const4) // %1(?) (0x0000000000FFFFFFLL) - -#if 0 /* %mm0, ..., %mm4 not supported by gcc 2.7.2.3 or egcs 1.1 */ - : "%mm0", "%mm1", "%mm2" /* clobber list */ - , "%mm3", "%mm4" -#endif - ); - } - else if (((pass == 2) || (pass == 3)) && width) - { - int dummy_value_c; /* fix 'forbidden register spilled' */ - int dummy_value_S; - int dummy_value_D; - - __asm__ __volatile__ ( - "subl $9, %%edi \n\t" - /* (png_pass_inc[pass] - 1)*pixel_bytes */ - - ".loop3_pass2: \n\t" - "movd (%%esi), %%mm0 \n\t" /* x x x x x 2 1 0 */ - "pand _const4, %%mm0 \n\t" /* z z z z z 2 1 0 */ - "movq %%mm0, %%mm1 \n\t" /* z z z z z 2 1 0 */ - "psllq $16, %%mm0 \n\t" /* z z z 2 1 0 z z */ - "movq %%mm0, %%mm2 \n\t" /* z z z 2 1 0 z z */ - "psllq $24, %%mm0 \n\t" /* 2 1 0 z z z z z */ - "psrlq $8, %%mm1 \n\t" /* z z z z z z 2 1 */ - "por %%mm2, %%mm0 \n\t" /* 2 1 0 2 1 0 z z */ - "por %%mm1, %%mm0 \n\t" /* 2 1 0 2 1 0 2 1 */ - "movq %%mm0, 4(%%edi) \n\t" - "psrlq $16, %%mm0 \n\t" /* z z 2 1 0 2 1 0 */ - "subl $3, %%esi \n\t" - "movd %%mm0, (%%edi) \n\t" - "subl $12, %%edi \n\t" - "decl %%ecx \n\t" - "jnz .loop3_pass2 \n\t" - "EMMS \n\t" /* DONE */ - - : "=c" (dummy_value_c), /* output regs (dummy) */ - "=S" (dummy_value_S), - "=D" (dummy_value_D) - - : "1" (sptr), // esi // input regs - "2" (dp), // edi - "0" (width), // ecx - "rim" (_const4) // (0x0000000000FFFFFFLL) - -#if 0 /* %mm0, ..., %mm2 not supported by gcc 2.7.2.3 or egcs 1.1 */ - : "%mm0", "%mm1", "%mm2" /* clobber list */ -#endif - ); - } - else if (width) /* && ((pass == 4) || (pass == 5)) */ - { - int width_mmx = ((width >> 1) << 1) - 8; /* GRR: huh? */ - if (width_mmx < 0) - width_mmx = 0; - width -= width_mmx; /* 8 or 9 pix, 24 or 27 bytes */ - if (width_mmx) - { - /* png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */ - /* sptr points at last pixel in pre-expanded row */ - /* dp points at last pixel position in expanded row */ - int dummy_value_c; /* fix 'forbidden register spilled' */ - int dummy_value_S; - int dummy_value_D; - - __asm__ __volatile__ ( - "subl $3, %%esi \n\t" - "subl $9, %%edi \n\t" - /* (png_pass_inc[pass] + 1)*pixel_bytes */ - - ".loop3_pass4: \n\t" - "movq (%%esi), %%mm0 \n\t" /* x x 5 4 3 2 1 0 */ - "movq %%mm0, %%mm1 \n\t" /* x x 5 4 3 2 1 0 */ - "movq %%mm0, %%mm2 \n\t" /* x x 5 4 3 2 1 0 */ - "psllq $24, %%mm0 \n\t" /* 4 3 2 1 0 z z z */ - "pand _const4, %%mm1 \n\t" /* z z z z z 2 1 0 */ - "psrlq $24, %%mm2 \n\t" /* z z z x x 5 4 3 */ - "por %%mm1, %%mm0 \n\t" /* 4 3 2 1 0 2 1 0 */ - "movq %%mm2, %%mm3 \n\t" /* z z z x x 5 4 3 */ - "psllq $8, %%mm2 \n\t" /* z z x x 5 4 3 z */ - "movq %%mm0, (%%edi) \n\t" - "psrlq $16, %%mm3 \n\t" /* z z z z z x x 5 */ - "pand _const6, %%mm3 \n\t" /* z z z z z z z 5 */ - "por %%mm3, %%mm2 \n\t" /* z z x x 5 4 3 5 */ - "subl $6, %%esi \n\t" - "movd %%mm2, 8(%%edi) \n\t" - "subl $12, %%edi \n\t" - "subl $2, %%ecx \n\t" - "jnz .loop3_pass4 \n\t" - "EMMS \n\t" /* DONE */ - - : "=c" (dummy_value_c), /* output regs (dummy) */ - "=S" (dummy_value_S), - "=D" (dummy_value_D) - - : "1" (sptr), // esi // input regs - "2" (dp), // edi - "0" (width_mmx), // ecx - "rim" (_const4), // 0x0000000000FFFFFFLL - "rim" (_const6) // 0x00000000000000FFLL - -#if 0 /* %mm0, ..., %mm3 not supported by gcc 2.7.2.3 or egcs 1.1 */ - : "%mm0", "%mm1" /* clobber list */ - , "%mm2", "%mm3" -#endif - ); - } - - sptr -= width_mmx*3; - dp -= width_mmx*6; - for (i = width; i; i--) - { - png_byte v[8]; - int j; - - png_memcpy(v, sptr, 3); - for (j = 0; j < png_pass_inc[pass]; j++) - { - png_memcpy(dp, v, 3); - dp -= 3; - } - sptr -= 3; - } - } - } /* end of pixel_bytes == 3 */ - - //-------------------------------------------------------------- - else if (pixel_bytes == 1) - { - if (((pass == 0) || (pass == 1)) && width) - { - int width_mmx = ((width >> 2) << 2); - width -= width_mmx; /* 0-3 pixels => 0-3 bytes */ - if (width_mmx) - { - int dummy_value_c; /* fix 'forbidden register spilled' */ - int dummy_value_S; - int dummy_value_D; - - __asm__ __volatile__ ( - "subl $3, %%esi \n\t" - "subl $31, %%edi \n\t" - - ".loop1_pass0: \n\t" - "movd (%%esi), %%mm0 \n\t" /* x x x x 3 2 1 0 */ - "movq %%mm0, %%mm1 \n\t" /* x x x x 3 2 1 0 */ - "punpcklbw %%mm0, %%mm0 \n\t" /* 3 3 2 2 1 1 0 0 */ - "movq %%mm0, %%mm2 \n\t" /* 3 3 2 2 1 1 0 0 */ - "punpcklwd %%mm0, %%mm0 \n\t" /* 1 1 1 1 0 0 0 0 */ - "movq %%mm0, %%mm3 \n\t" /* 1 1 1 1 0 0 0 0 */ - "punpckldq %%mm0, %%mm0 \n\t" /* 0 0 0 0 0 0 0 0 */ - "punpckhdq %%mm3, %%mm3 \n\t" /* 1 1 1 1 1 1 1 1 */ - "movq %%mm0, (%%edi) \n\t" - "punpckhwd %%mm2, %%mm2 \n\t" /* 3 3 3 3 2 2 2 2 */ - "movq %%mm3, 8(%%edi) \n\t" - "movq %%mm2, %%mm4 \n\t" /* 3 3 3 3 2 2 2 2 */ - "punpckldq %%mm2, %%mm2 \n\t" /* 2 2 2 2 2 2 2 2 */ - "punpckhdq %%mm4, %%mm4 \n\t" /* 3 3 3 3 3 3 3 3 */ - "movq %%mm2, 16(%%edi) \n\t" - "subl $4, %%esi \n\t" - "movq %%mm4, 24(%%edi) \n\t" - "subl $32, %%edi \n\t" - "subl $4, %%ecx \n\t" - "jnz .loop1_pass0 \n\t" - "EMMS \n\t" /* DONE */ - - : "=c" (dummy_value_c), /* output regs (dummy) */ - "=S" (dummy_value_S), - "=D" (dummy_value_D) - - : "1" (sptr), /* esi // input regs */ - "2" (dp), /* edi */ - "0" (width_mmx) /* ecx */ - -#if 0 /* %mm0, ..., %mm4 not supported by gcc 2.7.2.3 or egcs 1.1 */ - : "%mm0", "%mm1", "%mm2" /* clobber list */ - , "%mm3", "%mm4" -#endif - ); - } - - sptr -= width_mmx; - dp -= width_mmx*8; - for (i = width; i; i--) - { - int j; - - /* I simplified this part in version 1.0.4e - * here and in several other instances where - * pixel_bytes == 1 -- GR-P - * - * Original code: - * - * png_byte v[8]; - * png_memcpy(v, sptr, pixel_bytes); - * for (j = 0; j < png_pass_inc[pass]; j++) - * { - * png_memcpy(dp, v, pixel_bytes); - * dp -= pixel_bytes; - * } - * sptr -= pixel_bytes; - * - * Replacement code is in the next three lines: - */ - - for (j = 0; j < png_pass_inc[pass]; j++) - { - *dp-- = *sptr; - } - --sptr; - } - } - else if (((pass == 2) || (pass == 3)) && width) - { - int width_mmx = ((width >> 2) << 2); - width -= width_mmx; /* 0-3 pixels => 0-3 bytes */ - if (width_mmx) - { - int dummy_value_c; /* fix 'forbidden register spilled' */ - int dummy_value_S; - int dummy_value_D; - - __asm__ __volatile__ ( - "subl $3, %%esi \n\t" - "subl $15, %%edi \n\t" - - ".loop1_pass2: \n\t" - "movd (%%esi), %%mm0 \n\t" /* x x x x 3 2 1 0 */ - "punpcklbw %%mm0, %%mm0 \n\t" /* 3 3 2 2 1 1 0 0 */ - "movq %%mm0, %%mm1 \n\t" /* 3 3 2 2 1 1 0 0 */ - "punpcklwd %%mm0, %%mm0 \n\t" /* 1 1 1 1 0 0 0 0 */ - "punpckhwd %%mm1, %%mm1 \n\t" /* 3 3 3 3 2 2 2 2 */ - "movq %%mm0, (%%edi) \n\t" - "subl $4, %%esi \n\t" - "movq %%mm1, 8(%%edi) \n\t" - "subl $16, %%edi \n\t" - "subl $4, %%ecx \n\t" - "jnz .loop1_pass2 \n\t" - "EMMS \n\t" /* DONE */ - - : "=c" (dummy_value_c), /* output regs (dummy) */ - "=S" (dummy_value_S), - "=D" (dummy_value_D) - - : "1" (sptr), /* esi // input regs */ - "2" (dp), /* edi */ - "0" (width_mmx) /* ecx */ - -#if 0 /* %mm0, %mm1 not supported by gcc 2.7.2.3 or egcs 1.1 */ - : "%mm0", "%mm1" /* clobber list */ -#endif - ); - } - - sptr -= width_mmx; - dp -= width_mmx*4; - for (i = width; i; i--) - { - int j; - - for (j = 0; j < png_pass_inc[pass]; j++) - { - *dp-- = *sptr; - } - --sptr; - } - } - else if (width) /* && ((pass == 4) || (pass == 5)) */ - { - int width_mmx = ((width >> 3) << 3); - width -= width_mmx; /* 0-3 pixels => 0-3 bytes */ - if (width_mmx) - { - int dummy_value_c; /* fix 'forbidden register spilled' */ - int dummy_value_S; - int dummy_value_D; - - __asm__ __volatile__ ( - "subl $7, %%esi \n\t" - "subl $15, %%edi \n\t" - - ".loop1_pass4: \n\t" - "movq (%%esi), %%mm0 \n\t" /* 7 6 5 4 3 2 1 0 */ - "movq %%mm0, %%mm1 \n\t" /* 7 6 5 4 3 2 1 0 */ - "punpcklbw %%mm0, %%mm0 \n\t" /* 3 3 2 2 1 1 0 0 */ - "punpckhbw %%mm1, %%mm1 \n\t" /* 7 7 6 6 5 5 4 4 */ - "movq %%mm1, 8(%%edi) \n\t" - "subl $8, %%esi \n\t" - "movq %%mm0, (%%edi) \n\t" - "subl $16, %%edi \n\t" - "subl $8, %%ecx \n\t" - "jnz .loop1_pass4 \n\t" - "EMMS \n\t" /* DONE */ - - : "=c" (dummy_value_c), /* output regs (none) */ - "=S" (dummy_value_S), - "=D" (dummy_value_D) - - : "1" (sptr), /* esi // input regs */ - "2" (dp), /* edi */ - "0" (width_mmx) /* ecx */ - -#if 0 /* %mm0, %mm1 not supported by gcc 2.7.2.3 or egcs 1.1 */ - : "%mm0", "%mm1" /* clobber list */ -#endif - ); - } - - sptr -= width_mmx; - dp -= width_mmx*2; - for (i = width; i; i--) - { - int j; - - for (j = 0; j < png_pass_inc[pass]; j++) - { - *dp-- = *sptr; - } - --sptr; - } - } - } /* end of pixel_bytes == 1 */ - - //-------------------------------------------------------------- - else if (pixel_bytes == 2) - { - if (((pass == 0) || (pass == 1)) && width) - { - int width_mmx = ((width >> 1) << 1); - width -= width_mmx; /* 0,1 pixels => 0,2 bytes */ - if (width_mmx) - { - int dummy_value_c; /* fix 'forbidden register spilled' */ - int dummy_value_S; - int dummy_value_D; - - __asm__ __volatile__ ( - "subl $2, %%esi \n\t" - "subl $30, %%edi \n\t" - - ".loop2_pass0: \n\t" - "movd (%%esi), %%mm0 \n\t" /* x x x x 3 2 1 0 */ - "punpcklwd %%mm0, %%mm0 \n\t" /* 3 2 3 2 1 0 1 0 */ - "movq %%mm0, %%mm1 \n\t" /* 3 2 3 2 1 0 1 0 */ - "punpckldq %%mm0, %%mm0 \n\t" /* 1 0 1 0 1 0 1 0 */ - "punpckhdq %%mm1, %%mm1 \n\t" /* 3 2 3 2 3 2 3 2 */ - "movq %%mm0, (%%edi) \n\t" - "movq %%mm0, 8(%%edi) \n\t" - "movq %%mm1, 16(%%edi) \n\t" - "subl $4, %%esi \n\t" - "movq %%mm1, 24(%%edi) \n\t" - "subl $32, %%edi \n\t" - "subl $2, %%ecx \n\t" - "jnz .loop2_pass0 \n\t" - "EMMS \n\t" /* DONE */ - - : "=c" (dummy_value_c), /* output regs (dummy) */ - "=S" (dummy_value_S), - "=D" (dummy_value_D) - - : "1" (sptr), /* esi // input regs */ - "2" (dp), /* edi */ - "0" (width_mmx) /* ecx */ - -#if 0 /* %mm0, %mm1 not supported by gcc 2.7.2.3 or egcs 1.1 */ - : "%mm0", "%mm1" /* clobber list */ -#endif - ); - } - - sptr -= (width_mmx*2 - 2); /* sign fixed */ - dp -= (width_mmx*16 - 2); /* sign fixed */ - for (i = width; i; i--) - { - png_byte v[8]; - int j; - sptr -= 2; - png_memcpy(v, sptr, 2); - for (j = 0; j < png_pass_inc[pass]; j++) - { - dp -= 2; - png_memcpy(dp, v, 2); - } - } - } - else if (((pass == 2) || (pass == 3)) && width) - { - int width_mmx = ((width >> 1) << 1) ; - width -= width_mmx; /* 0,1 pixels => 0,2 bytes */ - if (width_mmx) - { - int dummy_value_c; /* fix 'forbidden register spilled' */ - int dummy_value_S; - int dummy_value_D; - - __asm__ __volatile__ ( - "subl $2, %%esi \n\t" - "subl $14, %%edi \n\t" - - ".loop2_pass2: \n\t" - "movd (%%esi), %%mm0 \n\t" /* x x x x 3 2 1 0 */ - "punpcklwd %%mm0, %%mm0 \n\t" /* 3 2 3 2 1 0 1 0 */ - "movq %%mm0, %%mm1 \n\t" /* 3 2 3 2 1 0 1 0 */ - "punpckldq %%mm0, %%mm0 \n\t" /* 1 0 1 0 1 0 1 0 */ - "punpckhdq %%mm1, %%mm1 \n\t" /* 3 2 3 2 3 2 3 2 */ - "movq %%mm0, (%%edi) \n\t" - "subl $4, %%esi \n\t" - "movq %%mm1, 8(%%edi) \n\t" - "subl $16, %%edi \n\t" - "subl $2, %%ecx \n\t" - "jnz .loop2_pass2 \n\t" - "EMMS \n\t" /* DONE */ - - : "=c" (dummy_value_c), /* output regs (dummy) */ - "=S" (dummy_value_S), - "=D" (dummy_value_D) - - : "1" (sptr), /* esi // input regs */ - "2" (dp), /* edi */ - "0" (width_mmx) /* ecx */ - -#if 0 /* %mm0, %mm1 not supported by gcc 2.7.2.3 or egcs 1.1 */ - : "%mm0", "%mm1" /* clobber list */ -#endif - ); - } - - sptr -= (width_mmx*2 - 2); /* sign fixed */ - dp -= (width_mmx*8 - 2); /* sign fixed */ - for (i = width; i; i--) - { - png_byte v[8]; - int j; - sptr -= 2; - png_memcpy(v, sptr, 2); - for (j = 0; j < png_pass_inc[pass]; j++) - { - dp -= 2; - png_memcpy(dp, v, 2); - } - } - } - else if (width) /* pass == 4 or 5 */ - { - int width_mmx = ((width >> 1) << 1) ; - width -= width_mmx; /* 0,1 pixels => 0,2 bytes */ - if (width_mmx) - { - int dummy_value_c; /* fix 'forbidden register spilled' */ - int dummy_value_S; - int dummy_value_D; - - __asm__ __volatile__ ( - "subl $2, %%esi \n\t" - "subl $6, %%edi \n\t" - - ".loop2_pass4: \n\t" - "movd (%%esi), %%mm0 \n\t" /* x x x x 3 2 1 0 */ - "punpcklwd %%mm0, %%mm0 \n\t" /* 3 2 3 2 1 0 1 0 */ - "subl $4, %%esi \n\t" - "movq %%mm0, (%%edi) \n\t" - "subl $8, %%edi \n\t" - "subl $2, %%ecx \n\t" - "jnz .loop2_pass4 \n\t" - "EMMS \n\t" /* DONE */ - - : "=c" (dummy_value_c), /* output regs (dummy) */ - "=S" (dummy_value_S), - "=D" (dummy_value_D) - - : "1" (sptr), /* esi // input regs */ - "2" (dp), /* edi */ - "0" (width_mmx) /* ecx */ - -#if 0 /* %mm0 not supported by gcc 2.7.2.3 or egcs 1.1 */ - : "%mm0" /* clobber list */ -#endif - ); - } - - sptr -= (width_mmx*2 - 2); /* sign fixed */ - dp -= (width_mmx*4 - 2); /* sign fixed */ - for (i = width; i; i--) - { - png_byte v[8]; - int j; - sptr -= 2; - png_memcpy(v, sptr, 2); - for (j = 0; j < png_pass_inc[pass]; j++) - { - dp -= 2; - png_memcpy(dp, v, 2); - } - } - } - } /* end of pixel_bytes == 2 */ - - //-------------------------------------------------------------- - else if (pixel_bytes == 4) - { - if (((pass == 0) || (pass == 1)) && width) - { - int width_mmx = ((width >> 1) << 1); - width -= width_mmx; /* 0,1 pixels => 0,4 bytes */ - if (width_mmx) - { - int dummy_value_c; /* fix 'forbidden register spilled' */ - int dummy_value_S; - int dummy_value_D; - - __asm__ __volatile__ ( - "subl $4, %%esi \n\t" - "subl $60, %%edi \n\t" - - ".loop4_pass0: \n\t" - "movq (%%esi), %%mm0 \n\t" /* 7 6 5 4 3 2 1 0 */ - "movq %%mm0, %%mm1 \n\t" /* 7 6 5 4 3 2 1 0 */ - "punpckldq %%mm0, %%mm0 \n\t" /* 3 2 1 0 3 2 1 0 */ - "punpckhdq %%mm1, %%mm1 \n\t" /* 7 6 5 4 7 6 5 4 */ - "movq %%mm0, (%%edi) \n\t" - "movq %%mm0, 8(%%edi) \n\t" - "movq %%mm0, 16(%%edi) \n\t" - "movq %%mm0, 24(%%edi) \n\t" - "movq %%mm1, 32(%%edi) \n\t" - "movq %%mm1, 40(%%edi) \n\t" - "movq %%mm1, 48(%%edi) \n\t" - "subl $8, %%esi \n\t" - "movq %%mm1, 56(%%edi) \n\t" - "subl $64, %%edi \n\t" - "subl $2, %%ecx \n\t" - "jnz .loop4_pass0 \n\t" - "EMMS \n\t" /* DONE */ - - : "=c" (dummy_value_c), /* output regs (dummy) */ - "=S" (dummy_value_S), - "=D" (dummy_value_D) - - : "1" (sptr), /* esi // input regs */ - "2" (dp), /* edi */ - "0" (width_mmx) /* ecx */ - -#if 0 /* %mm0, %mm1 not supported by gcc 2.7.2.3 or egcs 1.1 */ - : "%mm0", "%mm1" /* clobber list */ -#endif - ); - } - - sptr -= (width_mmx*4 - 4); /* sign fixed */ - dp -= (width_mmx*32 - 4); /* sign fixed */ - for (i = width; i; i--) - { - png_byte v[8]; - int j; - sptr -= 4; - png_memcpy(v, sptr, 4); - for (j = 0; j < png_pass_inc[pass]; j++) - { - dp -= 4; - png_memcpy(dp, v, 4); - } - } - } - else if (((pass == 2) || (pass == 3)) && width) - { - int width_mmx = ((width >> 1) << 1); - width -= width_mmx; /* 0,1 pixels => 0,4 bytes */ - if (width_mmx) - { - int dummy_value_c; /* fix 'forbidden register spilled' */ - int dummy_value_S; - int dummy_value_D; - - __asm__ __volatile__ ( - "subl $4, %%esi \n\t" - "subl $28, %%edi \n\t" - - ".loop4_pass2: \n\t" - "movq (%%esi), %%mm0 \n\t" /* 7 6 5 4 3 2 1 0 */ - "movq %%mm0, %%mm1 \n\t" /* 7 6 5 4 3 2 1 0 */ - "punpckldq %%mm0, %%mm0 \n\t" /* 3 2 1 0 3 2 1 0 */ - "punpckhdq %%mm1, %%mm1 \n\t" /* 7 6 5 4 7 6 5 4 */ - "movq %%mm0, (%%edi) \n\t" - "movq %%mm0, 8(%%edi) \n\t" - "movq %%mm1, 16(%%edi) \n\t" - "movq %%mm1, 24(%%edi) \n\t" - "subl $8, %%esi \n\t" - "subl $32, %%edi \n\t" - "subl $2, %%ecx \n\t" - "jnz .loop4_pass2 \n\t" - "EMMS \n\t" /* DONE */ - - : "=c" (dummy_value_c), /* output regs (dummy) */ - "=S" (dummy_value_S), - "=D" (dummy_value_D) - - : "1" (sptr), /* esi // input regs */ - "2" (dp), /* edi */ - "0" (width_mmx) /* ecx */ - -#if 0 /* %mm0, %mm1 not supported by gcc 2.7.2.3 or egcs 1.1 */ - : "%mm0", "%mm1" /* clobber list */ -#endif - ); - } - - sptr -= (width_mmx*4 - 4); /* sign fixed */ - dp -= (width_mmx*16 - 4); /* sign fixed */ - for (i = width; i; i--) - { - png_byte v[8]; - int j; - sptr -= 4; - png_memcpy(v, sptr, 4); - for (j = 0; j < png_pass_inc[pass]; j++) - { - dp -= 4; - png_memcpy(dp, v, 4); - } - } - } - else if (width) /* pass == 4 or 5 */ - { - int width_mmx = ((width >> 1) << 1) ; - width -= width_mmx; /* 0,1 pixels => 0,4 bytes */ - if (width_mmx) - { - int dummy_value_c; /* fix 'forbidden register spilled' */ - int dummy_value_S; - int dummy_value_D; - - __asm__ __volatile__ ( - "subl $4, %%esi \n\t" - "subl $12, %%edi \n\t" - - ".loop4_pass4: \n\t" - "movq (%%esi), %%mm0 \n\t" /* 7 6 5 4 3 2 1 0 */ - "movq %%mm0, %%mm1 \n\t" /* 7 6 5 4 3 2 1 0 */ - "punpckldq %%mm0, %%mm0 \n\t" /* 3 2 1 0 3 2 1 0 */ - "punpckhdq %%mm1, %%mm1 \n\t" /* 7 6 5 4 7 6 5 4 */ - "movq %%mm0, (%%edi) \n\t" - "subl $8, %%esi \n\t" - "movq %%mm1, 8(%%edi) \n\t" - "subl $16, %%edi \n\t" - "subl $2, %%ecx \n\t" - "jnz .loop4_pass4 \n\t" - "EMMS \n\t" /* DONE */ - - : "=c" (dummy_value_c), /* output regs (dummy) */ - "=S" (dummy_value_S), - "=D" (dummy_value_D) - - : "1" (sptr), /* esi // input regs */ - "2" (dp), /* edi */ - "0" (width_mmx) /* ecx */ - -#if 0 /* %mm0, %mm1 not supported by gcc 2.7.2.3 or egcs 1.1 */ - : "%mm0", "%mm1" /* clobber list */ -#endif - ); - } - - sptr -= (width_mmx*4 - 4); /* sign fixed */ - dp -= (width_mmx*8 - 4); /* sign fixed */ - for (i = width; i; i--) - { - png_byte v[8]; - int j; - sptr -= 4; - png_memcpy(v, sptr, 4); - for (j = 0; j < png_pass_inc[pass]; j++) - { - dp -= 4; - png_memcpy(dp, v, 4); - } - } - } - } /* end of pixel_bytes == 4 */ - - //-------------------------------------------------------------- - else if (pixel_bytes == 8) - { -/* GRR TEST: should work, but needs testing (special 64-bit version of rpng2?) */ - /* GRR NOTE: no need to combine passes here! */ - if (((pass == 0) || (pass == 1)) && width) - { - int dummy_value_c; /* fix 'forbidden register spilled' */ - int dummy_value_S; - int dummy_value_D; - - /* source is 8-byte RRGGBBAA */ - /* dest is 64-byte RRGGBBAA RRGGBBAA RRGGBBAA RRGGBBAA ... */ - __asm__ __volatile__ ( - "subl $56, %%edi \n\t" /* start of last block */ - - ".loop8_pass0: \n\t" - "movq (%%esi), %%mm0 \n\t" /* 7 6 5 4 3 2 1 0 */ - "movq %%mm0, (%%edi) \n\t" - "movq %%mm0, 8(%%edi) \n\t" - "movq %%mm0, 16(%%edi) \n\t" - "movq %%mm0, 24(%%edi) \n\t" - "movq %%mm0, 32(%%edi) \n\t" - "movq %%mm0, 40(%%edi) \n\t" - "movq %%mm0, 48(%%edi) \n\t" - "subl $8, %%esi \n\t" - "movq %%mm0, 56(%%edi) \n\t" - "subl $64, %%edi \n\t" - "decl %%ecx \n\t" - "jnz .loop8_pass0 \n\t" - "EMMS \n\t" /* DONE */ - - : "=c" (dummy_value_c), /* output regs (dummy) */ - "=S" (dummy_value_S), - "=D" (dummy_value_D) - - : "1" (sptr), /* esi // input regs */ - "2" (dp), /* edi */ - "0" (width) /* ecx */ - -#if 0 /* %mm0 not supported by gcc 2.7.2.3 or egcs 1.1 */ - : "%mm0" /* clobber list */ -#endif - ); - } - else if (((pass == 2) || (pass == 3)) && width) - { - /* source is 8-byte RRGGBBAA */ - /* dest is 32-byte RRGGBBAA RRGGBBAA RRGGBBAA RRGGBBAA */ - /* (recall that expansion is _in place_: sptr and dp */ - /* both point at locations within same row buffer) */ - { - int dummy_value_c; /* fix 'forbidden register spilled' */ - int dummy_value_S; - int dummy_value_D; - - __asm__ __volatile__ ( - "subl $24, %%edi \n\t" /* start of last block */ - - ".loop8_pass2: \n\t" - "movq (%%esi), %%mm0 \n\t" /* 7 6 5 4 3 2 1 0 */ - "movq %%mm0, (%%edi) \n\t" - "movq %%mm0, 8(%%edi) \n\t" - "movq %%mm0, 16(%%edi) \n\t" - "subl $8, %%esi \n\t" - "movq %%mm0, 24(%%edi) \n\t" - "subl $32, %%edi \n\t" - "decl %%ecx \n\t" - "jnz .loop8_pass2 \n\t" - "EMMS \n\t" /* DONE */ - - : "=c" (dummy_value_c), /* output regs (dummy) */ - "=S" (dummy_value_S), - "=D" (dummy_value_D) - - : "1" (sptr), /* esi // input regs */ - "2" (dp), /* edi */ - "0" (width) /* ecx */ - -#if 0 /* %mm0 not supported by gcc 2.7.2.3 or egcs 1.1 */ - : "%mm0" /* clobber list */ -#endif - ); - } - } - else if (width) /* pass == 4 or 5 */ - { - /* source is 8-byte RRGGBBAA */ - /* dest is 16-byte RRGGBBAA RRGGBBAA */ - { - int dummy_value_c; /* fix 'forbidden register spilled' */ - int dummy_value_S; - int dummy_value_D; - - __asm__ __volatile__ ( - "subl $8, %%edi \n\t" /* start of last block */ - - ".loop8_pass4: \n\t" - "movq (%%esi), %%mm0 \n\t" /* 7 6 5 4 3 2 1 0 */ - "movq %%mm0, (%%edi) \n\t" - "subl $8, %%esi \n\t" - "movq %%mm0, 8(%%edi) \n\t" - "subl $16, %%edi \n\t" - "decl %%ecx \n\t" - "jnz .loop8_pass4 \n\t" - "EMMS \n\t" /* DONE */ - - : "=c" (dummy_value_c), /* output regs (dummy) */ - "=S" (dummy_value_S), - "=D" (dummy_value_D) - - : "1" (sptr), /* esi // input regs */ - "2" (dp), /* edi */ - "0" (width) /* ecx */ - -#if 0 /* %mm0 not supported by gcc 2.7.2.3 or egcs 1.1 */ - : "%mm0" /* clobber list */ -#endif - ); - } - } - - } /* end of pixel_bytes == 8 */ - - //-------------------------------------------------------------- - else if (pixel_bytes == 6) - { - for (i = width; i; i--) - { - png_byte v[8]; - int j; - png_memcpy(v, sptr, 6); - for (j = 0; j < png_pass_inc[pass]; j++) - { - png_memcpy(dp, v, 6); - dp -= 6; - } - sptr -= 6; - } - } /* end of pixel_bytes == 6 */ - - //-------------------------------------------------------------- - else - { - for (i = width; i; i--) - { - png_byte v[8]; - int j; - png_memcpy(v, sptr, pixel_bytes); - for (j = 0; j < png_pass_inc[pass]; j++) - { - png_memcpy(dp, v, pixel_bytes); - dp -= pixel_bytes; - } - sptr-= pixel_bytes; - } - } - } /* end of _mmx_supported ======================================== */ - - else /* MMX not supported: use modified C code - takes advantage - * of inlining of png_memcpy for a constant */ - /* GRR 19991007: does it? or should pixel_bytes in each - * block be replaced with immediate value (e.g., 1)? */ - /* GRR 19991017: replaced with constants in each case */ -#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ - { - if (pixel_bytes == 1) - { - for (i = width; i; i--) - { - int j; - for (j = 0; j < png_pass_inc[pass]; j++) - { - *dp-- = *sptr; - } - --sptr; - } - } - else if (pixel_bytes == 3) - { - for (i = width; i; i--) - { - png_byte v[8]; - int j; - png_memcpy(v, sptr, 3); - for (j = 0; j < png_pass_inc[pass]; j++) - { - png_memcpy(dp, v, 3); - dp -= 3; - } - sptr -= 3; - } - } - else if (pixel_bytes == 2) - { - for (i = width; i; i--) - { - png_byte v[8]; - int j; - png_memcpy(v, sptr, 2); - for (j = 0; j < png_pass_inc[pass]; j++) - { - png_memcpy(dp, v, 2); - dp -= 2; - } - sptr -= 2; - } - } - else if (pixel_bytes == 4) - { - for (i = width; i; i--) - { - png_byte v[8]; - int j; - png_memcpy(v, sptr, 4); - for (j = 0; j < png_pass_inc[pass]; j++) - { -#ifdef PNG_DEBUG - if (dp < row || dp+3 > row+png_ptr->row_buf_size) - { - printf("dp out of bounds: row=%d, dp=%d, rp=%d\n", - row, dp, row+png_ptr->row_buf_size); - printf("row_buf=%d\n",png_ptr->row_buf_size); - } -#endif - png_memcpy(dp, v, 4); - dp -= 4; - } - sptr -= 4; - } - } - else if (pixel_bytes == 6) - { - for (i = width; i; i--) - { - png_byte v[8]; - int j; - png_memcpy(v, sptr, 6); - for (j = 0; j < png_pass_inc[pass]; j++) - { - png_memcpy(dp, v, 6); - dp -= 6; - } - sptr -= 6; - } - } - else if (pixel_bytes == 8) - { - for (i = width; i; i--) - { - png_byte v[8]; - int j; - png_memcpy(v, sptr, 8); - for (j = 0; j < png_pass_inc[pass]; j++) - { - png_memcpy(dp, v, 8); - dp -= 8; - } - sptr -= 8; - } - } - else /* GRR: should never be reached */ - { - for (i = width; i; i--) - { - png_byte v[8]; - int j; - png_memcpy(v, sptr, pixel_bytes); - for (j = 0; j < png_pass_inc[pass]; j++) - { - png_memcpy(dp, v, pixel_bytes); - dp -= pixel_bytes; - } - sptr -= pixel_bytes; - } - } - - } /* end if (MMX not supported) */ - break; - } - } /* end switch (row_info->pixel_depth) */ - - row_info->width = final_width; - - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,final_width); - } - -} /* end png_do_read_interlace() */ - -#endif /* PNG_HAVE_ASSEMBLER_READ_INTERLACE */ -#endif /* PNG_READ_INTERLACING_SUPPORTED */ - - - -#if defined(PNG_HAVE_ASSEMBLER_READ_FILTER_ROW) -#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) - -/* These variables are utilized in the functions below. They are declared */ -/* globally here to ensure alignment on 8-byte boundaries. */ - -union uAll { - long long use; - double align; -} _LBCarryMask = {0x0101010101010101LL}, - _HBClearMask = {0x7f7f7f7f7f7f7f7fLL}, - _ActiveMask, _ActiveMask2, _ActiveMaskEnd, _ShiftBpp, _ShiftRem; - -#ifdef PNG_THREAD_UNSAFE_OK -/*===========================================================================*/ -/* */ -/* P N G _ R E A D _ F I L T E R _ R O W _ M M X _ A V G */ -/* */ -/*===========================================================================*/ - -/* Optimized code for PNG Average filter decoder */ - -static void /* PRIVATE */ -png_read_filter_row_mmx_avg(png_row_infop row_info, png_bytep row, - png_bytep prev_row) -{ - int bpp; - int dummy_value_c; /* fix 'forbidden register 2 (cx) was spilled' error */ - int dummy_value_S; - int dummy_value_D; - - bpp = (row_info->pixel_depth + 7) >> 3; /* get # bytes per pixel */ - _FullLength = row_info->rowbytes; /* # of bytes to filter */ - - __asm__ __volatile__ ( - /* initialize address pointers and offset */ -#ifdef __PIC__ - "pushl %%ebx \n\t" /* save index to Global Offset Table */ -#endif -/*pre "movl row, %%edi \n\t" */ /* edi: Avg(x) */ - "xorl %%ebx, %%ebx \n\t" /* ebx: x */ - "movl %%edi, %%edx \n\t" -/*pre "movl prev_row, %%esi \n\t" */ /* esi: Prior(x) */ -/*pre "subl bpp, %%edx \n\t" */ /* (bpp is preloaded into ecx) */ - "subl %%ecx, %%edx \n\t" /* edx: Raw(x-bpp) */ - - "xorl %%eax,%%eax \n\t" - - /* Compute the Raw value for the first bpp bytes */ - /* Raw(x) = Avg(x) + (Prior(x)/2) */ - "avg_rlp: \n\t" - "movb (%%esi,%%ebx,),%%al \n\t" /* load al with Prior(x) */ - "incl %%ebx \n\t" - "shrb %%al \n\t" /* divide by 2 */ - "addb -1(%%edi,%%ebx,),%%al \n\t" /* add Avg(x); -1 to offset inc ebx */ -/* pre "cmpl bpp, %%ebx \n\t" */ /* (bpp is preloaded into ecx) */ - "cmpl %%ecx, %%ebx \n\t" - "movb %%al,-1(%%edi,%%ebx,) \n\t" /* write Raw(x); -1 to offset inc ebx */ - "jb avg_rlp \n\t" /* mov does not affect flags */ - - /* get # of bytes to alignment */ - "movl %%edi, _dif \n\t" /* take start of row */ - "addl %%ebx, _dif \n\t" /* add bpp */ - "addl $0xf, _dif \n\t" /* add 7+8 to incr past alignment bdry */ - "andl $0xfffffff8, _dif \n\t" /* mask to alignment boundary */ - "subl %%edi, _dif \n\t" /* subtract from start => value ebx at */ - "jz avg_go \n\t" /* alignment */ - - /* fix alignment */ - /* Compute the Raw value for the bytes up to the alignment boundary */ - /* Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2) */ - "xorl %%ecx, %%ecx \n\t" - - "avg_lp1: \n\t" - "xorl %%eax, %%eax \n\t" - "movb (%%esi,%%ebx,), %%cl \n\t" /* load cl with Prior(x) */ - "movb (%%edx,%%ebx,), %%al \n\t" /* load al with Raw(x-bpp) */ - "addw %%cx, %%ax \n\t" - "incl %%ebx \n\t" - "shrw %%ax \n\t" /* divide by 2 */ - "addb -1(%%edi,%%ebx,), %%al \n\t" /* add Avg(x); -1 to offset inc ebx */ - "cmpl _dif, %%ebx \n\t" /* check if at alignment boundary */ - "movb %%al, -1(%%edi,%%ebx,) \n\t" /* write Raw(x); -1 to offset inc ebx */ - "jb avg_lp1 \n\t" /* repeat until at alignment boundary */ - - "avg_go: \n\t" - "movl _FullLength, %%eax \n\t" - "movl %%eax, %%ecx \n\t" - "subl %%ebx, %%eax \n\t" /* subtract alignment fix */ - "andl $0x00000007, %%eax \n\t" /* calc bytes over mult of 8 */ - "subl %%eax, %%ecx \n\t" /* drop over bytes from original length */ - "movl %%ecx, _MMXLength \n\t" -#ifdef __PIC__ - "popl %%ebx \n\t" /* restore index to Global Offset Table */ -#endif - - : "=c" (dummy_value_c), /* output regs (dummy) */ - "=S" (dummy_value_S), - "=D" (dummy_value_D) - - : "0" (bpp), /* ecx // input regs */ - "1" (prev_row), /* esi */ - "2" (row) /* edi */ - - : "%eax", "%edx" /* clobber list */ -#ifndef __PIC__ - , "%ebx" -#endif - /* GRR: INCLUDE "memory" as clobbered? (_dif, _MMXLength) */ - /* (seems to work fine without...) */ - ); - - /* now do the math for the rest of the row */ - switch (bpp) - { - case 3: - { - _ActiveMask.use = 0x0000000000ffffffLL; - _ShiftBpp.use = 24; /* == 3 * 8 */ - _ShiftRem.use = 40; /* == 64 - 24 */ - - __asm__ __volatile__ ( - /* re-init address pointers and offset */ - "movq _ActiveMask, %%mm7 \n\t" - "movl _dif, %%ecx \n\t" /* ecx: x = offset to */ - "movq _LBCarryMask, %%mm5 \n\t" /* alignment boundary */ -/* preload "movl row, %%edi \n\t" // edi: Avg(x) */ - "movq _HBClearMask, %%mm4 \n\t" -/* preload "movl prev_row, %%esi \n\t" // esi: Prior(x) */ - - /* prime the pump: load the first Raw(x-bpp) data set */ - "movq -8(%%edi,%%ecx,), %%mm2 \n\t" /* load previous aligned 8 bytes */ - /* (correct pos. in loop below) */ - "avg_3lp: \n\t" - "movq (%%edi,%%ecx,), %%mm0 \n\t" /* load mm0 with Avg(x) */ - "movq %%mm5, %%mm3 \n\t" - "psrlq _ShiftRem, %%mm2 \n\t" /* correct position Raw(x-bpp) */ - /* data */ - "movq (%%esi,%%ecx,), %%mm1 \n\t" /* load mm1 with Prior(x) */ - "movq %%mm7, %%mm6 \n\t" - "pand %%mm1, %%mm3 \n\t" /* get lsb for each prev_row byte */ - "psrlq $1, %%mm1 \n\t" /* divide prev_row bytes by 2 */ - "pand %%mm4, %%mm1 \n\t" /* clear invalid bit 7 of each */ - /* byte */ - "paddb %%mm1, %%mm0 \n\t" /* add (Prev_row/2) to Avg for */ - /* each byte */ - /* add 1st active group (Raw(x-bpp)/2) to average with LBCarry */ - "movq %%mm3, %%mm1 \n\t" /* now use mm1 for getting */ - /* LBCarrys */ - "pand %%mm2, %%mm1 \n\t" /* get LBCarrys for each byte */ - /* where both */ - /* lsb's were == 1 (only valid for active group) */ - "psrlq $1, %%mm2 \n\t" /* divide raw bytes by 2 */ - "pand %%mm4, %%mm2 \n\t" /* clear invalid bit 7 of each */ - /* byte */ - "paddb %%mm1, %%mm2 \n\t" /* add LBCarrys to (Raw(x-bpp)/2) */ - /* for each byte */ - "pand %%mm6, %%mm2 \n\t" /* leave only Active Group 1 */ - /* bytes to add to Avg */ - "paddb %%mm2, %%mm0 \n\t" /* add (Raw/2) + LBCarrys to */ - /* Avg for each Active */ - /* byte */ - /* add 2nd active group (Raw(x-bpp)/2) to average with _LBCarry */ - "psllq _ShiftBpp, %%mm6 \n\t" /* shift the mm6 mask to cover */ - /* bytes 3-5 */ - "movq %%mm0, %%mm2 \n\t" /* mov updated Raws to mm2 */ - "psllq _ShiftBpp, %%mm2 \n\t" /* shift data to pos. correctly */ - "movq %%mm3, %%mm1 \n\t" /* now use mm1 for getting */ - /* LBCarrys */ - "pand %%mm2, %%mm1 \n\t" /* get LBCarrys for each byte */ - /* where both */ - /* lsb's were == 1 (only valid for active group) */ - "psrlq $1, %%mm2 \n\t" /* divide raw bytes by 2 */ - "pand %%mm4, %%mm2 \n\t" /* clear invalid bit 7 of each */ - /* byte */ - "paddb %%mm1, %%mm2 \n\t" /* add LBCarrys to (Raw(x-bpp)/2) */ - /* for each byte */ - "pand %%mm6, %%mm2 \n\t" /* leave only Active Group 2 */ - /* bytes to add to Avg */ - "paddb %%mm2, %%mm0 \n\t" /* add (Raw/2) + LBCarrys to */ - /* Avg for each Active */ - /* byte */ - - /* add 3rd active group (Raw(x-bpp)/2) to average with _LBCarry */ - "psllq _ShiftBpp, %%mm6 \n\t" /* shift mm6 mask to cover last */ - /* two */ - /* bytes */ - "movq %%mm0, %%mm2 \n\t" /* mov updated Raws to mm2 */ - "psllq _ShiftBpp, %%mm2 \n\t" /* shift data to pos. correctly */ - /* Data only needs to be shifted once here to */ - /* get the correct x-bpp offset. */ - "movq %%mm3, %%mm1 \n\t" /* now use mm1 for getting */ - /* LBCarrys */ - "pand %%mm2, %%mm1 \n\t" /* get LBCarrys for each byte */ - /* where both */ - /* lsb's were == 1 (only valid for active group) */ - "psrlq $1, %%mm2 \n\t" /* divide raw bytes by 2 */ - "pand %%mm4, %%mm2 \n\t" /* clear invalid bit 7 of each */ - /* byte */ - "paddb %%mm1, %%mm2 \n\t" /* add LBCarrys to (Raw(x-bpp)/2) */ - /* for each byte */ - "pand %%mm6, %%mm2 \n\t" /* leave only Active Group 2 */ - /* bytes to add to Avg */ - "addl $8, %%ecx \n\t" - "paddb %%mm2, %%mm0 \n\t" /* add (Raw/2) + LBCarrys to */ - /* Avg for each Active */ - /* byte */ - /* now ready to write back to memory */ - "movq %%mm0, -8(%%edi,%%ecx,) \n\t" - /* move updated Raw(x) to use as Raw(x-bpp) for next loop */ - "cmpl _MMXLength, %%ecx \n\t" - "movq %%mm0, %%mm2 \n\t" /* mov updated Raw(x) to mm2 */ - "jb avg_3lp \n\t" - - : "=S" (dummy_value_S), /* output regs (dummy) */ - "=D" (dummy_value_D) - - : "0" (prev_row), /* esi // input regs */ - "1" (row) /* edi */ - - : "%ecx" /* clobber list */ -#if 0 /* %mm0, ..., %mm7 not supported by gcc 2.7.2.3 or egcs 1.1 */ - , "%mm0", "%mm1", "%mm2", "%mm3" - , "%mm4", "%mm5", "%mm6", "%mm7" -#endif - ); - } - break; /* end 3 bpp */ - - case 6: - case 4: - //case 7: /* who wrote this? PNG doesn't support 5 or 7 bytes/pixel */ - //case 5: /* GRR BOGUS */ - { - _ActiveMask.use = 0xffffffffffffffffLL; /* use shift below to clear */ - /* appropriate inactive bytes */ - _ShiftBpp.use = bpp << 3; - _ShiftRem.use = 64 - _ShiftBpp.use; - - __asm__ __volatile__ ( - "movq _HBClearMask, %%mm4 \n\t" - - /* re-init address pointers and offset */ - "movl _dif, %%ecx \n\t" /* ecx: x = offset to */ - /* alignment boundary */ - - /* load _ActiveMask and clear all bytes except for 1st active group */ - "movq _ActiveMask, %%mm7 \n\t" -/* preload "movl row, %%edi \n\t" // edi: Avg(x) */ - "psrlq _ShiftRem, %%mm7 \n\t" -/* preload "movl prev_row, %%esi \n\t" // esi: Prior(x) */ - "movq %%mm7, %%mm6 \n\t" - "movq _LBCarryMask, %%mm5 \n\t" - "psllq _ShiftBpp, %%mm6 \n\t" /* create mask for 2nd active */ - /* group */ - - /* prime the pump: load the first Raw(x-bpp) data set */ - "movq -8(%%edi,%%ecx,), %%mm2 \n\t" /* load previous aligned 8 bytes */ - /* (we correct pos. in loop below) */ - "avg_4lp: \n\t" - "movq (%%edi,%%ecx,), %%mm0 \n\t" - "psrlq _ShiftRem, %%mm2 \n\t" /* shift data to pos. correctly */ - "movq (%%esi,%%ecx,), %%mm1 \n\t" - /* add (Prev_row/2) to average */ - "movq %%mm5, %%mm3 \n\t" - "pand %%mm1, %%mm3 \n\t" /* get lsb for each prev_row byte */ - "psrlq $1, %%mm1 \n\t" /* divide prev_row bytes by 2 */ - "pand %%mm4, %%mm1 \n\t" /* clear invalid bit 7 of each */ - /* byte */ - "paddb %%mm1, %%mm0 \n\t" /* add (Prev_row/2) to Avg for */ - /* each byte */ - /* add 1st active group (Raw(x-bpp)/2) to average with _LBCarry */ - "movq %%mm3, %%mm1 \n\t" /* now use mm1 for getting */ - /* LBCarrys */ - "pand %%mm2, %%mm1 \n\t" /* get LBCarrys for each byte */ - /* where both */ - /* lsb's were == 1 (only valid for active group) */ - "psrlq $1, %%mm2 \n\t" /* divide raw bytes by 2 */ - "pand %%mm4, %%mm2 \n\t" /* clear invalid bit 7 of each */ - /* byte */ - "paddb %%mm1, %%mm2 \n\t" /* add LBCarrys to (Raw(x-bpp)/2) */ - /* for each byte */ - "pand %%mm7, %%mm2 \n\t" /* leave only Active Group 1 */ - /* bytes to add to Avg */ - "paddb %%mm2, %%mm0 \n\t" /* add (Raw/2) + LBCarrys to Avg */ - /* for each Active */ - /* byte */ - /* add 2nd active group (Raw(x-bpp)/2) to average with _LBCarry */ - "movq %%mm0, %%mm2 \n\t" /* mov updated Raws to mm2 */ - "psllq _ShiftBpp, %%mm2 \n\t" /* shift data to pos. correctly */ - "addl $8, %%ecx \n\t" - "movq %%mm3, %%mm1 \n\t" /* now use mm1 for getting */ - /* LBCarrys */ - "pand %%mm2, %%mm1 \n\t" /* get LBCarrys for each byte */ - /* where both */ - /* lsb's were == 1 (only valid for active group) */ - "psrlq $1, %%mm2 \n\t" /* divide raw bytes by 2 */ - "pand %%mm4, %%mm2 \n\t" /* clear invalid bit 7 of each */ - /* byte */ - "paddb %%mm1, %%mm2 \n\t" /* add LBCarrys to (Raw(x-bpp)/2) */ - /* for each byte */ - "pand %%mm6, %%mm2 \n\t" /* leave only Active Group 2 */ - /* bytes to add to Avg */ - "paddb %%mm2, %%mm0 \n\t" /* add (Raw/2) + LBCarrys to */ - /* Avg for each Active */ - /* byte */ - "cmpl _MMXLength, %%ecx \n\t" - /* now ready to write back to memory */ - "movq %%mm0, -8(%%edi,%%ecx,) \n\t" - /* prep Raw(x-bpp) for next loop */ - "movq %%mm0, %%mm2 \n\t" /* mov updated Raws to mm2 */ - "jb avg_4lp \n\t" - - : "=S" (dummy_value_S), /* output regs (dummy) */ - "=D" (dummy_value_D) - - : "0" (prev_row), /* esi // input regs */ - "1" (row) /* edi */ - - : "%ecx" /* clobber list */ -#if 0 /* %mm0, ..., %mm7 not supported by gcc 2.7.2.3 or egcs 1.1 */ - , "%mm0", "%mm1", "%mm2", "%mm3" - , "%mm4", "%mm5", "%mm6", "%mm7" -#endif - ); - } - break; /* end 4,6 bpp */ - - case 2: - { - _ActiveMask.use = 0x000000000000ffffLL; - _ShiftBpp.use = 16; /* == 2 * 8 */ - _ShiftRem.use = 48; /* == 64 - 16 */ - - __asm__ __volatile__ ( - /* load _ActiveMask */ - "movq _ActiveMask, %%mm7 \n\t" - /* re-init address pointers and offset */ - "movl _dif, %%ecx \n\t" /* ecx: x = offset to alignment */ - /* boundary */ - "movq _LBCarryMask, %%mm5 \n\t" -/* preload "movl row, %%edi \n\t" // edi: Avg(x) */ - "movq _HBClearMask, %%mm4 \n\t" -/* preload "movl prev_row, %%esi \n\t" // esi: Prior(x) */ - - /* prime the pump: load the first Raw(x-bpp) data set */ - "movq -8(%%edi,%%ecx,), %%mm2 \n\t" /* load previous aligned 8 bytes */ - /* (we correct pos. in loop below) */ - "avg_2lp: \n\t" - "movq (%%edi,%%ecx,), %%mm0 \n\t" - "psrlq _ShiftRem, %%mm2 \n\t" /* shift data to pos. correctly */ - "movq (%%esi,%%ecx,), %%mm1 \n\t" /* (GRR BUGFIX: was psllq) */ - /* add (Prev_row/2) to average */ - "movq %%mm5, %%mm3 \n\t" - "pand %%mm1, %%mm3 \n\t" /* get lsb for each prev_row byte */ - "psrlq $1, %%mm1 \n\t" /* divide prev_row bytes by 2 */ - "pand %%mm4, %%mm1 \n\t" /* clear invalid bit 7 of each */ - /* byte */ - "movq %%mm7, %%mm6 \n\t" - "paddb %%mm1, %%mm0 \n\t" /* add (Prev_row/2) to Avg for */ - /* each byte */ - - /* add 1st active group (Raw(x-bpp)/2) to average with _LBCarry */ - "movq %%mm3, %%mm1 \n\t" /* now use mm1 for getting */ - /* LBCarrys */ - "pand %%mm2, %%mm1 \n\t" /* get LBCarrys for each byte */ - /* where both */ - /* lsb's were == 1 (only valid */ - /* for active group) */ - "psrlq $1, %%mm2 \n\t" /* divide raw bytes by 2 */ - "pand %%mm4, %%mm2 \n\t" /* clear invalid bit 7 of each */ - /* byte */ - "paddb %%mm1, %%mm2 \n\t" /* add LBCarrys to (Raw(x-bpp)/2) */ - /* for each byte */ - "pand %%mm6, %%mm2 \n\t" /* leave only Active Group 1 */ - /* bytes to add to Avg */ - "paddb %%mm2, %%mm0 \n\t" /* add (Raw/2) + LBCarrys to Avg */ - /* for each Active byte */ - - /* add 2nd active group (Raw(x-bpp)/2) to average with _LBCarry */ - "psllq _ShiftBpp, %%mm6 \n\t" /* shift the mm6 mask to cover */ - /* bytes 2 & 3 */ - "movq %%mm0, %%mm2 \n\t" /* mov updated Raws to mm2 */ - "psllq _ShiftBpp, %%mm2 \n\t" /* shift data to pos. correctly */ - "movq %%mm3, %%mm1 \n\t" /* now use mm1 for getting */ - /* LBCarrys */ - "pand %%mm2, %%mm1 \n\t" /* get LBCarrys for each byte */ - /* where both */ - /* lsb's were == 1 (only valid */ - /* for active group) */ - "psrlq $1, %%mm2 \n\t" /* divide raw bytes by 2 */ - "pand %%mm4, %%mm2 \n\t" /* clear invalid bit 7 of each */ - /* byte */ - "paddb %%mm1, %%mm2 \n\t" /* add LBCarrys to (Raw(x-bpp)/2) */ - /* for each byte */ - "pand %%mm6, %%mm2 \n\t" /* leave only Active Group 2 */ - /* bytes to add to Avg */ - "paddb %%mm2, %%mm0 \n\t" /* add (Raw/2) + LBCarrys to */ - /* Avg for each Active byte */ - - /* add 3rd active group (Raw(x-bpp)/2) to average with _LBCarry */ - "psllq _ShiftBpp, %%mm6 \n\t" /* shift the mm6 mask to cover */ - /* bytes 4 & 5 */ - "movq %%mm0, %%mm2 \n\t" /* mov updated Raws to mm2 */ - "psllq _ShiftBpp, %%mm2 \n\t" /* shift data to pos. correctly */ - "movq %%mm3, %%mm1 \n\t" /* now use mm1 for getting */ - /* LBCarrys */ - "pand %%mm2, %%mm1 \n\t" /* get LBCarrys for each byte */ - /* where both lsb's were == 1 */ - /* (only valid for active group) */ - "psrlq $1, %%mm2 \n\t" /* divide raw bytes by 2 */ - "pand %%mm4, %%mm2 \n\t" /* clear invalid bit 7 of each */ - /* byte */ - "paddb %%mm1, %%mm2 \n\t" /* add LBCarrys to (Raw(x-bpp)/2) */ - /* for each byte */ - "pand %%mm6, %%mm2 \n\t" /* leave only Active Group 2 */ - /* bytes to add to Avg */ - "paddb %%mm2, %%mm0 \n\t" /* add (Raw/2) + LBCarrys to */ - /* Avg for each Active byte */ - - /* add 4th active group (Raw(x-bpp)/2) to average with _LBCarry */ - "psllq _ShiftBpp, %%mm6 \n\t" /* shift the mm6 mask to cover */ - /* bytes 6 & 7 */ - "movq %%mm0, %%mm2 \n\t" /* mov updated Raws to mm2 */ - "psllq _ShiftBpp, %%mm2 \n\t" /* shift data to pos. correctly */ - "addl $8, %%ecx \n\t" - "movq %%mm3, %%mm1 \n\t" /* now use mm1 for getting */ - /* LBCarrys */ - "pand %%mm2, %%mm1 \n\t" /* get LBCarrys for each byte */ - /* where both */ - /* lsb's were == 1 (only valid */ - /* for active group) */ - "psrlq $1, %%mm2 \n\t" /* divide raw bytes by 2 */ - "pand %%mm4, %%mm2 \n\t" /* clear invalid bit 7 of each */ - /* byte */ - "paddb %%mm1, %%mm2 \n\t" /* add LBCarrys to (Raw(x-bpp)/2) */ - /* for each byte */ - "pand %%mm6, %%mm2 \n\t" /* leave only Active Group 2 */ - /* bytes to add to Avg */ - "paddb %%mm2, %%mm0 \n\t" /* add (Raw/2) + LBCarrys to */ - /* Avg for each Active byte */ - - "cmpl _MMXLength, %%ecx \n\t" - /* now ready to write back to memory */ - "movq %%mm0, -8(%%edi,%%ecx,) \n\t" - /* prep Raw(x-bpp) for next loop */ - "movq %%mm0, %%mm2 \n\t" /* mov updated Raws to mm2 */ - "jb avg_2lp \n\t" - - : "=S" (dummy_value_S), /* output regs (dummy) */ - "=D" (dummy_value_D) - - : "0" (prev_row), /* esi // input regs */ - "1" (row) /* edi */ - - : "%ecx" /* clobber list */ -#if 0 /* %mm0, ..., %mm7 not supported by gcc 2.7.2.3 or egcs 1.1 */ - , "%mm0", "%mm1", "%mm2", "%mm3" - , "%mm4", "%mm5", "%mm6", "%mm7" -#endif - ); - } - break; /* end 2 bpp */ - - case 1: - { - __asm__ __volatile__ ( - /* re-init address pointers and offset */ -#ifdef __PIC__ - "pushl %%ebx \n\t" /* save Global Offset Table index */ -#endif - "movl _dif, %%ebx \n\t" /* ebx: x = offset to alignment */ - /* boundary */ -/* preload "movl row, %%edi \n\t" // edi: Avg(x) */ - "cmpl _FullLength, %%ebx \n\t" /* test if offset at end of array */ - "jnb avg_1end \n\t" - /* do Paeth decode for remaining bytes */ -/* preload "movl prev_row, %%esi \n\t" // esi: Prior(x) */ - "movl %%edi, %%edx \n\t" -/* preload "subl bpp, %%edx \n\t" // (bpp is preloaded into ecx) */ - "subl %%ecx, %%edx \n\t" /* edx: Raw(x-bpp) */ - "xorl %%ecx, %%ecx \n\t" /* zero ecx before using cl & cx */ - /* in loop below */ - "avg_1lp: \n\t" - /* Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2) */ - "xorl %%eax, %%eax \n\t" - "movb (%%esi,%%ebx,), %%cl \n\t" /* load cl with Prior(x) */ - "movb (%%edx,%%ebx,), %%al \n\t" /* load al with Raw(x-bpp) */ - "addw %%cx, %%ax \n\t" - "incl %%ebx \n\t" - "shrw %%ax \n\t" /* divide by 2 */ - "addb -1(%%edi,%%ebx,), %%al \n\t" /* add Avg(x); -1 to offset */ - /* inc ebx */ - "cmpl _FullLength, %%ebx \n\t" /* check if at end of array */ - "movb %%al, -1(%%edi,%%ebx,) \n\t" /* write back Raw(x); */ - /* mov does not affect flags; -1 to offset inc ebx */ - "jb avg_1lp \n\t" - - "avg_1end: \n\t" -#ifdef __PIC__ - "popl %%ebx \n\t" /* Global Offset Table index */ -#endif - - : "=c" (dummy_value_c), /* output regs (dummy) */ - "=S" (dummy_value_S), - "=D" (dummy_value_D) - - : "0" (bpp), /* ecx // input regs */ - "1" (prev_row), /* esi */ - "2" (row) /* edi */ - - : "%eax", "%edx" /* clobber list */ -#ifndef __PIC__ - , "%ebx" -#endif - ); - } - return; /* end 1 bpp */ - - case 8: - { - __asm__ __volatile__ ( - /* re-init address pointers and offset */ - "movl _dif, %%ecx \n\t" /* ecx: x == offset to alignment */ - "movq _LBCarryMask, %%mm5 \n\t" /* boundary */ -/* preload "movl row, %%edi \n\t" // edi: Avg(x) */ - "movq _HBClearMask, %%mm4 \n\t" -/* preload "movl prev_row, %%esi \n\t" // esi: Prior(x) */ - - /* prime the pump: load the first Raw(x-bpp) data set */ - "movq -8(%%edi,%%ecx,), %%mm2 \n\t" /* load previous aligned 8 bytes */ - /* (NO NEED to correct pos. in loop below) */ - - "avg_8lp: \n\t" - "movq (%%edi,%%ecx,), %%mm0 \n\t" - "movq %%mm5, %%mm3 \n\t" - "movq (%%esi,%%ecx,), %%mm1 \n\t" - "addl $8, %%ecx \n\t" - "pand %%mm1, %%mm3 \n\t" /* get lsb for each prev_row byte */ - "psrlq $1, %%mm1 \n\t" /* divide prev_row bytes by 2 */ - "pand %%mm2, %%mm3 \n\t" /* get LBCarrys for each byte */ - /* where both lsb's were == 1 */ - "psrlq $1, %%mm2 \n\t" /* divide raw bytes by 2 */ - "pand %%mm4, %%mm1 \n\t" /* clear invalid bit 7, each byte */ - "paddb %%mm3, %%mm0 \n\t" /* add LBCarrys to Avg, each byte */ - "pand %%mm4, %%mm2 \n\t" /* clear invalid bit 7, each byte */ - "paddb %%mm1, %%mm0 \n\t" /* add (Prev_row/2) to Avg, each */ - "paddb %%mm2, %%mm0 \n\t" /* add (Raw/2) to Avg for each */ - "cmpl _MMXLength, %%ecx \n\t" - "movq %%mm0, -8(%%edi,%%ecx,) \n\t" - "movq %%mm0, %%mm2 \n\t" /* reuse as Raw(x-bpp) */ - "jb avg_8lp \n\t" - - : "=S" (dummy_value_S), /* output regs (dummy) */ - "=D" (dummy_value_D) - - : "0" (prev_row), /* esi // input regs */ - "1" (row) /* edi */ - - : "%ecx" /* clobber list */ -#if 0 /* %mm0, ..., %mm5 not supported by gcc 2.7.2.3 or egcs 1.1 */ - , "%mm0", "%mm1", "%mm2" - , "%mm3", "%mm4", "%mm5" -#endif - ); - } - break; /* end 8 bpp */ - - default: /* bpp greater than 8 (!= 1,2,3,4,[5],6,[7],8) */ - { - -#ifdef PNG_DEBUG - /* GRR: PRINT ERROR HERE: SHOULD NEVER BE REACHED */ - png_debug(1, - "Internal logic error in pnggccrd (png_read_filter_row_mmx_avg())\n"); -#endif - -#if 0 - __asm__ __volatile__ ( - "movq _LBCarryMask, %%mm5 \n\t" - /* re-init address pointers and offset */ - "movl _dif, %%ebx \n\t" /* ebx: x = offset to */ - /* alignment boundary */ - "movl row, %%edi \n\t" /* edi: Avg(x) */ - "movq _HBClearMask, %%mm4 \n\t" - "movl %%edi, %%edx \n\t" - "movl prev_row, %%esi \n\t" /* esi: Prior(x) */ - "subl bpp, %%edx \n\t" /* edx: Raw(x-bpp) */ - "avg_Alp: \n\t" - "movq (%%edi,%%ebx,), %%mm0 \n\t" - "movq %%mm5, %%mm3 \n\t" - "movq (%%esi,%%ebx,), %%mm1 \n\t" - "pand %%mm1, %%mm3 \n\t" /* get lsb for each prev_row byte */ - "movq (%%edx,%%ebx,), %%mm2 \n\t" - "psrlq $1, %%mm1 \n\t" /* divide prev_row bytes by 2 */ - "pand %%mm2, %%mm3 \n\t" /* get LBCarrys for each byte */ - /* where both lsb's were == 1 */ - "psrlq $1, %%mm2 \n\t" /* divide raw bytes by 2 */ - "pand %%mm4, %%mm1 \n\t" /* clear invalid bit 7 of each */ - /* byte */ - "paddb %%mm3, %%mm0 \n\t" /* add LBCarrys to Avg for each */ - /* byte */ - "pand %%mm4, %%mm2 \n\t" /* clear invalid bit 7 of each */ - /* byte */ - "paddb %%mm1, %%mm0 \n\t" /* add (Prev_row/2) to Avg for */ - /* each byte */ - "addl $8, %%ebx \n\t" - "paddb %%mm2, %%mm0 \n\t" /* add (Raw/2) to Avg for each */ - /* byte */ - "cmpl _MMXLength, %%ebx \n\t" - "movq %%mm0, -8(%%edi,%%ebx,) \n\t" - "jb avg_Alp \n\t" - - : /* FIXASM: output regs/vars go here, e.g.: "=m" (memory_var) */ - - : /* FIXASM: input regs, e.g.: "c" (count), "S" (src), "D" (dest) */ - - : "%ebx", "%edx", "%edi", "%esi" /* CHECKASM: clobber list */ - ); -#endif /* 0 - NEVER REACHED */ - } - break; - - } /* end switch (bpp) */ - - __asm__ __volatile__ ( - /* MMX acceleration complete; now do clean-up */ - /* check if any remaining bytes left to decode */ -#ifdef __PIC__ - "pushl %%ebx \n\t" /* save index to Global Offset Table */ -#endif - "movl _MMXLength, %%ebx \n\t" /* ebx: x == offset bytes after MMX */ -/* pre "movl row, %%edi \n\t" */ /* edi: Avg(x) */ - "cmpl _FullLength, %%ebx \n\t" /* test if offset at end of array */ - "jnb avg_end \n\t" - - /* do Avg decode for remaining bytes */ -/*pre "movl prev_row, %%esi \n\t" */ /* esi: Prior(x) */ - "movl %%edi, %%edx \n\t" -/*pre "subl bpp, %%edx \n\t" */ /* (bpp is preloaded into ecx) */ - "subl %%ecx, %%edx \n\t" /* edx: Raw(x-bpp) */ - "xorl %%ecx, %%ecx \n\t" /* zero ecx before using cl & cx below */ - - "avg_lp2: \n\t" - /* Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2) */ - "xorl %%eax, %%eax \n\t" - "movb (%%esi,%%ebx,), %%cl \n\t" /* load cl with Prior(x) */ - "movb (%%edx,%%ebx,), %%al \n\t" /* load al with Raw(x-bpp) */ - "addw %%cx, %%ax \n\t" - "incl %%ebx \n\t" - "shrw %%ax \n\t" /* divide by 2 */ - "addb -1(%%edi,%%ebx,), %%al \n\t" /* add Avg(x); -1 to offset inc ebx */ - "cmpl _FullLength, %%ebx \n\t" /* check if at end of array */ - "movb %%al, -1(%%edi,%%ebx,) \n\t" /* write back Raw(x) [mov does not */ - "jb avg_lp2 \n\t" /* affect flags; -1 to offset inc ebx] */ - - "avg_end: \n\t" - "EMMS \n\t" /* end MMX; prep for poss. FP instrs. */ -#ifdef __PIC__ - "popl %%ebx \n\t" /* restore index to Global Offset Table */ -#endif - - : "=c" (dummy_value_c), /* output regs (dummy) */ - "=S" (dummy_value_S), - "=D" (dummy_value_D) - - : "0" (bpp), /* ecx // input regs */ - "1" (prev_row), /* esi */ - "2" (row) /* edi */ - - : "%eax", "%edx" /* clobber list */ -#ifndef __PIC__ - , "%ebx" -#endif - ); - -} /* end png_read_filter_row_mmx_avg() */ -#endif - - - -#ifdef PNG_THREAD_UNSAFE_OK -/*===========================================================================*/ -/* */ -/* P N G _ R E A D _ F I L T E R _ R O W _ M M X _ P A E T H */ -/* */ -/*===========================================================================*/ - -/* Optimized code for PNG Paeth filter decoder */ - -static void /* PRIVATE */ -png_read_filter_row_mmx_paeth(png_row_infop row_info, png_bytep row, - png_bytep prev_row) -{ - int bpp; - int dummy_value_c; /* fix 'forbidden register 2 (cx) was spilled' error */ - int dummy_value_S; - int dummy_value_D; - - bpp = (row_info->pixel_depth + 7) >> 3; /* Get # bytes per pixel */ - _FullLength = row_info->rowbytes; /* # of bytes to filter */ - - __asm__ __volatile__ ( -#ifdef __PIC__ - "pushl %%ebx \n\t" /* save index to Global Offset Table */ -#endif - "xorl %%ebx, %%ebx \n\t" /* ebx: x offset */ -/*pre "movl row, %%edi \n\t" */ - "xorl %%edx, %%edx \n\t" /* edx: x-bpp offset */ -/*pre "movl prev_row, %%esi \n\t" */ - "xorl %%eax, %%eax \n\t" - - /* Compute the Raw value for the first bpp bytes */ - /* Note: the formula works out to be always */ - /* Paeth(x) = Raw(x) + Prior(x) where x < bpp */ - "paeth_rlp: \n\t" - "movb (%%edi,%%ebx,), %%al \n\t" - "addb (%%esi,%%ebx,), %%al \n\t" - "incl %%ebx \n\t" -/*pre "cmpl bpp, %%ebx \n\t" (bpp is preloaded into ecx) */ - "cmpl %%ecx, %%ebx \n\t" - "movb %%al, -1(%%edi,%%ebx,) \n\t" - "jb paeth_rlp \n\t" - /* get # of bytes to alignment */ - "movl %%edi, _dif \n\t" /* take start of row */ - "addl %%ebx, _dif \n\t" /* add bpp */ - "xorl %%ecx, %%ecx \n\t" - "addl $0xf, _dif \n\t" /* add 7 + 8 to incr past alignment */ - /* boundary */ - "andl $0xfffffff8, _dif \n\t" /* mask to alignment boundary */ - "subl %%edi, _dif \n\t" /* subtract from start ==> value ebx */ - /* at alignment */ - "jz paeth_go \n\t" - /* fix alignment */ - - "paeth_lp1: \n\t" - "xorl %%eax, %%eax \n\t" - /* pav = p - a = (a + b - c) - a = b - c */ - "movb (%%esi,%%ebx,), %%al \n\t" /* load Prior(x) into al */ - "movb (%%esi,%%edx,), %%cl \n\t" /* load Prior(x-bpp) into cl */ - "subl %%ecx, %%eax \n\t" /* subtract Prior(x-bpp) */ - "movl %%eax, _patemp \n\t" /* Save pav for later use */ - "xorl %%eax, %%eax \n\t" - /* pbv = p - b = (a + b - c) - b = a - c */ - "movb (%%edi,%%edx,), %%al \n\t" /* load Raw(x-bpp) into al */ - "subl %%ecx, %%eax \n\t" /* subtract Prior(x-bpp) */ - "movl %%eax, %%ecx \n\t" - /* pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv */ - "addl _patemp, %%eax \n\t" /* pcv = pav + pbv */ - /* pc = abs(pcv) */ - "testl $0x80000000, %%eax \n\t" - "jz paeth_pca \n\t" - "negl %%eax \n\t" /* reverse sign of neg values */ - - "paeth_pca: \n\t" - "movl %%eax, _pctemp \n\t" /* save pc for later use */ - /* pb = abs(pbv) */ - "testl $0x80000000, %%ecx \n\t" - "jz paeth_pba \n\t" - "negl %%ecx \n\t" /* reverse sign of neg values */ - - "paeth_pba: \n\t" - "movl %%ecx, _pbtemp \n\t" /* save pb for later use */ - /* pa = abs(pav) */ - "movl _patemp, %%eax \n\t" - "testl $0x80000000, %%eax \n\t" - "jz paeth_paa \n\t" - "negl %%eax \n\t" /* reverse sign of neg values */ - - "paeth_paa: \n\t" - "movl %%eax, _patemp \n\t" /* save pa for later use */ - /* test if pa <= pb */ - "cmpl %%ecx, %%eax \n\t" - "jna paeth_abb \n\t" - /* pa > pb; now test if pb <= pc */ - "cmpl _pctemp, %%ecx \n\t" - "jna paeth_bbc \n\t" - /* pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp) */ - "movb (%%esi,%%edx,), %%cl \n\t" /* load Prior(x-bpp) into cl */ - "jmp paeth_paeth \n\t" - - "paeth_bbc: \n\t" - /* pb <= pc; Raw(x) = Paeth(x) + Prior(x) */ - "movb (%%esi,%%ebx,), %%cl \n\t" /* load Prior(x) into cl */ - "jmp paeth_paeth \n\t" - - "paeth_abb: \n\t" - /* pa <= pb; now test if pa <= pc */ - "cmpl _pctemp, %%eax \n\t" - "jna paeth_abc \n\t" - /* pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp) */ - "movb (%%esi,%%edx,), %%cl \n\t" /* load Prior(x-bpp) into cl */ - "jmp paeth_paeth \n\t" - - "paeth_abc: \n\t" - /* pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp) */ - "movb (%%edi,%%edx,), %%cl \n\t" /* load Raw(x-bpp) into cl */ - - "paeth_paeth: \n\t" - "incl %%ebx \n\t" - "incl %%edx \n\t" - /* Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256 */ - "addb %%cl, -1(%%edi,%%ebx,) \n\t" - "cmpl _dif, %%ebx \n\t" - "jb paeth_lp1 \n\t" - - "paeth_go: \n\t" - "movl _FullLength, %%ecx \n\t" - "movl %%ecx, %%eax \n\t" - "subl %%ebx, %%eax \n\t" /* subtract alignment fix */ - "andl $0x00000007, %%eax \n\t" /* calc bytes over mult of 8 */ - "subl %%eax, %%ecx \n\t" /* drop over bytes from original length */ - "movl %%ecx, _MMXLength \n\t" -#ifdef __PIC__ - "popl %%ebx \n\t" /* restore index to Global Offset Table */ -#endif - - : "=c" (dummy_value_c), /* output regs (dummy) */ - "=S" (dummy_value_S), - "=D" (dummy_value_D) - - : "0" (bpp), /* ecx // input regs */ - "1" (prev_row), /* esi */ - "2" (row) /* edi */ - - : "%eax", "%edx" /* clobber list */ -#ifndef __PIC__ - , "%ebx" -#endif - ); - - /* now do the math for the rest of the row */ - switch (bpp) - { - case 3: - { - _ActiveMask.use = 0x0000000000ffffffLL; - _ActiveMaskEnd.use = 0xffff000000000000LL; - _ShiftBpp.use = 24; /* == bpp(3) * 8 */ - _ShiftRem.use = 40; /* == 64 - 24 */ - - __asm__ __volatile__ ( - "movl _dif, %%ecx \n\t" -/* preload "movl row, %%edi \n\t" */ -/* preload "movl prev_row, %%esi \n\t" */ - "pxor %%mm0, %%mm0 \n\t" - /* prime the pump: load the first Raw(x-bpp) data set */ - "movq -8(%%edi,%%ecx,), %%mm1 \n\t" - "paeth_3lp: \n\t" - "psrlq _ShiftRem, %%mm1 \n\t" /* shift last 3 bytes to 1st */ - /* 3 bytes */ - "movq (%%esi,%%ecx,), %%mm2 \n\t" /* load b=Prior(x) */ - "punpcklbw %%mm0, %%mm1 \n\t" /* unpack High bytes of a */ - "movq -8(%%esi,%%ecx,), %%mm3 \n\t" /* prep c=Prior(x-bpp) bytes */ - "punpcklbw %%mm0, %%mm2 \n\t" /* unpack High bytes of b */ - "psrlq _ShiftRem, %%mm3 \n\t" /* shift last 3 bytes to 1st */ - /* 3 bytes */ - /* pav = p - a = (a + b - c) - a = b - c */ - "movq %%mm2, %%mm4 \n\t" - "punpcklbw %%mm0, %%mm3 \n\t" /* unpack High bytes of c */ - /* pbv = p - b = (a + b - c) - b = a - c */ - "movq %%mm1, %%mm5 \n\t" - "psubw %%mm3, %%mm4 \n\t" - "pxor %%mm7, %%mm7 \n\t" - /* pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv */ - "movq %%mm4, %%mm6 \n\t" - "psubw %%mm3, %%mm5 \n\t" - - /* pa = abs(p-a) = abs(pav) */ - /* pb = abs(p-b) = abs(pbv) */ - /* pc = abs(p-c) = abs(pcv) */ - "pcmpgtw %%mm4, %%mm0 \n\t" /* create mask pav bytes < 0 */ - "paddw %%mm5, %%mm6 \n\t" - "pand %%mm4, %%mm0 \n\t" /* only pav bytes < 0 in mm7 */ - "pcmpgtw %%mm5, %%mm7 \n\t" /* create mask pbv bytes < 0 */ - "psubw %%mm0, %%mm4 \n\t" - "pand %%mm5, %%mm7 \n\t" /* only pbv bytes < 0 in mm0 */ - "psubw %%mm0, %%mm4 \n\t" - "psubw %%mm7, %%mm5 \n\t" - "pxor %%mm0, %%mm0 \n\t" - "pcmpgtw %%mm6, %%mm0 \n\t" /* create mask pcv bytes < 0 */ - "pand %%mm6, %%mm0 \n\t" /* only pav bytes < 0 in mm7 */ - "psubw %%mm7, %%mm5 \n\t" - "psubw %%mm0, %%mm6 \n\t" - /* test pa <= pb */ - "movq %%mm4, %%mm7 \n\t" - "psubw %%mm0, %%mm6 \n\t" - "pcmpgtw %%mm5, %%mm7 \n\t" /* pa > pb? */ - "movq %%mm7, %%mm0 \n\t" - /* use mm7 mask to merge pa & pb */ - "pand %%mm7, %%mm5 \n\t" - /* use mm0 mask copy to merge a & b */ - "pand %%mm0, %%mm2 \n\t" - "pandn %%mm4, %%mm7 \n\t" - "pandn %%mm1, %%mm0 \n\t" - "paddw %%mm5, %%mm7 \n\t" - "paddw %%mm2, %%mm0 \n\t" - /* test ((pa <= pb)? pa:pb) <= pc */ - "pcmpgtw %%mm6, %%mm7 \n\t" /* pab > pc? */ - "pxor %%mm1, %%mm1 \n\t" - "pand %%mm7, %%mm3 \n\t" - "pandn %%mm0, %%mm7 \n\t" - "paddw %%mm3, %%mm7 \n\t" - "pxor %%mm0, %%mm0 \n\t" - "packuswb %%mm1, %%mm7 \n\t" - "movq (%%esi,%%ecx,), %%mm3 \n\t" /* load c=Prior(x-bpp) */ - "pand _ActiveMask, %%mm7 \n\t" - "movq %%mm3, %%mm2 \n\t" /* load b=Prior(x) step 1 */ - "paddb (%%edi,%%ecx,), %%mm7 \n\t" /* add Paeth predictor with Raw(x) */ - "punpcklbw %%mm0, %%mm3 \n\t" /* unpack High bytes of c */ - "movq %%mm7, (%%edi,%%ecx,) \n\t" /* write back updated value */ - "movq %%mm7, %%mm1 \n\t" /* now mm1 will be used as */ - /* Raw(x-bpp) */ - /* now do Paeth for 2nd set of bytes (3-5) */ - "psrlq _ShiftBpp, %%mm2 \n\t" /* load b=Prior(x) step 2 */ - "punpcklbw %%mm0, %%mm1 \n\t" /* unpack High bytes of a */ - "pxor %%mm7, %%mm7 \n\t" - "punpcklbw %%mm0, %%mm2 \n\t" /* unpack High bytes of b */ - /* pbv = p - b = (a + b - c) - b = a - c */ - "movq %%mm1, %%mm5 \n\t" - /* pav = p - a = (a + b - c) - a = b - c */ - "movq %%mm2, %%mm4 \n\t" - "psubw %%mm3, %%mm5 \n\t" - "psubw %%mm3, %%mm4 \n\t" - /* pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = */ - /* pav + pbv = pbv + pav */ - "movq %%mm5, %%mm6 \n\t" - "paddw %%mm4, %%mm6 \n\t" - - /* pa = abs(p-a) = abs(pav) */ - /* pb = abs(p-b) = abs(pbv) */ - /* pc = abs(p-c) = abs(pcv) */ - "pcmpgtw %%mm5, %%mm0 \n\t" /* create mask pbv bytes < 0 */ - "pcmpgtw %%mm4, %%mm7 \n\t" /* create mask pav bytes < 0 */ - "pand %%mm5, %%mm0 \n\t" /* only pbv bytes < 0 in mm0 */ - "pand %%mm4, %%mm7 \n\t" /* only pav bytes < 0 in mm7 */ - "psubw %%mm0, %%mm5 \n\t" - "psubw %%mm7, %%mm4 \n\t" - "psubw %%mm0, %%mm5 \n\t" - "psubw %%mm7, %%mm4 \n\t" - "pxor %%mm0, %%mm0 \n\t" - "pcmpgtw %%mm6, %%mm0 \n\t" /* create mask pcv bytes < 0 */ - "pand %%mm6, %%mm0 \n\t" /* only pav bytes < 0 in mm7 */ - "psubw %%mm0, %%mm6 \n\t" - /* test pa <= pb */ - "movq %%mm4, %%mm7 \n\t" - "psubw %%mm0, %%mm6 \n\t" - "pcmpgtw %%mm5, %%mm7 \n\t" /* pa > pb? */ - "movq %%mm7, %%mm0 \n\t" - /* use mm7 mask to merge pa & pb */ - "pand %%mm7, %%mm5 \n\t" - /* use mm0 mask copy to merge a & b */ - "pand %%mm0, %%mm2 \n\t" - "pandn %%mm4, %%mm7 \n\t" - "pandn %%mm1, %%mm0 \n\t" - "paddw %%mm5, %%mm7 \n\t" - "paddw %%mm2, %%mm0 \n\t" - /* test ((pa <= pb)? pa:pb) <= pc */ - "pcmpgtw %%mm6, %%mm7 \n\t" /* pab > pc? */ - "movq (%%esi,%%ecx,), %%mm2 \n\t" /* load b=Prior(x) */ - "pand %%mm7, %%mm3 \n\t" - "pandn %%mm0, %%mm7 \n\t" - "pxor %%mm1, %%mm1 \n\t" - "paddw %%mm3, %%mm7 \n\t" - "pxor %%mm0, %%mm0 \n\t" - "packuswb %%mm1, %%mm7 \n\t" - "movq %%mm2, %%mm3 \n\t" /* load c=Prior(x-bpp) step 1 */ - "pand _ActiveMask, %%mm7 \n\t" - "punpckhbw %%mm0, %%mm2 \n\t" /* unpack High bytes of b */ - "psllq _ShiftBpp, %%mm7 \n\t" /* shift bytes to 2nd group of */ - /* 3 bytes */ - /* pav = p - a = (a + b - c) - a = b - c */ - "movq %%mm2, %%mm4 \n\t" - "paddb (%%edi,%%ecx,), %%mm7 \n\t" /* add Paeth predictor with Raw(x) */ - "psllq _ShiftBpp, %%mm3 \n\t" /* load c=Prior(x-bpp) step 2 */ - "movq %%mm7, (%%edi,%%ecx,) \n\t" /* write back updated value */ - "movq %%mm7, %%mm1 \n\t" - "punpckhbw %%mm0, %%mm3 \n\t" /* unpack High bytes of c */ - "psllq _ShiftBpp, %%mm1 \n\t" /* shift bytes */ - /* now mm1 will be used as Raw(x-bpp) */ - /* now do Paeth for 3rd, and final, set of bytes (6-7) */ - "pxor %%mm7, %%mm7 \n\t" - "punpckhbw %%mm0, %%mm1 \n\t" /* unpack High bytes of a */ - "psubw %%mm3, %%mm4 \n\t" - /* pbv = p - b = (a + b - c) - b = a - c */ - "movq %%mm1, %%mm5 \n\t" - /* pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv */ - "movq %%mm4, %%mm6 \n\t" - "psubw %%mm3, %%mm5 \n\t" - "pxor %%mm0, %%mm0 \n\t" - "paddw %%mm5, %%mm6 \n\t" - - /* pa = abs(p-a) = abs(pav) */ - /* pb = abs(p-b) = abs(pbv) */ - /* pc = abs(p-c) = abs(pcv) */ - "pcmpgtw %%mm4, %%mm0 \n\t" /* create mask pav bytes < 0 */ - "pcmpgtw %%mm5, %%mm7 \n\t" /* create mask pbv bytes < 0 */ - "pand %%mm4, %%mm0 \n\t" /* only pav bytes < 0 in mm7 */ - "pand %%mm5, %%mm7 \n\t" /* only pbv bytes < 0 in mm0 */ - "psubw %%mm0, %%mm4 \n\t" - "psubw %%mm7, %%mm5 \n\t" - "psubw %%mm0, %%mm4 \n\t" - "psubw %%mm7, %%mm5 \n\t" - "pxor %%mm0, %%mm0 \n\t" - "pcmpgtw %%mm6, %%mm0 \n\t" /* create mask pcv bytes < 0 */ - "pand %%mm6, %%mm0 \n\t" /* only pav bytes < 0 in mm7 */ - "psubw %%mm0, %%mm6 \n\t" - /* test pa <= pb */ - "movq %%mm4, %%mm7 \n\t" - "psubw %%mm0, %%mm6 \n\t" - "pcmpgtw %%mm5, %%mm7 \n\t" /* pa > pb? */ - "movq %%mm7, %%mm0 \n\t" - /* use mm0 mask copy to merge a & b */ - "pand %%mm0, %%mm2 \n\t" - /* use mm7 mask to merge pa & pb */ - "pand %%mm7, %%mm5 \n\t" - "pandn %%mm1, %%mm0 \n\t" - "pandn %%mm4, %%mm7 \n\t" - "paddw %%mm2, %%mm0 \n\t" - "paddw %%mm5, %%mm7 \n\t" - /* test ((pa <= pb)? pa:pb) <= pc */ - "pcmpgtw %%mm6, %%mm7 \n\t" /* pab > pc? */ - "pand %%mm7, %%mm3 \n\t" - "pandn %%mm0, %%mm7 \n\t" - "paddw %%mm3, %%mm7 \n\t" - "pxor %%mm1, %%mm1 \n\t" - "packuswb %%mm7, %%mm1 \n\t" - /* step ecx to next set of 8 bytes and repeat loop til done */ - "addl $8, %%ecx \n\t" - "pand _ActiveMaskEnd, %%mm1 \n\t" - "paddb -8(%%edi,%%ecx,), %%mm1 \n\t" /* add Paeth predictor with */ - /* Raw(x) */ - - "cmpl _MMXLength, %%ecx \n\t" - "pxor %%mm0, %%mm0 \n\t" /* pxor does not affect flags */ - "movq %%mm1, -8(%%edi,%%ecx,) \n\t" /* write back updated value */ - /* mm1 will be used as Raw(x-bpp) next loop */ - /* mm3 ready to be used as Prior(x-bpp) next loop */ - "jb paeth_3lp \n\t" - - : "=S" (dummy_value_S), /* output regs (dummy) */ - "=D" (dummy_value_D) - - : "0" (prev_row), /* esi // input regs */ - "1" (row) /* edi */ - - : "%ecx" /* clobber list */ -#if 0 /* %mm0, ..., %mm7 not supported by gcc 2.7.2.3 or egcs 1.1 */ - , "%mm0", "%mm1", "%mm2", "%mm3" - , "%mm4", "%mm5", "%mm6", "%mm7" -#endif - ); - } - break; /* end 3 bpp */ - - case 6: - //case 7: /* GRR BOGUS */ - //case 5: /* GRR BOGUS */ - { - _ActiveMask.use = 0x00000000ffffffffLL; - _ActiveMask2.use = 0xffffffff00000000LL; - _ShiftBpp.use = bpp << 3; /* == bpp * 8 */ - _ShiftRem.use = 64 - _ShiftBpp.use; - - __asm__ __volatile__ ( - "movl _dif, %%ecx \n\t" -/* preload "movl row, %%edi \n\t" */ -/* preload "movl prev_row, %%esi \n\t" */ - /* prime the pump: load the first Raw(x-bpp) data set */ - "movq -8(%%edi,%%ecx,), %%mm1 \n\t" - "pxor %%mm0, %%mm0 \n\t" - - "paeth_6lp: \n\t" - /* must shift to position Raw(x-bpp) data */ - "psrlq _ShiftRem, %%mm1 \n\t" - /* do first set of 4 bytes */ - "movq -8(%%esi,%%ecx,), %%mm3 \n\t" /* read c=Prior(x-bpp) bytes */ - "punpcklbw %%mm0, %%mm1 \n\t" /* unpack Low bytes of a */ - "movq (%%esi,%%ecx,), %%mm2 \n\t" /* load b=Prior(x) */ - "punpcklbw %%mm0, %%mm2 \n\t" /* unpack Low bytes of b */ - /* must shift to position Prior(x-bpp) data */ - "psrlq _ShiftRem, %%mm3 \n\t" - /* pav = p - a = (a + b - c) - a = b - c */ - "movq %%mm2, %%mm4 \n\t" - "punpcklbw %%mm0, %%mm3 \n\t" /* unpack Low bytes of c */ - /* pbv = p - b = (a + b - c) - b = a - c */ - "movq %%mm1, %%mm5 \n\t" - "psubw %%mm3, %%mm4 \n\t" - "pxor %%mm7, %%mm7 \n\t" - /* pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv */ - "movq %%mm4, %%mm6 \n\t" - "psubw %%mm3, %%mm5 \n\t" - /* pa = abs(p-a) = abs(pav) */ - /* pb = abs(p-b) = abs(pbv) */ - /* pc = abs(p-c) = abs(pcv) */ - "pcmpgtw %%mm4, %%mm0 \n\t" /* create mask pav bytes < 0 */ - "paddw %%mm5, %%mm6 \n\t" - "pand %%mm4, %%mm0 \n\t" /* only pav bytes < 0 in mm7 */ - "pcmpgtw %%mm5, %%mm7 \n\t" /* create mask pbv bytes < 0 */ - "psubw %%mm0, %%mm4 \n\t" - "pand %%mm5, %%mm7 \n\t" /* only pbv bytes < 0 in mm0 */ - "psubw %%mm0, %%mm4 \n\t" - "psubw %%mm7, %%mm5 \n\t" - "pxor %%mm0, %%mm0 \n\t" - "pcmpgtw %%mm6, %%mm0 \n\t" /* create mask pcv bytes < 0 */ - "pand %%mm6, %%mm0 \n\t" /* only pav bytes < 0 in mm7 */ - "psubw %%mm7, %%mm5 \n\t" - "psubw %%mm0, %%mm6 \n\t" - /* test pa <= pb */ - "movq %%mm4, %%mm7 \n\t" - "psubw %%mm0, %%mm6 \n\t" - "pcmpgtw %%mm5, %%mm7 \n\t" /* pa > pb? */ - "movq %%mm7, %%mm0 \n\t" - /* use mm7 mask to merge pa & pb */ - "pand %%mm7, %%mm5 \n\t" - /* use mm0 mask copy to merge a & b */ - "pand %%mm0, %%mm2 \n\t" - "pandn %%mm4, %%mm7 \n\t" - "pandn %%mm1, %%mm0 \n\t" - "paddw %%mm5, %%mm7 \n\t" - "paddw %%mm2, %%mm0 \n\t" - /* test ((pa <= pb)? pa:pb) <= pc */ - "pcmpgtw %%mm6, %%mm7 \n\t" /* pab > pc? */ - "pxor %%mm1, %%mm1 \n\t" - "pand %%mm7, %%mm3 \n\t" - "pandn %%mm0, %%mm7 \n\t" - "paddw %%mm3, %%mm7 \n\t" - "pxor %%mm0, %%mm0 \n\t" - "packuswb %%mm1, %%mm7 \n\t" - "movq -8(%%esi,%%ecx,), %%mm3 \n\t" /* load c=Prior(x-bpp) */ - "pand _ActiveMask, %%mm7 \n\t" - "psrlq _ShiftRem, %%mm3 \n\t" - "movq (%%esi,%%ecx,), %%mm2 \n\t" /* load b=Prior(x) step 1 */ - "paddb (%%edi,%%ecx,), %%mm7 \n\t" /* add Paeth predictor and Raw(x) */ - "movq %%mm2, %%mm6 \n\t" - "movq %%mm7, (%%edi,%%ecx,) \n\t" /* write back updated value */ - "movq -8(%%edi,%%ecx,), %%mm1 \n\t" - "psllq _ShiftBpp, %%mm6 \n\t" - "movq %%mm7, %%mm5 \n\t" - "psrlq _ShiftRem, %%mm1 \n\t" - "por %%mm6, %%mm3 \n\t" - "psllq _ShiftBpp, %%mm5 \n\t" - "punpckhbw %%mm0, %%mm3 \n\t" /* unpack High bytes of c */ - "por %%mm5, %%mm1 \n\t" - /* do second set of 4 bytes */ - "punpckhbw %%mm0, %%mm2 \n\t" /* unpack High bytes of b */ - "punpckhbw %%mm0, %%mm1 \n\t" /* unpack High bytes of a */ - /* pav = p - a = (a + b - c) - a = b - c */ - "movq %%mm2, %%mm4 \n\t" - /* pbv = p - b = (a + b - c) - b = a - c */ - "movq %%mm1, %%mm5 \n\t" - "psubw %%mm3, %%mm4 \n\t" - "pxor %%mm7, %%mm7 \n\t" - /* pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv */ - "movq %%mm4, %%mm6 \n\t" - "psubw %%mm3, %%mm5 \n\t" - /* pa = abs(p-a) = abs(pav) */ - /* pb = abs(p-b) = abs(pbv) */ - /* pc = abs(p-c) = abs(pcv) */ - "pcmpgtw %%mm4, %%mm0 \n\t" /* create mask pav bytes < 0 */ - "paddw %%mm5, %%mm6 \n\t" - "pand %%mm4, %%mm0 \n\t" /* only pav bytes < 0 in mm7 */ - "pcmpgtw %%mm5, %%mm7 \n\t" /* create mask pbv bytes < 0 */ - "psubw %%mm0, %%mm4 \n\t" - "pand %%mm5, %%mm7 \n\t" /* only pbv bytes < 0 in mm0 */ - "psubw %%mm0, %%mm4 \n\t" - "psubw %%mm7, %%mm5 \n\t" - "pxor %%mm0, %%mm0 \n\t" - "pcmpgtw %%mm6, %%mm0 \n\t" /* create mask pcv bytes < 0 */ - "pand %%mm6, %%mm0 \n\t" /* only pav bytes < 0 in mm7 */ - "psubw %%mm7, %%mm5 \n\t" - "psubw %%mm0, %%mm6 \n\t" - /* test pa <= pb */ - "movq %%mm4, %%mm7 \n\t" - "psubw %%mm0, %%mm6 \n\t" - "pcmpgtw %%mm5, %%mm7 \n\t" /* pa > pb? */ - "movq %%mm7, %%mm0 \n\t" - /* use mm7 mask to merge pa & pb */ - "pand %%mm7, %%mm5 \n\t" - /* use mm0 mask copy to merge a & b */ - "pand %%mm0, %%mm2 \n\t" - "pandn %%mm4, %%mm7 \n\t" - "pandn %%mm1, %%mm0 \n\t" - "paddw %%mm5, %%mm7 \n\t" - "paddw %%mm2, %%mm0 \n\t" - /* test ((pa <= pb)? pa:pb) <= pc */ - "pcmpgtw %%mm6, %%mm7 \n\t" /* pab > pc? */ - "pxor %%mm1, %%mm1 \n\t" - "pand %%mm7, %%mm3 \n\t" - "pandn %%mm0, %%mm7 \n\t" - "pxor %%mm1, %%mm1 \n\t" - "paddw %%mm3, %%mm7 \n\t" - "pxor %%mm0, %%mm0 \n\t" - /* step ecx to next set of 8 bytes and repeat loop til done */ - "addl $8, %%ecx \n\t" - "packuswb %%mm7, %%mm1 \n\t" - "paddb -8(%%edi,%%ecx,), %%mm1 \n\t" /* add Paeth predictor with Raw(x) */ - "cmpl _MMXLength, %%ecx \n\t" - "movq %%mm1, -8(%%edi,%%ecx,) \n\t" /* write back updated value */ - /* mm1 will be used as Raw(x-bpp) next loop */ - "jb paeth_6lp \n\t" - - : "=S" (dummy_value_S), /* output regs (dummy) */ - "=D" (dummy_value_D) - - : "0" (prev_row), /* esi // input regs */ - "1" (row) /* edi */ - - : "%ecx" /* clobber list */ -#if 0 /* %mm0, ..., %mm7 not supported by gcc 2.7.2.3 or egcs 1.1 */ - , "%mm0", "%mm1", "%mm2", "%mm3" - , "%mm4", "%mm5", "%mm6", "%mm7" -#endif - ); - } - break; /* end 6 bpp */ - - case 4: - { - _ActiveMask.use = 0x00000000ffffffffLL; - - __asm__ __volatile__ ( - "movl _dif, %%ecx \n\t" -/* preload "movl row, %%edi \n\t" */ -/* preload "movl prev_row, %%esi \n\t" */ - "pxor %%mm0, %%mm0 \n\t" - /* prime the pump: load the first Raw(x-bpp) data set */ - "movq -8(%%edi,%%ecx,), %%mm1 \n\t" /* only time should need to read */ - /* a=Raw(x-bpp) bytes */ - "paeth_4lp: \n\t" - /* do first set of 4 bytes */ - "movq -8(%%esi,%%ecx,), %%mm3 \n\t" /* read c=Prior(x-bpp) bytes */ - "punpckhbw %%mm0, %%mm1 \n\t" /* unpack Low bytes of a */ - "movq (%%esi,%%ecx,), %%mm2 \n\t" /* load b=Prior(x) */ - "punpcklbw %%mm0, %%mm2 \n\t" /* unpack High bytes of b */ - /* pav = p - a = (a + b - c) - a = b - c */ - "movq %%mm2, %%mm4 \n\t" - "punpckhbw %%mm0, %%mm3 \n\t" /* unpack High bytes of c */ - /* pbv = p - b = (a + b - c) - b = a - c */ - "movq %%mm1, %%mm5 \n\t" - "psubw %%mm3, %%mm4 \n\t" - "pxor %%mm7, %%mm7 \n\t" - /* pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv */ - "movq %%mm4, %%mm6 \n\t" - "psubw %%mm3, %%mm5 \n\t" - /* pa = abs(p-a) = abs(pav) */ - /* pb = abs(p-b) = abs(pbv) */ - /* pc = abs(p-c) = abs(pcv) */ - "pcmpgtw %%mm4, %%mm0 \n\t" /* create mask pav bytes < 0 */ - "paddw %%mm5, %%mm6 \n\t" - "pand %%mm4, %%mm0 \n\t" /* only pav bytes < 0 in mm7 */ - "pcmpgtw %%mm5, %%mm7 \n\t" /* create mask pbv bytes < 0 */ - "psubw %%mm0, %%mm4 \n\t" - "pand %%mm5, %%mm7 \n\t" /* only pbv bytes < 0 in mm0 */ - "psubw %%mm0, %%mm4 \n\t" - "psubw %%mm7, %%mm5 \n\t" - "pxor %%mm0, %%mm0 \n\t" - "pcmpgtw %%mm6, %%mm0 \n\t" /* create mask pcv bytes < 0 */ - "pand %%mm6, %%mm0 \n\t" /* only pav bytes < 0 in mm7 */ - "psubw %%mm7, %%mm5 \n\t" - "psubw %%mm0, %%mm6 \n\t" - /* test pa <= pb */ - "movq %%mm4, %%mm7 \n\t" - "psubw %%mm0, %%mm6 \n\t" - "pcmpgtw %%mm5, %%mm7 \n\t" /* pa > pb? */ - "movq %%mm7, %%mm0 \n\t" - /* use mm7 mask to merge pa & pb */ - "pand %%mm7, %%mm5 \n\t" - /* use mm0 mask copy to merge a & b */ - "pand %%mm0, %%mm2 \n\t" - "pandn %%mm4, %%mm7 \n\t" - "pandn %%mm1, %%mm0 \n\t" - "paddw %%mm5, %%mm7 \n\t" - "paddw %%mm2, %%mm0 \n\t" - /* test ((pa <= pb)? pa:pb) <= pc */ - "pcmpgtw %%mm6, %%mm7 \n\t" /* pab > pc? */ - "pxor %%mm1, %%mm1 \n\t" - "pand %%mm7, %%mm3 \n\t" - "pandn %%mm0, %%mm7 \n\t" - "paddw %%mm3, %%mm7 \n\t" - "pxor %%mm0, %%mm0 \n\t" - "packuswb %%mm1, %%mm7 \n\t" - "movq (%%esi,%%ecx,), %%mm3 \n\t" /* load c=Prior(x-bpp) */ - "pand _ActiveMask, %%mm7 \n\t" - "movq %%mm3, %%mm2 \n\t" /* load b=Prior(x) step 1 */ - "paddb (%%edi,%%ecx,), %%mm7 \n\t" /* add Paeth predictor with Raw(x) */ - "punpcklbw %%mm0, %%mm3 \n\t" /* unpack High bytes of c */ - "movq %%mm7, (%%edi,%%ecx,) \n\t" /* write back updated value */ - "movq %%mm7, %%mm1 \n\t" /* now mm1 will be used as Raw(x-bpp) */ - /* do second set of 4 bytes */ - "punpckhbw %%mm0, %%mm2 \n\t" /* unpack Low bytes of b */ - "punpcklbw %%mm0, %%mm1 \n\t" /* unpack Low bytes of a */ - /* pav = p - a = (a + b - c) - a = b - c */ - "movq %%mm2, %%mm4 \n\t" - /* pbv = p - b = (a + b - c) - b = a - c */ - "movq %%mm1, %%mm5 \n\t" - "psubw %%mm3, %%mm4 \n\t" - "pxor %%mm7, %%mm7 \n\t" - /* pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv */ - "movq %%mm4, %%mm6 \n\t" - "psubw %%mm3, %%mm5 \n\t" - /* pa = abs(p-a) = abs(pav) */ - /* pb = abs(p-b) = abs(pbv) */ - /* pc = abs(p-c) = abs(pcv) */ - "pcmpgtw %%mm4, %%mm0 \n\t" /* create mask pav bytes < 0 */ - "paddw %%mm5, %%mm6 \n\t" - "pand %%mm4, %%mm0 \n\t" /* only pav bytes < 0 in mm7 */ - "pcmpgtw %%mm5, %%mm7 \n\t" /* create mask pbv bytes < 0 */ - "psubw %%mm0, %%mm4 \n\t" - "pand %%mm5, %%mm7 \n\t" /* only pbv bytes < 0 in mm0 */ - "psubw %%mm0, %%mm4 \n\t" - "psubw %%mm7, %%mm5 \n\t" - "pxor %%mm0, %%mm0 \n\t" - "pcmpgtw %%mm6, %%mm0 \n\t" /* create mask pcv bytes < 0 */ - "pand %%mm6, %%mm0 \n\t" /* only pav bytes < 0 in mm7 */ - "psubw %%mm7, %%mm5 \n\t" - "psubw %%mm0, %%mm6 \n\t" - /* test pa <= pb */ - "movq %%mm4, %%mm7 \n\t" - "psubw %%mm0, %%mm6 \n\t" - "pcmpgtw %%mm5, %%mm7 \n\t" /* pa > pb? */ - "movq %%mm7, %%mm0 \n\t" - /* use mm7 mask to merge pa & pb */ - "pand %%mm7, %%mm5 \n\t" - /* use mm0 mask copy to merge a & b */ - "pand %%mm0, %%mm2 \n\t" - "pandn %%mm4, %%mm7 \n\t" - "pandn %%mm1, %%mm0 \n\t" - "paddw %%mm5, %%mm7 \n\t" - "paddw %%mm2, %%mm0 \n\t" - /* test ((pa <= pb)? pa:pb) <= pc */ - "pcmpgtw %%mm6, %%mm7 \n\t" /* pab > pc? */ - "pxor %%mm1, %%mm1 \n\t" - "pand %%mm7, %%mm3 \n\t" - "pandn %%mm0, %%mm7 \n\t" - "pxor %%mm1, %%mm1 \n\t" - "paddw %%mm3, %%mm7 \n\t" - "pxor %%mm0, %%mm0 \n\t" - /* step ecx to next set of 8 bytes and repeat loop til done */ - "addl $8, %%ecx \n\t" - "packuswb %%mm7, %%mm1 \n\t" - "paddb -8(%%edi,%%ecx,), %%mm1 \n\t" /* add predictor with Raw(x) */ - "cmpl _MMXLength, %%ecx \n\t" - "movq %%mm1, -8(%%edi,%%ecx,) \n\t" /* write back updated value */ - /* mm1 will be used as Raw(x-bpp) next loop */ - "jb paeth_4lp \n\t" - - : "=S" (dummy_value_S), /* output regs (dummy) */ - "=D" (dummy_value_D) - - : "0" (prev_row), /* esi // input regs */ - "1" (row) /* edi */ - - : "%ecx" /* clobber list */ -#if 0 /* %mm0, ..., %mm7 not supported by gcc 2.7.2.3 or egcs 1.1 */ - , "%mm0", "%mm1", "%mm2", "%mm3" - , "%mm4", "%mm5", "%mm6", "%mm7" -#endif - ); - } - break; /* end 4 bpp */ - - case 8: /* bpp == 8 */ - { - _ActiveMask.use = 0x00000000ffffffffLL; - - __asm__ __volatile__ ( - "movl _dif, %%ecx \n\t" -/* preload "movl row, %%edi \n\t" */ -/* preload "movl prev_row, %%esi \n\t" */ - "pxor %%mm0, %%mm0 \n\t" - /* prime the pump: load the first Raw(x-bpp) data set */ - "movq -8(%%edi,%%ecx,), %%mm1 \n\t" /* only time should need to read */ - /* a=Raw(x-bpp) bytes */ - "paeth_8lp: \n\t" - /* do first set of 4 bytes */ - "movq -8(%%esi,%%ecx,), %%mm3 \n\t" /* read c=Prior(x-bpp) bytes */ - "punpcklbw %%mm0, %%mm1 \n\t" /* unpack Low bytes of a */ - "movq (%%esi,%%ecx,), %%mm2 \n\t" /* load b=Prior(x) */ - "punpcklbw %%mm0, %%mm2 \n\t" /* unpack Low bytes of b */ - /* pav = p - a = (a + b - c) - a = b - c */ - "movq %%mm2, %%mm4 \n\t" - "punpcklbw %%mm0, %%mm3 \n\t" /* unpack Low bytes of c */ - /* pbv = p - b = (a + b - c) - b = a - c */ - "movq %%mm1, %%mm5 \n\t" - "psubw %%mm3, %%mm4 \n\t" - "pxor %%mm7, %%mm7 \n\t" - /* pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv */ - "movq %%mm4, %%mm6 \n\t" - "psubw %%mm3, %%mm5 \n\t" - /* pa = abs(p-a) = abs(pav) */ - /* pb = abs(p-b) = abs(pbv) */ - /* pc = abs(p-c) = abs(pcv) */ - "pcmpgtw %%mm4, %%mm0 \n\t" /* create mask pav bytes < 0 */ - "paddw %%mm5, %%mm6 \n\t" - "pand %%mm4, %%mm0 \n\t" /* only pav bytes < 0 in mm7 */ - "pcmpgtw %%mm5, %%mm7 \n\t" /* create mask pbv bytes < 0 */ - "psubw %%mm0, %%mm4 \n\t" - "pand %%mm5, %%mm7 \n\t" /* only pbv bytes < 0 in mm0 */ - "psubw %%mm0, %%mm4 \n\t" - "psubw %%mm7, %%mm5 \n\t" - "pxor %%mm0, %%mm0 \n\t" - "pcmpgtw %%mm6, %%mm0 \n\t" /* create mask pcv bytes < 0 */ - "pand %%mm6, %%mm0 \n\t" /* only pav bytes < 0 in mm7 */ - "psubw %%mm7, %%mm5 \n\t" - "psubw %%mm0, %%mm6 \n\t" - /* test pa <= pb */ - "movq %%mm4, %%mm7 \n\t" - "psubw %%mm0, %%mm6 \n\t" - "pcmpgtw %%mm5, %%mm7 \n\t" /* pa > pb? */ - "movq %%mm7, %%mm0 \n\t" - /* use mm7 mask to merge pa & pb */ - "pand %%mm7, %%mm5 \n\t" - /* use mm0 mask copy to merge a & b */ - "pand %%mm0, %%mm2 \n\t" - "pandn %%mm4, %%mm7 \n\t" - "pandn %%mm1, %%mm0 \n\t" - "paddw %%mm5, %%mm7 \n\t" - "paddw %%mm2, %%mm0 \n\t" - /* test ((pa <= pb)? pa:pb) <= pc */ - "pcmpgtw %%mm6, %%mm7 \n\t" /* pab > pc? */ - "pxor %%mm1, %%mm1 \n\t" - "pand %%mm7, %%mm3 \n\t" - "pandn %%mm0, %%mm7 \n\t" - "paddw %%mm3, %%mm7 \n\t" - "pxor %%mm0, %%mm0 \n\t" - "packuswb %%mm1, %%mm7 \n\t" - "movq -8(%%esi,%%ecx,), %%mm3 \n\t" /* read c=Prior(x-bpp) bytes */ - "pand _ActiveMask, %%mm7 \n\t" - "movq (%%esi,%%ecx,), %%mm2 \n\t" /* load b=Prior(x) */ - "paddb (%%edi,%%ecx,), %%mm7 \n\t" /* add Paeth predictor with Raw(x) */ - "punpckhbw %%mm0, %%mm3 \n\t" /* unpack High bytes of c */ - "movq %%mm7, (%%edi,%%ecx,) \n\t" /* write back updated value */ - "movq -8(%%edi,%%ecx,), %%mm1 \n\t" /* read a=Raw(x-bpp) bytes */ - - /* do second set of 4 bytes */ - "punpckhbw %%mm0, %%mm2 \n\t" /* unpack High bytes of b */ - "punpckhbw %%mm0, %%mm1 \n\t" /* unpack High bytes of a */ - /* pav = p - a = (a + b - c) - a = b - c */ - "movq %%mm2, %%mm4 \n\t" - /* pbv = p - b = (a + b - c) - b = a - c */ - "movq %%mm1, %%mm5 \n\t" - "psubw %%mm3, %%mm4 \n\t" - "pxor %%mm7, %%mm7 \n\t" - /* pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv */ - "movq %%mm4, %%mm6 \n\t" - "psubw %%mm3, %%mm5 \n\t" - /* pa = abs(p-a) = abs(pav) */ - /* pb = abs(p-b) = abs(pbv) */ - /* pc = abs(p-c) = abs(pcv) */ - "pcmpgtw %%mm4, %%mm0 \n\t" /* create mask pav bytes < 0 */ - "paddw %%mm5, %%mm6 \n\t" - "pand %%mm4, %%mm0 \n\t" /* only pav bytes < 0 in mm7 */ - "pcmpgtw %%mm5, %%mm7 \n\t" /* create mask pbv bytes < 0 */ - "psubw %%mm0, %%mm4 \n\t" - "pand %%mm5, %%mm7 \n\t" /* only pbv bytes < 0 in mm0 */ - "psubw %%mm0, %%mm4 \n\t" - "psubw %%mm7, %%mm5 \n\t" - "pxor %%mm0, %%mm0 \n\t" - "pcmpgtw %%mm6, %%mm0 \n\t" /* create mask pcv bytes < 0 */ - "pand %%mm6, %%mm0 \n\t" /* only pav bytes < 0 in mm7 */ - "psubw %%mm7, %%mm5 \n\t" - "psubw %%mm0, %%mm6 \n\t" - /* test pa <= pb */ - "movq %%mm4, %%mm7 \n\t" - "psubw %%mm0, %%mm6 \n\t" - "pcmpgtw %%mm5, %%mm7 \n\t" /* pa > pb? */ - "movq %%mm7, %%mm0 \n\t" - /* use mm7 mask to merge pa & pb */ - "pand %%mm7, %%mm5 \n\t" - /* use mm0 mask copy to merge a & b */ - "pand %%mm0, %%mm2 \n\t" - "pandn %%mm4, %%mm7 \n\t" - "pandn %%mm1, %%mm0 \n\t" - "paddw %%mm5, %%mm7 \n\t" - "paddw %%mm2, %%mm0 \n\t" - /* test ((pa <= pb)? pa:pb) <= pc */ - "pcmpgtw %%mm6, %%mm7 \n\t" /* pab > pc? */ - "pxor %%mm1, %%mm1 \n\t" - "pand %%mm7, %%mm3 \n\t" - "pandn %%mm0, %%mm7 \n\t" - "pxor %%mm1, %%mm1 \n\t" - "paddw %%mm3, %%mm7 \n\t" - "pxor %%mm0, %%mm0 \n\t" - /* step ecx to next set of 8 bytes and repeat loop til done */ - "addl $8, %%ecx \n\t" - "packuswb %%mm7, %%mm1 \n\t" - "paddb -8(%%edi,%%ecx,), %%mm1 \n\t" /* add Paeth predictor with Raw(x) */ - "cmpl _MMXLength, %%ecx \n\t" - "movq %%mm1, -8(%%edi,%%ecx,) \n\t" /* write back updated value */ - /* mm1 will be used as Raw(x-bpp) next loop */ - "jb paeth_8lp \n\t" - - : "=S" (dummy_value_S), /* output regs (dummy) */ - "=D" (dummy_value_D) - - : "0" (prev_row), /* esi // input regs */ - "1" (row) /* edi */ - - : "%ecx" /* clobber list */ -#if 0 /* %mm0, ..., %mm7 not supported by gcc 2.7.2.3 or egcs 1.1 */ - , "%mm0", "%mm1", "%mm2", "%mm3" - , "%mm4", "%mm5", "%mm6", "%mm7" -#endif - ); - } - break; /* end 8 bpp */ - - case 1: /* bpp = 1 */ - case 2: /* bpp = 2 */ - default: /* bpp > 8 */ - { - __asm__ __volatile__ ( -#ifdef __PIC__ - "pushl %%ebx \n\t" /* save Global Offset Table index */ -#endif - "movl _dif, %%ebx \n\t" - "cmpl _FullLength, %%ebx \n\t" - "jnb paeth_dend \n\t" - -/* preload "movl row, %%edi \n\t" */ -/* preload "movl prev_row, %%esi \n\t" */ - /* do Paeth decode for remaining bytes */ - "movl %%ebx, %%edx \n\t" -/* preload "subl bpp, %%edx \n\t" // (bpp is preloaded into ecx) */ - "subl %%ecx, %%edx \n\t" /* edx = ebx - bpp */ - "xorl %%ecx, %%ecx \n\t" /* zero ecx before using cl & cx */ - - "paeth_dlp: \n\t" - "xorl %%eax, %%eax \n\t" - /* pav = p - a = (a + b - c) - a = b - c */ - "movb (%%esi,%%ebx,), %%al \n\t" /* load Prior(x) into al */ - "movb (%%esi,%%edx,), %%cl \n\t" /* load Prior(x-bpp) into cl */ - "subl %%ecx, %%eax \n\t" /* subtract Prior(x-bpp) */ - "movl %%eax, _patemp \n\t" /* Save pav for later use */ - "xorl %%eax, %%eax \n\t" - /* pbv = p - b = (a + b - c) - b = a - c */ - "movb (%%edi,%%edx,), %%al \n\t" /* load Raw(x-bpp) into al */ - "subl %%ecx, %%eax \n\t" /* subtract Prior(x-bpp) */ - "movl %%eax, %%ecx \n\t" - /* pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv */ - "addl _patemp, %%eax \n\t" /* pcv = pav + pbv */ - /* pc = abs(pcv) */ - "testl $0x80000000, %%eax \n\t" - "jz paeth_dpca \n\t" - "negl %%eax \n\t" /* reverse sign of neg values */ - - "paeth_dpca: \n\t" - "movl %%eax, _pctemp \n\t" /* save pc for later use */ - /* pb = abs(pbv) */ - "testl $0x80000000, %%ecx \n\t" - "jz paeth_dpba \n\t" - "negl %%ecx \n\t" /* reverse sign of neg values */ - - "paeth_dpba: \n\t" - "movl %%ecx, _pbtemp \n\t" /* save pb for later use */ - /* pa = abs(pav) */ - "movl _patemp, %%eax \n\t" - "testl $0x80000000, %%eax \n\t" - "jz paeth_dpaa \n\t" - "negl %%eax \n\t" /* reverse sign of neg values */ - - "paeth_dpaa: \n\t" - "movl %%eax, _patemp \n\t" /* save pa for later use */ - /* test if pa <= pb */ - "cmpl %%ecx, %%eax \n\t" - "jna paeth_dabb \n\t" - /* pa > pb; now test if pb <= pc */ - "cmpl _pctemp, %%ecx \n\t" - "jna paeth_dbbc \n\t" - /* pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp) */ - "movb (%%esi,%%edx,), %%cl \n\t" /* load Prior(x-bpp) into cl */ - "jmp paeth_dpaeth \n\t" - - "paeth_dbbc: \n\t" - /* pb <= pc; Raw(x) = Paeth(x) + Prior(x) */ - "movb (%%esi,%%ebx,), %%cl \n\t" /* load Prior(x) into cl */ - "jmp paeth_dpaeth \n\t" - - "paeth_dabb: \n\t" - /* pa <= pb; now test if pa <= pc */ - "cmpl _pctemp, %%eax \n\t" - "jna paeth_dabc \n\t" - /* pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp) */ - "movb (%%esi,%%edx,), %%cl \n\t" /* load Prior(x-bpp) into cl */ - "jmp paeth_dpaeth \n\t" - - "paeth_dabc: \n\t" - /* pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp) */ - "movb (%%edi,%%edx,), %%cl \n\t" /* load Raw(x-bpp) into cl */ - - "paeth_dpaeth: \n\t" - "incl %%ebx \n\t" - "incl %%edx \n\t" - /* Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256 */ - "addb %%cl, -1(%%edi,%%ebx,) \n\t" - "cmpl _FullLength, %%ebx \n\t" - "jb paeth_dlp \n\t" - - "paeth_dend: \n\t" -#ifdef __PIC__ - "popl %%ebx \n\t" /* index to Global Offset Table */ -#endif - - : "=c" (dummy_value_c), /* output regs (dummy) */ - "=S" (dummy_value_S), - "=D" (dummy_value_D) - - : "0" (bpp), /* ecx // input regs */ - "1" (prev_row), /* esi */ - "2" (row) /* edi */ - - : "%eax", "%edx" /* clobber list */ -#ifndef __PIC__ - , "%ebx" -#endif - ); - } - return; /* No need to go further with this one */ - - } /* end switch (bpp) */ - - __asm__ __volatile__ ( - /* MMX acceleration complete; now do clean-up */ - /* check if any remaining bytes left to decode */ -#ifdef __PIC__ - "pushl %%ebx \n\t" /* save index to Global Offset Table */ -#endif - "movl _MMXLength, %%ebx \n\t" - "cmpl _FullLength, %%ebx \n\t" - "jnb paeth_end \n\t" -/*pre "movl row, %%edi \n\t" */ -/*pre "movl prev_row, %%esi \n\t" */ - /* do Paeth decode for remaining bytes */ - "movl %%ebx, %%edx \n\t" -/*pre "subl bpp, %%edx \n\t" */ /* (bpp is preloaded into ecx) */ - "subl %%ecx, %%edx \n\t" /* edx = ebx - bpp */ - "xorl %%ecx, %%ecx \n\t" /* zero ecx before using cl & cx below */ - - "paeth_lp2: \n\t" - "xorl %%eax, %%eax \n\t" - /* pav = p - a = (a + b - c) - a = b - c */ - "movb (%%esi,%%ebx,), %%al \n\t" /* load Prior(x) into al */ - "movb (%%esi,%%edx,), %%cl \n\t" /* load Prior(x-bpp) into cl */ - "subl %%ecx, %%eax \n\t" /* subtract Prior(x-bpp) */ - "movl %%eax, _patemp \n\t" /* Save pav for later use */ - "xorl %%eax, %%eax \n\t" - /* pbv = p - b = (a + b - c) - b = a - c */ - "movb (%%edi,%%edx,), %%al \n\t" /* load Raw(x-bpp) into al */ - "subl %%ecx, %%eax \n\t" /* subtract Prior(x-bpp) */ - "movl %%eax, %%ecx \n\t" - /* pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv */ - "addl _patemp, %%eax \n\t" /* pcv = pav + pbv */ - /* pc = abs(pcv) */ - "testl $0x80000000, %%eax \n\t" - "jz paeth_pca2 \n\t" - "negl %%eax \n\t" /* reverse sign of neg values */ - - "paeth_pca2: \n\t" - "movl %%eax, _pctemp \n\t" /* save pc for later use */ - /* pb = abs(pbv) */ - "testl $0x80000000, %%ecx \n\t" - "jz paeth_pba2 \n\t" - "negl %%ecx \n\t" /* reverse sign of neg values */ - - "paeth_pba2: \n\t" - "movl %%ecx, _pbtemp \n\t" /* save pb for later use */ - /* pa = abs(pav) */ - "movl _patemp, %%eax \n\t" - "testl $0x80000000, %%eax \n\t" - "jz paeth_paa2 \n\t" - "negl %%eax \n\t" /* reverse sign of neg values */ - - "paeth_paa2: \n\t" - "movl %%eax, _patemp \n\t" /* save pa for later use */ - /* test if pa <= pb */ - "cmpl %%ecx, %%eax \n\t" - "jna paeth_abb2 \n\t" - /* pa > pb; now test if pb <= pc */ - "cmpl _pctemp, %%ecx \n\t" - "jna paeth_bbc2 \n\t" - /* pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp) */ - "movb (%%esi,%%edx,), %%cl \n\t" /* load Prior(x-bpp) into cl */ - "jmp paeth_paeth2 \n\t" - - "paeth_bbc2: \n\t" - /* pb <= pc; Raw(x) = Paeth(x) + Prior(x) */ - "movb (%%esi,%%ebx,), %%cl \n\t" /* load Prior(x) into cl */ - "jmp paeth_paeth2 \n\t" - - "paeth_abb2: \n\t" - /* pa <= pb; now test if pa <= pc */ - "cmpl _pctemp, %%eax \n\t" - "jna paeth_abc2 \n\t" - /* pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp) */ - "movb (%%esi,%%edx,), %%cl \n\t" /* load Prior(x-bpp) into cl */ - "jmp paeth_paeth2 \n\t" - - "paeth_abc2: \n\t" - /* pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp) */ - "movb (%%edi,%%edx,), %%cl \n\t" /* load Raw(x-bpp) into cl */ - - "paeth_paeth2: \n\t" - "incl %%ebx \n\t" - "incl %%edx \n\t" - /* Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256 */ - "addb %%cl, -1(%%edi,%%ebx,) \n\t" - "cmpl _FullLength, %%ebx \n\t" - "jb paeth_lp2 \n\t" - - "paeth_end: \n\t" - "EMMS \n\t" /* end MMX; prep for poss. FP instrs. */ -#ifdef __PIC__ - "popl %%ebx \n\t" /* restore index to Global Offset Table */ -#endif - - : "=c" (dummy_value_c), /* output regs (dummy) */ - "=S" (dummy_value_S), - "=D" (dummy_value_D) - - : "0" (bpp), /* ecx // input regs */ - "1" (prev_row), /* esi */ - "2" (row) /* edi */ - - : "%eax", "%edx" /* clobber list (no input regs!) */ -#ifndef __PIC__ - , "%ebx" -#endif - ); - -} /* end png_read_filter_row_mmx_paeth() */ -#endif - - - - -#ifdef PNG_THREAD_UNSAFE_OK -/*===========================================================================*/ -/* */ -/* P N G _ R E A D _ F I L T E R _ R O W _ M M X _ S U B */ -/* */ -/*===========================================================================*/ - -/* Optimized code for PNG Sub filter decoder */ - -static void /* PRIVATE */ -png_read_filter_row_mmx_sub(png_row_infop row_info, png_bytep row) -{ - int bpp; - int dummy_value_a; - int dummy_value_D; - - bpp = (row_info->pixel_depth + 7) >> 3; /* calc number of bytes per pixel */ - _FullLength = row_info->rowbytes - bpp; /* number of bytes to filter */ - - __asm__ __volatile__ ( -/*pre "movl row, %%edi \n\t" */ - "movl %%edi, %%esi \n\t" /* lp = row */ -/*pre "movl bpp, %%eax \n\t" */ - "addl %%eax, %%edi \n\t" /* rp = row + bpp */ -/*irr "xorl %%eax, %%eax \n\t" */ - /* get # of bytes to alignment */ - "movl %%edi, _dif \n\t" /* take start of row */ - "addl $0xf, _dif \n\t" /* add 7 + 8 to incr past */ - /* alignment boundary */ - "xorl %%ecx, %%ecx \n\t" - "andl $0xfffffff8, _dif \n\t" /* mask to alignment boundary */ - "subl %%edi, _dif \n\t" /* subtract from start ==> value */ - "jz sub_go \n\t" /* ecx at alignment */ - - "sub_lp1: \n\t" /* fix alignment */ - "movb (%%esi,%%ecx,), %%al \n\t" - "addb %%al, (%%edi,%%ecx,) \n\t" - "incl %%ecx \n\t" - "cmpl _dif, %%ecx \n\t" - "jb sub_lp1 \n\t" - - "sub_go: \n\t" - "movl _FullLength, %%eax \n\t" - "movl %%eax, %%edx \n\t" - "subl %%ecx, %%edx \n\t" /* subtract alignment fix */ - "andl $0x00000007, %%edx \n\t" /* calc bytes over mult of 8 */ - "subl %%edx, %%eax \n\t" /* drop over bytes from length */ - "movl %%eax, _MMXLength \n\t" - - : "=a" (dummy_value_a), /* 0 // output regs (dummy) */ - "=D" (dummy_value_D) /* 1 */ - - : "0" (bpp), /* eax // input regs */ - "1" (row) /* edi */ - - : "%esi", "%ecx", "%edx" // clobber list - -#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ - , "%mm0", "%mm1", "%mm2", "%mm3" - , "%mm4", "%mm5", "%mm6", "%mm7" -#endif - ); - - /* now do the math for the rest of the row */ - switch (bpp) - { - case 3: - { - _ActiveMask.use = 0x0000ffffff000000LL; - _ShiftBpp.use = 24; /* == 3 * 8 */ - _ShiftRem.use = 40; /* == 64 - 24 */ - - __asm__ __volatile__ ( -/* preload "movl row, %%edi \n\t" */ - "movq _ActiveMask, %%mm7 \n\t" /* load _ActiveMask for 2nd */ - /* active byte group */ - "movl %%edi, %%esi \n\t" /* lp = row */ -/* preload "movl bpp, %%eax \n\t" */ - "addl %%eax, %%edi \n\t" /* rp = row + bpp */ - "movq %%mm7, %%mm6 \n\t" - "movl _dif, %%edx \n\t" - "psllq _ShiftBpp, %%mm6 \n\t" /* move mask in mm6 to cover */ - /* 3rd active byte group */ - /* prime the pump: load the first Raw(x-bpp) data set */ - "movq -8(%%edi,%%edx,), %%mm1 \n\t" - - "sub_3lp: \n\t" /* shift data for adding first */ - "psrlq _ShiftRem, %%mm1 \n\t" /* bpp bytes (no need for mask; */ - /* shift clears inactive bytes) */ - /* add 1st active group */ - "movq (%%edi,%%edx,), %%mm0 \n\t" - "paddb %%mm1, %%mm0 \n\t" - - /* add 2nd active group */ - "movq %%mm0, %%mm1 \n\t" /* mov updated Raws to mm1 */ - "psllq _ShiftBpp, %%mm1 \n\t" /* shift data to pos. correctly */ - "pand %%mm7, %%mm1 \n\t" /* mask to use 2nd active group */ - "paddb %%mm1, %%mm0 \n\t" - - /* add 3rd active group */ - "movq %%mm0, %%mm1 \n\t" /* mov updated Raws to mm1 */ - "psllq _ShiftBpp, %%mm1 \n\t" /* shift data to pos. correctly */ - "pand %%mm6, %%mm1 \n\t" /* mask to use 3rd active group */ - "addl $8, %%edx \n\t" - "paddb %%mm1, %%mm0 \n\t" - - "cmpl _MMXLength, %%edx \n\t" - "movq %%mm0, -8(%%edi,%%edx,) \n\t" /* write updated Raws to array */ - "movq %%mm0, %%mm1 \n\t" /* prep 1st add at top of loop */ - "jb sub_3lp \n\t" - - : "=a" (dummy_value_a), /* 0 // output regs (dummy) */ - "=D" (dummy_value_D) /* 1 */ - - : "0" (bpp), /* eax // input regs */ - "1" (row) /* edi */ - - : "%edx", "%esi" /* clobber list */ -#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ - , "%mm0", "%mm1", "%mm6", "%mm7" -#endif - ); - } - break; - - case 1: - { - __asm__ __volatile__ ( - "movl _dif, %%edx \n\t" -/* preload "movl row, %%edi \n\t" */ - "cmpl _FullLength, %%edx \n\t" - "jnb sub_1end \n\t" - "movl %%edi, %%esi \n\t" /* lp = row */ - "xorl %%eax, %%eax \n\t" -/* preload "movl bpp, %%eax \n\t" */ - "addl %%eax, %%edi \n\t" /* rp = row + bpp */ - - "sub_1lp: \n\t" - "movb (%%esi,%%edx,), %%al \n\t" - "addb %%al, (%%edi,%%edx,) \n\t" - "incl %%edx \n\t" - "cmpl _FullLength, %%edx \n\t" - "jb sub_1lp \n\t" - - "sub_1end: \n\t" - - : "=a" (dummy_value_a), /* 0 // output regs (dummy) */ - "=D" (dummy_value_D) /* 1 */ - - : "0" (bpp), /* eax // input regs */ - "1" (row) /* edi */ - - : "%edx", "%esi" /* clobber list */ - ); - } - return; - - case 6: - case 4: - //case 7: /* GRR BOGUS */ - //case 5: /* GRR BOGUS */ - { - _ShiftBpp.use = bpp << 3; - _ShiftRem.use = 64 - _ShiftBpp.use; - - __asm__ __volatile__ ( -/* preload "movl row, %%edi \n\t" */ - "movl _dif, %%edx \n\t" - "movl %%edi, %%esi \n\t" /* lp = row */ -/* preload "movl bpp, %%eax \n\t" */ - "addl %%eax, %%edi \n\t" /* rp = row + bpp */ - - /* prime the pump: load the first Raw(x-bpp) data set */ - "movq -8(%%edi,%%edx,), %%mm1 \n\t" - - "sub_4lp: \n\t" /* shift data for adding first */ - "psrlq _ShiftRem, %%mm1 \n\t" /* bpp bytes (no need for mask; */ - /* shift clears inactive bytes) */ - "movq (%%edi,%%edx,), %%mm0 \n\t" - "paddb %%mm1, %%mm0 \n\t" - - /* add 2nd active group */ - "movq %%mm0, %%mm1 \n\t" /* mov updated Raws to mm1 */ - "psllq _ShiftBpp, %%mm1 \n\t" /* shift data to pos. correctly */ - "addl $8, %%edx \n\t" - "paddb %%mm1, %%mm0 \n\t" - - "cmpl _MMXLength, %%edx \n\t" - "movq %%mm0, -8(%%edi,%%edx,) \n\t" - "movq %%mm0, %%mm1 \n\t" /* prep 1st add at top of loop */ - "jb sub_4lp \n\t" - - : "=a" (dummy_value_a), /* 0 // output regs (dummy) */ - "=D" (dummy_value_D) /* 1 */ - - : "0" (bpp), /* eax // input regs */ - "1" (row) /* edi */ - - : "%edx", "%esi" /* clobber list */ -#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ - , "%mm0", "%mm1" -#endif - ); - } - break; - - case 2: - { - _ActiveMask.use = 0x00000000ffff0000LL; - _ShiftBpp.use = 16; /* == 2 * 8 */ - _ShiftRem.use = 48; /* == 64 - 16 */ - - __asm__ __volatile__ ( - "movq _ActiveMask, %%mm7 \n\t" /* load _ActiveMask for 2nd */ - /* active byte group */ - "movl _dif, %%edx \n\t" - "movq %%mm7, %%mm6 \n\t" -/* preload "movl row, %%edi \n\t" */ - "psllq _ShiftBpp, %%mm6 \n\t" /* move mask in mm6 to cover */ - /* 3rd active byte group */ - "movl %%edi, %%esi \n\t" /* lp = row */ - "movq %%mm6, %%mm5 \n\t" -/* preload "movl bpp, %%eax \n\t" */ - "addl %%eax, %%edi \n\t" /* rp = row + bpp */ - "psllq _ShiftBpp, %%mm5 \n\t" /* move mask in mm5 to cover */ - /* 4th active byte group */ - /* prime the pump: load the first Raw(x-bpp) data set */ - "movq -8(%%edi,%%edx,), %%mm1 \n\t" - - "sub_2lp: \n\t" /* shift data for adding first */ - "psrlq _ShiftRem, %%mm1 \n\t" /* bpp bytes (no need for mask; */ - /* shift clears inactive bytes) */ - /* add 1st active group */ - "movq (%%edi,%%edx,), %%mm0 \n\t" - "paddb %%mm1, %%mm0 \n\t" - - /* add 2nd active group */ - "movq %%mm0, %%mm1 \n\t" /* mov updated Raws to mm1 */ - "psllq _ShiftBpp, %%mm1 \n\t" /* shift data to pos. correctly */ - "pand %%mm7, %%mm1 \n\t" /* mask to use 2nd active group */ - "paddb %%mm1, %%mm0 \n\t" - - /* add 3rd active group */ - "movq %%mm0, %%mm1 \n\t" /* mov updated Raws to mm1 */ - "psllq _ShiftBpp, %%mm1 \n\t" /* shift data to pos. correctly */ - "pand %%mm6, %%mm1 \n\t" /* mask to use 3rd active group */ - "paddb %%mm1, %%mm0 \n\t" - - /* add 4th active group */ - "movq %%mm0, %%mm1 \n\t" /* mov updated Raws to mm1 */ - "psllq _ShiftBpp, %%mm1 \n\t" /* shift data to pos. correctly */ - "pand %%mm5, %%mm1 \n\t" /* mask to use 4th active group */ - "addl $8, %%edx \n\t" - "paddb %%mm1, %%mm0 \n\t" - "cmpl _MMXLength, %%edx \n\t" - "movq %%mm0, -8(%%edi,%%edx,) \n\t" /* write updated Raws to array */ - "movq %%mm0, %%mm1 \n\t" /* prep 1st add at top of loop */ - "jb sub_2lp \n\t" - - : "=a" (dummy_value_a), /* 0 // output regs (dummy) */ - "=D" (dummy_value_D) /* 1 */ - - : "0" (bpp), /* eax // input regs */ - "1" (row) /* edi */ - - : "%edx", "%esi" /* clobber list */ -#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ - , "%mm0", "%mm1", "%mm5", "%mm6", "%mm7" -#endif - ); - } - break; - - case 8: - { - __asm__ __volatile__ ( -/* preload "movl row, %%edi \n\t" */ - "movl _dif, %%edx \n\t" - "movl %%edi, %%esi \n\t" /* lp = row */ -/* preload "movl bpp, %%eax \n\t" */ - "addl %%eax, %%edi \n\t" /* rp = row + bpp */ - "movl _MMXLength, %%ecx \n\t" - - /* prime the pump: load the first Raw(x-bpp) data set */ - "movq -8(%%edi,%%edx,), %%mm7 \n\t" - "andl $0x0000003f, %%ecx \n\t" /* calc bytes over mult of 64 */ - - "sub_8lp: \n\t" - "movq (%%edi,%%edx,), %%mm0 \n\t" /* load Sub(x) for 1st 8 bytes */ - "paddb %%mm7, %%mm0 \n\t" - "movq 8(%%edi,%%edx,), %%mm1 \n\t" /* load Sub(x) for 2nd 8 bytes */ - "movq %%mm0, (%%edi,%%edx,) \n\t" /* write Raw(x) for 1st 8 bytes */ - - /* Now mm0 will be used as Raw(x-bpp) for the 2nd group of 8 bytes. */ - /* This will be repeated for each group of 8 bytes with the 8th */ - /* group being used as the Raw(x-bpp) for the 1st group of the */ - /* next loop. */ - - "paddb %%mm0, %%mm1 \n\t" - "movq 16(%%edi,%%edx,), %%mm2 \n\t" /* load Sub(x) for 3rd 8 bytes */ - "movq %%mm1, 8(%%edi,%%edx,) \n\t" /* write Raw(x) for 2nd 8 bytes */ - "paddb %%mm1, %%mm2 \n\t" - "movq 24(%%edi,%%edx,), %%mm3 \n\t" /* load Sub(x) for 4th 8 bytes */ - "movq %%mm2, 16(%%edi,%%edx,) \n\t" /* write Raw(x) for 3rd 8 bytes */ - "paddb %%mm2, %%mm3 \n\t" - "movq 32(%%edi,%%edx,), %%mm4 \n\t" /* load Sub(x) for 5th 8 bytes */ - "movq %%mm3, 24(%%edi,%%edx,) \n\t" /* write Raw(x) for 4th 8 bytes */ - "paddb %%mm3, %%mm4 \n\t" - "movq 40(%%edi,%%edx,), %%mm5 \n\t" /* load Sub(x) for 6th 8 bytes */ - "movq %%mm4, 32(%%edi,%%edx,) \n\t" /* write Raw(x) for 5th 8 bytes */ - "paddb %%mm4, %%mm5 \n\t" - "movq 48(%%edi,%%edx,), %%mm6 \n\t" /* load Sub(x) for 7th 8 bytes */ - "movq %%mm5, 40(%%edi,%%edx,) \n\t" /* write Raw(x) for 6th 8 bytes */ - "paddb %%mm5, %%mm6 \n\t" - "movq 56(%%edi,%%edx,), %%mm7 \n\t" /* load Sub(x) for 8th 8 bytes */ - "movq %%mm6, 48(%%edi,%%edx,) \n\t" /* write Raw(x) for 7th 8 bytes */ - "addl $64, %%edx \n\t" - "paddb %%mm6, %%mm7 \n\t" - "cmpl %%ecx, %%edx \n\t" - "movq %%mm7, -8(%%edi,%%edx,) \n\t" /* write Raw(x) for 8th 8 bytes */ - "jb sub_8lp \n\t" - - "cmpl _MMXLength, %%edx \n\t" - "jnb sub_8lt8 \n\t" - - "sub_8lpA: \n\t" - "movq (%%edi,%%edx,), %%mm0 \n\t" - "addl $8, %%edx \n\t" - "paddb %%mm7, %%mm0 \n\t" - "cmpl _MMXLength, %%edx \n\t" - "movq %%mm0, -8(%%edi,%%edx,) \n\t" /* -8 to offset early addl edx */ - "movq %%mm0, %%mm7 \n\t" /* move calculated Raw(x) data */ - /* to mm1 to be new Raw(x-bpp) */ - /* for next loop */ - "jb sub_8lpA \n\t" - - "sub_8lt8: \n\t" - - : "=a" (dummy_value_a), /* 0 // output regs (dummy) */ - "=D" (dummy_value_D) /* 1 */ - - : "0" (bpp), /* eax // input regs */ - "1" (row) /* edi */ - - : "%ecx", "%edx", "%esi" /* clobber list */ -#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ - , "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7" -#endif - ); - } - break; - - default: /* bpp greater than 8 bytes GRR BOGUS */ - { - __asm__ __volatile__ ( - "movl _dif, %%edx \n\t" -/* preload "movl row, %%edi \n\t" */ - "movl %%edi, %%esi \n\t" /* lp = row */ -/* preload "movl bpp, %%eax \n\t" */ - "addl %%eax, %%edi \n\t" /* rp = row + bpp */ - - "sub_Alp: \n\t" - "movq (%%edi,%%edx,), %%mm0 \n\t" - "movq (%%esi,%%edx,), %%mm1 \n\t" - "addl $8, %%edx \n\t" - "paddb %%mm1, %%mm0 \n\t" - "cmpl _MMXLength, %%edx \n\t" - "movq %%mm0, -8(%%edi,%%edx,) \n\t" /* mov does not affect flags; */ - /* -8 to offset addl edx */ - "jb sub_Alp \n\t" - - : "=a" (dummy_value_a), /* 0 // output regs (dummy) */ - "=D" (dummy_value_D) /* 1 */ - - : "0" (bpp), /* eax // input regs */ - "1" (row) /* edi */ - - : "%edx", "%esi" /* clobber list */ -#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ - , "%mm0", "%mm1" -#endif - ); - } - break; - - } /* end switch (bpp) */ - - __asm__ __volatile__ ( - "movl _MMXLength, %%edx \n\t" -/* pre "movl row, %%edi \n\t" */ - "cmpl _FullLength, %%edx \n\t" - "jnb sub_end \n\t" - - "movl %%edi, %%esi \n\t" /* lp = row */ -/* pre "movl bpp, %%eax \n\t" */ - "addl %%eax, %%edi \n\t" /* rp = row + bpp */ - "xorl %%eax, %%eax \n\t" - - "sub_lp2: \n\t" - "movb (%%esi,%%edx,), %%al \n\t" - "addb %%al, (%%edi,%%edx,) \n\t" - "incl %%edx \n\t" - "cmpl _FullLength, %%edx \n\t" - "jb sub_lp2 \n\t" - - "sub_end: \n\t" - "EMMS \n\t" /* end MMX instructions */ - - : "=a" (dummy_value_a), /* 0 // output regs (dummy) */ - "=D" (dummy_value_D) /* 1 */ - - : "0" (bpp), /* eax // input regs */ - "1" (row) /* edi */ - - : "%edx", "%esi" /* clobber list */ - ); - -} /* end of png_read_filter_row_mmx_sub() */ -#endif - - - - -/*===========================================================================*/ -/* */ -/* P N G _ R E A D _ F I L T E R _ R O W _ M M X _ U P */ -/* */ -/*===========================================================================*/ - -/* Optimized code for PNG Up filter decoder */ - -static void /* PRIVATE */ -png_read_filter_row_mmx_up(png_row_infop row_info, png_bytep row, - png_bytep prev_row) -{ - png_uint_32 len; - int dummy_value_d; /* fix 'forbidden register 3 (dx) was spilled' error */ - int dummy_value_S; - int dummy_value_D; - - len = row_info->rowbytes; /* number of bytes to filter */ - - __asm__ __volatile__ ( -/* pre "movl row, %%edi \n\t" */ - /* get # of bytes to alignment */ -#ifdef __PIC__ - "pushl %%ebx \n\t" -#endif - "movl %%edi, %%ecx \n\t" - "xorl %%ebx, %%ebx \n\t" - "addl $0x7, %%ecx \n\t" - "xorl %%eax, %%eax \n\t" - "andl $0xfffffff8, %%ecx \n\t" -/* pre "movl prev_row, %%esi \n\t" */ - "subl %%edi, %%ecx \n\t" - "jz up_go \n\t" - - "up_lp1: \n\t" /* fix alignment */ - "movb (%%edi,%%ebx,), %%al \n\t" - "addb (%%esi,%%ebx,), %%al \n\t" - "incl %%ebx \n\t" - "cmpl %%ecx, %%ebx \n\t" - "movb %%al, -1(%%edi,%%ebx,) \n\t" /* mov does not affect flags; -1 to */ - "jb up_lp1 \n\t" /* offset incl ebx */ - - "up_go: \n\t" -/* pre "movl len, %%edx \n\t" */ - "movl %%edx, %%ecx \n\t" - "subl %%ebx, %%edx \n\t" /* subtract alignment fix */ - "andl $0x0000003f, %%edx \n\t" /* calc bytes over mult of 64 */ - "subl %%edx, %%ecx \n\t" /* drop over bytes from length */ - - /* unrolled loop - use all MMX registers and interleave to reduce */ - /* number of branch instructions (loops) and reduce partial stalls */ - "up_loop: \n\t" - "movq (%%esi,%%ebx,), %%mm1 \n\t" - "movq (%%edi,%%ebx,), %%mm0 \n\t" - "movq 8(%%esi,%%ebx,), %%mm3 \n\t" - "paddb %%mm1, %%mm0 \n\t" - "movq 8(%%edi,%%ebx,), %%mm2 \n\t" - "movq %%mm0, (%%edi,%%ebx,) \n\t" - "paddb %%mm3, %%mm2 \n\t" - "movq 16(%%esi,%%ebx,), %%mm5 \n\t" - "movq %%mm2, 8(%%edi,%%ebx,) \n\t" - "movq 16(%%edi,%%ebx,), %%mm4 \n\t" - "movq 24(%%esi,%%ebx,), %%mm7 \n\t" - "paddb %%mm5, %%mm4 \n\t" - "movq 24(%%edi,%%ebx,), %%mm6 \n\t" - "movq %%mm4, 16(%%edi,%%ebx,) \n\t" - "paddb %%mm7, %%mm6 \n\t" - "movq 32(%%esi,%%ebx,), %%mm1 \n\t" - "movq %%mm6, 24(%%edi,%%ebx,) \n\t" - "movq 32(%%edi,%%ebx,), %%mm0 \n\t" - "movq 40(%%esi,%%ebx,), %%mm3 \n\t" - "paddb %%mm1, %%mm0 \n\t" - "movq 40(%%edi,%%ebx,), %%mm2 \n\t" - "movq %%mm0, 32(%%edi,%%ebx,) \n\t" - "paddb %%mm3, %%mm2 \n\t" - "movq 48(%%esi,%%ebx,), %%mm5 \n\t" - "movq %%mm2, 40(%%edi,%%ebx,) \n\t" - "movq 48(%%edi,%%ebx,), %%mm4 \n\t" - "movq 56(%%esi,%%ebx,), %%mm7 \n\t" - "paddb %%mm5, %%mm4 \n\t" - "movq 56(%%edi,%%ebx,), %%mm6 \n\t" - "movq %%mm4, 48(%%edi,%%ebx,) \n\t" - "addl $64, %%ebx \n\t" - "paddb %%mm7, %%mm6 \n\t" - "cmpl %%ecx, %%ebx \n\t" - "movq %%mm6, -8(%%edi,%%ebx,) \n\t" /* (+56)movq does not affect flags; */ - "jb up_loop \n\t" /* -8 to offset addl ebx */ - - "cmpl $0, %%edx \n\t" /* test for bytes over mult of 64 */ - "jz up_end \n\t" - - "cmpl $8, %%edx \n\t" /* test for less than 8 bytes */ - "jb up_lt8 \n\t" /* [added by lcreeve@netins.net] */ - - "addl %%edx, %%ecx \n\t" - "andl $0x00000007, %%edx \n\t" /* calc bytes over mult of 8 */ - "subl %%edx, %%ecx \n\t" /* drop over bytes from length */ - "jz up_lt8 \n\t" - - "up_lpA: \n\t" /* use MMX regs to update 8 bytes sim. */ - "movq (%%esi,%%ebx,), %%mm1 \n\t" - "movq (%%edi,%%ebx,), %%mm0 \n\t" - "addl $8, %%ebx \n\t" - "paddb %%mm1, %%mm0 \n\t" - "cmpl %%ecx, %%ebx \n\t" - "movq %%mm0, -8(%%edi,%%ebx,) \n\t" /* movq does not affect flags; -8 to */ - "jb up_lpA \n\t" /* offset add ebx */ - "cmpl $0, %%edx \n\t" /* test for bytes over mult of 8 */ - "jz up_end \n\t" - - "up_lt8: \n\t" - "xorl %%eax, %%eax \n\t" - "addl %%edx, %%ecx \n\t" /* move over byte count into counter */ - - "up_lp2: \n\t" /* use x86 regs for remaining bytes */ - "movb (%%edi,%%ebx,), %%al \n\t" - "addb (%%esi,%%ebx,), %%al \n\t" - "incl %%ebx \n\t" - "cmpl %%ecx, %%ebx \n\t" - "movb %%al, -1(%%edi,%%ebx,) \n\t" /* mov does not affect flags; -1 to */ - "jb up_lp2 \n\t" /* offset inc ebx */ - - "up_end: \n\t" - "EMMS \n\t" /* conversion of filtered row complete */ -#ifdef __PIC__ - "popl %%ebx \n\t" -#endif - - : "=d" (dummy_value_d), /* 0 // output regs (dummy) */ - "=S" (dummy_value_S), /* 1 */ - "=D" (dummy_value_D) /* 2 */ - - : "0" (len), /* edx // input regs */ - "1" (prev_row), /* esi */ - "2" (row) /* edi */ - - : "%eax", "%ecx" // clobber list (no input regs!) -#ifndef __PIC__ - , "%ebx" -#endif - -#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */ - , "%mm0", "%mm1", "%mm2", "%mm3" - , "%mm4", "%mm5", "%mm6", "%mm7" -#endif - ); - -} /* end of png_read_filter_row_mmx_up() */ - -#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ - - - - -/*===========================================================================*/ -/* */ -/* P N G _ R E A D _ F I L T E R _ R O W */ -/* */ -/*===========================================================================*/ - - -/* Optimized png_read_filter_row routines */ - -void /* PRIVATE */ -png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep - row, png_bytep prev_row, int filter) -{ -#ifdef PNG_DEBUG - char filnm[10]; -#endif - -#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) -/* GRR: these are superseded by png_ptr->asm_flags: */ -#define UseMMX_sub 1 /* GRR: converted 20000730 */ -#define UseMMX_up 1 /* GRR: converted 20000729 */ -#define UseMMX_avg 1 /* GRR: converted 20000828 (+ 16-bit bugfix 20000916) */ -#define UseMMX_paeth 1 /* GRR: converted 20000828 */ - - if (_mmx_supported == 2) { - /* this should have happened in png_init_mmx_flags() already */ -#if !defined(PNG_1_0_X) - png_warning(png_ptr, "asm_flags may not have been initialized"); -#endif - png_mmx_support(); - } -#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ - -#ifdef PNG_DEBUG - png_debug(1, "in png_read_filter_row (pnggccrd.c)\n"); - switch (filter) - { - case 0: sprintf(filnm, "none"); - break; - case 1: sprintf(filnm, "sub-%s", -#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) -#if !defined(PNG_1_0_X) - (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_SUB)? "MMX" : -#endif -#endif -"x86"); - break; - case 2: sprintf(filnm, "up-%s", -#ifdef PNG_ASSEMBLER_CODE_SUPPORTED -#if !defined(PNG_1_0_X) - (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_UP)? "MMX" : -#endif -#endif - "x86"); - break; - case 3: sprintf(filnm, "avg-%s", -#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) -#if !defined(PNG_1_0_X) - (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_AVG)? "MMX" : -#endif -#endif - "x86"); - break; - case 4: sprintf(filnm, "Paeth-%s", -#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) -#if !defined(PNG_1_0_X) - (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_PAETH)? "MMX": -#endif -#endif -"x86"); - break; - default: sprintf(filnm, "unknw"); - break; - } - png_debug2(0, "row_number=%5ld, %5s, ", png_ptr->row_number, filnm); - png_debug1(0, "row=0x%08lx, ", (unsigned long)row); - png_debug2(0, "pixdepth=%2d, bytes=%d, ", (int)row_info->pixel_depth, - (int)((row_info->pixel_depth + 7) >> 3)); - png_debug1(0,"rowbytes=%8ld\n", row_info->rowbytes); -#endif /* PNG_DEBUG */ - - switch (filter) - { - case PNG_FILTER_VALUE_NONE: - break; - - case PNG_FILTER_VALUE_SUB: -#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) -#if !defined(PNG_1_0_X) - if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_SUB) && - (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && - (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) -#else - if (_mmx_supported) -#endif - { - png_read_filter_row_mmx_sub(row_info, row); - } - else -#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ - { - png_uint_32 i; - png_uint_32 istop = row_info->rowbytes; - png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; - png_bytep rp = row + bpp; - png_bytep lp = row; - - for (i = bpp; i < istop; i++) - { - *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff); - rp++; - } - } /* end !UseMMX_sub */ - break; - - case PNG_FILTER_VALUE_UP: -#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) -#if !defined(PNG_1_0_X) - if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_UP) && - (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && - (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) -#else - if (_mmx_supported) -#endif - { - png_read_filter_row_mmx_up(row_info, row, prev_row); - } - else -#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ - { - png_uint_32 i; - png_uint_32 istop = row_info->rowbytes; - png_bytep rp = row; - png_bytep pp = prev_row; - - for (i = 0; i < istop; ++i) - { - *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); - rp++; - } - } /* end !UseMMX_up */ - break; - - case PNG_FILTER_VALUE_AVG: -#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) -#if !defined(PNG_1_0_X) - if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_AVG) && - (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && - (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) -#else - if (_mmx_supported) -#endif - { - png_read_filter_row_mmx_avg(row_info, row, prev_row); - } - else -#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ - { - png_uint_32 i; - png_bytep rp = row; - png_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; - - for (i = 0; i < bpp; i++) - { - *rp = (png_byte)(((int)(*rp) + - ((int)(*pp++) >> 1)) & 0xff); - rp++; - } - - for (i = 0; i < istop; i++) - { - *rp = (png_byte)(((int)(*rp) + - ((int)(*pp++ + *lp++) >> 1)) & 0xff); - rp++; - } - } /* end !UseMMX_avg */ - break; - - case PNG_FILTER_VALUE_PAETH: -#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) -#if !defined(PNG_1_0_X) - if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_PAETH) && - (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && - (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) -#else - if (_mmx_supported) -#endif - { - png_read_filter_row_mmx_paeth(row_info, row, prev_row); - } - else -#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ - { - png_uint_32 i; - png_bytep rp = row; - png_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; - - for (i = 0; i < bpp; i++) - { - *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); - rp++; - } - - for (i = 0; i < istop; i++) /* use leftover rp,pp */ - { - int a, b, c, pa, pb, pc, p; - - a = *lp++; - b = *pp++; - c = *cp++; - - p = b - c; - pc = a - c; - -#ifdef PNG_USE_ABS - pa = abs(p); - pb = abs(pc); - pc = abs(p + pc); -#else - pa = p < 0 ? -p : p; - pb = pc < 0 ? -pc : pc; - pc = (p + pc) < 0 ? -(p + pc) : p + pc; -#endif - - /* - if (pa <= pb && pa <= pc) - p = a; - else if (pb <= pc) - p = b; - else - p = c; - */ - - p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c; - - *rp = (png_byte)(((int)(*rp) + p) & 0xff); - rp++; - } - } /* end !UseMMX_paeth */ - break; - - default: - png_warning(png_ptr, "Ignoring bad row-filter type"); - *row=0; - break; - } -} - -#endif /* PNG_HAVE_ASSEMBLER_READ_FILTER_ROW */ - - -/*===========================================================================*/ -/* */ -/* P N G _ M M X _ S U P P O R T */ -/* */ -/*===========================================================================*/ - -/* GRR NOTES: (1) the following code assumes 386 or better (pushfl/popfl) - * (2) all instructions compile with gcc 2.7.2.3 and later - * (3) the function is moved down here to prevent gcc from - * inlining it in multiple places and then barfing be- - * cause the ".NOT_SUPPORTED" label is multiply defined - * [is there a way to signal that a *single* function should - * not be inlined? is there a way to modify the label for - * each inlined instance, e.g., by appending _1, _2, etc.? - * maybe if don't use leading "." in label name? (nope...sigh)] - */ - -int PNGAPI -png_mmx_support(void) -{ -#if defined(PNG_MMX_CODE_SUPPORTED) - __asm__ __volatile__ ( - "pushl %%ebx \n\t" // ebx gets clobbered by CPUID instruction - "pushl %%ecx \n\t" // so does ecx... - "pushl %%edx \n\t" // ...and edx (but ecx & edx safe on Linux) -// ".byte 0x66 \n\t" // convert 16-bit pushf to 32-bit pushfd -// "pushf \n\t" // 16-bit pushf - "pushfl \n\t" // save Eflag to stack - "popl %%eax \n\t" // get Eflag from stack into eax - "movl %%eax, %%ecx \n\t" // make another copy of Eflag in ecx - "xorl $0x200000, %%eax \n\t" // toggle ID bit in Eflag (i.e., bit 21) - "pushl %%eax \n\t" // save modified Eflag back to stack -// ".byte 0x66 \n\t" // convert 16-bit popf to 32-bit popfd -// "popf \n\t" // 16-bit popf - "popfl \n\t" // restore modified value to Eflag reg - "pushfl \n\t" // save Eflag to stack - "popl %%eax \n\t" // get Eflag from stack - "pushl %%ecx \n\t" // save original Eflag to stack - "popfl \n\t" // restore original Eflag - "xorl %%ecx, %%eax \n\t" // compare new Eflag with original Eflag - "jz 0f \n\t" // if same, CPUID instr. is not supported - - "xorl %%eax, %%eax \n\t" // set eax to zero -// ".byte 0x0f, 0xa2 \n\t" // CPUID instruction (two-byte opcode) - "cpuid \n\t" // get the CPU identification info - "cmpl $1, %%eax \n\t" // make sure eax return non-zero value - "jl 0f \n\t" // if eax is zero, MMX is not supported - - "xorl %%eax, %%eax \n\t" // set eax to zero and... - "incl %%eax \n\t" // ...increment eax to 1. This pair is - // faster than the instruction "mov eax, 1" - "cpuid \n\t" // get the CPU identification info again - "andl $0x800000, %%edx \n\t" // mask out all bits but MMX bit (23) - "cmpl $0, %%edx \n\t" // 0 = MMX not supported - "jz 0f \n\t" // non-zero = yes, MMX IS supported - - "movl $1, %%eax \n\t" // set return value to 1 - "jmp 1f \n\t" // DONE: have MMX support - - "0: \n\t" // .NOT_SUPPORTED: target label for jump instructions - "movl $0, %%eax \n\t" // set return value to 0 - "1: \n\t" // .RETURN: target label for jump instructions - "movl %%eax, _mmx_supported \n\t" // save in global static variable, too - "popl %%edx \n\t" // restore edx - "popl %%ecx \n\t" // restore ecx - "popl %%ebx \n\t" // restore ebx - -// "ret \n\t" // DONE: no MMX support - // (fall through to standard C "ret") - - : // output list (none) - - : // any variables used on input (none) - - : "%eax" // clobber list -// , "%ebx", "%ecx", "%edx" // GRR: we handle these manually -// , "memory" // if write to a variable gcc thought was in a reg -// , "cc" // "condition codes" (flag bits) - ); -#else - _mmx_supported = 0; -#endif /* PNG_MMX_CODE_SUPPORTED */ - - return _mmx_supported; -} - - -#endif /* PNG_USE_PNGGCCRD */ diff --git a/3rdparty/wxWidgets/src/png/pngget.c b/3rdparty/wxWidgets/src/png/pngget.c index 1d1cc218bd..38e4f9eefe 100644 --- a/3rdparty/wxWidgets/src/png/pngget.c +++ b/3rdparty/wxWidgets/src/png/pngget.c @@ -1,21 +1,27 @@ /* pngget.c - retrieval of values from info struct * - * libpng 1.2.7 - September 12, 2004 - * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2004 Glenn Randers-Pehrson + * Last changed in libpng 1.2.37 [June 4, 2009] + * Copyright (c) 1998-2009 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. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * */ #define PNG_INTERNAL #include "png.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); } @@ -25,6 +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); } @@ -35,20 +42,20 @@ 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); } #endif #ifdef PNG_EASY_ACCESS_SUPPORTED -/* easy access to info, added in libpng-0.99 */ +/* Easy access to info, added in libpng-0.99 */ png_uint_32 PNGAPI png_get_image_width(png_structp png_ptr, png_infop info_ptr) { if (png_ptr != NULL && info_ptr != NULL) - { return info_ptr->width; - } + return (0); } @@ -56,9 +63,8 @@ png_uint_32 PNGAPI png_get_image_height(png_structp png_ptr, png_infop info_ptr) { if (png_ptr != NULL && info_ptr != NULL) - { return info_ptr->height; - } + return (0); } @@ -66,9 +72,8 @@ png_byte PNGAPI png_get_bit_depth(png_structp png_ptr, png_infop info_ptr) { if (png_ptr != NULL && info_ptr != NULL) - { return info_ptr->bit_depth; - } + return (0); } @@ -76,9 +81,8 @@ png_byte PNGAPI png_get_color_type(png_structp png_ptr, png_infop info_ptr) { if (png_ptr != NULL && info_ptr != NULL) - { return info_ptr->color_type; - } + return (0); } @@ -86,9 +90,8 @@ png_byte PNGAPI png_get_filter_type(png_structp png_ptr, png_infop info_ptr) { if (png_ptr != NULL && info_ptr != NULL) - { return info_ptr->filter_type; - } + return (0); } @@ -96,9 +99,8 @@ png_byte PNGAPI png_get_interlace_type(png_structp png_ptr, png_infop info_ptr) { if (png_ptr != NULL && info_ptr != NULL) - { return info_ptr->interlace_type; - } + return (0); } @@ -106,9 +108,8 @@ png_byte PNGAPI png_get_compression_type(png_structp png_ptr, png_infop info_ptr) { if (png_ptr != NULL && info_ptr != NULL) - { return info_ptr->compression_type; - } + return (0); } @@ -119,10 +120,13 @@ png_get_x_pixels_per_meter(png_structp png_ptr, png_infop info_ptr) #if defined(PNG_pHYs_SUPPORTED) if (info_ptr->valid & PNG_INFO_pHYs) { - png_debug1(1, "in %s retrieval function\n", "png_get_x_pixels_per_meter"); - if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER) + 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 (info_ptr->x_pixels_per_unit); } #else return (0); @@ -137,10 +141,13 @@ png_get_y_pixels_per_meter(png_structp png_ptr, png_infop info_ptr) #if defined(PNG_pHYs_SUPPORTED) if (info_ptr->valid & PNG_INFO_pHYs) { - png_debug1(1, "in %s retrieval function\n", "png_get_y_pixels_per_meter"); - if(info_ptr->phys_unit_type != PNG_RESOLUTION_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); + + else + return (info_ptr->y_pixels_per_unit); } #else return (0); @@ -155,11 +162,14 @@ png_get_pixels_per_meter(png_structp png_ptr, png_infop info_ptr) #if defined(PNG_pHYs_SUPPORTED) if (info_ptr->valid & PNG_INFO_pHYs) { - png_debug1(1, "in %s retrieval function\n", "png_get_pixels_per_meter"); - if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER || + 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); + + else + return (info_ptr->x_pixels_per_unit); } #else return (0); @@ -173,9 +183,10 @@ png_get_pixel_aspect_ratio(png_structp png_ptr, png_infop info_ptr) { if (png_ptr != NULL && info_ptr != NULL) #if defined(PNG_pHYs_SUPPORTED) + if (info_ptr->valid & PNG_INFO_pHYs) { - png_debug1(1, "in %s retrieval function\n", "png_get_aspect_ratio"); + png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio"); if (info_ptr->x_pixels_per_unit == 0) return ((float)0.0); else @@ -183,7 +194,7 @@ png_get_pixel_aspect_ratio(png_structp png_ptr, png_infop info_ptr) /(float)info_ptr->x_pixels_per_unit)); } #else - return (0.0); + return (0.0); #endif return ((float)0.0); } @@ -194,15 +205,19 @@ png_get_x_offset_microns(png_structp png_ptr, png_infop info_ptr) { if (png_ptr != NULL && info_ptr != NULL) #if defined(PNG_oFFs_SUPPORTED) + if (info_ptr->valid & PNG_INFO_oFFs) { - png_debug1(1, "in %s retrieval function\n", "png_get_x_offset_microns"); - if(info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER) + 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); + + else + return (info_ptr->x_offset); } #else - return (0); + return (0); #endif return (0); } @@ -211,13 +226,17 @@ png_int_32 PNGAPI png_get_y_offset_microns(png_structp png_ptr, png_infop info_ptr) { if (png_ptr != NULL && info_ptr != NULL) + #if defined(PNG_oFFs_SUPPORTED) if (info_ptr->valid & PNG_INFO_oFFs) { - png_debug1(1, "in %s retrieval function\n", "png_get_y_offset_microns"); - if(info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER) + 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); + + else + return (info_ptr->y_offset); } #else return (0); @@ -229,13 +248,17 @@ png_int_32 PNGAPI png_get_x_offset_pixels(png_structp png_ptr, png_infop info_ptr) { if (png_ptr != NULL && info_ptr != NULL) + #if defined(PNG_oFFs_SUPPORTED) if (info_ptr->valid & PNG_INFO_oFFs) { - png_debug1(1, "in %s retrieval function\n", "png_get_x_offset_microns"); - if(info_ptr->offset_unit_type != PNG_OFFSET_PIXEL) + png_debug1(1, "in %s retrieval function", "png_get_x_offset_microns"); + + if (info_ptr->offset_unit_type != PNG_OFFSET_PIXEL) return (0); - else return (info_ptr->x_offset); + + else + return (info_ptr->x_offset); } #else return (0); @@ -247,13 +270,17 @@ png_int_32 PNGAPI png_get_y_offset_pixels(png_structp png_ptr, png_infop info_ptr) { if (png_ptr != NULL && info_ptr != NULL) + #if defined(PNG_oFFs_SUPPORTED) if (info_ptr->valid & PNG_INFO_oFFs) { - png_debug1(1, "in %s retrieval function\n", "png_get_y_offset_microns"); - if(info_ptr->offset_unit_type != PNG_OFFSET_PIXEL) + png_debug1(1, "in %s retrieval function", "png_get_y_offset_microns"); + + if (info_ptr->offset_unit_type != PNG_OFFSET_PIXEL) return (0); - else return (info_ptr->y_offset); + + else + return (info_ptr->y_offset); } #else return (0); @@ -306,7 +333,7 @@ png_get_pHYs_dpi(png_structp png_ptr, png_infop info_ptr, if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) { - png_debug1(1, "in %s retrieval function\n", "pHYs"); + png_debug1(1, "in %s retrieval function", "pHYs"); if (res_x != NULL) { *res_x = info_ptr->x_pixels_per_unit; @@ -321,7 +348,7 @@ png_get_pHYs_dpi(png_structp png_ptr, png_infop info_ptr, { *unit_type = (int)info_ptr->phys_unit_type; retval |= PNG_INFO_pHYs; - if(*unit_type == 1) + if (*unit_type == 1) { if (res_x != NULL) *res_x = (png_uint_32)(*res_x * .0254 + .50); if (res_y != NULL) *res_y = (png_uint_32)(*res_y * .0254 + .50); @@ -363,7 +390,7 @@ png_get_bKGD(png_structp png_ptr, png_infop info_ptr, if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) && background != NULL) { - png_debug1(1, "in %s retrieval function\n", "bKGD"); + png_debug1(1, "in %s retrieval function", "bKGD"); *background = &(info_ptr->background); return (PNG_INFO_bKGD); } @@ -380,7 +407,7 @@ png_get_cHRM(png_structp png_ptr, png_infop info_ptr, { if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) { - png_debug1(1, "in %s retrieval function\n", "cHRM"); + png_debug1(1, "in %s retrieval function", "cHRM"); if (white_x != NULL) *white_x = (double)info_ptr->x_white; if (white_y != NULL) @@ -411,7 +438,7 @@ png_get_cHRM_fixed(png_structp png_ptr, png_infop info_ptr, { if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) { - png_debug1(1, "in %s retrieval function\n", "cHRM"); + png_debug1(1, "in %s retrieval function", "cHRM"); if (white_x != NULL) *white_x = info_ptr->int_x_white; if (white_y != NULL) @@ -443,7 +470,7 @@ png_get_gAMA(png_structp png_ptr, png_infop info_ptr, double *file_gamma) if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) && file_gamma != NULL) { - png_debug1(1, "in %s retrieval function\n", "gAMA"); + png_debug1(1, "in %s retrieval function", "gAMA"); *file_gamma = (double)info_ptr->gamma; return (PNG_INFO_gAMA); } @@ -458,7 +485,7 @@ png_get_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) && int_file_gamma != NULL) { - png_debug1(1, "in %s retrieval function\n", "gAMA"); + png_debug1(1, "in %s retrieval function", "gAMA"); *int_file_gamma = info_ptr->int_gamma; return (PNG_INFO_gAMA); } @@ -474,7 +501,7 @@ png_get_sRGB(png_structp png_ptr, png_infop info_ptr, int *file_srgb_intent) if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB) && file_srgb_intent != NULL) { - png_debug1(1, "in %s retrieval function\n", "sRGB"); + png_debug1(1, "in %s retrieval function", "sRGB"); *file_srgb_intent = (int)info_ptr->srgb_intent; return (PNG_INFO_sRGB); } @@ -491,11 +518,12 @@ png_get_iCCP(png_structp png_ptr, png_infop info_ptr, if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP) && name != NULL && profile != NULL && proflen != NULL) { - png_debug1(1, "in %s retrieval function\n", "iCCP"); + png_debug1(1, "in %s retrieval function", "iCCP"); *name = info_ptr->iccp_name; *profile = info_ptr->iccp_profile; - /* compression_type is a dummy so the API won't have to change - if we introduce multiple compression types later. */ + /* Compression_type is a dummy so the API won't have to change + * if we introduce multiple compression types later. + */ *proflen = (int)info_ptr->iccp_proflen; *compression_type = (int)info_ptr->iccp_compression; return (PNG_INFO_iCCP); @@ -510,8 +538,11 @@ png_get_sPLT(png_structp png_ptr, png_infop info_ptr, 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); + return ((png_uint_32)info_ptr->splt_palettes_num); + } + return (0); } #endif @@ -522,7 +553,7 @@ png_get_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p *hist) if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) && hist != NULL) { - png_debug1(1, "in %s retrieval function\n", "hIST"); + png_debug1(1, "in %s retrieval function", "hIST"); *hist = info_ptr->hist; return (PNG_INFO_hIST); } @@ -540,27 +571,34 @@ png_get_IHDR(png_structp png_ptr, png_infop info_ptr, if (png_ptr != NULL && info_ptr != NULL && width != NULL && height != NULL && bit_depth != NULL && color_type != NULL) { - png_debug1(1, "in %s retrieval function\n", "IHDR"); + png_debug1(1, "in %s retrieval function", "IHDR"); *width = info_ptr->width; *height = info_ptr->height; *bit_depth = info_ptr->bit_depth; if (info_ptr->bit_depth < 1 || info_ptr->bit_depth > 16) - png_error(png_ptr, "Invalid bit depth"); + png_error(png_ptr, "Invalid bit depth"); + *color_type = info_ptr->color_type; + if (info_ptr->color_type > 6) - png_error(png_ptr, "Invalid color type"); + png_error(png_ptr, "Invalid color type"); + if (compression_type != NULL) *compression_type = info_ptr->compression_type; + if (filter_type != NULL) *filter_type = info_ptr->filter_type; + if (interlace_type != NULL) *interlace_type = info_ptr->interlace_type; - /* check for potential overflow of rowbytes */ - if (width == 0 || *width > PNG_UINT_31_MAX) + /* Check for potential overflow of rowbytes */ + if (*width == 0 || *width > PNG_UINT_31_MAX) png_error(png_ptr, "Invalid image width"); - if (height == 0 || *height > PNG_UINT_31_MAX) + + if (*height == 0 || *height > PNG_UINT_31_MAX) png_error(png_ptr, "Invalid image height"); + if (info_ptr->width > (PNG_UINT_32_MAX >> 3) /* 8-byte RGBA pixels */ - 64 /* bigrowbuf hack */ @@ -571,6 +609,7 @@ png_get_IHDR(png_structp png_ptr, png_infop info_ptr, png_warning(png_ptr, "Width too large for libpng to process image data."); } + return (1); } return (0); @@ -584,7 +623,7 @@ png_get_oFFs(png_structp png_ptr, png_infop info_ptr, if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs) && offset_x != NULL && offset_y != NULL && unit_type != NULL) { - png_debug1(1, "in %s retrieval function\n", "oFFs"); + png_debug1(1, "in %s retrieval function", "oFFs"); *offset_x = info_ptr->x_offset; *offset_y = info_ptr->y_offset; *unit_type = (int)info_ptr->offset_unit_type; @@ -601,10 +640,10 @@ png_get_pCAL(png_structp png_ptr, png_infop info_ptr, png_charp *units, png_charpp *params) { if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL) - && purpose != NULL && X0 != NULL && X1 != NULL && type != NULL && - nparams != NULL && units != NULL && params != NULL) + && purpose != NULL && X0 != NULL && X1 != NULL && type != NULL && + nparams != NULL && units != NULL && params != NULL) { - png_debug1(1, "in %s retrieval function\n", "pCAL"); + png_debug1(1, "in %s retrieval function", "pCAL"); *purpose = info_ptr->pcal_purpose; *X0 = info_ptr->pcal_X0; *X1 = info_ptr->pcal_X1; @@ -625,7 +664,7 @@ png_get_sCAL(png_structp png_ptr, png_infop info_ptr, int *unit, double *width, double *height) { if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_sCAL)) + (info_ptr->valid & PNG_INFO_sCAL)) { *unit = info_ptr->scal_unit; *width = info_ptr->scal_pixel_width; @@ -641,7 +680,7 @@ png_get_sCAL_s(png_structp png_ptr, png_infop info_ptr, int *unit, png_charpp width, png_charpp height) { if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_sCAL)) + (info_ptr->valid & PNG_INFO_sCAL)) { *unit = info_ptr->scal_unit; *width = info_ptr->scal_s_width; @@ -664,17 +703,20 @@ png_get_pHYs(png_structp png_ptr, png_infop info_ptr, if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) { - png_debug1(1, "in %s retrieval function\n", "pHYs"); + png_debug1(1, "in %s retrieval function", "pHYs"); + if (res_x != NULL) { *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; @@ -692,10 +734,10 @@ png_get_PLTE(png_structp png_ptr, png_infop info_ptr, png_colorp *palette, if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_PLTE) && palette != NULL) { - png_debug1(1, "in %s retrieval function\n", "PLTE"); + png_debug1(1, "in %s retrieval function", "PLTE"); *palette = info_ptr->palette; *num_palette = info_ptr->num_palette; - png_debug1(3, "num_palette = %d\n", *num_palette); + png_debug1(3, "num_palette = %d", *num_palette); return (PNG_INFO_PLTE); } return (0); @@ -708,7 +750,7 @@ png_get_sBIT(png_structp png_ptr, png_infop info_ptr, png_color_8p *sig_bit) if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT) && sig_bit != NULL) { - png_debug1(1, "in %s retrieval function\n", "sBIT"); + png_debug1(1, "in %s retrieval function", "sBIT"); *sig_bit = &(info_ptr->sig_bit); return (PNG_INFO_sBIT); } @@ -723,13 +765,16 @@ png_get_text(png_structp png_ptr, png_infop info_ptr, png_textp *text_ptr, { if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0) { - png_debug1(1, "in %s retrieval function\n", + png_debug1(1, "in %s retrieval function", (png_ptr->chunk_name[0] == '\0' ? "text" : (png_const_charp)png_ptr->chunk_name)); + if (text_ptr != NULL) *text_ptr = info_ptr->text; + if (num_text != NULL) *num_text = info_ptr->num_text; + return ((png_uint_32)info_ptr->num_text); } if (num_text != NULL) @@ -745,7 +790,7 @@ png_get_tIME(png_structp png_ptr, png_infop info_ptr, png_timep *mod_time) if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME) && mod_time != NULL) { - png_debug1(1, "in %s retrieval function\n", "tIME"); + png_debug1(1, "in %s retrieval function", "tIME"); *mod_time = &(info_ptr->mod_time); return (PNG_INFO_tIME); } @@ -761,7 +806,7 @@ png_get_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 retval = 0; if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) { - png_debug1(1, "in %s retrieval function\n", "tRNS"); + png_debug1(1, "in %s retrieval function", "tRNS"); if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { if (trans != NULL) @@ -769,6 +814,7 @@ png_get_tRNS(png_structp png_ptr, png_infop info_ptr, *trans = info_ptr->trans; retval |= PNG_INFO_tRNS; } + if (trans_values != NULL) *trans_values = &(info_ptr->trans_values); } @@ -779,10 +825,11 @@ png_get_tRNS(png_structp png_ptr, png_infop info_ptr, *trans_values = &(info_ptr->trans_values); retval |= PNG_INFO_tRNS; } - if(trans != NULL) + + if (trans != NULL) *trans = NULL; } - if(num_trans != NULL) + if (num_trans != NULL) { *num_trans = info_ptr->num_trans; retval |= PNG_INFO_tRNS; @@ -798,8 +845,11 @@ png_get_unknown_chunks(png_structp png_ptr, png_infop info_ptr, 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); + return ((png_uint_32)info_ptr->unknown_chunks_num); + } + return (0); } #endif @@ -827,98 +877,56 @@ png_get_compression_buffer_size(png_structp png_ptr) } #endif -#ifndef PNG_1_0_X #ifdef PNG_ASSEMBLER_CODE_SUPPORTED -/* this function was added to libpng 1.2.0 and should exist by default */ +#ifndef PNG_1_0_X +/* This function was added to libpng 1.2.0 and should exist by default */ png_uint_32 PNGAPI png_get_asm_flags (png_structp png_ptr) { - return (png_uint_32)(png_ptr? png_ptr->asm_flags : 0L); + /* Obsolete, to be removed from libpng-1.4.0 */ + return (png_ptr? 0L: 0L); } -/* this function was added to libpng 1.2.0 and should exist by default */ +/* This function was added to libpng 1.2.0 and should exist by default */ png_uint_32 PNGAPI png_get_asm_flagmask (int flag_select) { - png_uint_32 settable_asm_flags = 0; - - if (flag_select & PNG_SELECT_READ) - settable_asm_flags |= - PNG_ASM_FLAG_MMX_READ_COMBINE_ROW | - PNG_ASM_FLAG_MMX_READ_INTERLACE | - PNG_ASM_FLAG_MMX_READ_FILTER_SUB | - PNG_ASM_FLAG_MMX_READ_FILTER_UP | - PNG_ASM_FLAG_MMX_READ_FILTER_AVG | - PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ; - /* no non-MMX flags yet */ - -#if 0 - /* GRR: no write-flags yet, either, but someday... */ - if (flag_select & PNG_SELECT_WRITE) - settable_asm_flags |= - PNG_ASM_FLAG_MMX_WRITE_ [whatever] ; -#endif /* 0 */ - - return settable_asm_flags; /* _theoretically_ settable capabilities only */ + /* Obsolete, to be removed from libpng-1.4.0 */ + flag_select=flag_select; + return 0L; } -#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ - -#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) /* GRR: could add this: && defined(PNG_MMX_CODE_SUPPORTED) */ -/* this function was added to libpng 1.2.0 */ +/* This function was added to libpng 1.2.0 */ png_uint_32 PNGAPI png_get_mmx_flagmask (int flag_select, int *compilerID) { - png_uint_32 settable_mmx_flags = 0; - - if (flag_select & PNG_SELECT_READ) - settable_mmx_flags |= - PNG_ASM_FLAG_MMX_READ_COMBINE_ROW | - PNG_ASM_FLAG_MMX_READ_INTERLACE | - PNG_ASM_FLAG_MMX_READ_FILTER_SUB | - PNG_ASM_FLAG_MMX_READ_FILTER_UP | - PNG_ASM_FLAG_MMX_READ_FILTER_AVG | - PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ; -#if 0 - /* GRR: no MMX write support yet, but someday... */ - if (flag_select & PNG_SELECT_WRITE) - settable_mmx_flags |= - PNG_ASM_FLAG_MMX_WRITE_ [whatever] ; -#endif /* 0 */ - - if (compilerID != NULL) { -#ifdef PNG_USE_PNGVCRD - *compilerID = 1; /* MSVC */ -#else -#ifdef PNG_USE_PNGGCCRD - *compilerID = 2; /* gcc/gas */ -#else - *compilerID = -1; /* unknown (i.e., no asm/MMX code compiled) */ -#endif -#endif - } - - return settable_mmx_flags; /* _theoretically_ settable capabilities only */ + /* Obsolete, to be removed from libpng-1.4.0 */ + flag_select=flag_select; + *compilerID = -1; /* unknown (i.e., no asm/MMX code compiled) */ + return 0L; } -/* this function was added to libpng 1.2.0 */ +/* This function was added to libpng 1.2.0 */ png_byte PNGAPI png_get_mmx_bitdepth_threshold (png_structp png_ptr) { - return (png_byte)(png_ptr? png_ptr->mmx_bitdepth_threshold : 0); + /* Obsolete, to be removed from libpng-1.4.0 */ + return (png_ptr? 0: 0); } -/* this function was added to libpng 1.2.0 */ +/* This function was added to libpng 1.2.0 */ png_uint_32 PNGAPI png_get_mmx_rowbytes_threshold (png_structp png_ptr) { - return (png_uint_32)(png_ptr? png_ptr->mmx_rowbytes_threshold : 0L); + /* Obsolete, to be removed from libpng-1.4.0 */ + return (png_ptr? 0L: 0L); } +#endif /* ?PNG_1_0_X */ #endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */ #ifdef PNG_SET_USER_LIMITS_SUPPORTED -/* these functions were added to libpng 1.2.6 */ +/* These functions were added to libpng 1.2.6 */ png_uint_32 PNGAPI png_get_user_width_max (png_structp png_ptr) { @@ -931,4 +939,5 @@ png_get_user_height_max (png_structp png_ptr) } #endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */ -#endif /* ?PNG_1_0_X */ + +#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ diff --git a/3rdparty/wxWidgets/src/png/pngmem.c b/3rdparty/wxWidgets/src/png/pngmem.c index 2682394ab7..e190cc3bf7 100644 --- a/3rdparty/wxWidgets/src/png/pngmem.c +++ b/3rdparty/wxWidgets/src/png/pngmem.c @@ -1,12 +1,15 @@ /* pngmem.c - stub functions for memory allocation * - * libpng version 1.2.7 - September 12, 2004 - * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2004 Glenn Randers-Pehrson + * Last changed in libpng 1.2.37 [June 4, 2009] + * Copyright (c) 1998-2009 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. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * * This file provides a location for all memory allocation. Users who * need special memory handling are expected to supply replacement * functions for png_malloc() and png_free(), and to use @@ -16,10 +19,11 @@ #define PNG_INTERNAL #include "png.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 */ +/* 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. */ @@ -39,14 +43,14 @@ png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr) png_voidp struct_ptr; if (type == PNG_STRUCT_INFO) - size = png_sizeof(png_info); + size = png_sizeof(png_info); else if (type == PNG_STRUCT_PNG) - size = png_sizeof(png_struct); + size = png_sizeof(png_struct); else - return (png_get_copyright(NULL)); + return (png_get_copyright(NULL)); #ifdef PNG_USER_MEM_SUPPORTED - if(malloc_fn != NULL) + if (malloc_fn != NULL) { png_struct dummy_struct; png_structp png_ptr = &dummy_struct; @@ -55,7 +59,7 @@ png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr) } else #endif /* PNG_USER_MEM_SUPPORTED */ - struct_ptr = (png_voidp)farmalloc(size); + struct_ptr = (png_voidp)farmalloc(size); if (struct_ptr != NULL) png_memset(struct_ptr, 0, size); return (struct_ptr); @@ -78,7 +82,7 @@ png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn, if (struct_ptr != NULL) { #ifdef PNG_USER_MEM_SUPPORTED - if(free_fn != NULL) + if (free_fn != NULL) { png_struct dummy_struct; png_structp png_ptr = &dummy_struct; @@ -120,10 +124,10 @@ png_malloc(png_structp png_ptr, png_uint_32 size) return (NULL); #ifdef PNG_USER_MEM_SUPPORTED - if(png_ptr->malloc_fn != NULL) - ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size)); + 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)); + 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); @@ -135,6 +139,9 @@ png_malloc_default(png_structp png_ptr, png_uint_32 size) png_voidp ret; #endif /* PNG_USER_MEM_SUPPORTED */ + if (png_ptr == NULL || size == 0) + return (NULL); + #ifdef PNG_MAX_MALLOC_64K if (size > (png_uint_32)65536L) { @@ -145,12 +152,12 @@ png_malloc_default(png_structp png_ptr, png_uint_32 size) #endif if (size != (size_t)size) - ret = NULL; + ret = NULL; else if (size == (png_uint_32)65536L) { if (png_ptr->offset_table == NULL) { - /* try to see if we need to do any of this fancy stuff */ + /* Try to see if we need to do any of this fancy stuff */ ret = farmalloc(size); if (ret == NULL || ((png_size_t)ret & 0xffff)) { @@ -166,7 +173,7 @@ png_malloc_default(png_structp png_ptr, png_uint_32 size) ret = NULL; } - if(png_ptr->zlib_window_bits > 14) + if (png_ptr->zlib_window_bits > 14) num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14)); else num_blocks = 1; @@ -205,7 +212,7 @@ png_malloc_default(png_structp png_ptr, png_uint_32 size) png_ptr->offset_table = table; png_ptr->offset_table_ptr = farmalloc(num_blocks * - png_sizeof (png_bytep)); + png_sizeof(png_bytep)); if (png_ptr->offset_table_ptr == NULL) { @@ -265,9 +272,10 @@ png_malloc_default(png_structp png_ptr, png_uint_32 size) return (ret); } -/* free a pointer allocated by png_malloc(). In the default - configuration, png_ptr is not used, but is passed in case it - is needed. If ptr is NULL, return without taking any action. */ +/* Free a pointer allocated by png_malloc(). In the default + * configuration, png_ptr is not used, but is passed in case it + * is needed. If ptr is NULL, return without taking any action. + */ void PNGAPI png_free(png_structp png_ptr, png_voidp ptr) { @@ -280,7 +288,8 @@ png_free(png_structp png_ptr, png_voidp ptr) (*(png_ptr->free_fn))(png_ptr, ptr); return; } - else png_free_default(png_ptr, ptr); + else + png_free_default(png_ptr, ptr); } void PNGAPI @@ -288,6 +297,9 @@ png_free_default(png_structp png_ptr, png_voidp ptr) { #endif /* PNG_USER_MEM_SUPPORTED */ + if (png_ptr == NULL || ptr == NULL) + return; + if (png_ptr->offset_table != NULL) { int i; @@ -346,7 +358,7 @@ png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr) return (NULL); #ifdef PNG_USER_MEM_SUPPORTED - if(malloc_fn != NULL) + if (malloc_fn != NULL) { png_struct dummy_struct; png_structp png_ptr = &dummy_struct; @@ -362,7 +374,7 @@ png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr) struct_ptr = (png_voidp)farmalloc(size); #else # if defined(_MSC_VER) && defined(MAXSEG_64K) - struct_ptr = (png_voidp)halloc(size,1); + struct_ptr = (png_voidp)halloc(size, 1); # else struct_ptr = (png_voidp)malloc(size); # endif @@ -391,7 +403,7 @@ png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn, if (struct_ptr != NULL) { #ifdef PNG_USER_MEM_SUPPORTED - if(free_fn != NULL) + if (free_fn != NULL) { png_struct dummy_struct; png_structp png_ptr = &dummy_struct; @@ -413,10 +425,12 @@ png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn, } /* Allocate memory. For reasonable files, size should never exceed - 64K. However, zlib may allocate more then 64K if you don't tell - it not to. See zconf.h and png.h for more information. zlib does - need to allocate exactly 64K, so whatever you call here must - have the ability to do that. */ + * 64K. However, zlib may allocate more then 64K if you don't tell + * it not to. See zconf.h and png.h for more information. zlib does + * need to allocate exactly 64K, so whatever you call here must + * have the ability to do that. + */ + png_voidp PNGAPI png_malloc(png_structp png_ptr, png_uint_32 size) @@ -427,10 +441,10 @@ png_malloc(png_structp png_ptr, png_uint_32 size) 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)); + 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)); + 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); @@ -449,7 +463,7 @@ png_malloc_default(png_structp png_ptr, png_uint_32 size) if (size > (png_uint_32)65536L) { #ifndef PNG_USER_MEM_SUPPORTED - if(png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) + if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) png_error(png_ptr, "Cannot Allocate > 64K"); else #endif @@ -457,23 +471,23 @@ png_malloc_default(png_structp png_ptr, png_uint_32 size) } #endif - /* Check for overflow */ + /* Check for overflow */ #if defined(__TURBOC__) && !defined(__FLAT__) - if (size != (unsigned long)size) - ret = NULL; - else - ret = farmalloc(size); + if (size != (unsigned long)size) + ret = NULL; + else + ret = farmalloc(size); #else # if defined(_MSC_VER) && defined(MAXSEG_64K) - if (size != (unsigned long)size) - ret = NULL; - else - ret = halloc(size, 1); + if (size != (unsigned long)size) + ret = NULL; + else + ret = halloc(size, 1); # else - if (size != (size_t)size) - ret = NULL; - else - ret = malloc((size_t)size); + if (size != (size_t)size) + ret = NULL; + else + ret = malloc((size_t)size); # endif #endif @@ -486,7 +500,8 @@ png_malloc_default(png_structp png_ptr, png_uint_32 size) } /* Free a pointer allocated by png_malloc(). If ptr is NULL, return - without taking any action. */ + * without taking any action. + */ void PNGAPI png_free(png_structp png_ptr, png_voidp ptr) { @@ -499,7 +514,8 @@ png_free(png_structp png_ptr, png_voidp ptr) (*(png_ptr->free_fn))(png_ptr, ptr); return; } - else png_free_default(png_ptr, ptr); + else + png_free_default(png_ptr, ptr); } void PNGAPI png_free_default(png_structp png_ptr, png_voidp ptr) @@ -534,8 +550,11 @@ png_voidp PNGAPI png_malloc_warn(png_structp png_ptr, png_uint_32 size) { png_voidp ptr; - png_uint_32 save_flags=png_ptr->flags; + png_uint_32 save_flags; + if (png_ptr == NULL) + return (NULL); + save_flags = png_ptr->flags; png_ptr->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK; ptr = (png_voidp)png_malloc((png_structp)png_ptr, size); png_ptr->flags=save_flags; @@ -551,7 +570,7 @@ png_memcpy_check (png_structp png_ptr, png_voidp s1, png_voidp s2, size = (png_size_t)length; if ((png_uint_32)size != length) - png_error(png_ptr,"Overflow in png_memcpy_check."); + png_error(png_ptr, "Overflow in png_memcpy_check."); return(png_memcpy (s1, s2, size)); } @@ -564,7 +583,7 @@ png_memset_check (png_structp png_ptr, png_voidp s1, int value, size = (png_size_t)length; if ((png_uint_32)size != length) - png_error(png_ptr,"Overflow in png_memset_check."); + png_error(png_ptr, "Overflow in png_memset_check."); return (png_memset (s1, value, size)); @@ -578,9 +597,12 @@ void PNGAPI png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn) { - png_ptr->mem_ptr = mem_ptr; - png_ptr->malloc_fn = malloc_fn; - png_ptr->free_fn = free_fn; + if (png_ptr != NULL) + { + png_ptr->mem_ptr = mem_ptr; + png_ptr->malloc_fn = malloc_fn; + png_ptr->free_fn = free_fn; + } } /* This function returns a pointer to the mem_ptr associated with the user @@ -590,6 +612,9 @@ png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr png_voidp PNGAPI 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 */ +#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ diff --git a/3rdparty/wxWidgets/src/png/pngpread.c b/3rdparty/wxWidgets/src/png/pngpread.c index bbf2e14ad0..7adb7b854f 100644 --- a/3rdparty/wxWidgets/src/png/pngpread.c +++ b/3rdparty/wxWidgets/src/png/pngpread.c @@ -1,19 +1,21 @@ /* pngpread.c - read a png file in push mode * - * libpng version 1.2.7 - September 12, 2004 - * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2004 Glenn Randers-Pehrson + * Last changed in libpng 1.2.38 [July 16, 2009] + * Copyright (c) 1998-2009 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. + * For conditions of distribution and use, see the disclaimer + * and license in png.h */ #define PNG_INTERNAL #include "png.h" - #ifdef PNG_PROGRESSIVE_READ_SUPPORTED -/* push model modes */ +/* Push model modes */ #define PNG_READ_SIG_MODE 0 #define PNG_READ_CHUNK_MODE 1 #define PNG_READ_IDAT_MODE 2 @@ -28,6 +30,9 @@ void PNGAPI png_process_data(png_structp png_ptr, png_infop info_ptr, png_bytep buffer, png_size_t buffer_size) { + if (png_ptr == NULL || info_ptr == NULL) + return; + png_push_restore_buffer(png_ptr, buffer, buffer_size); while (png_ptr->buffer_size) @@ -42,6 +47,9 @@ png_process_data(png_structp png_ptr, png_infop info_ptr, void /* PRIVATE */ png_process_some_data(png_structp png_ptr, png_infop info_ptr) { + if (png_ptr == NULL) + return; + switch (png_ptr->process_mode) { case PNG_READ_SIG_MODE: @@ -49,22 +57,26 @@ png_process_some_data(png_structp png_ptr, png_infop info_ptr) png_push_read_sig(png_ptr, info_ptr); break; } + case PNG_READ_CHUNK_MODE: { png_push_read_chunk(png_ptr, info_ptr); break; } + case PNG_READ_IDAT_MODE: { png_push_read_IDAT(png_ptr); break; } + #if defined(PNG_READ_tEXt_SUPPORTED) case PNG_READ_tEXt_MODE: { png_push_read_tEXt(png_ptr, info_ptr); break; } + #endif #if defined(PNG_READ_zTXt_SUPPORTED) case PNG_READ_zTXt_MODE: @@ -72,6 +84,7 @@ png_process_some_data(png_structp png_ptr, png_infop info_ptr) png_push_read_zTXt(png_ptr, info_ptr); break; } + #endif #if defined(PNG_READ_iTXt_SUPPORTED) case PNG_READ_iTXt_MODE: @@ -79,12 +92,14 @@ png_process_some_data(png_structp png_ptr, png_infop info_ptr) png_push_read_iTXt(png_ptr, info_ptr); break; } + #endif case PNG_SKIP_MODE: { png_push_crc_finish(png_ptr); break; } + default: { png_ptr->buffer_size = 0; @@ -112,7 +127,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); - png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes+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,60 +150,60 @@ void /* PRIVATE */ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) { #ifdef PNG_USE_LOCAL_ARRAYS - PNG_IHDR; - PNG_IDAT; - PNG_IEND; - PNG_PLTE; + PNG_CONST PNG_IHDR; + PNG_CONST PNG_IDAT; + PNG_CONST PNG_IEND; + PNG_CONST PNG_PLTE; #if defined(PNG_READ_bKGD_SUPPORTED) - PNG_bKGD; + PNG_CONST PNG_bKGD; #endif #if defined(PNG_READ_cHRM_SUPPORTED) - PNG_cHRM; + PNG_CONST PNG_cHRM; #endif #if defined(PNG_READ_gAMA_SUPPORTED) - PNG_gAMA; + PNG_CONST PNG_gAMA; #endif #if defined(PNG_READ_hIST_SUPPORTED) - PNG_hIST; + PNG_CONST PNG_hIST; #endif #if defined(PNG_READ_iCCP_SUPPORTED) - PNG_iCCP; + PNG_CONST PNG_iCCP; #endif #if defined(PNG_READ_iTXt_SUPPORTED) - PNG_iTXt; + PNG_CONST PNG_iTXt; #endif #if defined(PNG_READ_oFFs_SUPPORTED) - PNG_oFFs; + PNG_CONST PNG_oFFs; #endif #if defined(PNG_READ_pCAL_SUPPORTED) - PNG_pCAL; + PNG_CONST PNG_pCAL; #endif #if defined(PNG_READ_pHYs_SUPPORTED) - PNG_pHYs; + PNG_CONST PNG_pHYs; #endif #if defined(PNG_READ_sBIT_SUPPORTED) - PNG_sBIT; + PNG_CONST PNG_sBIT; #endif #if defined(PNG_READ_sCAL_SUPPORTED) - PNG_sCAL; + PNG_CONST PNG_sCAL; #endif #if defined(PNG_READ_sRGB_SUPPORTED) - PNG_sRGB; + PNG_CONST PNG_sRGB; #endif #if defined(PNG_READ_sPLT_SUPPORTED) - PNG_sPLT; + PNG_CONST PNG_sPLT; #endif #if defined(PNG_READ_tEXt_SUPPORTED) - PNG_tEXt; + PNG_CONST PNG_tEXt; #endif #if defined(PNG_READ_tIME_SUPPORTED) - PNG_tIME; + PNG_CONST PNG_tIME; #endif #if defined(PNG_READ_tRNS_SUPPORTED) - PNG_tRNS; + PNG_CONST PNG_tRNS; #endif #if defined(PNG_READ_zTXt_SUPPORTED) - PNG_zTXt; + PNG_CONST PNG_zTXt; #endif #endif /* PNG_USE_LOCAL_ARRAYS */ /* First we make sure we have enough data for the 4 byte chunk name @@ -208,21 +223,31 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) } png_push_fill_buffer(png_ptr, chunk_length, 4); - png_ptr->push_length = png_get_uint_31(png_ptr,chunk_length); + png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length); png_reset_crc(png_ptr); png_crc_read(png_ptr, png_ptr->chunk_name, 4); + png_check_chunk_name(png_ptr, png_ptr->chunk_name); png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; } + 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_memcmp(png_ptr->chunk_name, png_IHDR, 4)) { + if (png_ptr->push_length != 13) + png_error(png_ptr, "Invalid IHDR length"); + if (png_ptr->push_length + 4 > png_ptr->buffer_size) { png_push_save_buffer(png_ptr); return; } + png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length); } + else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) @@ -230,11 +255,13 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length); png_ptr->process_mode = PNG_READ_DONE_MODE; png_push_have_end(png_ptr, info_ptr); } + #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name)) { @@ -243,20 +270,26 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) png_ptr->mode |= PNG_HAVE_IDAT; + png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length); + if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) png_ptr->mode |= PNG_HAVE_PLTE; + else if (!png_memcmp(png_ptr->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_error(png_ptr, "Missing PLTE before IDAT"); } } + #endif else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) { @@ -267,22 +300,26 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) } png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length); } - else if (!png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4)) + + else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) { /* If we reach an IDAT chunk, this means we have read all of the * header chunks, and we can start reading the image (or if this * is called after the image has been read - we have an error). */ - if (!(png_ptr->mode & PNG_HAVE_IHDR)) - png_error(png_ptr, "Missing IHDR before IDAT"); - else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && - !(png_ptr->mode & PNG_HAVE_PLTE)) - png_error(png_ptr, "Missing PLTE before IDAT"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) + png_error(png_ptr, "Missing IHDR before IDAT"); + + else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && + !(png_ptr->mode & PNG_HAVE_PLTE)) + png_error(png_ptr, "Missing PLTE before IDAT"); if (png_ptr->mode & PNG_HAVE_IDAT) { - if (png_ptr->push_length == 0) - return; + if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) + if (png_ptr->push_length == 0) + return; if (png_ptr->mode & PNG_AFTER_IDAT) png_error(png_ptr, "Too many IDAT's found"); @@ -296,6 +333,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_ptr->zstream.next_out = png_ptr->row_buf; return; } + #if defined(PNG_READ_gAMA_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4)) { @@ -304,8 +342,10 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length); } + #endif #if defined(PNG_READ_sBIT_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4)) @@ -315,8 +355,10 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length); } + #endif #if defined(PNG_READ_cHRM_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4)) @@ -326,8 +368,10 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length); } + #endif #if defined(PNG_READ_sRGB_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4)) @@ -337,8 +381,10 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length); } + #endif #if defined(PNG_READ_iCCP_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4)) @@ -348,8 +394,10 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length); } + #endif #if defined(PNG_READ_sPLT_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4)) @@ -359,8 +407,10 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length); } + #endif #if defined(PNG_READ_tRNS_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4)) @@ -370,8 +420,10 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length); } + #endif #if defined(PNG_READ_bKGD_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4)) @@ -381,8 +433,10 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length); } + #endif #if defined(PNG_READ_hIST_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4)) @@ -392,8 +446,10 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length); } + #endif #if defined(PNG_READ_pHYs_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4)) @@ -403,8 +459,10 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length); } + #endif #if defined(PNG_READ_oFFs_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4)) @@ -414,9 +472,11 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length); } #endif + #if defined(PNG_READ_pCAL_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4)) { @@ -425,8 +485,10 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length); } + #endif #if defined(PNG_READ_sCAL_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4)) @@ -436,8 +498,10 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length); } + #endif #if defined(PNG_READ_tIME_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4)) @@ -447,8 +511,10 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length); } + #endif #if defined(PNG_READ_tEXt_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4)) @@ -458,8 +524,10 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length); } + #endif #if defined(PNG_READ_zTXt_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4)) @@ -469,8 +537,10 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length); } + #endif #if defined(PNG_READ_iTXt_SUPPORTED) else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4)) @@ -480,8 +550,10 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_push_save_buffer(png_ptr); return; } + png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length); } + #endif else { @@ -556,6 +628,9 @@ png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length) { png_bytep ptr; + if (png_ptr == NULL) + return; + ptr = buffer; if (png_ptr->save_buffer_size) { @@ -579,6 +654,7 @@ png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length) if (length < png_ptr->current_buffer_size) save_size = length; + else save_size = png_ptr->current_buffer_size; @@ -596,7 +672,7 @@ png_push_save_buffer(png_structp png_ptr) { if (png_ptr->save_buffer_ptr != png_ptr->save_buffer) { - png_size_t i,istop; + png_size_t i, istop; png_bytep sp; png_bytep dp; @@ -614,11 +690,12 @@ png_push_save_buffer(png_structp png_ptr) png_size_t new_max; png_bytep old_buffer; - if (png_ptr->save_buffer_size > PNG_SIZE_MAX - + if (png_ptr->save_buffer_size > PNG_SIZE_MAX - (png_ptr->current_buffer_size + 256)) { 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(png_ptr, @@ -652,7 +729,7 @@ void /* PRIVATE */ png_push_read_IDAT(png_structp png_ptr) { #ifdef PNG_USE_LOCAL_ARRAYS - PNG_IDAT; + PNG_CONST PNG_IDAT; #endif if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER)) { @@ -665,12 +742,12 @@ png_push_read_IDAT(png_structp png_ptr) } png_push_fill_buffer(png_ptr, chunk_length, 4); - png_ptr->push_length = png_get_uint_31(png_ptr,chunk_length); + png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length); png_reset_crc(png_ptr); png_crc_read(png_ptr, png_ptr->chunk_name, 4); png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; - if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4)) + 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)) @@ -687,16 +764,19 @@ png_push_read_IDAT(png_structp png_ptr) if (png_ptr->idat_size < (png_uint_32)png_ptr->save_buffer_size) { save_size = (png_size_t)png_ptr->idat_size; - /* check for overflow */ - if((png_uint_32)save_size != png_ptr->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; png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); + if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size); + png_ptr->idat_size -= save_size; png_ptr->buffer_size -= save_size; png_ptr->save_buffer_size -= save_size; @@ -709,8 +789,9 @@ png_push_read_IDAT(png_structp png_ptr) if (png_ptr->idat_size < (png_uint_32)png_ptr->current_buffer_size) { save_size = (png_size_t)png_ptr->idat_size; - /* check for overflow */ - if((png_uint_32)save_size != png_ptr->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 @@ -750,7 +831,7 @@ png_process_IDAT_data(png_structp png_ptr, png_bytep buffer, png_ptr->zstream.next_in = buffer; png_ptr->zstream.avail_in = (uInt)buffer_length; - for(;;) + for (;;) { ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); if (ret != Z_OK) @@ -759,6 +840,7 @@ png_process_IDAT_data(png_structp png_ptr, png_bytep buffer, { if (png_ptr->zstream.avail_in) png_error(png_ptr, "Extra compressed data"); + if (!(png_ptr->zstream.avail_out)) { png_push_process_row(png_ptr); @@ -770,6 +852,7 @@ png_process_IDAT_data(png_structp png_ptr, png_bytep buffer, } else if (ret == Z_BUF_ERROR) break; + else png_error(png_ptr, "Decompression Error"); } @@ -791,6 +874,7 @@ png_process_IDAT_data(png_structp png_ptr, png_bytep buffer, png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes; png_ptr->zstream.next_out = png_ptr->row_buf; } + else break; } @@ -815,11 +899,11 @@ png_push_process_row(png_structp png_ptr) png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf, png_ptr->rowbytes + 1); - if (png_ptr->transformations) + if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA)) png_do_read_transformations(png_ptr); #if defined(PNG_READ_INTERLACING_SUPPORTED) - /* blow up interlaced rows to full size */ + /* Blow up interlaced rows to full size */ if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) { if (png_ptr->pass < 6) @@ -837,9 +921,10 @@ png_push_process_row(png_structp png_ptr) for (i = 0; i < 8 && png_ptr->pass == 0; i++) { png_push_have_row(png_ptr, png_ptr->row_buf + 1); - png_read_push_finish_row(png_ptr); /* updates png_ptr->pass */ + png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */ } - if (png_ptr->pass == 2) /* pass 1 might be empty */ + + if (png_ptr->pass == 2) /* Pass 1 might be empty */ { for (i = 0; i < 4 && png_ptr->pass == 2; i++) { @@ -847,6 +932,7 @@ png_push_process_row(png_structp png_ptr) png_read_push_finish_row(png_ptr); } } + if (png_ptr->pass == 4 && png_ptr->height <= 4) { for (i = 0; i < 2 && png_ptr->pass == 4; i++) @@ -855,13 +941,16 @@ png_push_process_row(png_structp png_ptr) png_read_push_finish_row(png_ptr); } } + if (png_ptr->pass == 6 && png_ptr->height <= 4) { png_push_have_row(png_ptr, png_bytep_NULL); png_read_push_finish_row(png_ptr); } + break; } + case 1: { int i; @@ -870,7 +959,8 @@ png_push_process_row(png_structp png_ptr) png_push_have_row(png_ptr, png_ptr->row_buf + 1); png_read_push_finish_row(png_ptr); } - if (png_ptr->pass == 2) /* skip top 4 generated rows */ + + if (png_ptr->pass == 2) /* Skip top 4 generated rows */ { for (i = 0; i < 4 && png_ptr->pass == 2; i++) { @@ -878,22 +968,27 @@ png_push_process_row(png_structp png_ptr) png_read_push_finish_row(png_ptr); } } + break; } + case 2: { int i; + for (i = 0; i < 4 && png_ptr->pass == 2; i++) { png_push_have_row(png_ptr, png_ptr->row_buf + 1); png_read_push_finish_row(png_ptr); } + for (i = 0; i < 4 && png_ptr->pass == 2; i++) { png_push_have_row(png_ptr, png_bytep_NULL); png_read_push_finish_row(png_ptr); } - if (png_ptr->pass == 4) /* pass 3 might be empty */ + + if (png_ptr->pass == 4) /* Pass 3 might be empty */ { for (i = 0; i < 2 && png_ptr->pass == 4; i++) { @@ -901,17 +996,21 @@ png_push_process_row(png_structp png_ptr) png_read_push_finish_row(png_ptr); } } + break; } + case 3: { int i; + for (i = 0; i < 4 && png_ptr->pass == 3; i++) { png_push_have_row(png_ptr, png_ptr->row_buf + 1); png_read_push_finish_row(png_ptr); } - if (png_ptr->pass == 4) /* skip top two generated rows */ + + if (png_ptr->pass == 4) /* Skip top two generated rows */ { for (i = 0; i < 2 && png_ptr->pass == 4; i++) { @@ -919,49 +1018,61 @@ png_push_process_row(png_structp png_ptr) png_read_push_finish_row(png_ptr); } } + break; } + case 4: { int i; + for (i = 0; i < 2 && png_ptr->pass == 4; i++) { png_push_have_row(png_ptr, png_ptr->row_buf + 1); png_read_push_finish_row(png_ptr); } + for (i = 0; i < 2 && png_ptr->pass == 4; i++) { png_push_have_row(png_ptr, png_bytep_NULL); png_read_push_finish_row(png_ptr); } - if (png_ptr->pass == 6) /* pass 5 might be empty */ + + if (png_ptr->pass == 6) /* Pass 5 might be empty */ { png_push_have_row(png_ptr, png_bytep_NULL); png_read_push_finish_row(png_ptr); } + break; } + case 5: { int i; + for (i = 0; i < 2 && png_ptr->pass == 5; i++) { png_push_have_row(png_ptr, png_ptr->row_buf + 1); png_read_push_finish_row(png_ptr); } - if (png_ptr->pass == 6) /* skip top generated row */ + + if (png_ptr->pass == 6) /* Skip top generated row */ { png_push_have_row(png_ptr, png_bytep_NULL); png_read_push_finish_row(png_ptr); } + break; } case 6: { png_push_have_row(png_ptr, png_ptr->row_buf + 1); png_read_push_finish_row(png_ptr); + if (png_ptr->pass != 6) break; + png_push_have_row(png_ptr, png_bytep_NULL); png_read_push_finish_row(png_ptr); } @@ -979,28 +1090,23 @@ void /* PRIVATE */ png_read_push_finish_row(png_structp png_ptr) { #ifdef PNG_USE_LOCAL_ARRAYS - /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - /* start of interlace block */ - const int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; + /* Start of interlace block */ + PNG_CONST int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; - /* offset to next interlace block */ - const int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; + /* Offset to next interlace block */ + PNG_CONST int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; - /* start of interlace block in the y direction */ - const int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; + /* Start of interlace block in the y direction */ + PNG_CONST int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; - /* offset to next interlace block in the y direction */ - const int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; - - /* Width of interlace block. This is not currently used - if you need - * it, uncomment it here and in png.h - const int FARDATA png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; - */ + /* Offset to next interlace block in the y direction */ + PNG_CONST int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; /* Height of interlace block. This is not currently used - if you need * it, uncomment it here and in png.h - const int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1}; + PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1}; */ #endif @@ -1008,6 +1114,7 @@ png_read_push_finish_row(png_structp png_ptr) if (png_ptr->row_number < png_ptr->num_rows) return; +#if defined(PNG_READ_INTERLACING_SUPPORTED) if (png_ptr->interlaced) { png_ptr->row_number = 0; @@ -1023,6 +1130,7 @@ png_read_push_finish_row(png_structp png_ptr) if (png_ptr->pass > 7) png_ptr->pass--; + if (png_ptr->pass >= 7) break; @@ -1044,6 +1152,7 @@ png_read_push_finish_row(png_structp png_ptr) } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0); } +#endif /* PNG_READ_INTERLACING_SUPPORTED */ } #if defined(PNG_READ_tEXt_SUPPORTED) @@ -1054,8 +1163,7 @@ png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) { png_error(png_ptr, "Out of place tEXt"); - /* to quiet some compiler warnings */ - if(info_ptr == NULL) return; + info_ptr = info_ptr; /* To quiet some compiler warnings */ } #ifdef PNG_MAX_MALLOC_64K @@ -1070,7 +1178,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_uint_32)(length+1)); + (png_uint_32)(length + 1)); png_ptr->current_text[length] = '\0'; png_ptr->current_text_ptr = png_ptr->current_text; png_ptr->current_text_size = (png_size_t)length; @@ -1087,8 +1195,10 @@ png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr) if (png_ptr->buffer_size < png_ptr->current_text_left) text_size = png_ptr->buffer_size; + else text_size = png_ptr->current_text_left; + png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size); png_ptr->current_text_left -= text_size; png_ptr->current_text_ptr += text_size; @@ -1116,9 +1226,9 @@ png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr) key = png_ptr->current_text; for (text = key; *text; text++) - /* empty loop */ ; + /* Empty loop */ ; - if (text != key + png_ptr->current_text_size) + if (text < key + png_ptr->current_text_size) text++; text_ptr = (png_textp)png_malloc(png_ptr, @@ -1151,8 +1261,7 @@ png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) { png_error(png_ptr, "Out of place zTXt"); - /* to quiet some compiler warnings */ - if(info_ptr == NULL) return; + info_ptr = info_ptr; /* To quiet some compiler warnings */ } #ifdef PNG_MAX_MALLOC_64K @@ -1169,7 +1278,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_uint_32)(length+1)); + (png_uint_32)(length + 1)); png_ptr->current_text[length] = '\0'; png_ptr->current_text_ptr = png_ptr->current_text; png_ptr->current_text_size = (png_size_t)length; @@ -1186,8 +1295,10 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr) if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left) text_size = png_ptr->buffer_size; + else text_size = png_ptr->current_text_left; + png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size); png_ptr->current_text_left -= text_size; png_ptr->current_text_ptr += text_size; @@ -1211,10 +1322,10 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr) key = png_ptr->current_text; for (text = key; *text; text++) - /* empty loop */ ; + /* Empty loop */ ; /* zTXt can't have zero text */ - if (text == key + png_ptr->current_text_size) + if (text >= key + png_ptr->current_text_size) { png_ptr->current_text = NULL; png_free(png_ptr, key); @@ -1223,7 +1334,7 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr) text++; - if (*text != PNG_TEXT_COMPRESSION_zTXt) /* check compression byte */ + if (*text != PNG_TEXT_COMPRESSION_zTXt) /* Check compression byte */ { png_ptr->current_text = NULL; png_free(png_ptr, key); @@ -1260,13 +1371,17 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr) if (text == NULL) { text = (png_charp)png_malloc(png_ptr, - (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out - + key_size + 1)); + (png_uint_32)(png_ptr->zbuf_size + - png_ptr->zstream.avail_out + key_size + 1)); + png_memcpy(text + key_size, png_ptr->zbuf, png_ptr->zbuf_size - png_ptr->zstream.avail_out); + png_memcpy(text, key, key_size); + text_size = key_size + png_ptr->zbuf_size - png_ptr->zstream.avail_out; + *(text + text_size) = '\0'; } else @@ -1275,12 +1390,15 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr) tmp = text; text = (png_charp)png_malloc(png_ptr, text_size + - (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out - + 1)); + (png_uint_32)(png_ptr->zbuf_size + - png_ptr->zstream.avail_out + 1)); + png_memcpy(text, tmp, text_size); png_free(png_ptr, tmp); + png_memcpy(text + text_size, png_ptr->zbuf, png_ptr->zbuf_size - png_ptr->zstream.avail_out); + text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out; *(text + text_size) = '\0'; } @@ -1344,8 +1462,7 @@ png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) { png_error(png_ptr, "Out of place iTXt"); - /* to quiet some compiler warnings */ - if(info_ptr == NULL) return; + info_ptr = info_ptr; /* To quiet some compiler warnings */ } #ifdef PNG_MAX_MALLOC_64K @@ -1360,7 +1477,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_uint_32)(length+1)); + (png_uint_32)(length + 1)); png_ptr->current_text[length] = '\0'; png_ptr->current_text_ptr = png_ptr->current_text; png_ptr->current_text_size = (png_size_t)length; @@ -1378,8 +1495,10 @@ png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr) if (png_ptr->buffer_size < png_ptr->current_text_left) text_size = png_ptr->buffer_size; + else text_size = png_ptr->current_text_left; + png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size); png_ptr->current_text_left -= text_size; png_ptr->current_text_ptr += text_size; @@ -1410,26 +1529,33 @@ png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr) key = png_ptr->current_text; for (lang = key; *lang; lang++) - /* empty loop */ ; + /* Empty loop */ ; - if (lang != key + png_ptr->current_text_size) + if (lang < key + png_ptr->current_text_size - 3) lang++; comp_flag = *lang++; - lang++; /* skip comp_type, always zero */ + lang++; /* Skip comp_type, always zero */ for (lang_key = lang; *lang_key; lang_key++) - /* empty loop */ ; - lang_key++; /* skip NUL separator */ + /* Empty loop */ ; - for (text = lang_key; *text; text++) - /* empty loop */ ; + lang_key++; /* Skip NUL separator */ - if (text != key + png_ptr->current_text_size) + text=lang_key; + + if (lang_key < key + png_ptr->current_text_size - 1) + { + for (; *text; text++) + /* Empty loop */ ; + } + + if (text < key + png_ptr->current_text_size) text++; text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)png_sizeof(png_text)); + text_ptr->compression = comp_flag + 2; text_ptr->key = key; text_ptr->lang = lang; @@ -1457,62 +1583,81 @@ void /* PRIVATE */ png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { - png_uint_32 skip=0; - png_check_chunk_name(png_ptr, png_ptr->chunk_name); + png_uint_32 skip = 0; if (!(png_ptr->chunk_name[0] & 0x20)) { #if defined(PNG_READ_UNKNOWN_CHUNKS_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 #if defined(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"); - /* to quiet compiler warnings about unused info_ptr */ - if (info_ptr == NULL) - return; + info_ptr = info_ptr; /* To quiet some compiler warnings */ } #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) { - png_unknown_chunk chunk; - #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_ptr->unknown_chunk.data = NULL; + + else + { + png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, + (png_uint_32)length); + png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length); + } - png_strcpy((png_charp)chunk.name, (png_charp)png_ptr->chunk_name); - chunk.data = (png_bytep)png_malloc(png_ptr, length); - png_crc_read(png_ptr, chunk.data, length); - chunk.size = length; #if defined(PNG_READ_USER_CHUNKS_SUPPORTED) - if(png_ptr->read_user_chunk_fn != NULL) - { - /* callback to user unknown chunk handler */ - if ((*(png_ptr->read_user_chunk_fn)) (png_ptr, &chunk) <= 0) - { - if (!(png_ptr->chunk_name[0] & 0x20)) - if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != - PNG_HANDLE_CHUNK_ALWAYS) - png_chunk_error(png_ptr, "unknown critical chunk"); - } - png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1); - } - else + 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_handle_as_unknown(png_ptr, png_ptr->chunk_name) != + 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); + } + } + + else #endif - png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1); - png_free(png_ptr, chunk.data); + 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; @@ -1546,9 +1691,12 @@ png_progressive_combine_row (png_structp png_ptr, png_bytep old_row, png_bytep new_row) { #ifdef PNG_USE_LOCAL_ARRAYS - const int FARDATA png_pass_dsp_mask[7] = + PNG_CONST int FARDATA png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff}; #endif + if (png_ptr == NULL) + return; + if (new_row != NULL) /* new_row must == png_ptr->row_buf here. */ png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]); } @@ -1558,6 +1706,9 @@ 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) { + if (png_ptr == NULL) + return; + png_ptr->info_fn = info_fn; png_ptr->row_fn = row_fn; png_ptr->end_fn = end_fn; @@ -1568,6 +1719,9 @@ png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr, png_voidp PNGAPI png_get_progressive_ptr(png_structp png_ptr) { + if (png_ptr == NULL) + return (NULL); + return png_ptr->io_ptr; } #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ diff --git a/3rdparty/wxWidgets/src/png/pngread.c b/3rdparty/wxWidgets/src/png/pngread.c index 22240227d6..a4cbb3e226 100644 --- a/3rdparty/wxWidgets/src/png/pngread.c +++ b/3rdparty/wxWidgets/src/png/pngread.c @@ -1,18 +1,22 @@ /* pngread.c - read a PNG file * - * libpng 1.2.7 - September 12, 2004 - * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2004 Glenn Randers-Pehrson + * Last changed in libpng 1.2.37 [June 4, 2009] + * Copyright (c) 1998-2009 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. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * * This file contains routines that an application calls directly to * read a PNG file or stream. */ #define PNG_INTERNAL #include "png.h" +#if defined(PNG_READ_SUPPORTED) /* Create a PNG structure for reading, and allocate any memory needed. */ png_structp PNGAPI @@ -33,6 +37,9 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, { #endif /* PNG_USER_MEM_SUPPORTED */ +#ifdef PNG_SETJMP_SUPPORTED + volatile +#endif png_structp png_ptr; #ifdef PNG_SETJMP_SUPPORTED @@ -43,7 +50,7 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, int i; - png_debug(1, "in png_create_read_struct\n"); + png_debug(1, "in png_create_read_struct"); #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); @@ -53,13 +60,7 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, if (png_ptr == NULL) return (NULL); -#if !defined(PNG_1_0_X) -#ifdef PNG_ASSEMBLER_CODE_SUPPORTED - png_init_mmx_flags(png_ptr); /* 1.2.0 addition */ -#endif -#endif /* PNG_1_0_X */ - - /* added at libpng-1.2.6 */ + /* Added at libpng-1.2.6 */ #ifdef PNG_SET_USER_LIMITS_SUPPORTED png_ptr->user_width_max=PNG_USER_WIDTH_MAX; png_ptr->user_height_max=PNG_USER_HEIGHT_MAX; @@ -73,9 +74,9 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, #endif { png_free(png_ptr, png_ptr->zbuf); - png_ptr->zbuf=NULL; + png_ptr->zbuf = NULL; #ifdef PNG_USER_MEM_SUPPORTED - png_destroy_struct_2((png_voidp)png_ptr, + png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn, (png_voidp)mem_ptr); #else png_destroy_struct((png_voidp)png_ptr); @@ -83,7 +84,7 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, return (NULL); } #ifdef USE_FAR_KEYWORD - png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf)); + png_memcpy(png_ptr->jmpbuf, jmpbuf, png_sizeof(jmp_buf)); #endif #endif @@ -93,12 +94,18 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn); - i=0; - do + if (user_png_ver) { - if(user_png_ver[i] != png_libpng_ver[i]) + 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; - } while (png_libpng_ver[i++]); + if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH) { @@ -115,23 +122,25 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, char msg[80]; if (user_png_ver) { - sprintf(msg, "Application was compiled with png.h from libpng-%.20s", + png_snprintf(msg, 80, + "Application was compiled with png.h from libpng-%.20s", user_png_ver); png_warning(png_ptr, msg); } - sprintf(msg, "Application is running with png.c from libpng-%.20s", + png_snprintf(msg, 80, + "Application is running with png.c from libpng-%.20s", png_libpng_ver); png_warning(png_ptr, msg); #endif #ifdef PNG_ERROR_NUMBERS_SUPPORTED - png_ptr->flags=0; + png_ptr->flags = 0; #endif png_error(png_ptr, "Incompatible libpng version in application and library"); } } - /* initialize zbuf - compression buffer */ + /* Initialize zbuf - compression buffer */ png_ptr->zbuf_size = PNG_ZBUF_SIZE; png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, (png_uint_32)png_ptr->zbuf_size); @@ -160,7 +169,7 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, #ifdef USE_FAR_KEYWORD if (setjmp(jmpbuf)) PNG_ABORT(); - png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf)); + png_memcpy(png_ptr->jmpbuf, jmpbuf, png_sizeof(jmp_buf)); #else if (setjmp(png_ptr->jmpbuf)) PNG_ABORT(); @@ -169,9 +178,10 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, return (png_ptr); } +#if defined(PNG_1_0_X) || defined(PNG_1_2_X) /* Initialize PNG structure for reading, and allocate any memory needed. This interface is deprecated in favour of the png_create_read_struct(), - and it will eventually disappear. */ + and it will disappear as of libpng-1.3.0. */ #undef png_read_init void PNGAPI png_read_init(png_structp png_ptr) @@ -185,43 +195,48 @@ png_read_init_2(png_structp png_ptr, png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t png_info_size) { /* We only come here via pre-1.0.12-compiled applications */ + if (png_ptr == NULL) + return; #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) - if(png_sizeof(png_struct) > png_struct_size || + if (png_sizeof(png_struct) > png_struct_size || png_sizeof(png_info) > png_info_size) { char msg[80]; - png_ptr->warning_fn=NULL; + png_ptr->warning_fn = NULL; if (user_png_ver) { - sprintf(msg, "Application was compiled with png.h from libpng-%.20s", + png_snprintf(msg, 80, + "Application was compiled with png.h from libpng-%.20s", user_png_ver); png_warning(png_ptr, msg); } - sprintf(msg, "Application is running with png.c from libpng-%.20s", + png_snprintf(msg, 80, + "Application is running with png.c from libpng-%.20s", png_libpng_ver); png_warning(png_ptr, msg); } #endif - if(png_sizeof(png_struct) > png_struct_size) + if (png_sizeof(png_struct) > png_struct_size) { - png_ptr->error_fn=NULL; + png_ptr->error_fn = NULL; #ifdef PNG_ERROR_NUMBERS_SUPPORTED - png_ptr->flags=0; + png_ptr->flags = 0; #endif png_error(png_ptr, "The png struct allocated by the application for reading is too small."); } - if(png_sizeof(png_info) > png_info_size) + if (png_sizeof(png_info) > png_info_size) { - png_ptr->error_fn=NULL; + png_ptr->error_fn = NULL; #ifdef PNG_ERROR_NUMBERS_SUPPORTED - png_ptr->flags=0; + png_ptr->flags = 0; #endif png_error(png_ptr, "The info struct allocated by application for reading is too small."); } png_read_init_3(&png_ptr, user_png_ver, png_struct_size); } +#endif /* PNG_1_0_X || PNG_1_2_X */ void PNGAPI png_read_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver, @@ -231,18 +246,21 @@ png_read_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver, jmp_buf tmp_jmp; /* to save current jump buffer */ #endif - int i=0; + int i = 0; png_structp png_ptr=*ptr_ptr; + if (png_ptr == NULL) + return; + do { - if(user_png_ver[i] != png_libpng_ver[i]) + if (user_png_ver[i] != png_libpng_ver[i]) { #ifdef PNG_LEGACY_SUPPORTED png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; #else - png_ptr->warning_fn=NULL; + png_ptr->warning_fn = NULL; png_warning(png_ptr, "Application uses deprecated png_read_init() and should be recompiled."); break; @@ -250,35 +268,35 @@ png_read_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver, } } while (png_libpng_ver[i++]); - png_debug(1, "in png_read_init_3\n"); + png_debug(1, "in png_read_init_3"); #ifdef PNG_SETJMP_SUPPORTED - /* save jump buffer and error functions */ - png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf)); + /* Save jump buffer and error functions */ + png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof(jmp_buf)); #endif - if(png_sizeof(png_struct) > png_struct_size) - { - png_destroy_struct(png_ptr); - *ptr_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); - png_ptr = *ptr_ptr; - } + if (png_sizeof(png_struct) > png_struct_size) + { + png_destroy_struct(png_ptr); + *ptr_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG); + png_ptr = *ptr_ptr; + } - /* reset all variables to 0 */ - png_memset(png_ptr, 0, png_sizeof (png_struct)); + /* Reset all variables to 0 */ + png_memset(png_ptr, 0, png_sizeof(png_struct)); #ifdef PNG_SETJMP_SUPPORTED - /* restore jump buffer */ - png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf)); + /* Restore jump buffer */ + png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof(jmp_buf)); #endif - /* added at libpng-1.2.6 */ + /* Added at libpng-1.2.6 */ #ifdef PNG_SET_USER_LIMITS_SUPPORTED png_ptr->user_width_max=PNG_USER_WIDTH_MAX; png_ptr->user_height_max=PNG_USER_HEIGHT_MAX; #endif - /* initialize zbuf - compression buffer */ + /* Initialize zbuf - compression buffer */ png_ptr->zbuf_size = PNG_ZBUF_SIZE; png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, (png_uint_32)png_ptr->zbuf_size); @@ -313,7 +331,9 @@ png_read_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver, void PNGAPI png_read_info(png_structp png_ptr, png_infop info_ptr) { - png_debug(1, "in png_read_info\n"); + if (png_ptr == NULL || info_ptr == NULL) + return; + png_debug(1, "in png_read_info"); /* If we haven't checked all of the PNG signature bytes, do so now. */ if (png_ptr->sig_bytes < 8) { @@ -335,93 +355,88 @@ png_read_info(png_structp png_ptr, png_infop info_ptr) png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE; } - for(;;) + for (;;) { #ifdef PNG_USE_LOCAL_ARRAYS - PNG_IHDR; - PNG_IDAT; - PNG_IEND; - PNG_PLTE; + PNG_CONST PNG_IHDR; + PNG_CONST PNG_IDAT; + PNG_CONST PNG_IEND; + PNG_CONST PNG_PLTE; #if defined(PNG_READ_bKGD_SUPPORTED) - PNG_bKGD; + PNG_CONST PNG_bKGD; #endif #if defined(PNG_READ_cHRM_SUPPORTED) - PNG_cHRM; + PNG_CONST PNG_cHRM; #endif #if defined(PNG_READ_gAMA_SUPPORTED) - PNG_gAMA; + PNG_CONST PNG_gAMA; #endif #if defined(PNG_READ_hIST_SUPPORTED) - PNG_hIST; + PNG_CONST PNG_hIST; #endif #if defined(PNG_READ_iCCP_SUPPORTED) - PNG_iCCP; + PNG_CONST PNG_iCCP; #endif #if defined(PNG_READ_iTXt_SUPPORTED) - PNG_iTXt; + PNG_CONST PNG_iTXt; #endif #if defined(PNG_READ_oFFs_SUPPORTED) - PNG_oFFs; + PNG_CONST PNG_oFFs; #endif #if defined(PNG_READ_pCAL_SUPPORTED) - PNG_pCAL; + PNG_CONST PNG_pCAL; #endif #if defined(PNG_READ_pHYs_SUPPORTED) - PNG_pHYs; + PNG_CONST PNG_pHYs; #endif #if defined(PNG_READ_sBIT_SUPPORTED) - PNG_sBIT; + PNG_CONST PNG_sBIT; #endif #if defined(PNG_READ_sCAL_SUPPORTED) - PNG_sCAL; + PNG_CONST PNG_sCAL; #endif #if defined(PNG_READ_sPLT_SUPPORTED) - PNG_sPLT; + PNG_CONST PNG_sPLT; #endif #if defined(PNG_READ_sRGB_SUPPORTED) - PNG_sRGB; + PNG_CONST PNG_sRGB; #endif #if defined(PNG_READ_tEXt_SUPPORTED) - PNG_tEXt; + PNG_CONST PNG_tEXt; #endif #if defined(PNG_READ_tIME_SUPPORTED) - PNG_tIME; + PNG_CONST PNG_tIME; #endif #if defined(PNG_READ_tRNS_SUPPORTED) - PNG_tRNS; + PNG_CONST PNG_tRNS; #endif #if defined(PNG_READ_zTXt_SUPPORTED) - PNG_zTXt; + PNG_CONST PNG_zTXt; #endif -#endif /* PNG_GLOBAL_ARRAYS */ - png_byte chunk_length[4]; - png_uint_32 length; - - png_read_data(png_ptr, chunk_length, 4); - length = png_get_uint_31(png_ptr,chunk_length); - - png_reset_crc(png_ptr); - png_crc_read(png_ptr, png_ptr->chunk_name, 4); - - png_debug2(0, "Reading %s chunk, length=%lu.\n", png_ptr->chunk_name, - length); +#endif /* PNG_USE_LOCAL_ARRAYS */ + png_uint_32 length = png_read_chunk_header(png_ptr); + PNG_CONST png_bytep chunk_name = png_ptr->chunk_name; /* This should be a binary subdivision search or a hash for * matching the chunk name rather than a linear search. */ - if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4)) + 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_memcmp(chunk_name, png_IHDR, 4)) png_handle_IHDR(png_ptr, info_ptr, length); - else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4)) + 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, png_ptr->chunk_name)) + else if (png_handle_as_unknown(png_ptr, chunk_name)) { - if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) + 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(png_ptr->chunk_name, png_PLTE, 4)) + if (!png_memcmp(chunk_name, png_PLTE, 4)) png_ptr->mode |= PNG_HAVE_PLTE; - else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) + else if (!png_memcmp(chunk_name, png_IDAT, 4)) { if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before IDAT"); @@ -432,9 +447,9 @@ png_read_info(png_structp png_ptr, png_infop info_ptr) } } #endif - else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) + else if (!png_memcmp(chunk_name, png_PLTE, 4)) png_handle_PLTE(png_ptr, info_ptr, length); - else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) + else if (!png_memcmp(chunk_name, png_IDAT, 4)) { if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before IDAT"); @@ -447,71 +462,71 @@ png_read_info(png_structp png_ptr, png_infop info_ptr) break; } #if defined(PNG_READ_bKGD_SUPPORTED) - else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4)) + else if (!png_memcmp(chunk_name, png_bKGD, 4)) png_handle_bKGD(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_cHRM_SUPPORTED) - else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4)) + else if (!png_memcmp(chunk_name, png_cHRM, 4)) png_handle_cHRM(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_gAMA_SUPPORTED) - else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4)) + else if (!png_memcmp(chunk_name, png_gAMA, 4)) png_handle_gAMA(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_hIST_SUPPORTED) - else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4)) + else if (!png_memcmp(chunk_name, png_hIST, 4)) png_handle_hIST(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_oFFs_SUPPORTED) - else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4)) + else if (!png_memcmp(chunk_name, png_oFFs, 4)) png_handle_oFFs(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_pCAL_SUPPORTED) - else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4)) + else if (!png_memcmp(chunk_name, png_pCAL, 4)) png_handle_pCAL(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_sCAL_SUPPORTED) - else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4)) + else if (!png_memcmp(chunk_name, png_sCAL, 4)) png_handle_sCAL(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_pHYs_SUPPORTED) - else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4)) + else if (!png_memcmp(chunk_name, png_pHYs, 4)) png_handle_pHYs(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_sBIT_SUPPORTED) - else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4)) + else if (!png_memcmp(chunk_name, png_sBIT, 4)) png_handle_sBIT(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_sRGB_SUPPORTED) - else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4)) + else if (!png_memcmp(chunk_name, png_sRGB, 4)) png_handle_sRGB(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_iCCP_SUPPORTED) - else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4)) + else if (!png_memcmp(chunk_name, png_iCCP, 4)) png_handle_iCCP(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_sPLT_SUPPORTED) - else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4)) + else if (!png_memcmp(chunk_name, png_sPLT, 4)) png_handle_sPLT(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_tEXt_SUPPORTED) - else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4)) + else if (!png_memcmp(chunk_name, png_tEXt, 4)) png_handle_tEXt(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_tIME_SUPPORTED) - else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4)) + else if (!png_memcmp(chunk_name, png_tIME, 4)) png_handle_tIME(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_tRNS_SUPPORTED) - else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4)) + else if (!png_memcmp(chunk_name, png_tRNS, 4)) png_handle_tRNS(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_zTXt_SUPPORTED) - else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4)) + else if (!png_memcmp(chunk_name, png_zTXt, 4)) png_handle_zTXt(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_iTXt_SUPPORTED) - else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4)) + else if (!png_memcmp(chunk_name, png_iTXt, 4)) png_handle_iTXt(png_ptr, info_ptr, length); #endif else @@ -520,11 +535,13 @@ png_read_info(png_structp png_ptr, png_infop info_ptr) } #endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */ -/* optional call to update the users info_ptr structure */ +/* Optional call to update the users info_ptr structure */ void PNGAPI png_read_update_info(png_structp png_ptr, png_infop info_ptr) { - png_debug(1, "in png_read_update_info\n"); + png_debug(1, "in png_read_update_info"); + if (png_ptr == NULL) + return; if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) png_read_start_row(png_ptr); else @@ -542,7 +559,9 @@ png_read_update_info(png_structp png_ptr, png_infop info_ptr) void PNGAPI png_start_read_image(png_structp png_ptr) { - png_debug(1, "in png_start_read_image\n"); + png_debug(1, "in png_start_read_image"); + if (png_ptr == NULL) + return; if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) png_read_start_row(png_ptr); } @@ -553,18 +572,21 @@ void PNGAPI png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) { #ifdef PNG_USE_LOCAL_ARRAYS - PNG_IDAT; - const int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff}; - const int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff}; + PNG_CONST PNG_IDAT; + PNG_CONST int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, + 0xff}; + PNG_CONST int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff}; #endif int ret; - png_debug2(1, "in png_read_row (row %lu, pass %d)\n", + if (png_ptr == NULL) + return; + png_debug2(1, "in png_read_row (row %lu, pass %d)", 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 */ + /* 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_READ_INVERT_SUPPORTED is not defined."); @@ -596,7 +618,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) } #if defined(PNG_READ_INTERLACING_SUPPORTED) - /* if interlaced and we do not need a new row, combine row and return */ + /* If interlaced and we do not need a new row, combine row and return */ if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) { switch (png_ptr->pass) @@ -683,15 +705,9 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) { while (!png_ptr->idat_size) { - png_byte chunk_length[4]; - png_crc_finish(png_ptr, 0); - png_read_data(png_ptr, chunk_length, 4); - png_ptr->idat_size = png_get_uint_31(png_ptr,chunk_length); - - png_reset_crc(png_ptr); - png_crc_read(png_ptr, png_ptr->chunk_name, 4); + png_ptr->idat_size = png_read_chunk_header(png_ptr); if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) png_error(png_ptr, "Not enough image data"); } @@ -727,16 +743,16 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->row_info.width); - if(png_ptr->row_buf[0]) + 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_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf, png_ptr->rowbytes + 1); - + #if defined(PNG_MNG_FEATURES_SUPPORTED) - if((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && + if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) { /* Intrapixel differencing */ @@ -744,19 +760,20 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) } #endif - if (png_ptr->transformations) + + if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA)) png_do_read_transformations(png_ptr); #if defined(PNG_READ_INTERLACING_SUPPORTED) - /* blow up interlaced rows to full size */ + /* Blow up interlaced rows to full size */ if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) { if (png_ptr->pass < 6) -/* old interface (pre-1.0.9): - png_do_read_interlace(&(png_ptr->row_info), - png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations); - */ + /* Old interface (pre-1.0.9): + * png_do_read_interlace(&(png_ptr->row_info), + * png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations); + */ png_do_read_interlace(png_ptr); if (dsp_row != NULL) @@ -803,7 +820,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) * not called png_set_interlace_handling(), the display_row buffer will * be ignored, so pass NULL to it. * - * [*] png_handle_alpha() does not exist yet, as of libpng version 1.2.7 + * [*] png_handle_alpha() does not exist yet, as of this version of libpng */ void PNGAPI @@ -814,7 +831,9 @@ png_read_rows(png_structp png_ptr, png_bytepp row, png_bytepp rp; png_bytepp dp; - png_debug(1, "in png_read_rows\n"); + png_debug(1, "in png_read_rows"); + if (png_ptr == NULL) + return; rp = row; dp = display_row; if (rp != NULL && dp != NULL) @@ -825,14 +844,14 @@ png_read_rows(png_structp png_ptr, png_bytepp row, png_read_row(png_ptr, rptr, dptr); } - else if(rp != NULL) + else if (rp != NULL) for (i = 0; i < num_rows; i++) { png_bytep rptr = *rp; png_read_row(png_ptr, rptr, png_bytep_NULL); rp++; } - else if(dp != NULL) + else if (dp != NULL) for (i = 0; i < num_rows; i++) { png_bytep dptr = *dp; @@ -853,16 +872,18 @@ png_read_rows(png_structp png_ptr, png_bytepp row, * only call this function once. If you desire to have an image for * each pass of a interlaced image, use png_read_rows() instead. * - * [*] png_handle_alpha() does not exist yet, as of libpng version 1.2.7 + * [*] png_handle_alpha() does not exist yet, as of this version of libpng */ void PNGAPI png_read_image(png_structp png_ptr, png_bytepp image) { - png_uint_32 i,image_height; + png_uint_32 i, image_height; int pass, j; png_bytepp rp; - png_debug(1, "in png_read_image\n"); + png_debug(1, "in png_read_image"); + if (png_ptr == NULL) + return; #ifdef PNG_READ_INTERLACING_SUPPORTED pass = png_set_interlace_handling(png_ptr); @@ -897,176 +918,167 @@ png_read_image(png_structp png_ptr, png_bytepp image) void PNGAPI png_read_end(png_structp png_ptr, png_infop info_ptr) { - png_byte chunk_length[4]; - png_uint_32 length; - - png_debug(1, "in png_read_end\n"); + png_debug(1, "in png_read_end"); + if (png_ptr == NULL) + return; png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */ do { #ifdef PNG_USE_LOCAL_ARRAYS - PNG_IHDR; - PNG_IDAT; - PNG_IEND; - PNG_PLTE; + PNG_CONST PNG_IHDR; + PNG_CONST PNG_IDAT; + PNG_CONST PNG_IEND; + PNG_CONST PNG_PLTE; #if defined(PNG_READ_bKGD_SUPPORTED) - PNG_bKGD; + PNG_CONST PNG_bKGD; #endif #if defined(PNG_READ_cHRM_SUPPORTED) - PNG_cHRM; + PNG_CONST PNG_cHRM; #endif #if defined(PNG_READ_gAMA_SUPPORTED) - PNG_gAMA; + PNG_CONST PNG_gAMA; #endif #if defined(PNG_READ_hIST_SUPPORTED) - PNG_hIST; + PNG_CONST PNG_hIST; #endif #if defined(PNG_READ_iCCP_SUPPORTED) - PNG_iCCP; + PNG_CONST PNG_iCCP; #endif #if defined(PNG_READ_iTXt_SUPPORTED) - PNG_iTXt; + PNG_CONST PNG_iTXt; #endif #if defined(PNG_READ_oFFs_SUPPORTED) - PNG_oFFs; + PNG_CONST PNG_oFFs; #endif #if defined(PNG_READ_pCAL_SUPPORTED) - PNG_pCAL; + PNG_CONST PNG_pCAL; #endif #if defined(PNG_READ_pHYs_SUPPORTED) - PNG_pHYs; + PNG_CONST PNG_pHYs; #endif #if defined(PNG_READ_sBIT_SUPPORTED) - PNG_sBIT; + PNG_CONST PNG_sBIT; #endif #if defined(PNG_READ_sCAL_SUPPORTED) - PNG_sCAL; + PNG_CONST PNG_sCAL; #endif #if defined(PNG_READ_sPLT_SUPPORTED) - PNG_sPLT; + PNG_CONST PNG_sPLT; #endif #if defined(PNG_READ_sRGB_SUPPORTED) - PNG_sRGB; + PNG_CONST PNG_sRGB; #endif #if defined(PNG_READ_tEXt_SUPPORTED) - PNG_tEXt; + PNG_CONST PNG_tEXt; #endif #if defined(PNG_READ_tIME_SUPPORTED) - PNG_tIME; + PNG_CONST PNG_tIME; #endif #if defined(PNG_READ_tRNS_SUPPORTED) - PNG_tRNS; + PNG_CONST PNG_tRNS; #endif #if defined(PNG_READ_zTXt_SUPPORTED) - PNG_zTXt; + PNG_CONST PNG_zTXt; #endif -#endif /* PNG_GLOBAL_ARRAYS */ +#endif /* PNG_USE_LOCAL_ARRAYS */ + png_uint_32 length = png_read_chunk_header(png_ptr); + PNG_CONST png_bytep chunk_name = png_ptr->chunk_name; - png_read_data(png_ptr, chunk_length, 4); - length = png_get_uint_31(png_ptr,chunk_length); - - png_reset_crc(png_ptr); - png_crc_read(png_ptr, png_ptr->chunk_name, 4); - - png_debug1(0, "Reading %s chunk.\n", png_ptr->chunk_name); - - if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4)) + if (!png_memcmp(chunk_name, png_IHDR, 4)) png_handle_IHDR(png_ptr, info_ptr, length); - else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4)) + 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, png_ptr->chunk_name)) + else if (png_handle_as_unknown(png_ptr, chunk_name)) { - if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) + if (!png_memcmp(chunk_name, png_IDAT, 4)) { - if (length > 0 || png_ptr->mode & PNG_AFTER_IDAT) + if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) png_error(png_ptr, "Too many IDAT's found"); } - else - png_ptr->mode |= PNG_AFTER_IDAT; png_handle_unknown(png_ptr, info_ptr, length); - if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) + if (!png_memcmp(chunk_name, png_PLTE, 4)) png_ptr->mode |= PNG_HAVE_PLTE; } #endif - else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) + else if (!png_memcmp(chunk_name, png_IDAT, 4)) { /* Zero length IDATs are legal after the last IDAT has been * read, but not after other chunks have been read. */ - if (length > 0 || png_ptr->mode & PNG_AFTER_IDAT) + if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) png_error(png_ptr, "Too many IDAT's found"); png_crc_finish(png_ptr, length); } - else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4)) + else if (!png_memcmp(chunk_name, png_PLTE, 4)) png_handle_PLTE(png_ptr, info_ptr, length); #if defined(PNG_READ_bKGD_SUPPORTED) - else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4)) + else if (!png_memcmp(chunk_name, png_bKGD, 4)) png_handle_bKGD(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_cHRM_SUPPORTED) - else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4)) + else if (!png_memcmp(chunk_name, png_cHRM, 4)) png_handle_cHRM(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_gAMA_SUPPORTED) - else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4)) + else if (!png_memcmp(chunk_name, png_gAMA, 4)) png_handle_gAMA(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_hIST_SUPPORTED) - else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4)) + else if (!png_memcmp(chunk_name, png_hIST, 4)) png_handle_hIST(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_oFFs_SUPPORTED) - else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4)) + else if (!png_memcmp(chunk_name, png_oFFs, 4)) png_handle_oFFs(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_pCAL_SUPPORTED) - else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4)) + else if (!png_memcmp(chunk_name, png_pCAL, 4)) png_handle_pCAL(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_sCAL_SUPPORTED) - else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4)) + else if (!png_memcmp(chunk_name, png_sCAL, 4)) png_handle_sCAL(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_pHYs_SUPPORTED) - else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4)) + else if (!png_memcmp(chunk_name, png_pHYs, 4)) png_handle_pHYs(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_sBIT_SUPPORTED) - else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4)) + else if (!png_memcmp(chunk_name, png_sBIT, 4)) png_handle_sBIT(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_sRGB_SUPPORTED) - else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4)) + else if (!png_memcmp(chunk_name, png_sRGB, 4)) png_handle_sRGB(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_iCCP_SUPPORTED) - else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4)) + else if (!png_memcmp(chunk_name, png_iCCP, 4)) png_handle_iCCP(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_sPLT_SUPPORTED) - else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4)) + else if (!png_memcmp(chunk_name, png_sPLT, 4)) png_handle_sPLT(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_tEXt_SUPPORTED) - else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4)) + else if (!png_memcmp(chunk_name, png_tEXt, 4)) png_handle_tEXt(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_tIME_SUPPORTED) - else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4)) + else if (!png_memcmp(chunk_name, png_tIME, 4)) png_handle_tIME(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_tRNS_SUPPORTED) - else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4)) + else if (!png_memcmp(chunk_name, png_tRNS, 4)) png_handle_tRNS(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_zTXt_SUPPORTED) - else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4)) + else if (!png_memcmp(chunk_name, png_zTXt, 4)) png_handle_zTXt(png_ptr, info_ptr, length); #endif #if defined(PNG_READ_iTXt_SUPPORTED) - else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4)) + else if (!png_memcmp(chunk_name, png_iTXt, 4)) png_handle_iTXt(png_ptr, info_ptr, length); #endif else @@ -1075,7 +1087,7 @@ png_read_end(png_structp png_ptr, png_infop info_ptr) } #endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */ -/* free all memory used by the read */ +/* 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) @@ -1083,13 +1095,20 @@ png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr, png_structp png_ptr = NULL; png_infop info_ptr = NULL, end_info_ptr = NULL; #ifdef PNG_USER_MEM_SUPPORTED - png_free_ptr free_fn; - png_voidp mem_ptr; + png_free_ptr free_fn = NULL; + png_voidp mem_ptr = NULL; #endif - png_debug(1, "in png_destroy_read_struct\n"); + png_debug(1, "in png_destroy_read_struct"); if (png_ptr_ptr != NULL) png_ptr = *png_ptr_ptr; + if (png_ptr == NULL) + return; + +#ifdef PNG_USER_MEM_SUPPORTED + free_fn = png_ptr->free_fn; + mem_ptr = png_ptr->mem_ptr; +#endif if (info_ptr_ptr != NULL) info_ptr = *info_ptr_ptr; @@ -1097,11 +1116,6 @@ png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr, if (end_info_ptr_ptr != NULL) end_info_ptr = *end_info_ptr_ptr; -#ifdef PNG_USER_MEM_SUPPORTED - free_fn = png_ptr->free_fn; - mem_ptr = png_ptr->mem_ptr; -#endif - png_read_destroy(png_ptr, info_ptr, end_info_ptr); if (info_ptr != NULL) @@ -1145,7 +1159,7 @@ png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr, } } -/* free all memory used by the read (old method) */ +/* Free all memory used by the read (old method) */ void /* PRIVATE */ png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr) { @@ -1159,7 +1173,7 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr png_free_ptr free_fn; #endif - png_debug(1, "in png_read_destroy\n"); + png_debug(1, "in png_read_destroy"); if (info_ptr != NULL) png_info_destroy(png_ptr, info_ptr); @@ -1169,6 +1183,7 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr png_free(png_ptr, png_ptr->zbuf); png_free(png_ptr, png_ptr->big_row_buf); png_free(png_ptr, png_ptr->prev_row); + png_free(png_ptr, png_ptr->chunkdata); #if defined(PNG_READ_DITHER_SUPPORTED) png_free(png_ptr, png_ptr->palette_lookup); png_free(png_ptr, png_ptr->dither_index); @@ -1265,7 +1280,7 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_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->jmpbuf, png_sizeof(jmp_buf)); #endif error_fn = png_ptr->error_fn; @@ -1275,7 +1290,7 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr free_fn = png_ptr->free_fn; #endif - png_memset(png_ptr, 0, png_sizeof (png_struct)); + png_memset(png_ptr, 0, png_sizeof(png_struct)); png_ptr->error_fn = error_fn; png_ptr->warning_fn = warning_fn; @@ -1285,7 +1300,7 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr #endif #ifdef PNG_SETJMP_SUPPORTED - png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf)); + png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof(jmp_buf)); #endif } @@ -1293,6 +1308,8 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr void PNGAPI 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; } @@ -1306,8 +1323,10 @@ png_read_png(png_structp png_ptr, png_infop info_ptr, { int row; + if (png_ptr == NULL) + return; #if defined(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); @@ -1318,15 +1337,15 @@ png_read_png(png_structp png_ptr, png_infop info_ptr, */ png_read_info(png_ptr, info_ptr); if (info_ptr->height > PNG_UINT_32_MAX/png_sizeof(png_bytep)) - png_error(png_ptr,"Image is too high to process with png_read_png()"); + png_error(png_ptr, "Image is too high to process with png_read_png()"); /* -------------- image transformations start here ------------------- */ #if defined(PNG_READ_16_TO_8_SUPPORTED) - /* tell libpng to strip 16 bit/color files down to 8 bits per color + /* Tell libpng to strip 16 bit/color files down to 8 bits per color. */ if (transforms & PNG_TRANSFORM_STRIP_16) - png_set_strip_16(png_ptr); + png_set_strip_16(png_ptr); #endif #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED) @@ -1334,7 +1353,7 @@ png_read_png(png_structp png_ptr, png_infop info_ptr, * the background (not recommended). */ if (transforms & PNG_TRANSFORM_STRIP_ALPHA) - png_set_strip_alpha(png_ptr); + png_set_strip_alpha(png_ptr); #endif #if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED) @@ -1342,7 +1361,7 @@ png_read_png(png_structp png_ptr, png_infop info_ptr, * byte into separate bytes (useful for paletted and grayscale images). */ if (transforms & PNG_TRANSFORM_PACKING) - png_set_packing(png_ptr); + png_set_packing(png_ptr); #endif #if defined(PNG_READ_PACKSWAP_SUPPORTED) @@ -1350,7 +1369,7 @@ png_read_png(png_structp png_ptr, png_infop info_ptr, * (not useful if you are using png_set_packing). */ if (transforms & PNG_TRANSFORM_PACKSWAP) - png_set_packswap(png_ptr); + png_set_packswap(png_ptr); #endif #if defined(PNG_READ_EXPAND_SUPPORTED) @@ -1360,9 +1379,9 @@ png_read_png(png_structp png_ptr, png_infop info_ptr, * channels so the data will be available as RGBA quartets. */ if (transforms & PNG_TRANSFORM_EXPAND) - if ((png_ptr->bit_depth < 8) || - (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) || - (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))) + if ((png_ptr->bit_depth < 8) || + (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) || + (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))) png_set_expand(png_ptr); #endif @@ -1370,10 +1389,10 @@ png_read_png(png_structp png_ptr, png_infop info_ptr, */ #if defined(PNG_READ_INVERT_SUPPORTED) - /* invert monochrome files to have 0 as white and 1 as black + /* Invert monochrome files to have 0 as white and 1 as black */ if (transforms & PNG_TRANSFORM_INVERT_MONO) - png_set_invert_mono(png_ptr); + png_set_invert_mono(png_ptr); #endif #if defined(PNG_READ_SHIFT_SUPPORTED) @@ -1392,24 +1411,24 @@ png_read_png(png_structp png_ptr, png_infop info_ptr, #endif #if defined(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); + png_set_bgr(png_ptr); #endif #if defined(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); #endif #if defined(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); + png_set_swap(png_ptr); #endif /* We don't handle adding filler bytes */ @@ -1425,29 +1444,30 @@ png_read_png(png_structp png_ptr, png_infop info_ptr, #ifdef PNG_FREE_ME_SUPPORTED png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0); #endif - if(info_ptr->row_pointers == NULL) + if (info_ptr->row_pointers == NULL) { info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr, info_ptr->height * png_sizeof(png_bytep)); + png_memset(info_ptr->row_pointers, 0, info_ptr->height + * png_sizeof(png_bytep)); #ifdef PNG_FREE_ME_SUPPORTED info_ptr->free_me |= PNG_FREE_ROWS; #endif for (row = 0; row < (int)info_ptr->height; row++) - { info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); - } } png_read_image(png_ptr, info_ptr->row_pointers); info_ptr->valid |= PNG_INFO_IDAT; - /* read rest of file, and get additional chunks in info_ptr - REQUIRED */ + /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */ png_read_end(png_ptr, info_ptr); - if(transforms == 0 || params == NULL) - /* quiet compiler warnings */ return; + transforms = transforms; /* Quiet compiler warnings */ + params = params; } -#endif +#endif /* PNG_INFO_IMAGE_SUPPORTED */ #endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */ +#endif /* PNG_READ_SUPPORTED */ diff --git a/3rdparty/wxWidgets/src/png/pngrio.c b/3rdparty/wxWidgets/src/png/pngrio.c index 806f791981..2267bca9a9 100644 --- a/3rdparty/wxWidgets/src/png/pngrio.c +++ b/3rdparty/wxWidgets/src/png/pngrio.c @@ -1,12 +1,15 @@ /* pngrio.c - functions for data input * - * libpng 1.2.7 - September 12, 2004 - * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2004 Glenn Randers-Pehrson + * Last changed in libpng 1.2.37 [June 4, 2009] + * Copyright (c) 1998-2009 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. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * * This file provides a location for all input. Users who need * special handling are expected to write a function that has the same * arguments as this and performs a similar function, but that possibly @@ -17,16 +20,18 @@ #define PNG_INTERNAL #include "png.h" +#if defined(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 - buffering if you are using unbuffered reads. This should never be asked - to read more then 64K on a 16 bit machine. */ + * reads from a file pointer. Note that this routine sometimes gets called + * with very small lengths, so you should implement some kind of simple + * buffering if you are using unbuffered reads. This should never be asked + * to read more then 64K on a 16 bit machine. + */ void /* PRIVATE */ png_read_data(png_structp png_ptr, png_bytep data, png_size_t length) { - png_debug1(4,"reading %d bytes\n", (int)length); + png_debug1(4, "reading %d bytes", (int)length); if (png_ptr->read_data_fn != NULL) (*(png_ptr->read_data_fn))(png_ptr, data, length); else @@ -35,15 +40,18 @@ png_read_data(png_structp png_ptr, png_bytep data, png_size_t length) #if !defined(PNG_NO_STDIO) /* This is the function that does the actual reading of data. If you are - not reading from a standard C stream, you should create a replacement - read_data function and use it at run time with png_set_read_fn(), rather - than changing the library. */ + * not reading from a standard C stream, you should create a replacement + * 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 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. */ @@ -59,7 +67,7 @@ png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length) png_error(png_ptr, "Read Error"); } #else -/* this is the model-independent version. Since the standard I/O library +/* 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. */ @@ -67,13 +75,15 @@ 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 /* PRIVATE */ +static void PNGAPI png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length) { int check; png_byte *n_data; png_FILE_p io_ptr; + 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); @@ -102,7 +112,7 @@ png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length) err = fread(buf, (png_size_t)1, read, io_ptr); #endif png_memcpy(data, buf, read); /* copy far buffer to near buffer */ - if(err != read) + if (err != read) break; else check += err; @@ -118,22 +128,27 @@ png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length) #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 - unsigned int that is the number of bytes to be read. - To exit and output any fatal error messages the new write - function should call png_error(png_ptr, "Error msg"). */ + * 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 + * unsigned int that is the number of bytes to be read. + * To exit and output any fatal error messages the new write + * function should call png_error(png_ptr, "Error msg"). + * May be NULL, in which case libpng's default function will + * be used. + */ void PNGAPI png_set_read_fn(png_structp png_ptr, png_voidp io_ptr, png_rw_ptr read_data_fn) { + if (png_ptr == NULL) + return; png_ptr->io_ptr = io_ptr; #if !defined(PNG_NO_STDIO) @@ -159,3 +174,4 @@ png_set_read_fn(png_structp png_ptr, png_voidp io_ptr, png_ptr->output_flush_fn = NULL; #endif } +#endif /* PNG_READ_SUPPORTED */ diff --git a/3rdparty/wxWidgets/src/png/pngrtran.c b/3rdparty/wxWidgets/src/png/pngrtran.c index b914d0e653..d7e6b4a95a 100644 --- a/3rdparty/wxWidgets/src/png/pngrtran.c +++ b/3rdparty/wxWidgets/src/png/pngrtran.c @@ -1,12 +1,15 @@ /* pngrtran.c - transforms the data in a row for PNG readers * - * libpng version 1.2.7 - September 12, 2004 - * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2004 Glenn Randers-Pehrson + * Last changed in libpng 1.2.38 [July 16, 2009] + * Copyright (c) 1998-2009 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. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * * This file contains functions optionally called by an application * in order to tell libpng how to handle data when reading a PNG. * Transformations that are used in both reading and writing are @@ -15,29 +18,37 @@ #define PNG_INTERNAL #include "png.h" +#if defined(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) { - png_debug(1, "in png_set_crc_action\n"); + png_debug(1, "in png_set_crc_action"); /* Tell libpng how we react to CRC errors in critical chunks */ + if (png_ptr == NULL) + return; switch (crit_action) { - case PNG_CRC_NO_CHANGE: /* leave setting as is */ + case PNG_CRC_NO_CHANGE: /* Leave setting as is */ break; - case PNG_CRC_WARN_USE: /* warn/use data */ + + case PNG_CRC_WARN_USE: /* Warn/use data */ png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE; break; - case PNG_CRC_QUIET_USE: /* quiet/use data */ + + case PNG_CRC_QUIET_USE: /* Quiet/use data */ png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE | PNG_FLAG_CRC_CRITICAL_IGNORE; break; - case PNG_CRC_WARN_DISCARD: /* not a valid action for critical data */ - png_warning(png_ptr, "Can't discard critical data on CRC error."); - case PNG_CRC_ERROR_QUIT: /* error/quit */ + + case PNG_CRC_WARN_DISCARD: /* Not a valid action for critical data */ + png_warning(png_ptr, + "Can't discard critical data on CRC error."); + case PNG_CRC_ERROR_QUIT: /* Error/quit */ + case PNG_CRC_DEFAULT: default: png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK; @@ -46,22 +57,27 @@ png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action) switch (ancil_action) { - case PNG_CRC_NO_CHANGE: /* leave setting as is */ + case PNG_CRC_NO_CHANGE: /* Leave setting as is */ break; - case PNG_CRC_WARN_USE: /* warn/use data */ + + case PNG_CRC_WARN_USE: /* Warn/use data */ png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE; break; - case PNG_CRC_QUIET_USE: /* quiet/use data */ + + case PNG_CRC_QUIET_USE: /* Quiet/use data */ png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN; break; - case PNG_CRC_ERROR_QUIT: /* error/quit */ + + case PNG_CRC_ERROR_QUIT: /* Error/quit */ png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN; break; - case PNG_CRC_WARN_DISCARD: /* warn/discard data */ + + case PNG_CRC_WARN_DISCARD: /* Warn/discard data */ + case PNG_CRC_DEFAULT: default: png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK; @@ -71,13 +87,15 @@ 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) -/* handle alpha and tRNS via a background color */ +/* 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) { - png_debug(1, "in png_set_background\n"); + png_debug(1, "in png_set_background"); + if (png_ptr == NULL) + return; if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN) { png_warning(png_ptr, "Application must supply a known background gamma"); @@ -90,26 +108,17 @@ png_set_background(png_structp png_ptr, png_ptr->background_gamma = (float)background_gamma; png_ptr->background_gamma_type = (png_byte)(background_gamma_code); png_ptr->transformations |= (need_expand ? PNG_BACKGROUND_EXPAND : 0); - - /* Note: if need_expand is set and color_type is either RGB or RGB_ALPHA - * (in which case need_expand is superfluous anyway), the background color - * might actually be gray yet not be flagged as such. This is not a problem - * for the current code, which uses PNG_BACKGROUND_IS_GRAY only to - * decide when to do the png_do_gray_to_rgb() transformation. - */ - if ((need_expand && !(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) || - (!need_expand && background_color->red == background_color->green && - background_color->red == background_color->blue)) - png_ptr->mode |= PNG_BACKGROUND_IS_GRAY; } #endif #if defined(PNG_READ_16_TO_8_SUPPORTED) -/* strip 16 bit depth files to 8 bit depth */ +/* Strip 16 bit depth files to 8 bit depth */ void PNGAPI png_set_strip_16(png_structp png_ptr) { - png_debug(1, "in png_set_strip_16\n"); + png_debug(1, "in png_set_strip_16"); + if (png_ptr == NULL) + return; png_ptr->transformations |= PNG_16_TO_8; } #endif @@ -118,8 +127,10 @@ png_set_strip_16(png_structp png_ptr) void PNGAPI png_set_strip_alpha(png_structp png_ptr) { - png_debug(1, "in png_set_strip_alpha\n"); - png_ptr->transformations |= PNG_STRIP_ALPHA; + png_debug(1, "in png_set_strip_alpha"); + if (png_ptr == NULL) + return; + png_ptr->flags |= PNG_FLAG_STRIP_ALPHA; } #endif @@ -147,7 +158,9 @@ png_set_dither(png_structp png_ptr, png_colorp palette, int num_palette, int maximum_colors, png_uint_16p histogram, int full_dither) { - png_debug(1, "in png_set_dither\n"); + png_debug(1, "in png_set_dither"); + if (png_ptr == NULL) + return; png_ptr->transformations |= PNG_DITHER; if (!full_dither) @@ -155,7 +168,7 @@ png_set_dither(png_structp png_ptr, png_colorp palette, int i; png_ptr->dither_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->dither_index[i] = (png_byte)i; } @@ -165,27 +178,29 @@ png_set_dither(png_structp png_ptr, png_colorp palette, if (histogram != NULL) { /* This is easy enough, just throw out the least used colors. - Perhaps not the best solution, but good enough. */ + * Perhaps not the best solution, but good enough. + */ int i; - /* initialize an array to sort colors */ + /* Initialize an array to sort colors */ png_ptr->dither_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 dither_sort array */ + /* Initialize the dither_sort array */ for (i = 0; i < num_palette; i++) png_ptr->dither_sort[i] = (png_byte)i; /* Find the least used palette entries by starting a - bubble sort, and running it until we have sorted - out enough colors. Note that we don't care about - sorting all the colors, just finding which are - least used. */ + * bubble sort, and running it until we have sorted + * out enough colors. Note that we don't care about + * sorting all the colors, just finding which are + * least used. + */ for (i = num_palette - 1; i >= maximum_colors; i--) { - int done; /* to stop early if the list is pre-sorted */ + int done; /* To stop early if the list is pre-sorted */ int j; done = 1; @@ -206,13 +221,14 @@ png_set_dither(png_structp png_ptr, png_colorp palette, break; } - /* swap the palette around, and set up a table, if necessary */ + /* Swap the palette around, and set up a table, if necessary */ if (full_dither) { int j = num_palette; - /* put all the useful colors within the max, but don't - move the others */ + /* Put all the useful colors within the max, but don't + * move the others. + */ for (i = 0; i < maximum_colors; i++) { if ((int)png_ptr->dither_sort[i] >= maximum_colors) @@ -228,11 +244,12 @@ png_set_dither(png_structp png_ptr, png_colorp palette, { int j = num_palette; - /* move all the used colors inside the max limit, and - develop a translation table */ + /* Move all the used colors inside the max limit, and + * develop a translation table. + */ for (i = 0; i < maximum_colors; i++) { - /* only move the colors we need to */ + /* Only move the colors we need to */ if ((int)png_ptr->dither_sort[i] >= maximum_colors) { png_color tmp_color; @@ -244,20 +261,20 @@ png_set_dither(png_structp png_ptr, png_colorp palette, tmp_color = palette[j]; palette[j] = palette[i]; palette[i] = tmp_color; - /* indicate where the color went */ + /* Indicate where the color went */ png_ptr->dither_index[j] = (png_byte)i; png_ptr->dither_index[i] = (png_byte)j; } } - /* find closest color for those colors we are not using */ + /* Find closest color for those colors we are not using */ for (i = 0; i < num_palette; i++) { if ((int)png_ptr->dither_index[i] >= maximum_colors) { int min_d, k, min_k, d_index; - /* find the closest color to one we threw out */ + /* Find the closest color to one we threw out */ d_index = png_ptr->dither_index[i]; min_d = PNG_COLOR_DIST(palette[d_index], palette[0]); for (k = 1, min_k = 0; k < maximum_colors; k++) @@ -272,39 +289,39 @@ png_set_dither(png_structp png_ptr, png_colorp palette, min_k = k; } } - /* point to closest color */ + /* Point to closest color */ png_ptr->dither_index[i] = (png_byte)min_k; } } } png_free(png_ptr, png_ptr->dither_sort); - png_ptr->dither_sort=NULL; + png_ptr->dither_sort = NULL; } else { /* This is much harder to do simply (and quickly). Perhaps - we need to go through a median cut routine, but those - don't always behave themselves with only a few colors - as input. So we will just find the closest two colors, - and throw out one of them (chosen somewhat randomly). - [We don't understand this at all, so if someone wants to - work on improving it, be our guest - AED, GRP] - */ + * we need to go through a median cut routine, but those + * don't always behave themselves with only a few colors + * as input. So we will just find the closest two colors, + * and throw out one of them (chosen somewhat randomly). + * [We don't understand this at all, so if someone wants to + * work on improving it, be our guest - AED, GRP] + */ int i; int max_d; int num_new_palette; png_dsortp t; png_dsortpp hash; - t=NULL; + t = NULL; - /* initialize palette index arrays */ + /* 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 */ + /* Initialize the sort array */ for (i = 0; i < num_palette; i++) { png_ptr->index_to_palette[i] = (png_byte)i; @@ -312,21 +329,19 @@ png_set_dither(png_structp png_ptr, png_colorp palette, } hash = (png_dsortpp)png_malloc(png_ptr, (png_uint_32)(769 * - png_sizeof (png_dsortp))); - for (i = 0; i < 769; i++) - hash[i] = NULL; -/* png_memset(hash, 0, 769 * png_sizeof (png_dsortp)); */ + png_sizeof(png_dsortp))); + png_memset(hash, 0, 769 * png_sizeof(png_dsortp)); num_new_palette = num_palette; - /* initial wild guess at how far apart the farthest pixel - pair we will be eliminating will be. Larger - numbers mean more areas will be allocated, Smaller - numbers run the risk of not saving enough data, and - having to do this all over again. - - I have not done extensive checking on this number. - */ + /* Initial wild guess at how far apart the farthest pixel + * pair we will be eliminating will be. Larger + * numbers mean more areas will be allocated, Smaller + * numbers run the risk of not saving enough data, and + * having to do this all over again. + * + * I have not done extensive checking on this number. + */ max_d = 96; while (num_new_palette > maximum_colors) @@ -440,8 +455,8 @@ png_set_dither(png_structp png_ptr, png_colorp palette, png_free(png_ptr, hash); png_free(png_ptr, png_ptr->palette_to_index); png_free(png_ptr, png_ptr->index_to_palette); - png_ptr->palette_to_index=NULL; - png_ptr->index_to_palette=NULL; + png_ptr->palette_to_index = NULL; + png_ptr->index_to_palette = NULL; } num_palette = maximum_colors; } @@ -461,12 +476,10 @@ png_set_dither(png_structp png_ptr, png_colorp palette, int num_green = (1 << PNG_DITHER_GREEN_BITS); int num_blue = (1 << PNG_DITHER_BLUE_BITS); png_size_t num_entries = ((png_size_t)1 << total_bits); - png_ptr->palette_lookup = (png_bytep )png_malloc(png_ptr, - (png_uint_32)(num_entries * png_sizeof (png_byte))); - + (png_uint_32)(num_entries * png_sizeof(png_byte))); png_memset(png_ptr->palette_lookup, 0, num_entries * - png_sizeof (png_byte)); + png_sizeof(png_byte)); distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries * png_sizeof(png_byte))); @@ -530,7 +543,9 @@ png_set_dither(png_structp png_ptr, png_colorp palette, void PNGAPI png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma) { - png_debug(1, "in png_set_gamma\n"); + png_debug(1, "in png_set_gamma"); + 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)) @@ -548,8 +563,11 @@ png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma) void PNGAPI png_set_expand(png_structp png_ptr) { - png_debug(1, "in png_set_expand\n"); - png_ptr->transformations |= PNG_EXPAND; + png_debug(1, "in png_set_expand"); + if (png_ptr == NULL) + return; + png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); + png_ptr->flags &= ~PNG_FLAG_ROW_INIT; } /* GRR 19990627: the following three functions currently are identical @@ -564,30 +582,56 @@ png_set_expand(png_structp png_ptr) * * More to the point, these functions make it obvious what libpng will be * doing, whereas "expand" can (and does) mean any number of things. + * + * GRP 20060307: In libpng-1.4.0, png_set_gray_1_2_4_to_8() was modified + * to expand only the sample depth but not to expand the tRNS to alpha. */ /* Expand paletted images to RGB. */ void PNGAPI png_set_palette_to_rgb(png_structp png_ptr) { - png_debug(1, "in png_set_expand\n"); - png_ptr->transformations |= PNG_EXPAND; + png_debug(1, "in png_set_palette_to_rgb"); + if (png_ptr == NULL) + return; + png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); + png_ptr->flags &= ~PNG_FLAG_ROW_INIT; } +#if !defined(PNG_1_0_X) /* Expand grayscale images of less than 8-bit depth to 8 bits. */ void PNGAPI +png_set_expand_gray_1_2_4_to_8(png_structp png_ptr) +{ + png_debug(1, "in png_set_expand_gray_1_2_4_to_8"); + if (png_ptr == NULL) + return; + png_ptr->transformations |= PNG_EXPAND; + png_ptr->flags &= ~PNG_FLAG_ROW_INIT; +} +#endif + +#if defined(PNG_1_0_X) || defined(PNG_1_2_X) +/* Expand grayscale images of less than 8-bit depth to 8 bits. */ +/* Deprecated as of libpng-1.2.9 */ +void PNGAPI png_set_gray_1_2_4_to_8(png_structp png_ptr) { - png_debug(1, "in png_set_expand\n"); - png_ptr->transformations |= PNG_EXPAND; + png_debug(1, "in png_set_gray_1_2_4_to_8"); + if (png_ptr == NULL) + return; + png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); } +#endif + /* Expand tRNS chunks to alpha channels. */ void PNGAPI png_set_tRNS_to_alpha(png_structp png_ptr) { - png_debug(1, "in png_set_expand\n"); - png_ptr->transformations |= PNG_EXPAND; + png_debug(1, "in png_set_tRNS_to_alpha"); + png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS); + png_ptr->flags &= ~PNG_FLAG_ROW_INIT; } #endif /* defined(PNG_READ_EXPAND_SUPPORTED) */ @@ -595,8 +639,9 @@ png_set_tRNS_to_alpha(png_structp png_ptr) void PNGAPI png_set_gray_to_rgb(png_structp png_ptr) { - png_debug(1, "in png_set_gray_to_rgb\n"); + png_debug(1, "in png_set_gray_to_rgb"); png_ptr->transformations |= PNG_GRAY_TO_RGB; + png_ptr->flags &= ~PNG_FLAG_ROW_INIT; } #endif @@ -610,9 +655,11 @@ 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); - png_set_rgb_to_gray_fixed(png_ptr, error_action, red_fixed, green_fixed); + 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 @@ -620,13 +667,17 @@ void PNGAPI png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action, png_fixed_point red, png_fixed_point green) { - png_debug(1, "in png_set_rgb_to_gray\n"); + png_debug(1, "in png_set_rgb_to_gray"); + if (png_ptr == NULL) + return; switch(error_action) { case 1: png_ptr->transformations |= PNG_RGB_TO_GRAY; break; + case 2: png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN; break; + case 3: png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR; } if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) @@ -634,21 +685,22 @@ png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action, png_ptr->transformations |= PNG_EXPAND; #else { - png_warning(png_ptr, "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED."); + png_warning(png_ptr, + "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED."); png_ptr->transformations &= ~PNG_RGB_TO_GRAY; } #endif { png_uint_16 red_int, green_int; - if(red < 0 || green < 0) + if (red < 0 || green < 0) { red_int = 6968; /* .212671 * 32768 + .5 */ green_int = 23434; /* .715160 * 32768 + .5 */ } - else if(red + green < 100000L) + 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); + red_int = (png_uint_16)(((png_uint_32)red*32768L)/100000L); + green_int = (png_uint_16)(((png_uint_32)green*32768L)/100000L); } else { @@ -658,25 +710,28 @@ png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action, } 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_ptr->rgb_to_gray_blue_coeff = + (png_uint_16)(32768 - red_int - green_int); } } #endif #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ - defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \ - defined(PNG_LEGACY_SUPPORTED) + defined(PNG_LEGACY_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) { - png_debug(1, "in png_set_read_user_transform_fn\n"); + png_debug(1, "in png_set_read_user_transform_fn"); + if (png_ptr == NULL) + return; #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) png_ptr->transformations |= PNG_USER_TRANSFORM; png_ptr->read_user_transform_fn = read_user_transform_fn; #endif #ifdef PNG_LEGACY_SUPPORTED - if(read_user_transform_fn) + if (read_user_transform_fn) png_warning(png_ptr, "This version of libpng does not support user transforms"); #endif @@ -689,9 +744,9 @@ png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr void /* PRIVATE */ png_init_read_transformations(png_structp png_ptr) { - png_debug(1, "in png_init_read_transformations\n"); + png_debug(1, "in png_init_read_transformations"); #if defined(PNG_USELESS_TESTS_SUPPORTED) - if(png_ptr != NULL) + if (png_ptr != NULL) #endif { #if defined(PNG_READ_BACKGROUND_SUPPORTED) || defined(PNG_READ_SHIFT_SUPPORTED) \ @@ -700,30 +755,79 @@ png_init_read_transformations(png_structp png_ptr) #endif #if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED) + +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) + /* Detect gray background and attempt to enable optimization + * for gray --> RGB case + * + * Note: if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or + * RGB_ALPHA (in which case need_expand is superfluous anyway), the + * background color might actually be gray yet not be flagged as such. + * This is not a problem for the current code, which uses + * PNG_BACKGROUND_IS_GRAY only to decide when to do the + * png_do_gray_to_rgb() transformation. + */ + 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; + png_ptr->background.gray = png_ptr->background.red; + } +#endif + if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) && (png_ptr->transformations & PNG_EXPAND)) { if (!(color_type & PNG_COLOR_MASK_COLOR)) /* i.e., GRAY or GRAY_ALPHA */ { - /* expand background chunk. */ + /* Expand background and tRNS chunks */ switch (png_ptr->bit_depth) { 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; + if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) + { + png_ptr->trans_values.gray *= (png_uint_16)0xff; + png_ptr->trans_values.red = png_ptr->trans_values.green + = png_ptr->trans_values.blue = png_ptr->trans_values.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; + if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) + { + png_ptr->trans_values.gray *= (png_uint_16)0x55; + png_ptr->trans_values.red = png_ptr->trans_values.green + = png_ptr->trans_values.blue = png_ptr->trans_values.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; + if (!(png_ptr->transformations & PNG_EXPAND_tRNS)) + { + png_ptr->trans_values.gray *= (png_uint_16)0x11; + png_ptr->trans_values.red = png_ptr->trans_values.green + = png_ptr->trans_values.blue = png_ptr->trans_values.gray; + } break; + case 8: + case 16: png_ptr->background.red = png_ptr->background.green = png_ptr->background.blue = png_ptr->background.gray; @@ -743,12 +847,13 @@ png_init_read_transformations(png_structp png_ptr) if (png_ptr->transformations & PNG_INVERT_ALPHA) { #if defined(PNG_READ_EXPAND_SUPPORTED) - if (!(png_ptr->transformations & PNG_EXPAND)) + 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 */ - int i,istop; + /* 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[i] = (png_byte)(255 - png_ptr->trans[i]); @@ -769,18 +874,19 @@ png_init_read_transformations(png_structp png_ptr) && (fabs(png_ptr->screen_gamma * png_ptr->gamma - 1.0) < PNG_GAMMA_THRESHOLD)) { - int i,k; + int i, k; k=0; for (i=0; inum_trans; i++) { if (png_ptr->trans[i] != 0 && png_ptr->trans[i] != 0xff) - k=1; /* partial transparency is present */ + k=1; /* Partial transparency is present */ } if (k == 0) - png_ptr->transformations &= (~PNG_GAMMA); + png_ptr->transformations &= ~PNG_GAMMA; } - if (png_ptr->transformations & (PNG_GAMMA | PNG_RGB_TO_GRAY)) + if ((png_ptr->transformations & (PNG_GAMMA | PNG_RGB_TO_GRAY)) && + png_ptr->gamma != 0.0) { png_build_gamma_table(png_ptr); #if defined(PNG_READ_BACKGROUND_SUPPORTED) @@ -788,8 +894,7 @@ png_init_read_transformations(png_structp png_ptr) { if (color_type == PNG_COLOR_TYPE_PALETTE) { - /* could skip if no transparency and - */ + /* Could skip if no transparency */ png_color back, back_1; png_colorp palette = png_ptr->palette; int num_palette = png_ptr->num_palette; @@ -814,10 +919,12 @@ png_init_read_transformations(png_structp png_ptr) g = (png_ptr->screen_gamma); gs = 1.0; break; + case PNG_BACKGROUND_GAMMA_FILE: g = 1.0 / (png_ptr->gamma); gs = 1.0 / (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 * @@ -883,6 +990,14 @@ png_init_read_transformations(png_structp png_ptr) palette[i].blue = png_ptr->gamma_table[palette[i].blue]; } } + /* Prevent the transformations being done again, and make sure + * that the now spurious alpha channel is stripped - the code + * has just reduced background composition and gamma correction + * to a simple alpha channel strip. + */ + png_ptr->transformations &= ~PNG_BACKGROUND; + png_ptr->transformations &= ~PNG_GAMMA; + png_ptr->transformations |= PNG_STRIP_ALPHA; } /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */ else @@ -898,10 +1013,12 @@ png_init_read_transformations(png_structp png_ptr) g = (png_ptr->screen_gamma); gs = 1.0; break; + case PNG_BACKGROUND_GAMMA_FILE: g = 1.0 / (png_ptr->gamma); gs = 1.0 / (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 * @@ -943,7 +1060,7 @@ png_init_read_transformations(png_structp png_ptr) } } else - /* transformation does not include PNG_BACKGROUND */ + /* Transformation does not include PNG_BACKGROUND */ #endif /* PNG_READ_BACKGROUND_SUPPORTED */ if (color_type == PNG_COLOR_TYPE_PALETTE) { @@ -957,6 +1074,9 @@ png_init_read_transformations(png_structp png_ptr) palette[i].green = png_ptr->gamma_table[palette[i].green]; palette[i].blue = png_ptr->gamma_table[palette[i].blue]; } + + /* Done the gamma correction. */ + png_ptr->transformations &= ~PNG_GAMMA; } } #if defined(PNG_READ_BACKGROUND_SUPPORTED) @@ -994,6 +1114,10 @@ png_init_read_transformations(png_structp png_ptr) png_ptr->trans[i], back.blue); } } + + /* Handled alpha, still need to strip the channel. */ + png_ptr->transformations &= ~PNG_BACKGROUND; + png_ptr->transformations |= PNG_STRIP_ALPHA; } #endif /* PNG_READ_BACKGROUND_SUPPORTED */ @@ -1024,7 +1148,7 @@ png_init_read_transformations(png_structp png_ptr) } #if !defined(PNG_READ_GAMMA_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) \ && !defined(PNG_READ_BACKGROUND_SUPPORTED) - if(png_ptr) + if (png_ptr) return; #endif } @@ -1036,13 +1160,14 @@ png_init_read_transformations(png_structp png_ptr) void /* PRIVATE */ png_read_transform_info(png_structp png_ptr, png_infop info_ptr) { - png_debug(1, "in png_read_transform_info\n"); + png_debug(1, "in png_read_transform_info"); #if defined(PNG_READ_EXPAND_SUPPORTED) if (png_ptr->transformations & PNG_EXPAND) { if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { - if (png_ptr->num_trans) + if (png_ptr->num_trans && + (png_ptr->transformations & PNG_EXPAND_tRNS)) info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA; else info_ptr->color_type = PNG_COLOR_TYPE_RGB; @@ -1052,7 +1177,10 @@ png_read_transform_info(png_structp png_ptr, png_infop info_ptr) else { if (png_ptr->num_trans) - info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; + { + if (png_ptr->transformations & PNG_EXPAND_tRNS) + info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; + } if (info_ptr->bit_depth < 8) info_ptr->bit_depth = 8; info_ptr->num_trans = 0; @@ -1086,12 +1214,22 @@ png_read_transform_info(png_structp png_ptr, png_infop info_ptr) info_ptr->bit_depth = 8; #endif +#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) + if (png_ptr->transformations & PNG_GRAY_TO_RGB) + info_ptr->color_type |= PNG_COLOR_MASK_COLOR; +#endif + +#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) + if (png_ptr->transformations & PNG_RGB_TO_GRAY) + info_ptr->color_type &= ~PNG_COLOR_MASK_COLOR; +#endif + #if defined(PNG_READ_DITHER_SUPPORTED) if (png_ptr->transformations & PNG_DITHER) { if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) || - (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) && - png_ptr->palette_lookup && info_ptr->bit_depth == 8) + (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) && + png_ptr->palette_lookup && info_ptr->bit_depth == 8) { info_ptr->color_type = PNG_COLOR_TYPE_PALETTE; } @@ -1103,16 +1241,6 @@ png_read_transform_info(png_structp png_ptr, png_infop info_ptr) info_ptr->bit_depth = 8; #endif -#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) - if (png_ptr->transformations & PNG_GRAY_TO_RGB) - info_ptr->color_type |= PNG_COLOR_MASK_COLOR; -#endif - -#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) - if (png_ptr->transformations & PNG_RGB_TO_GRAY) - info_ptr->color_type &= ~PNG_COLOR_MASK_COLOR; -#endif - if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) info_ptr->channels = 1; else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR) @@ -1121,7 +1249,7 @@ png_read_transform_info(png_structp png_ptr, png_infop info_ptr) info_ptr->channels = 1; #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED) - if (png_ptr->transformations & PNG_STRIP_ALPHA) + if (png_ptr->flags & PNG_FLAG_STRIP_ALPHA) info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA; #endif @@ -1135,7 +1263,7 @@ png_read_transform_info(png_structp png_ptr, png_infop info_ptr) (info_ptr->color_type == PNG_COLOR_TYPE_GRAY))) { info_ptr->channels++; - /* if adding a true alpha channel not just filler */ + /* If adding a true alpha channel not just filler */ #if !defined(PNG_1_0_X) if (png_ptr->transformations & PNG_ADD_ALPHA) info_ptr->color_type |= PNG_COLOR_MASK_ALPHA; @@ -1145,11 +1273,11 @@ png_read_transform_info(png_structp png_ptr, png_infop info_ptr) #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \ defined(PNG_READ_USER_TRANSFORM_SUPPORTED) - if(png_ptr->transformations & PNG_USER_TRANSFORM) + 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 @@ -1157,10 +1285,10 @@ defined(PNG_READ_USER_TRANSFORM_SUPPORTED) info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth); - info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth,info_ptr->width); + info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width); #if !defined(PNG_READ_EXPAND_SUPPORTED) - if(png_ptr) + if (png_ptr) return; #endif } @@ -1172,20 +1300,31 @@ defined(PNG_READ_USER_TRANSFORM_SUPPORTED) void /* PRIVATE */ png_do_read_transformations(png_structp png_ptr) { - png_debug(1, "in png_do_read_transformations\n"); -#if !defined(PNG_USELESS_TESTS_SUPPORTED) + png_debug(1, "in png_do_read_transformations"); if (png_ptr->row_buf == NULL) { #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) char msg[50]; - sprintf(msg, "NULL row buffer for row %ld, pass %d", png_ptr->row_number, + png_snprintf2(msg, 50, + "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"); #endif } +#ifdef PNG_WARN_UNINITIALIZED_ROW + if (!(png_ptr->flags & PNG_FLAG_ROW_INIT)) + /* Application has failed to call either png_read_start_image() + * or png_read_update_info() after setting transforms that expand + * pixels. This check added to libpng-1.2.19 + */ +#if (PNG_WARN_UNINITIALIZED_ROW==1) + png_error(png_ptr, "Uninitialized row"); +#else + png_warning(png_ptr, "Uninitialized row"); +#endif #endif #if defined(PNG_READ_EXPAND_SUPPORTED) @@ -1198,7 +1337,8 @@ png_do_read_transformations(png_structp png_ptr) } else { - if (png_ptr->num_trans) + 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_values)); else @@ -1209,9 +1349,9 @@ png_do_read_transformations(png_structp png_ptr) #endif #if defined(PNG_READ_STRIP_ALPHA_SUPPORTED) - if (png_ptr->transformations & PNG_STRIP_ALPHA) + 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_FLAG_FILLER_AFTER | (png_ptr->flags & PNG_FLAG_STRIP_ALPHA)); #endif #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) @@ -1219,50 +1359,54 @@ png_do_read_transformations(png_structp png_ptr) { int rgb_error = png_do_rgb_to_gray(png_ptr, &(png_ptr->row_info), png_ptr->row_buf + 1); - if(rgb_error) + if (rgb_error) { png_ptr->rgb_to_gray_status=1; - if(png_ptr->transformations == PNG_RGB_TO_GRAY_WARN) + 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_ERR) + 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"); } } #endif -/* -From Andreas Dilger e-mail to png-implement, 26 March 1998: - - In most cases, the "simple transparency" should be done prior to doing - gray-to-RGB, or you will have to test 3x as many bytes to check if a - pixel is transparent. You would also need to make sure that the - transparency information is upgraded to RGB. - - To summarize, the current flow is: - - Gray + simple transparency -> compare 1 or 2 gray bytes and composite - with background "in place" if transparent, - convert to RGB if necessary - - Gray + alpha -> composite with gray background and remove alpha bytes, - convert to RGB if necessary - - To support RGB backgrounds for gray images we need: - - Gray + simple transparency -> convert to RGB + simple transparency, compare - 3 or 6 bytes and composite with background - "in place" if transparent (3x compare/pixel - compared to doing composite with gray bkgrnd) - - Gray + alpha -> convert to RGB + alpha, composite with background and - remove alpha bytes (3x float operations/pixel - compared with composite on gray background) - - Greg's change will do this. The reason it wasn't done before is for - performance, as this increases the per-pixel operations. If we would check - in advance if the background was gray or RGB, and position the gray-to-RGB - transform appropriately, then it would save a lot of work/time. +/* From Andreas Dilger e-mail to png-implement, 26 March 1998: + * + * In most cases, the "simple transparency" should be done prior to doing + * gray-to-RGB, or you will have to test 3x as many bytes to check if a + * pixel is transparent. You would also need to make sure that the + * transparency information is upgraded to RGB. + * + * To summarize, the current flow is: + * - Gray + simple transparency -> compare 1 or 2 gray bytes and composite + * with background "in place" if transparent, + * convert to RGB if necessary + * - Gray + alpha -> composite with gray background and remove alpha bytes, + * convert to RGB if necessary + * + * To support RGB backgrounds for gray images we need: + * - Gray + simple transparency -> convert to RGB + simple transparency, + * compare 3 or 6 bytes and composite with + * background "in place" if transparent + * (3x compare/pixel compared to doing + * composite with gray bkgrnd) + * - Gray + alpha -> convert to RGB + alpha, composite with background and + * remove alpha bytes (3x float + * operations/pixel compared with composite + * on gray background) + * + * Greg's change will do this. The reason it wasn't done before is for + * performance, as this increases the per-pixel operations. If we would check + * in advance if the background was gray or RGB, and position the gray-to-RGB + * transform appropriately, then it would save a lot of work/time. */ #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) - /* if gray -> RGB, do so now only if background is non-gray; else do later - * for performance reasons */ + /* If gray -> RGB, do so now only if background is non-gray; else do later + * for performance reasons + */ if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1); @@ -1287,14 +1431,14 @@ From Andreas Dilger e-mail to png-implement, 26 March 1998: #if defined(PNG_READ_GAMMA_SUPPORTED) if ((png_ptr->transformations & PNG_GAMMA) && #if defined(PNG_READ_BACKGROUND_SUPPORTED) - !((png_ptr->transformations & PNG_BACKGROUND) && - ((png_ptr->num_trans != 0) || - (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) && + !((png_ptr->transformations & PNG_BACKGROUND) && + ((png_ptr->num_trans != 0) || + (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) && #endif - (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)) + (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)) png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1, - png_ptr->gamma_table, png_ptr->gamma_16_table, - png_ptr->gamma_shift); + png_ptr->gamma_table, png_ptr->gamma_16_table, + png_ptr->gamma_shift); #endif #if defined(PNG_READ_16_TO_8_SUPPORTED) @@ -1307,7 +1451,7 @@ From Andreas Dilger e-mail to png-implement, 26 March 1998: { png_do_dither((png_row_infop)&(png_ptr->row_info), png_ptr->row_buf + 1, png_ptr->palette_lookup, png_ptr->dither_index); - if(png_ptr->row_info.rowbytes == (png_uint_32)0) + if (png_ptr->row_info.rowbytes == (png_uint_32)0) png_error(png_ptr, "png_do_dither returned rowbytes=0"); } #endif @@ -1339,7 +1483,7 @@ From Andreas Dilger e-mail to png-implement, 26 March 1998: #endif #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) - /* if gray -> RGB, do so now only if we did not do so above */ + /* If gray -> RGB, do so now only if we did not do so above */ if ((png_ptr->transformations & PNG_GRAY_TO_RGB) && (png_ptr->mode & PNG_BACKGROUND_IS_GRAY)) png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1); @@ -1369,21 +1513,21 @@ From Andreas Dilger e-mail to png-implement, 26 March 1998: #if defined(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 */ + 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 */ #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) - if(png_ptr->user_transform_depth) + if (png_ptr->user_transform_depth) png_ptr->row_info.bit_depth = png_ptr->user_transform_depth; - if(png_ptr->user_transform_channels) + 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 * @@ -1405,7 +1549,7 @@ From Andreas Dilger e-mail to png-implement, 26 March 1998: void /* PRIVATE */ png_do_unpack(png_row_infop row_info, png_bytep row) { - png_debug(1, "in png_do_unpack\n"); + png_debug(1, "in png_do_unpack"); #if defined(PNG_USELESS_TESTS_SUPPORTED) if (row != NULL && row_info != NULL && row_info->bit_depth < 8) #else @@ -1437,6 +1581,7 @@ png_do_unpack(png_row_infop row_info, png_bytep row) } break; } + case 2: { @@ -1458,6 +1603,7 @@ png_do_unpack(png_row_infop row_info, png_bytep row) } break; } + case 4: { png_bytep sp = row + (png_size_t)((row_width - 1) >> 1); @@ -1495,7 +1641,7 @@ png_do_unpack(png_row_infop row_info, png_bytep row) void /* PRIVATE */ png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits) { - png_debug(1, "in png_do_unshift\n"); + png_debug(1, "in png_do_unshift"); if ( #if defined(PNG_USELESS_TESTS_SUPPORTED) row != NULL && row_info != NULL && sig_bits != NULL && @@ -1549,6 +1695,7 @@ png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits) } break; } + case 4: { png_bytep bp = row; @@ -1564,6 +1711,7 @@ png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits) } break; } + case 8: { png_bytep bp = row; @@ -1576,6 +1724,7 @@ png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits) } break; } + case 16: { png_bytep bp = row; @@ -1597,11 +1746,11 @@ png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits) #endif #if defined(PNG_READ_16_TO_8_SUPPORTED) -/* chop rows of bit depth 16 down to 8 */ +/* Chop rows of bit depth 16 down to 8 */ void /* PRIVATE */ png_do_chop(png_row_infop row_info, png_bytep row) { - png_debug(1, "in png_do_chop\n"); + png_debug(1, "in png_do_chop"); #if defined(PNG_USELESS_TESTS_SUPPORTED) if (row != NULL && row_info != NULL && row_info->bit_depth == 16) #else @@ -1621,14 +1770,17 @@ png_do_chop(png_row_infop row_info, png_bytep row) * * What the ideal calculation should be: * *dp = (((((png_uint_32)(*sp) << 8) | - * (png_uint_32)(*(sp + 1))) * 255 + 127) / (png_uint_32)65535L; + * (png_uint_32)(*(sp + 1))) * 255 + 127) + * / (png_uint_32)65535L; * * GRR: no, I think this is what it really should be: * *dp = (((((png_uint_32)(*sp) << 8) | - * (png_uint_32)(*(sp + 1))) + 128L) / (png_uint_32)257L; + * (png_uint_32)(*(sp + 1))) + 128L) + * / (png_uint_32)257L; * * GRR: here's the exact calculation with shifts: - * temp = (((png_uint_32)(*sp) << 8) | (png_uint_32)(*(sp + 1))) + 128L; + * temp = (((png_uint_32)(*sp) << 8) | + * (png_uint_32)(*(sp + 1))) + 128L; * *dp = (temp - (temp >> 8)) >> 8; * * Approximate calculation with shift/add instead of multiply/divide: @@ -1655,7 +1807,7 @@ png_do_chop(png_row_infop row_info, png_bytep row) void /* PRIVATE */ png_do_read_swap_alpha(png_row_infop row_info, png_bytep row) { - png_debug(1, "in png_do_read_swap_alpha\n"); + png_debug(1, "in png_do_read_swap_alpha"); #if defined(PNG_USELESS_TESTS_SUPPORTED) if (row != NULL && row_info != NULL) #endif @@ -1747,7 +1899,7 @@ 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_debug(1, "in png_do_read_invert_alpha\n"); + png_debug(1, "in png_do_read_invert_alpha"); #if defined(PNG_USELESS_TESTS_SUPPORTED) if (row != NULL && row_info != NULL) #endif @@ -1853,14 +2005,14 @@ png_do_read_filler(png_row_infop row_info, png_bytep row, png_byte hi_filler = (png_byte)((filler>>8) & 0xff); png_byte lo_filler = (png_byte)(filler & 0xff); - png_debug(1, "in png_do_read_filler\n"); + png_debug(1, "in png_do_read_filler"); if ( #if defined(PNG_USELESS_TESTS_SUPPORTED) row != NULL && row_info != NULL && #endif row_info->color_type == PNG_COLOR_TYPE_GRAY) { - if(row_info->bit_depth == 8) + if (row_info->bit_depth == 8) { /* This changes the data from G to GX */ if (flags & PNG_FLAG_FILLER_AFTER) @@ -1892,7 +2044,7 @@ png_do_read_filler(png_row_infop row_info, png_bytep row, row_info->rowbytes = row_width * 2; } } - else if(row_info->bit_depth == 16) + else if (row_info->bit_depth == 16) { /* This changes the data from GG to GGXX */ if (flags & PNG_FLAG_FILLER_AFTER) @@ -1932,7 +2084,7 @@ png_do_read_filler(png_row_infop row_info, png_bytep row, } /* COLOR_TYPE == GRAY */ else if (row_info->color_type == PNG_COLOR_TYPE_RGB) { - if(row_info->bit_depth == 8) + if (row_info->bit_depth == 8) { /* This changes the data from RGB to RGBX */ if (flags & PNG_FLAG_FILLER_AFTER) @@ -1968,7 +2120,7 @@ png_do_read_filler(png_row_infop row_info, png_bytep row, row_info->rowbytes = row_width * 4; } } - else if(row_info->bit_depth == 16) + else if (row_info->bit_depth == 16) { /* This changes the data from RRGGBB to RRGGBBXX */ if (flags & PNG_FLAG_FILLER_AFTER) @@ -2018,14 +2170,14 @@ png_do_read_filler(png_row_infop row_info, png_bytep row, #endif #if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) -/* expand grayscale files to RGB, with or without alpha */ +/* Expand grayscale files to RGB, with or without alpha */ void /* PRIVATE */ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) { png_uint_32 i; png_uint_32 row_width = row_info->width; - png_debug(1, "in png_do_gray_to_rgb\n"); + png_debug(1, "in png_do_gray_to_rgb"); if (row_info->bit_depth >= 8 && #if defined(PNG_USELESS_TESTS_SUPPORTED) row != NULL && row_info != NULL && @@ -2095,16 +2247,18 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row) row_info->color_type |= PNG_COLOR_MASK_COLOR; row_info->pixel_depth = (png_byte)(row_info->channels * row_info->bit_depth); - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width); + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); } } #endif #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) -/* reduce RGB files to grayscale, with or without alpha +/* Reduce RGB files to grayscale, with or without alpha * using the equation given in Poynton's ColorFAQ at - * - * Copyright (c) 1998-01-04 Charles Poynton poynton@inforamp.net + * (THIS LINK IS DEAD June 2008) + * New link: + * + * Charles Poynton poynton at poynton.com * * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B * @@ -2129,7 +2283,7 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) png_uint_32 row_width = row_info->width; int rgb_error = 0; - png_debug(1, "in png_do_rgb_to_gray\n"); + png_debug(1, "in png_do_rgb_to_gray"); if ( #if defined(PNG_USELESS_TESTS_SUPPORTED) row != NULL && row_info != NULL && @@ -2155,14 +2309,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) + 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); + *(dp++) = *(sp - 1); } } else @@ -2175,13 +2329,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) + if (red != green || red != blue) { rgb_error |= 1; - *(dp++) = (png_byte)((rc*red+gc*green+bc*blue)>>15); + *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15); } else - *(dp++) = *(sp-1); + *(dp++) = *(sp - 1); } } } @@ -2202,7 +2356,7 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) 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) + if (red == green && red == blue) w = red; else { @@ -2236,7 +2390,7 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) 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) + 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); @@ -2259,7 +2413,7 @@ 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) + if (red != green || red != blue) rgb_error |= 1; *(dp++) = png_ptr->gamma_from_1 [(rc*red + gc*green + bc*blue)>>15]; @@ -2276,7 +2430,7 @@ 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) + if (red != green || red != blue) rgb_error |= 1; *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15); *(dp++) = *(sp++); /* alpha */ @@ -2299,7 +2453,7 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) 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) + if (red == green && red == blue) w = red; else { @@ -2333,7 +2487,7 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) 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) + 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); @@ -2348,7 +2502,7 @@ png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row) row_info->color_type &= ~PNG_COLOR_MASK_COLOR; row_info->pixel_depth = (png_byte)(row_info->channels * row_info->bit_depth); - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width); + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); } return rgb_error; } @@ -2367,7 +2521,7 @@ png_build_grayscale_palette(int bit_depth, png_colorp palette) int i; int v; - png_debug(1, "in png_do_build_grayscale_palette\n"); + png_debug(1, "in png_do_build_grayscale_palette"); if (palette == NULL) return; @@ -2377,18 +2531,22 @@ png_build_grayscale_palette(int bit_depth, png_colorp palette) num_palette = 2; color_inc = 0xff; break; + case 2: num_palette = 4; color_inc = 0x55; break; + case 4: num_palette = 16; color_inc = 0x11; break; + case 8: num_palette = 256; color_inc = 1; break; + default: num_palette = 0; color_inc = 0; @@ -2409,7 +2567,7 @@ void /* PRIVATE */ png_correct_palette(png_structp png_ptr, png_colorp palette, int num_palette) { - png_debug(1, "in png_correct_palette\n"); + png_debug(1, "in png_correct_palette"); #if defined(PNG_READ_BACKGROUND_SUPPORTED) && \ defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED) if (png_ptr->transformations & (PNG_GAMMA | PNG_BACKGROUND)) @@ -2566,7 +2724,7 @@ png_correct_palette(png_structp png_ptr, png_colorp palette, } } } - else /* assume grayscale palette (what else could it be?) */ + else /* Assume grayscale palette (what else could it be?) */ { int i; @@ -2606,7 +2764,7 @@ png_do_background(png_row_infop row_info, png_bytep row, png_uint_32 row_width=row_info->width; int shift; - png_debug(1, "in png_do_background\n"); + png_debug(1, "in png_do_background"); if (background != NULL && #if defined(PNG_USELESS_TESTS_SUPPORTED) row != NULL && row_info != NULL && @@ -2642,6 +2800,7 @@ png_do_background(png_row_infop row_info, png_bytep row, } break; } + case 2: { #if defined(PNG_READ_GAMMA_SUPPORTED) @@ -2698,6 +2857,7 @@ png_do_background(png_row_infop row_info, png_bytep row, } break; } + case 4: { #if defined(PNG_READ_GAMMA_SUPPORTED) @@ -2754,6 +2914,7 @@ png_do_background(png_row_infop row_info, png_bytep row, } break; } + case 8: { #if defined(PNG_READ_GAMMA_SUPPORTED) @@ -2786,6 +2947,7 @@ png_do_background(png_row_infop row_info, png_bytep row, } break; } + case 16: { #if defined(PNG_READ_GAMMA_SUPPORTED) @@ -2799,7 +2961,7 @@ png_do_background(png_row_infop row_info, png_bytep row, v = (png_uint_16)(((*sp) << 8) + *(sp + 1)); if (v == trans_values->gray) { - /* background is already in screen gamma */ + /* Background is already in screen gamma */ *sp = (png_byte)((background->gray >> 8) & 0xff); *(sp + 1) = (png_byte)(background->gray & 0xff); } @@ -2832,6 +2994,7 @@ png_do_background(png_row_infop row_info, png_bytep row, } break; } + case PNG_COLOR_TYPE_RGB: { if (row_info->bit_depth == 8) @@ -2889,7 +3052,7 @@ png_do_background(png_row_infop row_info, png_bytep row, if (r == trans_values->red && g == trans_values->green && b == trans_values->blue) { - /* background is already in screen gamma */ + /* Background is already in screen gamma */ *sp = (png_byte)((background->red >> 8) & 0xff); *(sp + 1) = (png_byte)(background->red & 0xff); *(sp + 2) = (png_byte)((background->green >> 8) & 0xff); @@ -2936,6 +3099,7 @@ png_do_background(png_row_infop row_info, png_bytep row, } break; } + case PNG_COLOR_TYPE_GRAY_ALPHA: { if (row_info->bit_depth == 8) @@ -2956,7 +3120,7 @@ png_do_background(png_row_infop row_info, png_bytep row, } else if (a == 0) { - /* background is already in screen gamma */ + /* Background is already in screen gamma */ *dp = (png_byte)background->gray; } else @@ -3023,7 +3187,7 @@ png_do_background(png_row_infop row_info, png_bytep row, else #endif { - /* background is already in screen gamma */ + /* Background is already in screen gamma */ *dp = (png_byte)((background->gray >> 8) & 0xff); *(dp + 1) = (png_byte)(background->gray & 0xff); } @@ -3078,6 +3242,7 @@ png_do_background(png_row_infop row_info, png_bytep row, } break; } + case PNG_COLOR_TYPE_RGB_ALPHA: { if (row_info->bit_depth == 8) @@ -3100,7 +3265,7 @@ png_do_background(png_row_infop row_info, png_bytep row, } else if (a == 0) { - /* background is already in screen gamma */ + /* Background is already in screen gamma */ *dp = (png_byte)background->red; *(dp + 1) = (png_byte)background->green; *(dp + 2) = (png_byte)background->blue; @@ -3181,7 +3346,7 @@ png_do_background(png_row_infop row_info, png_bytep row, } else if (a == 0) { - /* background is already in screen gamma */ + /* Background is already in screen gamma */ *dp = (png_byte)((background->red >> 8) & 0xff); *(dp + 1) = (png_byte)(background->red & 0xff); *(dp + 2) = (png_byte)((background->green >> 8) & 0xff); @@ -3266,7 +3431,7 @@ png_do_background(png_row_infop row_info, png_bytep row, row_info->channels--; row_info->pixel_depth = (png_byte)(row_info->channels * row_info->bit_depth); - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width); + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); } } } @@ -3288,7 +3453,7 @@ png_do_gamma(png_row_infop row_info, png_bytep row, png_uint_32 i; png_uint_32 row_width=row_info->width; - png_debug(1, "in png_do_gamma\n"); + png_debug(1, "in png_do_gamma"); if ( #if defined(PNG_USELESS_TESTS_SUPPORTED) row != NULL && row_info != NULL && @@ -3336,6 +3501,7 @@ png_do_gamma(png_row_infop row_info, png_bytep row, } break; } + case PNG_COLOR_TYPE_RGB_ALPHA: { if (row_info->bit_depth == 8) @@ -3373,6 +3539,7 @@ png_do_gamma(png_row_infop row_info, png_bytep row, } break; } + case PNG_COLOR_TYPE_GRAY_ALPHA: { if (row_info->bit_depth == 8) @@ -3397,6 +3564,7 @@ png_do_gamma(png_row_infop row_info, png_bytep row, } break; } + case PNG_COLOR_TYPE_GRAY: { if (row_info->bit_depth == 2) @@ -3417,6 +3585,7 @@ png_do_gamma(png_row_infop row_info, png_bytep row, sp++; } } + if (row_info->bit_depth == 4) { sp = row; @@ -3430,6 +3599,7 @@ png_do_gamma(png_row_infop row_info, png_bytep row, sp++; } } + else if (row_info->bit_depth == 8) { sp = row; @@ -3439,6 +3609,7 @@ png_do_gamma(png_row_infop row_info, png_bytep row, sp++; } } + else if (row_info->bit_depth == 16) { sp = row; @@ -3470,7 +3641,7 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row, png_uint_32 i; png_uint_32 row_width=row_info->width; - png_debug(1, "in png_do_expand_palette\n"); + png_debug(1, "in png_do_expand_palette"); if ( #if defined(PNG_USELESS_TESTS_SUPPORTED) row != NULL && row_info != NULL && @@ -3504,6 +3675,7 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row, } break; } + case 2: { sp = row + (png_size_t)((row_width - 1) >> 2); @@ -3525,6 +3697,7 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row, } break; } + case 4: { sp = row + (png_size_t)((row_width - 1) >> 1); @@ -3589,6 +3762,7 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row, *dp-- = palette[*sp].red; sp--; } + row_info->bit_depth = 8; row_info->pixel_depth = 24; row_info->rowbytes = row_width * 3; @@ -3601,8 +3775,8 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row, } } -/* If the bit depth < 8, it is expanded to 8. Also, if the - * transparency value is supplied, an alpha channel is built. +/* If the bit depth < 8, it is expanded to 8. Also, if the already + * expanded transparency value is supplied, an alpha channel is built. */ void /* PRIVATE */ png_do_expand(png_row_infop row_info, png_bytep row, @@ -3613,7 +3787,7 @@ png_do_expand(png_row_infop row_info, png_bytep row, png_uint_32 i; png_uint_32 row_width=row_info->width; - png_debug(1, "in png_do_expand\n"); + png_debug(1, "in png_do_expand"); #if defined(PNG_USELESS_TESTS_SUPPORTED) if (row != NULL && row_info != NULL) #endif @@ -3628,7 +3802,7 @@ png_do_expand(png_row_infop row_info, png_bytep row, { case 1: { - gray = (png_uint_16)(gray*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); @@ -3650,9 +3824,10 @@ png_do_expand(png_row_infop row_info, png_bytep row, } break; } + case 2: { - gray = (png_uint_16)(gray*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); @@ -3673,9 +3848,10 @@ png_do_expand(png_row_infop row_info, png_bytep row, } break; } + case 4: { - gray = (png_uint_16)(gray*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); @@ -3696,6 +3872,7 @@ png_do_expand(png_row_infop row_info, png_bytep row, break; } } + row_info->bit_depth = 8; row_info->pixel_depth = 8; row_info->rowbytes = row_width; @@ -3705,6 +3882,7 @@ png_do_expand(png_row_infop row_info, png_bytep row, { if (row_info->bit_depth == 8) { + 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++) @@ -3716,14 +3894,16 @@ png_do_expand(png_row_infop row_info, png_bytep row, *dp-- = *sp--; } } + else if (row_info->bit_depth == 16) { + png_byte gray_high = (gray >> 8) & 0xff; + png_byte gray_low = gray & 0xff; sp = row + row_info->rowbytes - 1; dp = row + (row_info->rowbytes << 1) - 1; for (i = 0; i < row_width; i++) { - if (((png_uint_16)*(sp) | - ((png_uint_16)*(sp - 1) << 8)) == gray) + if (*(sp - 1) == gray_high && *(sp) == gray_low) { *dp-- = 0; *dp-- = 0; @@ -3737,6 +3917,7 @@ png_do_expand(png_row_infop row_info, png_bytep row, *dp-- = *sp--; } } + row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA; row_info->channels = 2; row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1); @@ -3748,13 +3929,14 @@ 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; 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) == trans_value->red && - *(sp - 1) == trans_value->green && - *(sp - 0) == trans_value->blue) + if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue) *dp-- = 0; else *dp-- = 0xff; @@ -3765,16 +3947,22 @@ 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; sp = row + row_info->rowbytes - 1; dp = row + (png_size_t)(row_width << 3) - 1; for (i = 0; i < row_width; i++) { - if ((((png_uint_16)*(sp - 4) | - ((png_uint_16)*(sp - 5) << 8)) == trans_value->red) && - (((png_uint_16)*(sp - 2) | - ((png_uint_16)*(sp - 3) << 8)) == trans_value->green) && - (((png_uint_16)*(sp - 0) | - ((png_uint_16)*(sp - 1) << 8)) == trans_value->blue)) + if (*(sp - 5) == red_high && + *(sp - 4) == red_low && + *(sp - 3) == green_high && + *(sp - 2) == green_low && + *(sp - 1) == blue_high && + *(sp ) == blue_low) { *dp-- = 0; *dp-- = 0; @@ -3795,7 +3983,7 @@ png_do_expand(png_row_infop row_info, png_bytep row, row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA; row_info->channels = 4; row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2); - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,row_width); + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); } } } @@ -3810,7 +3998,7 @@ png_do_dither(png_row_infop row_info, png_bytep row, png_uint_32 i; png_uint_32 row_width=row_info->width; - png_debug(1, "in png_do_dither\n"); + png_debug(1, "in png_do_dither"); #if defined(PNG_USELESS_TESTS_SUPPORTED) if (row != NULL && row_info != NULL) #endif @@ -3827,13 +4015,13 @@ png_do_dither(png_row_infop row_info, png_bytep row, g = *sp++; b = *sp++; - /* this looks real messy, but the compiler will reduce - it down to a reasonable formula. For example, with - 5 bits per color, we get: - p = (((r >> 3) & 0x1f) << 10) | - (((g >> 3) & 0x1f) << 5) | - ((b >> 3) & 0x1f); - */ + /* This looks real messy, but the compiler will reduce + * it down to a reasonable formula. For example, with + * 5 bits per color, we get: + * p = (((r >> 3) & 0x1f) << 10) | + * (((g >> 3) & 0x1f) << 5) | + * ((b >> 3) & 0x1f); + */ p = (((r >> (8 - PNG_DITHER_RED_BITS)) & ((1 << PNG_DITHER_RED_BITS) - 1)) << (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) | @@ -3848,7 +4036,7 @@ png_do_dither(png_row_infop row_info, png_bytep row, 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); + 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) @@ -3877,7 +4065,7 @@ png_do_dither(png_row_infop row_info, png_bytep row, 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); + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width); } else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE && dither_lookup && row_info->bit_depth == 8) @@ -3894,8 +4082,8 @@ png_do_dither(png_row_infop row_info, png_bytep row, #ifdef PNG_FLOATING_POINT_SUPPORTED #if defined(PNG_READ_GAMMA_SUPPORTED) -static int png_gamma_shift[] = - {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0}; +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 @@ -3905,222 +4093,233 @@ static int png_gamma_shift[] = void /* PRIVATE */ png_build_gamma_table(png_structp png_ptr) { - png_debug(1, "in png_build_gamma_table\n"); - if(png_ptr->gamma != 0.0) + png_debug(1, "in png_build_gamma_table"); + + if (png_ptr->bit_depth <= 8) { - if (png_ptr->bit_depth <= 8) - { - int i; - double g; + int i; + double g; - if (png_ptr->screen_gamma > .000001) - g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma); - else - g = 1.0; + if (png_ptr->screen_gamma > .000001) + g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma); - png_ptr->gamma_table = (png_bytep)png_malloc(png_ptr, - (png_uint_32)256); + else + g = 1.0; - for (i = 0; i < 256; i++) - { - png_ptr->gamma_table[i] = (png_byte)(pow((double)i / 255.0, - g) * 255.0 + .5); - } + 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)) - { + defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) + if (png_ptr->transformations & ((PNG_BACKGROUND) | PNG_RGB_TO_GRAY)) + { - g = 1.0 / (png_ptr->gamma); + g = 1.0 / (png_ptr->gamma); - png_ptr->gamma_to_1 = (png_bytep)png_malloc(png_ptr, - (png_uint_32)256); + 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); - } + 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); + 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 */ + if (png_ptr->screen_gamma > 0.000001) + g = 1.0 / png_ptr->screen_gamma; - for (i = 0; i < 256; i++) - { - png_ptr->gamma_from_1[i] = (png_byte)(pow((double)i / 255.0, - g) * 255.0 + .5); + 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; + } + 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 (png_ptr->color_type & PNG_COLOR_MASK_COLOR) + { + sig_bit = (int)png_ptr->sig_bit.red; - if (sig_bit > 0) - shift = 16 - sig_bit; - else - shift = 0; + if ((int)png_ptr->sig_bit.green > sig_bit) + sig_bit = png_ptr->sig_bit.green; - if (png_ptr->transformations & PNG_16_TO_8) - { - if (shift < (16 - PNG_MAX_GAMMA_8)) - shift = (16 - PNG_MAX_GAMMA_8); - } + 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 (shift > 8) - shift = 8; - if (shift < 0) - shift = 0; + if (sig_bit > 0) + shift = 16 - sig_bit; - png_ptr->gamma_shift = (png_byte)shift; + else + shift = 0; - num = (1 << (8 - shift)); + if (png_ptr->transformations & PNG_16_TO_8) + { + if (shift < (16 - PNG_MAX_GAMMA_8)) + shift = (16 - PNG_MAX_GAMMA_8); + } - if (png_ptr->screen_gamma > .000001) - g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma); - else - g = 1.0; + if (shift > 8) + shift = 8; - png_ptr->gamma_16_table = (png_uint_16pp)png_malloc(png_ptr, - (png_uint_32)(num * png_sizeof (png_uint_16p))); + if (shift < 0) + shift = 0; - if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND)) - { - double fin, fout; - png_uint_32 last, max; + png_ptr->gamma_shift = (png_byte)shift; - 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))); - } + num = (1 << (8 - shift)); - 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))); + if (png_ptr->screen_gamma > .000001) + g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma); + else + g = 1.0; - 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); - } - } - } + png_ptr->gamma_16_table = (png_uint_16pp)png_malloc(png_ptr, + (png_uint_32)(num * png_sizeof(png_uint_16p))); + png_memset(png_ptr->gamma_16_table, 0, 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)) - { + defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) + if (png_ptr->transformations & (PNG_BACKGROUND | PNG_RGB_TO_GRAY)) + { - g = 1.0 / (png_ptr->gamma); + g = 1.0 / (png_ptr->gamma); - png_ptr->gamma_16_to_1 = (png_uint_16pp)png_malloc(png_ptr, - (png_uint_32)(num * png_sizeof (png_uint_16p ))); + png_ptr->gamma_16_to_1 = (png_uint_16pp)png_malloc(png_ptr, + (png_uint_32)(num * png_sizeof(png_uint_16p ))); + png_memset(png_ptr->gamma_16_to_1, 0, 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))); + 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); - } - } + 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 */ + if (png_ptr->screen_gamma > 0.000001) + g = 1.0 / png_ptr->screen_gamma; - png_ptr->gamma_16_from_1 = (png_uint_16pp)png_malloc(png_ptr, - (png_uint_32)(num * png_sizeof (png_uint_16p))); + else + g = png_ptr->gamma; /* Probably doing rgb_to_gray */ - 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))); + png_ptr->gamma_16_from_1 = (png_uint_16pp)png_malloc(png_ptr, + (png_uint_32)(num * png_sizeof(png_uint_16p))); + png_memset(png_ptr->gamma_16_from_1, 0, + num * png_sizeof(png_uint_16p)); - 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); - } - } - } + 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 #if defined(PNG_MNG_FEATURES_SUPPORTED) -/* undoes intrapixel differencing */ +/* Undoes intrapixel differencing */ void /* PRIVATE */ png_do_read_intrapixel(png_row_infop row_info, png_bytep row) { - png_debug(1, "in png_do_read_intrapixel\n"); + png_debug(1, "in png_do_read_intrapixel"); if ( #if defined(PNG_USELESS_TESTS_SUPPORTED) row != NULL && row_info != NULL && @@ -4136,8 +4335,10 @@ png_do_read_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; @@ -4154,18 +4355,20 @@ png_do_read_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 red = (png_uint_32)((s0+s1+65536L) & 0xffffL); - png_uint_32 blue = (png_uint_32)((s2+s1+65536L) & 0xffffL); + 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 + 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); @@ -4175,3 +4378,4 @@ png_do_read_intrapixel(png_row_infop row_info, png_bytep row) } } #endif /* PNG_MNG_FEATURES_SUPPORTED */ +#endif /* PNG_READ_SUPPORTED */ diff --git a/3rdparty/wxWidgets/src/png/pngrutil.c b/3rdparty/wxWidgets/src/png/pngrutil.c index b61664aa6c..f656dfbdfd 100644 --- a/3rdparty/wxWidgets/src/png/pngrutil.c +++ b/3rdparty/wxWidgets/src/png/pngrutil.c @@ -1,53 +1,72 @@ + /* pngrutil.c - utilities to read a PNG file * - * libpng version 1.2.7 - September 12, 2004 - * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2004 Glenn Randers-Pehrson + * Last changed in libpng 1.2.38 [July 16, 2009] + * Copyright (c) 1998-2009 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. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * * This file contains routines that are only called from within * libpng itself during the course of reading an image. */ #define PNG_INTERNAL #include "png.h" +#if defined(PNG_READ_SUPPORTED) -#if defined(_WIN32_WCE) -/* strtod() function is not supported on WindowsCE */ -# ifdef PNG_FLOATING_POINT_SUPPORTED -__inline double strtod(const char *nptr, char **endptr) +#if defined(_WIN32_WCE) && (_WIN32_WCE<0x500) +# define WIN32_WCE_OLD +#endif + +#ifdef PNG_FLOATING_POINT_SUPPORTED +# if defined(WIN32_WCE_OLD) +/* The strtod() function is not supported on WindowsCE */ +__inline double png_strtod(png_structp png_ptr, PNG_CONST char *nptr, char **endptr) { double result = 0; int len; wchar_t *str, *end; len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0); - str = (wchar_t *)malloc(len * sizeof(wchar_t)); + str = (wchar_t *)png_malloc(png_ptr, len * png_sizeof(wchar_t)); if ( NULL != str ) { MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len); result = wcstod(str, &end); len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL); *endptr = (char *)nptr + (png_strlen(nptr) - len + 1); - free(str); + png_free(png_ptr, str); } return result; } +# else +# define png_strtod(p,a,b) strtod(a,b) # endif #endif -png_uint_32 /* PRIVATE */ +png_uint_32 PNGAPI png_get_uint_31(png_structp png_ptr, png_bytep buf) { +#ifdef PNG_READ_BIG_ENDIAN_SUPPORTED png_uint_32 i = png_get_uint_32(buf); +#else + /* Avoid an extra function call by inlining the result. */ + png_uint_32 i = ((png_uint_32)(*buf) << 24) + + ((png_uint_32)(*(buf + 1)) << 16) + + ((png_uint_32)(*(buf + 2)) << 8) + + (png_uint_32)(*(buf + 3)); +#endif if (i > PNG_UINT_31_MAX) - png_error(png_ptr, "PNG unsigned integer out of range.\n"); + png_error(png_ptr, "PNG unsigned integer out of range."); return (i); } #ifndef PNG_READ_BIG_ENDIAN_SUPPORTED /* Grab an unsigned 32-bit integer from a buffer in big-endian format. */ -png_uint_32 /* PRIVATE */ +png_uint_32 PNGAPI png_get_uint_32(png_bytep buf) { png_uint_32 i = ((png_uint_32)(*buf) << 24) + @@ -58,11 +77,11 @@ png_get_uint_32(png_bytep buf) return (i); } -#if defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_READ_oFFs_SUPPORTED) /* Grab a signed 32-bit integer from a buffer in big-endian format. The * data is stored in the PNG file in two's complement format, and it is - * assumed that the machine format for signed integers is the same. */ -png_int_32 /* PRIVATE */ + * assumed that the machine format for signed integers is the same. + */ +png_int_32 PNGAPI png_get_int_32(png_bytep buf) { png_int_32 i = ((png_int_32)(*buf) << 24) + @@ -72,10 +91,9 @@ png_get_int_32(png_bytep buf) return (i); } -#endif /* PNG_READ_pCAL_SUPPORTED */ /* Grab an unsigned 16-bit integer from a buffer in big-endian format. */ -png_uint_16 /* PRIVATE */ +png_uint_16 PNGAPI png_get_uint_16(png_bytep buf) { png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) + @@ -85,18 +103,50 @@ png_get_uint_16(png_bytep buf) } #endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */ +/* Read the chunk header (length + type name). + * Put the type name into png_ptr->chunk_name, and return the length. + */ +png_uint_32 /* PRIVATE */ +png_read_chunk_header(png_structp png_ptr) +{ + png_byte buf[8]; + png_uint_32 length; + + /* Read the length and the chunk name */ + png_read_data(png_ptr, buf, 8); + length = png_get_uint_31(png_ptr, buf); + + /* 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); + + /* Reset the crc and run it over the chunk name */ + png_reset_crc(png_ptr); + png_calculate_crc(png_ptr, png_ptr->chunk_name, 4); + + /* Check to see if chunk name is valid */ + png_check_chunk_name(png_ptr, png_ptr->chunk_name); + + return length; +} + /* Read data, and (optionally) run it through the CRC. */ void /* PRIVATE */ png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length) { + if (png_ptr == NULL) + return; png_read_data(png_ptr, buf, length); png_calculate_crc(png_ptr, buf, length); } /* Optionally skip data and then check the CRC. Depending on whether we - are reading a ancillary or critical chunk, and how the program has set - things up, we may calculate the CRC on the data and print a message. - Returns '1' if there was a CRC error, '0' otherwise. */ + * are reading a ancillary or critical chunk, and how the program has set + * things up, we may calculate the CRC on the data and print a message. + * Returns '1' if there was a CRC error, '0' otherwise. + */ int /* PRIVATE */ png_crc_finish(png_structp png_ptr, png_uint_32 skip) { @@ -115,7 +165,7 @@ png_crc_finish(png_structp png_ptr, png_uint_32 skip) if (png_crc_error(png_ptr)) { if (((png_ptr->chunk_name[0] & 0x20) && /* Ancillary */ - !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) || + !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) || (!(png_ptr->chunk_name[0] & 0x20) && /* Critical */ (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE))) { @@ -132,7 +182,8 @@ png_crc_finish(png_structp png_ptr, png_uint_32 skip) } /* Compare the CRC stored in the PNG file with that calculated by libpng from - the data it has read thus far. */ + * the data it has read thus far. + */ int /* PRIVATE */ png_crc_error(png_structp png_ptr) { @@ -172,19 +223,19 @@ png_crc_error(png_structp png_ptr) * holding the original prefix part and an uncompressed version of the * trailing part (the malloc area passed in is freed). */ -png_charp /* PRIVATE */ +void /* PRIVATE */ png_decompress_chunk(png_structp png_ptr, int comp_type, - png_charp chunkdata, png_size_t chunklength, + png_size_t chunklength, png_size_t prefix_size, png_size_t *newlength) { - static char msg[] = "Error decoding compressed text"; + static PNG_CONST char msg[] = "Error decoding compressed text"; png_charp text; png_size_t text_size; if (comp_type == PNG_COMPRESSION_TYPE_BASE) { int ret = Z_OK; - png_ptr->zstream.next_in = (png_bytep)(chunkdata + prefix_size); + png_ptr->zstream.next_in = (png_bytep)(png_ptr->chunkdata + prefix_size); png_ptr->zstream.avail_in = (uInt)(chunklength - prefix_size); png_ptr->zstream.next_out = png_ptr->zbuf; png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; @@ -210,19 +261,21 @@ png_decompress_chunk(png_structp png_ptr, int comp_type, text = (png_charp)png_malloc_warn(png_ptr, text_size); if (text == NULL) { - png_free(png_ptr,chunkdata); - png_error(png_ptr,"Not enough memory to decompress chunk"); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + png_error(png_ptr, "Not enough memory to decompress chunk"); } - png_memcpy(text, chunkdata, prefix_size); + png_memcpy(text, png_ptr->chunkdata, prefix_size); } text[text_size - 1] = 0x00; /* Copy what we can of the error message into the text chunk */ - text_size = (png_size_t)(chunklength - (text - chunkdata) - 1); - text_size = png_sizeof(msg) > text_size ? text_size : - png_sizeof(msg); - png_memcpy(text + prefix_size, msg, text_size + 1); + text_size = (png_size_t)(chunklength - + (text - png_ptr->chunkdata) - 1); + if (text_size > png_sizeof(msg)) + text_size = png_sizeof(msg); + png_memcpy(text + prefix_size, msg, text_size); break; } if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END) @@ -233,13 +286,15 @@ png_decompress_chunk(png_structp png_ptr, int comp_type, png_ptr->zbuf_size - png_ptr->zstream.avail_out; text = (png_charp)png_malloc_warn(png_ptr, text_size + 1); if (text == NULL) - { - png_free(png_ptr,chunkdata); - png_error(png_ptr,"Not enough memory to decompress chunk."); - } + { + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + png_error(png_ptr, + "Not enough memory to decompress chunk."); + } png_memcpy(text + prefix_size, png_ptr->zbuf, text_size - prefix_size); - png_memcpy(text, chunkdata, prefix_size); + png_memcpy(text, png_ptr->chunkdata, prefix_size); *(text + text_size) = 0x00; } else @@ -253,8 +308,10 @@ png_decompress_chunk(png_structp png_ptr, int comp_type, if (text == NULL) { png_free(png_ptr, tmp); - png_free(png_ptr, chunkdata); - png_error(png_ptr,"Not enough memory to decompress chunk.."); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + png_error(png_ptr, + "Not enough memory to decompress chunk.."); } png_memcpy(text, tmp, text_size); png_free(png_ptr, tmp); @@ -275,32 +332,39 @@ png_decompress_chunk(png_structp png_ptr, int comp_type, if (ret != Z_STREAM_END) { #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) - char umsg[50]; + char umsg[52]; if (ret == Z_BUF_ERROR) - sprintf(umsg,"Buffer error in compressed datastream in %s chunk", - (char *)png_ptr->chunk_name); + png_snprintf(umsg, 52, + "Buffer error in compressed datastream in %s chunk", + png_ptr->chunk_name); + else if (ret == Z_DATA_ERROR) - sprintf(umsg,"Data error in compressed datastream in %s chunk", - (char *)png_ptr->chunk_name); + png_snprintf(umsg, 52, + "Data error in compressed datastream in %s chunk", + png_ptr->chunk_name); + else - sprintf(umsg,"Incomplete compressed datastream in %s chunk", - (char *)png_ptr->chunk_name); + png_snprintf(umsg, 52, + "Incomplete compressed datastream in %s chunk", + png_ptr->chunk_name); + png_warning(png_ptr, umsg); #else png_warning(png_ptr, "Incomplete compressed datastream in chunk other than IDAT"); #endif - text_size=prefix_size; + text_size = prefix_size; if (text == NULL) { text = (png_charp)png_malloc_warn(png_ptr, text_size+1); if (text == NULL) { - png_free(png_ptr, chunkdata); - png_error(png_ptr,"Not enough memory for text."); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + png_error(png_ptr, "Not enough memory for text."); } - png_memcpy(text, chunkdata, prefix_size); + png_memcpy(text, png_ptr->chunkdata, prefix_size); } *(text + text_size) = 0x00; } @@ -308,8 +372,8 @@ png_decompress_chunk(png_structp png_ptr, int comp_type, inflateReset(&png_ptr->zstream); png_ptr->zstream.avail_in = 0; - png_free(png_ptr, chunkdata); - chunkdata = text; + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = text; *newlength=text_size; } else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */ @@ -317,21 +381,19 @@ png_decompress_chunk(png_structp png_ptr, int comp_type, #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) char umsg[50]; - sprintf(umsg, "Unknown zTXt compression type %d", comp_type); + png_snprintf(umsg, 50, "Unknown zTXt compression type %d", comp_type); png_warning(png_ptr, umsg); #else png_warning(png_ptr, "Unknown zTXt compression type"); #endif - *(chunkdata + prefix_size) = 0x00; - *newlength=prefix_size; + *(png_ptr->chunkdata + prefix_size) = 0x00; + *newlength = prefix_size; } - - return chunkdata; } #endif -/* read and check the IDHR chunk */ +/* Read and check the IDHR chunk */ void /* PRIVATE */ png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { @@ -340,12 +402,12 @@ png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) int bit_depth, color_type, compression_type, filter_type; int interlace_type; - png_debug(1, "in png_handle_IHDR\n"); + png_debug(1, "in png_handle_IHDR"); if (png_ptr->mode & PNG_HAVE_IHDR) png_error(png_ptr, "Out of place IHDR"); - /* check the length */ + /* Check the length */ if (length != 13) png_error(png_ptr, "Invalid IHDR chunk"); @@ -362,7 +424,7 @@ png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) filter_type = buf[11]; interlace_type = buf[12]; - /* set internal variables */ + /* Set internal variables */ png_ptr->width = width; png_ptr->height = height; png_ptr->bit_depth = (png_byte)bit_depth; @@ -373,36 +435,39 @@ png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) #endif png_ptr->compression_type = (png_byte)compression_type; - /* find number of channels */ + /* Find number of channels */ switch (png_ptr->color_type) { case PNG_COLOR_TYPE_GRAY: case PNG_COLOR_TYPE_PALETTE: png_ptr->channels = 1; break; + case PNG_COLOR_TYPE_RGB: png_ptr->channels = 3; break; + case PNG_COLOR_TYPE_GRAY_ALPHA: png_ptr->channels = 2; break; + case PNG_COLOR_TYPE_RGB_ALPHA: png_ptr->channels = 4; break; } - /* set up other useful info */ + /* Set up other useful info */ png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth * png_ptr->channels); - png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->width); - png_debug1(3,"bit_depth = %d\n", png_ptr->bit_depth); - png_debug1(3,"channels = %d\n", png_ptr->channels); - png_debug1(3,"rowbytes = %lu\n", png_ptr->rowbytes); + 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_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, interlace_type, compression_type, filter_type); } -/* read and check the palette */ +/* Read and check the palette */ void /* PRIVATE */ png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { @@ -412,16 +477,18 @@ png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_colorp pal_ptr; #endif - png_debug(1, "in png_handle_PLTE\n"); + png_debug(1, "in png_handle_PLTE"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before PLTE"); + else if (png_ptr->mode & PNG_HAVE_IDAT) { png_warning(png_ptr, "Invalid PLTE after IDAT"); png_crc_finish(png_ptr, length); return; } + else if (png_ptr->mode & PNG_HAVE_PLTE) png_error(png_ptr, "Duplicate PLTE chunk"); @@ -450,6 +517,7 @@ png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_crc_finish(png_ptr, length); return; } + else { png_error(png_ptr, "Invalid palette chunk"); @@ -474,7 +542,7 @@ png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_byte buf[3]; png_crc_read(png_ptr, buf, 3); - /* don't depend upon png_color being any order */ + /* Don't depend upon png_color being any order */ palette[i].red = buf[0]; palette[i].green = buf[1]; palette[i].blue = buf[2]; @@ -482,9 +550,10 @@ 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 - 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. */ + * 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. + */ #if !defined(PNG_READ_OPT_PLTE_SUPPORTED) if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) #endif @@ -544,7 +613,7 @@ png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) void /* PRIVATE */ png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { - png_debug(1, "in png_handle_IEND\n"); + png_debug(1, "in png_handle_IEND"); if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT)) { @@ -559,8 +628,7 @@ png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } png_crc_finish(png_ptr, length); - if (&info_ptr == NULL) /* quiet compiler warnings about unused info_ptr */ - return; + info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */ } #if defined(PNG_READ_gAMA_SUPPORTED) @@ -573,7 +641,7 @@ png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) #endif png_byte buf[4]; - png_debug(1, "in png_handle_gAMA\n"); + png_debug(1, "in png_handle_gAMA"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before gAMA"); @@ -610,7 +678,7 @@ png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) return; igamma = (png_fixed_point)png_get_uint_32(buf); - /* check for zero gamma */ + /* Check for zero gamma */ if (igamma == 0) { png_warning(png_ptr, @@ -619,13 +687,13 @@ png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } #if defined(PNG_READ_sRGB_SUPPORTED) - if (info_ptr->valid & PNG_INFO_sRGB) + 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"); #ifndef PNG_NO_CONSOLE_IO - fprintf(stderr, "gamma = (%d/100000)\n", (int)igamma); + fprintf(stderr, "gamma = (%d/100000)", (int)igamma); #endif return; } @@ -651,7 +719,7 @@ png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_size_t truelen; png_byte buf[4]; - png_debug(1, "in png_handle_sBIT\n"); + png_debug(1, "in png_handle_sBIT"); buf[0] = buf[1] = buf[2] = buf[3] = 0; @@ -714,7 +782,7 @@ png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) void /* PRIVATE */ png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { - png_byte buf[4]; + 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 @@ -723,7 +791,7 @@ png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_uint_32 uint_x, uint_y; - png_debug(1, "in png_handle_cHRM\n"); + png_debug(1, "in png_handle_cHRM"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before cHRM"); @@ -755,67 +823,27 @@ png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) return; } - png_crc_read(png_ptr, buf, 4); - uint_x = png_get_uint_32(buf); - - png_crc_read(png_ptr, buf, 4); - uint_y = png_get_uint_32(buf); - - if (uint_x > 80000L || uint_y > 80000L || - uint_x + uint_y > 100000L) - { - png_warning(png_ptr, "Invalid cHRM white point"); - png_crc_finish(png_ptr, 24); + 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; - png_crc_read(png_ptr, buf, 4); - uint_x = png_get_uint_32(buf); - - png_crc_read(png_ptr, buf, 4); - uint_y = png_get_uint_32(buf); - - if (uint_x > 80000L || uint_y > 80000L || - uint_x + uint_y > 100000L) - { - png_warning(png_ptr, "Invalid cHRM red point"); - png_crc_finish(png_ptr, 16); - return; - } + 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; - png_crc_read(png_ptr, buf, 4); - uint_x = png_get_uint_32(buf); - - png_crc_read(png_ptr, buf, 4); - uint_y = png_get_uint_32(buf); - - if (uint_x > 80000L || uint_y > 80000L || - uint_x + uint_y > 100000L) - { - png_warning(png_ptr, "Invalid cHRM green point"); - png_crc_finish(png_ptr, 8); - return; - } + 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; - png_crc_read(png_ptr, buf, 4); - uint_x = png_get_uint_32(buf); - - png_crc_read(png_ptr, buf, 4); - uint_y = png_get_uint_32(buf); - - if (uint_x > 80000L || uint_y > 80000L || - uint_x + uint_y > 100000L) - { - png_warning(png_ptr, "Invalid cHRM blue point"); - png_crc_finish(png_ptr, 0); - return; - } + 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; @@ -831,7 +859,7 @@ png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) #endif #if defined(PNG_READ_sRGB_SUPPORTED) - if (info_ptr->valid & PNG_INFO_sRGB) + if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB)) { if (PNG_OUT_OF_RANGE(int_x_white, 31270, 1000) || PNG_OUT_OF_RANGE(int_y_white, 32900, 1000) || @@ -842,24 +870,22 @@ png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 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"); #ifndef PNG_NO_CONSOLE_IO #ifdef PNG_FLOATING_POINT_SUPPORTED - fprintf(stderr,"wx=%f, wy=%f, rx=%f, ry=%f\n", + 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", + 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", + fprintf(stderr, "wx=%ld, wy=%ld, rx=%ld, ry=%ld\n", int_x_white, int_y_white, int_x_red, int_y_red); - fprintf(stderr,"gx=%ld, gy=%ld, bx=%ld, by=%ld\n", + fprintf(stderr, "gx=%ld, gy=%ld, bx=%ld, by=%ld\n", int_x_green, int_y_green, int_x_blue, int_y_blue); #endif #endif /* PNG_NO_CONSOLE_IO */ } - png_crc_finish(png_ptr, 0); return; } #endif /* PNG_READ_sRGB_SUPPORTED */ @@ -873,8 +899,6 @@ png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 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 - if (png_crc_finish(png_ptr, 0)) - return; } #endif @@ -885,7 +909,7 @@ png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) int intent; png_byte buf[1]; - png_debug(1, "in png_handle_sRGB\n"); + png_debug(1, "in png_handle_sRGB"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before sRGB"); @@ -918,7 +942,7 @@ png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) return; intent = buf[0]; - /* check for bad intent */ + /* Check for bad intent */ if (intent >= PNG_sRGB_INTENT_LAST) { png_warning(png_ptr, "Unknown sRGB intent"); @@ -926,7 +950,7 @@ 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->valid & PNG_INFO_gAMA)) + if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)) { png_fixed_point igamma; #ifdef PNG_FIXED_POINT_SUPPORTED @@ -942,10 +966,11 @@ png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) "Ignoring incorrect gAMA value when sRGB is also present"); #ifndef PNG_NO_CONSOLE_IO # ifdef PNG_FIXED_POINT_SUPPORTED - fprintf(stderr,"incorrect gamma=(%d/100000)\n",(int)png_ptr->int_gamma); + 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); + fprintf(stderr, "incorrect gamma=%f\n", png_ptr->gamma); # endif # endif #endif @@ -955,7 +980,7 @@ png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) #ifdef PNG_READ_cHRM_SUPPORTED #ifdef PNG_FIXED_POINT_SUPPORTED - if (info_ptr->valid & PNG_INFO_cHRM) + 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) || @@ -980,7 +1005,6 @@ void /* PRIVATE */ png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) /* Note: this does not properly handle chunks that are > 64K under DOS */ { - png_charp chunkdata; png_byte compression_type; png_bytep pC; png_charp profile; @@ -988,7 +1012,7 @@ png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_uint_32 profile_size, profile_length; png_size_t slength, prefix_length, data_length; - png_debug(1, "in png_handle_iCCP\n"); + png_debug(1, "in png_handle_iCCP"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before iCCP"); @@ -1018,74 +1042,81 @@ png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } #endif - chunkdata = (png_charp)png_malloc(png_ptr, length + 1); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1); slength = (png_size_t)length; - png_crc_read(png_ptr, (png_bytep)chunkdata, slength); + png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); if (png_crc_finish(png_ptr, skip)) { - png_free(png_ptr, chunkdata); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; return; } - chunkdata[slength] = 0x00; + png_ptr->chunkdata[slength] = 0x00; - for (profile = chunkdata; *profile; profile++) - /* empty loop to find end of name */ ; + for (profile = png_ptr->chunkdata; *profile; profile++) + /* Empty loop to find end of name */ ; ++profile; - /* there should be at least one zero (the compression type byte) - following the separator, and we should be on it */ - if ( profile >= chunkdata + slength) + /* 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) { - png_free(png_ptr, chunkdata); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; png_warning(png_ptr, "Malformed iCCP chunk"); return; } - /* compression_type should always be zero */ + /* Compression_type should always be zero */ compression_type = *profile++; if (compression_type) { png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk"); - compression_type=0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8 + compression_type = 0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8 wrote nonzero) */ } - prefix_length = profile - chunkdata; - chunkdata = png_decompress_chunk(png_ptr, compression_type, chunkdata, - slength, prefix_length, &data_length); + prefix_length = profile - png_ptr->chunkdata; + png_decompress_chunk(png_ptr, compression_type, + slength, prefix_length, &data_length); profile_length = data_length - prefix_length; if ( prefix_length > data_length || profile_length < 4) { - png_free(png_ptr, chunkdata); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; png_warning(png_ptr, "Profile size field missing from iCCP chunk"); return; } /* Check the profile_size recorded in the first 32 bits of the ICC profile */ - pC = (png_bytep)(chunkdata+prefix_length); - profile_size = ((*(pC ))<<24) | - ((*(pC+1))<<16) | - ((*(pC+2))<< 8) | - ((*(pC+3)) ); + pC = (png_bytep)(png_ptr->chunkdata + prefix_length); + profile_size = ((*(pC ))<<24) | + ((*(pC + 1))<<16) | + ((*(pC + 2))<< 8) | + ((*(pC + 3)) ); - if(profile_size < profile_length) + if (profile_size < profile_length) profile_length = profile_size; - if(profile_size > profile_length) + if (profile_size > profile_length) { - png_free(png_ptr, chunkdata); - png_warning(png_ptr, "Ignoring truncated iCCP profile.\n"); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + png_warning(png_ptr, "Ignoring truncated iCCP profile."); return; } - png_set_iCCP(png_ptr, info_ptr, chunkdata, compression_type, - chunkdata + prefix_length, profile_length); - png_free(png_ptr, chunkdata); + png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata, + compression_type, png_ptr->chunkdata + prefix_length, profile_length); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; } #endif /* PNG_READ_iCCP_SUPPORTED */ @@ -1094,7 +1125,6 @@ void /* PRIVATE */ png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) /* Note: this does not properly handle chunks that are > 64K under DOS */ { - png_bytep chunkdata; png_bytep entry_start; png_sPLT_t new_palette; #ifdef PNG_NO_POINTER_INDEXING @@ -1104,7 +1134,8 @@ png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_uint_32 skip = 0; png_size_t slength; - png_debug(1, "in png_handle_sPLT\n"); + png_debug(1, "in png_handle_sPLT"); + if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before sPLT"); @@ -1124,45 +1155,49 @@ png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } #endif - chunkdata = (png_bytep)png_malloc(png_ptr, length + 1); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1); slength = (png_size_t)length; - png_crc_read(png_ptr, (png_bytep)chunkdata, slength); + png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); if (png_crc_finish(png_ptr, skip)) { - png_free(png_ptr, chunkdata); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; return; } - chunkdata[slength] = 0x00; + png_ptr->chunkdata[slength] = 0x00; - for (entry_start = chunkdata; *entry_start; entry_start++) - /* empty loop to find end of name */ ; + 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 */ - if (entry_start > chunkdata + slength) + /* A sample depth should follow the separator, and we should be on it */ + if (entry_start > (png_bytep)png_ptr->chunkdata + slength - 2) { - png_free(png_ptr, chunkdata); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; png_warning(png_ptr, "malformed sPLT chunk"); return; } new_palette.depth = *entry_start++; entry_size = (new_palette.depth == 8 ? 6 : 10); - data_length = (slength - (entry_start - chunkdata)); + data_length = (slength - (entry_start - (png_bytep)png_ptr->chunkdata)); - /* integrity-check the data length */ + /* Integrity-check the data length */ if (data_length % entry_size) { - png_free(png_ptr, chunkdata); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; png_warning(png_ptr, "sPLT chunk has bad length"); return; } - new_palette.nentries = (png_uint_32) (data_length / entry_size); - if ((png_uint_32) new_palette.nentries > (png_uint_32) (PNG_SIZE_MAX / - png_sizeof(png_sPLT_entry))) + 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))) { png_warning(png_ptr, "sPLT chunk too long"); return; @@ -1219,12 +1254,13 @@ png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } #endif - /* discard all chunk data except the name and stash that */ - new_palette.name = (png_charp)chunkdata; + /* Discard all chunk data except the name and stash that */ + new_palette.name = png_ptr->chunkdata; png_set_sPLT(png_ptr, info_ptr, &new_palette, 1); - png_free(png_ptr, chunkdata); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; png_free(png_ptr, new_palette.entries); } #endif /* PNG_READ_sPLT_SUPPORTED */ @@ -1235,7 +1271,7 @@ png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { png_byte readbuf[PNG_MAX_PALETTE_LENGTH]; - png_debug(1, "in png_handle_tRNS\n"); + png_debug(1, "in png_handle_tRNS"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before tRNS"); @@ -1314,7 +1350,10 @@ png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } if (png_crc_finish(png_ptr, 0)) + { + png_ptr->num_trans = 0; return; + } png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans, &(png_ptr->trans_values)); @@ -1328,7 +1367,7 @@ png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_size_t truelen; png_byte buf[6]; - png_debug(1, "in png_handle_bKGD\n"); + png_debug(1, "in png_handle_bKGD"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before bKGD"); @@ -1377,9 +1416,9 @@ png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { png_ptr->background.index = buf[0]; - if(info_ptr->num_palette) + if (info_ptr && info_ptr->num_palette) { - if(buf[0] > info_ptr->num_palette) + if (buf[0] >= info_ptr->num_palette) { png_warning(png_ptr, "Incorrect bKGD chunk index value"); return; @@ -1417,7 +1456,7 @@ png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) unsigned int num, i; png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH]; - png_debug(1, "in png_handle_hIST\n"); + png_debug(1, "in png_handle_hIST"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before hIST"); @@ -1472,7 +1511,7 @@ png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_uint_32 res_x, res_y; int unit_type; - png_debug(1, "in png_handle_pHYs\n"); + png_debug(1, "in png_handle_pHYs"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before pHYs"); @@ -1515,7 +1554,7 @@ png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_int_32 offset_x, offset_y; int unit_type; - png_debug(1, "in png_handle_oFFs\n"); + png_debug(1, "in png_handle_oFFs"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before oFFs"); @@ -1551,11 +1590,10 @@ png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) #endif #if defined(PNG_READ_pCAL_SUPPORTED) -/* read the pCAL chunk (described in the PNG Extensions document) */ +/* Read the pCAL chunk (described in the PNG Extensions document) */ void /* PRIVATE */ png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { - png_charp purpose; png_int_32 X0, X1; png_byte type, nparams; png_charp buf, units, endptr; @@ -1563,7 +1601,7 @@ png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_size_t slength; int i; - png_debug(1, "in png_handle_pCAL\n"); + png_debug(1, "in png_handle_pCAL"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before pCAL"); @@ -1580,48 +1618,51 @@ 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)\n", + png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)", length + 1); - purpose = (png_charp)png_malloc_warn(png_ptr, length + 1); - if (purpose == NULL) + 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; } slength = (png_size_t)length; - png_crc_read(png_ptr, (png_bytep)purpose, slength); + png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); if (png_crc_finish(png_ptr, 0)) { - png_free(png_ptr, purpose); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; return; } - purpose[slength] = 0x00; /* null terminate the last string */ + png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */ - png_debug(3, "Finding end of pCAL purpose string\n"); - for (buf = purpose; *buf; buf++) - /* empty loop */ ; + png_debug(3, "Finding end of pCAL purpose string"); + for (buf = png_ptr->chunkdata; *buf; buf++) + /* Empty loop */ ; - endptr = purpose + slength; + endptr = png_ptr->chunkdata + slength; /* We need to have at least 12 bytes after the purpose string in order to get the parameter information. */ if (endptr <= buf + 12) { png_warning(png_ptr, "Invalid pCAL data"); - png_free(png_ptr, purpose); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; return; } - png_debug(3, "Reading pCAL X0, X1, type, nparams, and units\n"); + png_debug(3, "Reading pCAL X0, X1, type, nparams, and units"); X0 = png_get_int_32((png_bytep)buf+1); X1 = png_get_int_32((png_bytep)buf+5); type = buf[9]; nparams = buf[10]; units = buf + 11; - png_debug(3, "Checking pCAL equation type and number of parameters\n"); + png_debug(3, "Checking pCAL equation type and number of parameters"); /* Check that we have the right number of parameters for known equation types. */ if ((type == PNG_EQUATION_LINEAR && nparams != 2) || @@ -1630,7 +1671,8 @@ png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) (type == PNG_EQUATION_HYPERBOLIC && nparams != 4)) { png_warning(png_ptr, "Invalid pCAL parameters for equation type"); - png_free(png_ptr, purpose); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; return; } else if (type >= PNG_EQUATION_LAST) @@ -1641,12 +1683,13 @@ png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) for (buf = units; *buf; buf++) /* Empty loop to move past the units string. */ ; - png_debug(3, "Allocating pCAL parameters array\n"); - params = (png_charpp)png_malloc_warn(png_ptr, (png_uint_32)(nparams - *png_sizeof(png_charp))) ; + png_debug(3, "Allocating pCAL parameters array"); + params = (png_charpp)png_malloc_warn(png_ptr, + (png_uint_32)(nparams * png_sizeof(png_charp))) ; if (params == NULL) { - png_free(png_ptr, purpose); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; png_warning(png_ptr, "No memory for pCAL params."); return; } @@ -1656,34 +1699,36 @@ 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\n", i); - for (params[i] = buf; *buf != 0x00 && buf <= endptr; buf++) + 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 */ ; /* Make sure we haven't run out of data yet */ if (buf > endptr) { png_warning(png_ptr, "Invalid pCAL data"); - png_free(png_ptr, purpose); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; png_free(png_ptr, params); return; } } - png_set_pCAL(png_ptr, info_ptr, purpose, X0, X1, type, nparams, + png_set_pCAL(png_ptr, info_ptr, png_ptr->chunkdata, X0, X1, type, nparams, units, params); - png_free(png_ptr, purpose); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; png_free(png_ptr, params); } #endif #if defined(PNG_READ_sCAL_SUPPORTED) -/* read the sCAL chunk */ +/* Read the sCAL chunk */ void /* PRIVATE */ png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { - png_charp buffer, ep; + png_charp ep; #ifdef PNG_FLOATING_POINT_SUPPORTED double width, height; png_charp vp; @@ -1694,7 +1739,7 @@ png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) #endif png_size_t slength; - png_debug(1, "in png_handle_sCAL\n"); + png_debug(1, "in png_handle_sCAL"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before sCAL"); @@ -1711,77 +1756,91 @@ 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)\n", + png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)", length + 1); - buffer = (png_charp)png_malloc_warn(png_ptr, length + 1); - if (buffer == NULL) - { - png_warning(png_ptr, "Out of memory while processing sCAL chunk"); - return; - } + 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"); + return; + } slength = (png_size_t)length; - png_crc_read(png_ptr, (png_bytep)buffer, slength); + png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); if (png_crc_finish(png_ptr, 0)) { - png_free(png_ptr, buffer); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; return; } - buffer[slength] = 0x00; /* null terminate the last string */ + png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */ - ep = buffer + 1; /* skip unit byte */ + ep = png_ptr->chunkdata + 1; /* Skip unit byte */ #ifdef PNG_FLOATING_POINT_SUPPORTED - width = strtod(ep, &vp); + width = png_strtod(png_ptr, ep, &vp); if (*vp) { - png_warning(png_ptr, "malformed width string in sCAL chunk"); - return; + png_warning(png_ptr, "malformed width string in sCAL chunk"); + 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"); - return; - } + { + png_warning(png_ptr, "Out of memory while processing sCAL chunk width"); + return; + } png_memcpy(swidth, ep, (png_size_t)png_strlen(ep)); #endif #endif - for (ep = buffer; *ep; ep++) - /* empty loop */ ; + 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_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } + #ifdef PNG_FLOATING_POINT_SUPPORTED - height = strtod(ep, &vp); + height = png_strtod(png_ptr, ep, &vp); if (*vp) { - png_warning(png_ptr, "malformed height string in sCAL chunk"); - return; + png_warning(png_ptr, "malformed height string in sCAL chunk"); + return; } #else #ifdef PNG_FIXED_POINT_SUPPORTED sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1); - if (swidth == NULL) - { - png_warning(png_ptr, "Out of memory while processing sCAL chunk height"); - return; - } + if (sheight == NULL) + { + png_warning(png_ptr, "Out of memory while processing sCAL chunk height"); + return; + } png_memcpy(sheight, ep, (png_size_t)png_strlen(ep)); #endif #endif - if (buffer + slength < ep + if (png_ptr->chunkdata + slength < ep #ifdef PNG_FLOATING_POINT_SUPPORTED || width <= 0. || height <= 0. #endif ) { png_warning(png_ptr, "Invalid sCAL data"); - png_free(png_ptr, 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); @@ -1791,14 +1850,15 @@ png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) #ifdef PNG_FLOATING_POINT_SUPPORTED - png_set_sCAL(png_ptr, info_ptr, buffer[0], width, height); + 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, buffer[0], swidth, sheight); + png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0], swidth, sheight); #endif #endif - png_free(png_ptr, 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); @@ -1813,7 +1873,7 @@ png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_byte buf[7]; png_time mod_time; - png_debug(1, "in png_handle_tIME\n"); + png_debug(1, "in png_handle_tIME"); if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Out of place tIME chunk"); @@ -1861,7 +1921,8 @@ png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_size_t slength; int ret; - png_debug(1, "in png_handle_tEXt\n"); + png_debug(1, "in png_handle_tEXt"); + if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before tEXt"); @@ -1878,25 +1939,30 @@ png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } #endif - key = (png_charp)png_malloc_warn(png_ptr, length + 1); - if (key == NULL) + 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)key, slength); + png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); if (png_crc_finish(png_ptr, skip)) { - png_free(png_ptr, key); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; return; } + key = png_ptr->chunkdata; + key[slength] = 0x00; for (text = key; *text; text++) - /* empty loop to find end of key */ ; + /* Empty loop to find end of key */ ; if (text != key + slength) text++; @@ -1906,7 +1972,8 @@ png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) if (text_ptr == NULL) { png_warning(png_ptr, "Not enough memory to process text chunk."); - png_free(png_ptr, key); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; return; } text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; @@ -1919,9 +1986,10 @@ png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) text_ptr->text = text; text_ptr->text_length = png_strlen(text); - ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1); + ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); - png_free(png_ptr, key); + png_free(png_ptr, 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."); @@ -1929,18 +1997,19 @@ png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) #endif #if defined(PNG_READ_zTXt_SUPPORTED) -/* note: this does not correctly handle chunks that are > 64K under DOS */ +/* Note: this does not correctly handle chunks that are > 64K under DOS */ void /* PRIVATE */ png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { png_textp text_ptr; - png_charp chunkdata; png_charp text; int comp_type; int ret; png_size_t slength, prefix_len, data_len; - png_debug(1, "in png_handle_zTXt\n"); + png_debug(1, "in png_handle_zTXt"); + + if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before zTXt"); @@ -1952,36 +2021,40 @@ png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 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_warning(png_ptr, "zTXt chunk too large to fit in memory"); png_crc_finish(png_ptr, length); return; } #endif - chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); - if (chunkdata == NULL) + 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."); + png_warning(png_ptr, "Out of memory processing zTXt chunk."); return; } slength = (png_size_t)length; - png_crc_read(png_ptr, (png_bytep)chunkdata, slength); + png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); if (png_crc_finish(png_ptr, 0)) { - png_free(png_ptr, chunkdata); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; return; } - chunkdata[slength] = 0x00; + png_ptr->chunkdata[slength] = 0x00; - for (text = chunkdata; *text; text++) - /* empty loop */ ; + for (text = png_ptr->chunkdata; *text; text++) + /* Empty loop */ ; /* zTXt must have some text after the chunkdataword */ - if (text == chunkdata + slength) + if (text >= png_ptr->chunkdata + slength - 2) { - comp_type = PNG_TEXT_COMPRESSION_NONE; - png_warning(png_ptr, "Zero length zTXt chunk"); + png_warning(png_ptr, "Truncated zTXt chunk"); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; } else { @@ -1991,54 +2064,56 @@ png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_warning(png_ptr, "Unknown compression type in zTXt chunk"); comp_type = PNG_TEXT_COMPRESSION_zTXt; } - text++; /* skip the compression_method byte */ + text++; /* Skip the compression_method byte */ } - prefix_len = text - chunkdata; + prefix_len = text - png_ptr->chunkdata; - chunkdata = (png_charp)png_decompress_chunk(png_ptr, comp_type, chunkdata, - (png_size_t)length, prefix_len, &data_len); + png_decompress_chunk(png_ptr, comp_type, + (png_size_t)length, prefix_len, &data_len); text_ptr = (png_textp)png_malloc_warn(png_ptr, - (png_uint_32)png_sizeof(png_text)); + (png_uint_32)png_sizeof(png_text)); if (text_ptr == NULL) { - png_warning(png_ptr,"Not enough memory to process zTXt chunk."); - png_free(png_ptr, chunkdata); + 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 = chunkdata; + 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 = chunkdata + prefix_len; + text_ptr->text = png_ptr->chunkdata + prefix_len; text_ptr->text_length = data_len; - ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1); + ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); png_free(png_ptr, text_ptr); - png_free(png_ptr, chunkdata); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; if (ret) png_error(png_ptr, "Insufficient memory to store zTXt chunk."); } #endif #if defined(PNG_READ_iTXt_SUPPORTED) -/* note: this does not correctly handle chunks that are > 64K under DOS */ +/* Note: this does not correctly handle chunks that are > 64K under DOS */ void /* PRIVATE */ png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { png_textp text_ptr; - png_charp chunkdata; png_charp key, lang, text, lang_key; int comp_flag; int comp_type = 0; int ret; png_size_t slength, prefix_len, data_len; - png_debug(1, "in png_handle_iTXt\n"); + png_debug(1, "in png_handle_iTXt"); + if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before iTXt"); @@ -2051,40 +2126,45 @@ png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 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_warning(png_ptr, "iTXt chunk too large to fit in memory"); png_crc_finish(png_ptr, length); return; } #endif - chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); - if (chunkdata == NULL) + 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; } slength = (png_size_t)length; - png_crc_read(png_ptr, (png_bytep)chunkdata, slength); + png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); if (png_crc_finish(png_ptr, 0)) { - png_free(png_ptr, chunkdata); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; return; } - chunkdata[slength] = 0x00; + png_ptr->chunkdata[slength] = 0x00; - for (lang = chunkdata; *lang; lang++) - /* empty loop */ ; - lang++; /* skip NUL separator */ + for (lang = png_ptr->chunkdata; *lang; lang++) + /* Empty loop */ ; + lang++; /* Skip NUL separator */ /* iTXt must have a language tag (possibly empty), two compression bytes, - translated keyword (possibly empty), and possibly some text after the - keyword */ + * translated keyword (possibly empty), and possibly some text after the + * keyword + */ - if (lang >= chunkdata + slength) + if (lang >= png_ptr->chunkdata + slength - 3) { - comp_flag = PNG_TEXT_COMPRESSION_NONE; - png_warning(png_ptr, "Zero length iTXt chunk"); + png_warning(png_ptr, "Truncated iTXt chunk"); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; } else { @@ -2093,41 +2173,58 @@ png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } for (lang_key = lang; *lang_key; lang_key++) - /* empty loop */ ; - lang_key++; /* skip NUL separator */ + /* Empty loop */ ; + lang_key++; /* Skip NUL separator */ + + if (lang_key >= png_ptr->chunkdata + slength) + { + png_warning(png_ptr, "Truncated iTXt chunk"); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } for (text = lang_key; *text; text++) - /* empty loop */ ; - text++; /* skip NUL separator */ + /* Empty loop */ ; + text++; /* Skip NUL separator */ + if (text >= png_ptr->chunkdata + slength) + { + png_warning(png_ptr, "Malformed iTXt chunk"); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; + return; + } - prefix_len = text - chunkdata; + prefix_len = text - png_ptr->chunkdata; - key=chunkdata; + key=png_ptr->chunkdata; if (comp_flag) - chunkdata = png_decompress_chunk(png_ptr, comp_type, chunkdata, - (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(chunkdata + prefix_len); + data_len = png_strlen(png_ptr->chunkdata + prefix_len); text_ptr = (png_textp)png_malloc_warn(png_ptr, (png_uint_32)png_sizeof(png_text)); if (text_ptr == NULL) { - png_warning(png_ptr,"Not enough memory to process iTXt chunk."); - png_free(png_ptr, chunkdata); + 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 = chunkdata+(lang_key-key); - text_ptr->lang = chunkdata+(lang-key); + text_ptr->lang_key = png_ptr->chunkdata + (lang_key - key); + text_ptr->lang = png_ptr->chunkdata + (lang - key); text_ptr->itxt_length = data_len; text_ptr->text_length = 0; - text_ptr->key = chunkdata; - text_ptr->text = chunkdata + prefix_len; + text_ptr->key = png_ptr->chunkdata; + text_ptr->text = png_ptr->chunkdata + prefix_len; - ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1); + ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); png_free(png_ptr, text_ptr); - png_free(png_ptr, chunkdata); + png_free(png_ptr, png_ptr->chunkdata); + png_ptr->chunkdata = NULL; if (ret) png_error(png_ptr, "Insufficient memory to store iTXt chunk."); } @@ -2143,23 +2240,22 @@ png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { png_uint_32 skip = 0; - png_debug(1, "in png_handle_unknown\n"); + png_debug(1, "in png_handle_unknown"); + if (png_ptr->mode & PNG_HAVE_IDAT) { #ifdef PNG_USE_LOCAL_ARRAYS - PNG_IDAT; + PNG_CONST PNG_IDAT; #endif - if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) /* not an IDAT */ + if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) /* Not an IDAT */ png_ptr->mode |= PNG_AFTER_IDAT; } - png_check_chunk_name(png_ptr, png_ptr->chunk_name); - if (!(png_ptr->chunk_name[0] & 0x20)) { -#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) - if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != +#if defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED) + if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != PNG_HANDLE_CHUNK_ALWAYS #if defined(PNG_READ_USER_CHUNKS_SUPPORTED) && png_ptr->read_user_chunk_fn == NULL @@ -2170,10 +2266,12 @@ png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } #if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) - if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) + if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) +#if defined(PNG_READ_USER_CHUNKS_SUPPORTED) + || (png_ptr->read_user_chunk_fn != NULL) +#endif + ) { - png_unknown_chunk chunk; - #ifdef PNG_MAX_MALLOC_64K if (length > (png_uint_32)65535L) { @@ -2182,30 +2280,44 @@ png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) length = (png_uint_32)65535L; } #endif - png_strcpy((png_charp)chunk.name, (png_charp)png_ptr->chunk_name); - chunk.data = (png_bytep)png_malloc(png_ptr, length); - chunk.size = (png_size_t)length; - png_crc_read(png_ptr, (png_bytep)chunk.data, length); -#if defined(PNG_READ_USER_CHUNKS_SUPPORTED) - if(png_ptr->read_user_chunk_fn != NULL) + 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 { - /* callback to user unknown chunk handler */ - if ((*(png_ptr->read_user_chunk_fn)) (png_ptr, &chunk) <= 0) + 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); + } +#if defined(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_handle_as_unknown(png_ptr, png_ptr->chunk_name) != +#if defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED) + if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != PNG_HANDLE_CHUNK_ALWAYS) - { - png_free(png_ptr, chunk.data); +#endif png_chunk_error(png_ptr, "unknown critical chunk"); - } - png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1); + png_set_unknown_chunks(png_ptr, info_ptr, + &png_ptr->unknown_chunk, 1); } } else #endif - png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1); - png_free(png_ptr, chunk.data); + 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 @@ -2214,8 +2326,7 @@ png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_crc_finish(png_ptr, skip); #if !defined(PNG_READ_USER_CHUNKS_SUPPORTED) - if (&info_ptr == NULL) /* quiet compiler warnings about unused info_ptr */ - return; + info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */ #endif } @@ -2230,7 +2341,7 @@ png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) void /* PRIVATE */ png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name) { - png_debug(1, "in png_check_chunk_name\n"); + png_debug(1, "in png_check_chunk_name"); if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) || isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3])) { @@ -2248,11 +2359,11 @@ png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name) 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. */ -#ifndef PNG_HAVE_ASSEMBLER_COMBINE_ROW + void /* PRIVATE */ png_combine_row(png_structp png_ptr, png_bytep row, int mask) { - png_debug(1,"in png_combine_row\n"); + png_debug(1, "in png_combine_row"); if (mask == 0xff) { png_memcpy(row, png_ptr->row_buf + 1, @@ -2449,10 +2560,8 @@ png_combine_row(png_structp png_ptr, png_bytep row, int mask) } } } -#endif /* !PNG_HAVE_ASSEMBLER_COMBINE_ROW */ #ifdef PNG_READ_INTERLACING_SUPPORTED -#ifndef PNG_HAVE_ASSEMBLER_READ_INTERLACE /* else in pngvcrd.c, pnggccrd.c */ /* 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) @@ -2465,12 +2574,12 @@ png_do_read_interlace(png_structp png_ptr) int pass = png_ptr->pass; png_uint_32 transformations = png_ptr->transformations; #ifdef PNG_USE_LOCAL_ARRAYS - /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - /* offset to next interlace block */ - const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + /* Offset to next interlace block */ + PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; #endif - png_debug(1,"in png_do_read_interlace (stock C version)\n"); + png_debug(1, "in png_do_read_interlace"); if (row != NULL && row_info != NULL) { png_uint_32 final_width; @@ -2671,23 +2780,20 @@ png_do_read_interlace(png_structp png_ptr) } } row_info->width = final_width; - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,final_width); + row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width); } #if !defined(PNG_READ_PACKSWAP_SUPPORTED) - if (&transformations == NULL) /* silence compiler warning */ - return; + transformations = transformations; /* Silence compiler warning */ #endif } -#endif /* !PNG_HAVE_ASSEMBLER_READ_INTERLACE */ #endif /* PNG_READ_INTERLACING_SUPPORTED */ -#ifndef PNG_HAVE_ASSEMBLER_READ_FILTER_ROW 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_debug(1, "in png_read_filter_row\n"); - png_debug2(2,"row = %lu, filter = %d\n", png_ptr->row_number, filter); + png_debug(1, "in png_read_filter_row"); + png_debug2(2, "row = %lu, filter = %d", png_ptr->row_number, filter); switch (filter) { case PNG_FILTER_VALUE_NONE: @@ -2761,7 +2867,7 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row, rp++; } - for (i = 0; i < istop; i++) /* use leftover rp,pp */ + for (i = 0; i < istop; i++) /* Use leftover rp,pp */ { int a, b, c, pa, pb, pc, p; @@ -2791,7 +2897,7 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row, p = c; */ - p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; + p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c; *rp = (png_byte)(((int)(*rp) + p) & 0xff); rp++; @@ -2800,40 +2906,44 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row, } default: png_warning(png_ptr, "Ignoring bad adaptive filter type"); - *row=0; + *row = 0; break; } } -#endif /* !PNG_HAVE_ASSEMBLER_READ_FILTER_ROW */ +#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED void /* PRIVATE */ png_read_finish_row(png_structp png_ptr) { #ifdef PNG_USE_LOCAL_ARRAYS - /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ +#ifdef PNG_READ_INTERLACING_SUPPORTED + /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - /* start of interlace block */ - const int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + /* Start of interlace block */ + PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; - /* offset to next interlace block */ - const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + /* Offset to next interlace block */ + PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; - /* start of interlace block in the y direction */ - const int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + /* Start of interlace block in the y direction */ + PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; - /* offset to next interlace block in the y direction */ - const int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; + /* Offset to next interlace block in the y direction */ + PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; +#endif /* PNG_READ_INTERLACING_SUPPORTED */ #endif - png_debug(1, "in png_read_finish_row\n"); + png_debug(1, "in png_read_finish_row"); png_ptr->row_number++; if (png_ptr->row_number < png_ptr->num_rows) return; +#ifdef PNG_READ_INTERLACING_SUPPORTED if (png_ptr->interlaced) { png_ptr->row_number = 0; - png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1); + png_memset_check(png_ptr, png_ptr->prev_row, 0, + png_ptr->rowbytes + 1); do { png_ptr->pass++; @@ -2863,18 +2973,19 @@ png_read_finish_row(png_structp png_ptr) if (png_ptr->pass < 7) return; } +#endif /* PNG_READ_INTERLACING_SUPPORTED */ if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) { #ifdef PNG_USE_LOCAL_ARRAYS - PNG_IDAT; + PNG_CONST PNG_IDAT; #endif char extra; int ret; png_ptr->zstream.next_out = (Byte *)&extra; png_ptr->zstream.avail_out = (uInt)1; - for(;;) + for (;;) { if (!(png_ptr->zstream.avail_in)) { @@ -2888,7 +2999,7 @@ png_read_finish_row(png_structp png_ptr) png_ptr->idat_size = png_get_uint_31(png_ptr, chunk_length); png_reset_crc(png_ptr); png_crc_read(png_ptr, png_ptr->chunk_name, 4); - if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4)) + if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) png_error(png_ptr, "Not enough image data"); } @@ -2932,32 +3043,36 @@ png_read_finish_row(png_structp png_ptr) png_ptr->mode |= PNG_AFTER_IDAT; } +#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */ void /* PRIVATE */ png_read_start_row(png_structp png_ptr) { #ifdef PNG_USE_LOCAL_ARRAYS - /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ +#ifdef PNG_READ_INTERLACING_SUPPORTED + /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - /* start of interlace block */ - const int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + /* Start of interlace block */ + PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; - /* offset to next interlace block */ - const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + /* Offset to next interlace block */ + PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; - /* start of interlace block in the y direction */ - const int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + /* Start of interlace block in the y direction */ + PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; - /* offset to next interlace block in the y direction */ - const int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; + /* Offset to next interlace block in the y direction */ + PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; +#endif #endif int max_pixel_depth; - png_uint_32 row_bytes; + png_size_t row_bytes; - png_debug(1, "in png_read_start_row\n"); + png_debug(1, "in png_read_start_row"); png_ptr->zstream.avail_in = 0; png_init_read_transformations(png_ptr); +#ifdef PNG_READ_INTERLACING_SUPPORTED if (png_ptr->interlaced) { if (!(png_ptr->transformations & PNG_INTERLACE)) @@ -2971,13 +3086,11 @@ png_read_start_row(png_structp png_ptr) png_pass_start[png_ptr->pass]) / png_pass_inc[png_ptr->pass]; - row_bytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->iwidth) + 1; - - png_ptr->irowbytes = (png_size_t)row_bytes; - if((png_uint_32)png_ptr->irowbytes != row_bytes) - png_error(png_ptr, "Rowbytes overflow in png_read_start_row"); + png_ptr->irowbytes = + PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1; } else +#endif /* PNG_READ_INTERLACING_SUPPORTED */ { png_ptr->num_rows = png_ptr->height; png_ptr->iwidth = png_ptr->width; @@ -3076,49 +3189,64 @@ 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) + 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 - for interlacing */ + /* Align the width on the next larger 8 pixels. Mainly used + * for interlacing + */ row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7)); - /* calculate the maximum bytes needed, adding a byte and a pixel - for safety's sake */ - row_bytes = PNG_ROWBYTES(max_pixel_depth,row_bytes) + + /* Calculate the maximum bytes needed, adding a byte and a pixel + * for safety's sake + */ + row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) + 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"); #endif - png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes+64); - png_ptr->row_buf = png_ptr->big_row_buf+32; -#if defined(PNG_DEBUG) && defined(PNG_USE_PNGGCCRD) - png_ptr->row_buf_size = row_bytes; -#endif + + if (row_bytes + 64 > png_ptr->old_big_row_buf_size) + { + png_free(png_ptr, png_ptr->big_row_buf); + png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 64); + if (png_ptr->interlaced) + png_memset(png_ptr->big_row_buf, 0, row_bytes + 64); + png_ptr->row_buf = png_ptr->big_row_buf + 32; + png_ptr->old_big_row_buf_size = row_bytes + 64; + } #ifdef PNG_MAX_MALLOC_64K - if ((png_uint_32)png_ptr->rowbytes + 1 > (png_uint_32)65536L) + if ((png_uint_32)row_bytes + 1 > (png_uint_32)65536L) png_error(png_ptr, "This image requires a row greater than 64KB"); #endif - if ((png_uint_32)png_ptr->rowbytes + 1 > PNG_SIZE_MAX) + if ((png_uint_32)row_bytes > (png_uint_32)(PNG_SIZE_MAX - 1)) png_error(png_ptr, "Row has too many bytes to allocate in memory."); - png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)( - png_ptr->rowbytes + 1)); - png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1); + if (row_bytes + 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)( + row_bytes + 1)); + png_memset_check(png_ptr, png_ptr->prev_row, 0, row_bytes + 1); + png_ptr->old_prev_row_size = row_bytes + 1; + } - png_debug1(3, "width = %lu,\n", png_ptr->width); - png_debug1(3, "height = %lu,\n", png_ptr->height); - png_debug1(3, "iwidth = %lu,\n", png_ptr->iwidth); - png_debug1(3, "num_rows = %lu\n", png_ptr->num_rows); - png_debug1(3, "rowbytes = %lu,\n", png_ptr->rowbytes); - png_debug1(3, "irowbytes = %lu,\n", png_ptr->irowbytes); + png_ptr->rowbytes = row_bytes; + + 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_ptr->irowbytes); png_ptr->flags |= PNG_FLAG_ROW_INIT; } +#endif /* PNG_READ_SUPPORTED */ diff --git a/3rdparty/wxWidgets/src/png/pngset.c b/3rdparty/wxWidgets/src/png/pngset.c index b9677a12dd..3c110eba95 100644 --- a/3rdparty/wxWidgets/src/png/pngset.c +++ b/3rdparty/wxWidgets/src/png/pngset.c @@ -1,12 +1,15 @@ /* pngset.c - storage of image information into info struct * - * libpng 1.2.7 - September 12, 2004 - * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2004 Glenn Randers-Pehrson + * Last changed in libpng 1.2.39 [August 13, 2009] + * Copyright (c) 1998-2009 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. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * * The functions here are used during reads to store data from the file * into the info struct, and during writes to store application data * into the info struct for writing into the file. This abstracts the @@ -15,12 +18,13 @@ #define PNG_INTERNAL #include "png.h" +#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) #if defined(PNG_bKGD_SUPPORTED) void PNGAPI png_set_bKGD(png_structp png_ptr, png_infop info_ptr, png_color_16p background) { - png_debug1(1, "in %s storage function\n", "bKGD"); + png_debug1(1, "in %s storage function", "bKGD"); if (png_ptr == NULL || info_ptr == NULL) return; @@ -36,29 +40,10 @@ 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\n", "cHRM"); + png_debug1(1, "in %s storage function", "cHRM"); if (png_ptr == NULL || info_ptr == NULL) return; - if (white_x < 0.0 || white_y < 0.0 || - red_x < 0.0 || red_y < 0.0 || - green_x < 0.0 || green_y < 0.0 || - blue_x < 0.0 || blue_y < 0.0) - { - png_warning(png_ptr, - "Ignoring attempt to set negative chromaticity value"); - return; - } - if (white_x > 21474.83 || white_y > 21474.83 || - red_x > 21474.83 || red_y > 21474.83 || - green_x > 21474.83 || green_y > 21474.83 || - blue_x > 21474.83 || blue_y > 21474.83) - { - png_warning(png_ptr, - "Ignoring attempt to set chromaticity value exceeding 21474.83"); - return; - } - info_ptr->x_white = (float)white_x; info_ptr->y_white = (float)white_y; info_ptr->x_red = (float)red_x; @@ -79,7 +64,8 @@ png_set_cHRM(png_structp png_ptr, png_infop info_ptr, #endif info_ptr->valid |= PNG_INFO_cHRM; } -#endif +#endif /* PNG_FLOATING_POINT_SUPPORTED */ + #ifdef PNG_FIXED_POINT_SUPPORTED void PNGAPI png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr, @@ -87,62 +73,46 @@ png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr, 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\n", "cHRM"); + png_debug1(1, "in %s storage function", "cHRM fixed"); if (png_ptr == NULL || info_ptr == NULL) return; - if (white_x < 0 || white_y < 0 || - red_x < 0 || red_y < 0 || - green_x < 0 || green_y < 0 || - blue_x < 0 || blue_y < 0) - { - png_warning(png_ptr, - "Ignoring attempt to set negative chromaticity value"); - return; - } - if (white_x > (double) PNG_UINT_31_MAX || - white_y > (double) PNG_UINT_31_MAX || - red_x > (double) PNG_UINT_31_MAX || - red_y > (double) PNG_UINT_31_MAX || - green_x > (double) PNG_UINT_31_MAX || - green_y > (double) PNG_UINT_31_MAX || - blue_x > (double) PNG_UINT_31_MAX || - blue_y > (double) PNG_UINT_31_MAX) - { - png_warning(png_ptr, - "Ignoring attempt to set chromaticity value exceeding 21474.83"); - return; - } - info_ptr->int_x_white = white_x; - info_ptr->int_y_white = white_y; - info_ptr->int_x_red = red_x; - 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.); +#if !defined(PNG_NO_CHECK_cHRM) + if (png_check_cHRM_fixed(png_ptr, + white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y)) #endif - info_ptr->valid |= PNG_INFO_cHRM; + { + 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->valid |= PNG_INFO_cHRM; + } } -#endif -#endif +#endif /* PNG_FIXED_POINT_SUPPORTED */ +#endif /* PNG_cHRM_SUPPORTED */ #if defined(PNG_gAMA_SUPPORTED) #ifdef PNG_FLOATING_POINT_SUPPORTED void PNGAPI png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma) { - double gamma; - png_debug1(1, "in %s storage function\n", "gAMA"); + double png_gamma; + png_debug1(1, "in %s storage function", "gAMA"); if (png_ptr == NULL || info_ptr == NULL) return; @@ -150,16 +120,16 @@ png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma) if (file_gamma > 21474.83) { png_warning(png_ptr, "Limiting gamma to 21474.83"); - gamma=21474.83; + png_gamma=21474.83; } else - gamma=file_gamma; - info_ptr->gamma = (float)gamma; + png_gamma = file_gamma; + info_ptr->gamma = (float)png_gamma; #ifdef PNG_FIXED_POINT_SUPPORTED - info_ptr->int_gamma = (int)(gamma*100000.+.5); + info_ptr->int_gamma = (int)(png_gamma*100000.+.5); #endif info_ptr->valid |= PNG_INFO_gAMA; - if(gamma == 0.0) + if (png_gamma == 0.0) png_warning(png_ptr, "Setting gamma=0"); } #endif @@ -167,35 +137,35 @@ void PNGAPI png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point int_gamma) { - png_fixed_point gamma; + png_fixed_point png_gamma; - png_debug1(1, "in %s storage function\n", "gAMA"); + 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) + if (int_gamma > (png_fixed_point)PNG_UINT_31_MAX) { - png_warning(png_ptr, "Limiting gamma to 21474.83"); - gamma=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"); - gamma=0; - } - else - gamma=int_gamma; + 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)(gamma/100000.); + info_ptr->gamma = (float)(png_gamma/100000.); #endif #ifdef PNG_FIXED_POINT_SUPPORTED - info_ptr->int_gamma = gamma; + info_ptr->int_gamma = png_gamma; #endif info_ptr->valid |= PNG_INFO_gAMA; - if(gamma == 0) + if (png_gamma == 0) png_warning(png_ptr, "Setting gamma=0"); } #endif @@ -206,30 +176,33 @@ png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p hist) { int i; - png_debug1(1, "in %s storage function\n", "hIST"); + png_debug1(1, "in %s storage function", "hIST"); if (png_ptr == NULL || info_ptr == NULL) return; - if (info_ptr->num_palette == 0) + if (info_ptr->num_palette == 0 || info_ptr->num_palette + > PNG_MAX_PALETTE_LENGTH) { - png_warning(png_ptr, - "Palette size 0, hIST allocation skipped."); - return; + png_warning(png_ptr, + "Invalid palette size, hIST allocation skipped."); + return; } #ifdef PNG_FREE_ME_SUPPORTED png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0); #endif - /* Changed from info->num_palette to 256 in version 1.2.1 */ + /* 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_uint_32)(256 * png_sizeof (png_uint_16))); + (png_uint_32)(PNG_MAX_PALETTE_LENGTH * png_sizeof(png_uint_16))); if (png_ptr->hist == NULL) - { - png_warning(png_ptr, "Insufficient memory for hIST chunk data."); - return; - } + { + png_warning(png_ptr, "Insufficient memory for hIST chunk data."); + return; + } for (i = 0; i < info_ptr->num_palette; i++) - png_ptr->hist[i] = hist[i]; + png_ptr->hist[i] = hist[i]; info_ptr->hist = png_ptr->hist; info_ptr->valid |= PNG_INFO_hIST; @@ -247,11 +220,11 @@ png_set_IHDR(png_structp png_ptr, png_infop info_ptr, int color_type, int interlace_type, int compression_type, int filter_type) { - png_debug1(1, "in %s storage function\n", "IHDR"); + png_debug1(1, "in %s storage function", "IHDR"); if (png_ptr == NULL || info_ptr == NULL) return; - /* check for width and height valid values */ + /* Check for width and height valid values */ if (width == 0 || height == 0) png_error(png_ptr, "Image width or height is zero in IHDR"); #ifdef PNG_SET_USER_LIMITS_SUPPORTED @@ -271,13 +244,13 @@ png_set_IHDR(png_structp png_ptr, png_infop info_ptr, - 8) /* extra max_pixel_depth pad */ png_warning(png_ptr, "Width is too large for libpng to process pixels"); - /* check other values */ + /* Check other values */ if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 && - bit_depth != 8 && bit_depth != 16) + bit_depth != 8 && bit_depth != 16) png_error(png_ptr, "Invalid bit depth in IHDR"); if (color_type < 0 || color_type == 1 || - color_type == 5 || color_type > 6) + color_type == 5 || color_type > 6) png_error(png_ptr, "Invalid color type in IHDR"); if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) || @@ -302,21 +275,21 @@ png_set_IHDR(png_structp png_ptr, png_infop info_ptr, * 4. The filter_method is 64 and * 5. The color_type is RGB or RGBA */ - if((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)&&png_ptr->mng_features_permitted) - png_warning(png_ptr,"MNG features are not allowed in a PNG datastream\n"); - if(filter_type != PNG_FILTER_TYPE_BASE) + if ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)&&png_ptr->mng_features_permitted) + png_warning(png_ptr, "MNG features are not allowed in a PNG datastream"); + 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 || + 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))) png_error(png_ptr, "Unknown filter method in IHDR"); - if(png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) + if (png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) png_warning(png_ptr, "Invalid filter method in IHDR"); } #else - if(filter_type != PNG_FILTER_TYPE_BASE) + if (filter_type != PNG_FILTER_TYPE_BASE) png_error(png_ptr, "Unknown filter method in IHDR"); #endif @@ -337,8 +310,8 @@ png_set_IHDR(png_structp png_ptr, png_infop info_ptr, 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 + /* Check for potential overflow */ + if (width > (PNG_UINT_32_MAX >> 3) /* 8-byte RGBA pixels */ - 64 /* bigrowbuf hack */ - 1 /* filter byte */ @@ -346,7 +319,7 @@ png_set_IHDR(png_structp png_ptr, png_infop info_ptr, - 8) /* extra max_pixel_depth pad */ info_ptr->rowbytes = (png_size_t)0; else - info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth,width); + info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width); } #if defined(PNG_oFFs_SUPPORTED) @@ -354,7 +327,7 @@ 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_debug1(1, "in %s storage function\n", "oFFs"); + png_debug1(1, "in %s storage function", "oFFs"); if (png_ptr == NULL || info_ptr == NULL) return; @@ -374,56 +347,59 @@ png_set_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length; int i; - png_debug1(1, "in %s storage function\n", "pCAL"); + png_debug1(1, "in %s storage function", "pCAL"); if (png_ptr == NULL || info_ptr == NULL) return; length = png_strlen(purpose) + 1; - png_debug1(3, "allocating purpose for info (%lu bytes)\n", length); + png_debug1(3, "allocating purpose for info (%lu bytes)", + (unsigned long)length); info_ptr->pcal_purpose = (png_charp)png_malloc_warn(png_ptr, length); if (info_ptr->pcal_purpose == NULL) - { - png_warning(png_ptr, "Insufficient memory for pCAL purpose."); - return; - } + { + png_warning(png_ptr, "Insufficient memory for pCAL purpose."); + return; + } png_memcpy(info_ptr->pcal_purpose, purpose, (png_size_t)length); - png_debug(3, "storing X0, X1, type, and nparams in info\n"); + png_debug(3, "storing X0, X1, type, and nparams in info"); info_ptr->pcal_X0 = X0; info_ptr->pcal_X1 = X1; info_ptr->pcal_type = (png_byte)type; info_ptr->pcal_nparams = (png_byte)nparams; length = png_strlen(units) + 1; - png_debug1(3, "allocating units for info (%lu bytes)\n", length); + 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_warning(png_ptr, "Insufficient memory for pCAL units."); + return; + } png_memcpy(info_ptr->pcal_units, units, (png_size_t)length); info_ptr->pcal_params = (png_charpp)png_malloc_warn(png_ptr, (png_uint_32)((nparams + 1) * png_sizeof(png_charp))); if (info_ptr->pcal_params == NULL) - { - png_warning(png_ptr, "Insufficient memory for pCAL params."); - return; - } + { + png_warning(png_ptr, "Insufficient memory for pCAL params."); + return; + } - info_ptr->pcal_params[nparams] = NULL; + png_memset(info_ptr->pcal_params, 0, (nparams + 1) * png_sizeof(png_charp)); for (i = 0; i < nparams; i++) { length = png_strlen(params[i]) + 1; - png_debug2(3, "allocating parameter %d for info (%lu bytes)\n", i, length); + png_debug2(3, "allocating parameter %d for info (%lu bytes)", i, + (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_warning(png_ptr, "Insufficient memory for pCAL parameter."); + return; + } png_memcpy(info_ptr->pcal_params[i], params[i], (png_size_t)length); } @@ -440,7 +416,7 @@ 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\n", "sCAL"); + png_debug1(1, "in %s storage function", "sCAL"); if (png_ptr == NULL || info_ptr == NULL) return; @@ -458,31 +434,37 @@ png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr, { png_uint_32 length; - png_debug1(1, "in %s storage function\n", "sCAL"); + png_debug1(1, "in %s storage function", "sCAL"); if (png_ptr == NULL || info_ptr == NULL) return; info_ptr->scal_unit = (png_byte)unit; length = png_strlen(swidth) + 1; - png_debug1(3, "allocating unit for info (%d bytes)\n", length); + 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); 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, (png_size_t)length); length = png_strlen(sheight) + 1; - png_debug1(3, "allocating unit for info (%d bytes)\n", length); + 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); if (info_ptr->scal_s_height == NULL) { png_free (png_ptr, info_ptr->scal_s_width); - png_warning(png_ptr, "Memory allocation failed while processing sCAL."); + info_ptr->scal_s_width = NULL; + png_warning(png_ptr, + "Memory allocation failed while processing sCAL."); + return; } png_memcpy(info_ptr->scal_s_height, sheight, (png_size_t)length); - info_ptr->valid |= PNG_INFO_sCAL; #ifdef PNG_FREE_ME_SUPPORTED info_ptr->free_me |= PNG_FREE_SCAL; @@ -497,7 +479,7 @@ 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_debug1(1, "in %s storage function\n", "pHYs"); + png_debug1(1, "in %s storage function", "pHYs"); if (png_ptr == NULL || info_ptr == NULL) return; @@ -513,10 +495,21 @@ png_set_PLTE(png_structp png_ptr, png_infop info_ptr, png_colorp palette, int num_palette) { - png_debug1(1, "in %s storage function\n", "PLTE"); + png_debug1(1, "in %s storage function", "PLTE"); if (png_ptr == NULL || info_ptr == NULL) return; + if (num_palette < 0 || num_palette > PNG_MAX_PALETTE_LENGTH) + { + if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + png_error(png_ptr, "Invalid palette length"); + else + { + png_warning(png_ptr, "Invalid palette length"); + return; + } + } + /* * It may not actually be necessary to set png_ptr->palette here; * we do it for backward compatibility with the way the png_handle_tRNS @@ -526,12 +519,15 @@ png_set_PLTE(png_structp png_ptr, png_infop info_ptr, png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0); #endif - /* Changed in libpng-1.2.1 to allocate 256 instead of num_palette entries, - in case of an invalid PNG file that has too-large sample values. */ + /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead + * of num_palette entries, in case of an invalid PNG file that has + * too-large sample values. + */ png_ptr->palette = (png_colorp)png_malloc(png_ptr, - 256 * png_sizeof(png_color)); - png_memset(png_ptr->palette, 0, 256 * png_sizeof(png_color)); - png_memcpy(png_ptr->palette, palette, num_palette * png_sizeof (png_color)); + PNG_MAX_PALETTE_LENGTH * png_sizeof(png_color)); + png_memset(png_ptr->palette, 0, 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; @@ -549,11 +545,11 @@ void PNGAPI png_set_sBIT(png_structp png_ptr, png_infop info_ptr, png_color_8p sig_bit) { - png_debug1(1, "in %s storage function\n", "sBIT"); + png_debug1(1, "in %s storage function", "sBIT"); if (png_ptr == NULL || info_ptr == NULL) return; - png_memcpy(&(info_ptr->sig_bit), sig_bit, png_sizeof (png_color_8)); + png_memcpy(&(info_ptr->sig_bit), sig_bit, png_sizeof(png_color_8)); info_ptr->valid |= PNG_INFO_sBIT; } #endif @@ -562,7 +558,7 @@ png_set_sBIT(png_structp png_ptr, png_infop info_ptr, void PNGAPI png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int intent) { - png_debug1(1, "in %s storage function\n", "sRGB"); + png_debug1(1, "in %s storage function", "sRGB"); if (png_ptr == NULL || info_ptr == NULL) return; @@ -586,12 +582,10 @@ png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr, #ifdef PNG_FLOATING_POINT_SUPPORTED float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y; #endif -#ifdef PNG_FIXED_POINT_SUPPORTED 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 -#endif - png_debug1(1, "in %s storage function\n", "sRGB_gAMA_and_cHRM"); + png_debug1(1, "in %s storage function", "sRGB_gAMA_and_cHRM"); if (png_ptr == NULL || info_ptr == NULL) return; @@ -609,7 +603,6 @@ png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr, #endif #if defined(PNG_cHRM_SUPPORTED) -#ifdef PNG_FIXED_POINT_SUPPORTED int_white_x = 31270L; int_white_y = 32900L; int_red_x = 64000L; @@ -619,10 +612,6 @@ png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr, int_blue_x = 15000L; int_blue_y = 6000L; - 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 white_x = (float).3127; white_y = (float).3290; @@ -632,13 +621,27 @@ png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr, green_y = (float).60; blue_x = (float).15; blue_y = (float).06; +#endif - png_set_cHRM(png_ptr, info_ptr, - white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y); +#if !defined(PNG_NO_CHECK_cHRM) + 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 + { +#ifdef PNG_FIXED_POINT_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 */ } -#endif +#endif /* sRGB */ #if defined(PNG_iCCP_SUPPORTED) @@ -649,23 +652,26 @@ png_set_iCCP(png_structp png_ptr, png_infop info_ptr, { png_charp new_iccp_name; png_charp new_iccp_profile; + png_uint_32 length; - png_debug1(1, "in %s storage function\n", "iCCP"); + png_debug1(1, "in %s storage function", "iCCP"); if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL) return; - new_iccp_name = (png_charp)png_malloc_warn(png_ptr, png_strlen(name)+1); + 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_strcpy(new_iccp_name, name); + png_memcpy(new_iccp_name, name, length); new_iccp_profile = (png_charp)png_malloc_warn(png_ptr, proflen); if (new_iccp_profile == NULL) { png_free (png_ptr, new_iccp_name); - png_warning(png_ptr, "Insufficient memory to process iCCP profile."); + png_warning(png_ptr, + "Insufficient memory to process iCCP profile."); return; } png_memcpy(new_iccp_profile, profile, (png_size_t)proflen); @@ -688,21 +694,22 @@ png_set_iCCP(png_structp png_ptr, png_infop info_ptr, #if defined(PNG_TEXT_SUPPORTED) void PNGAPI png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, - int num_text) + int num_text) { int ret; - ret=png_set_text_2(png_ptr, info_ptr, text_ptr, num_text); + ret = png_set_text_2(png_ptr, info_ptr, text_ptr, num_text); if (ret) - png_error(png_ptr, "Insufficient memory to store text"); + png_error(png_ptr, "Insufficient memory to store text"); } int /* PRIVATE */ png_set_text_2(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, - int num_text) + int num_text) { int i; - png_debug1(1, "in %s storage function\n", (png_ptr->chunk_name[0] == '\0' ? + png_debug1(1, "in %s storage function", ((png_ptr == NULL || + png_ptr->chunk_name[0] == '\0') ? "text" : (png_const_charp)png_ptr->chunk_name)); if (png_ptr == NULL || info_ptr == NULL || num_text == 0) @@ -722,12 +729,12 @@ png_set_text_2(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, info_ptr->max_text = info_ptr->num_text + num_text + 8; old_text = info_ptr->text; info_ptr->text = (png_textp)png_malloc_warn(png_ptr, - (png_uint_32)(info_ptr->max_text * png_sizeof (png_text))); + (png_uint_32)(info_ptr->max_text * png_sizeof(png_text))); if (info_ptr->text == NULL) - { - png_free(png_ptr, old_text); - return(1); - } + { + 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_free(png_ptr, old_text); @@ -737,20 +744,20 @@ png_set_text_2(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, info_ptr->max_text = num_text + 8; info_ptr->num_text = 0; info_ptr->text = (png_textp)png_malloc_warn(png_ptr, - (png_uint_32)(info_ptr->max_text * png_sizeof (png_text))); + (png_uint_32)(info_ptr->max_text * png_sizeof(png_text))); if (info_ptr->text == NULL) - return(1); + return(1); #ifdef PNG_FREE_ME_SUPPORTED info_ptr->free_me |= PNG_FREE_TEXT; #endif } - png_debug1(3, "allocated %d entries for info_ptr->text\n", + png_debug1(3, "allocated %d entries for info_ptr->text", info_ptr->max_text); } for (i = 0; i < num_text; i++) { - png_size_t text_length,key_len; - png_size_t lang_len,lang_key_len; + png_size_t text_length, key_len; + png_size_t lang_len, lang_key_len; png_textp textp = &(info_ptr->text[info_ptr->num_text]); if (text_ptr[i].key == NULL) @@ -758,28 +765,28 @@ png_set_text_2(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, key_len = png_strlen(text_ptr[i].key); - if(text_ptr[i].compression <= 0) + if (text_ptr[i].compression <= 0) { - lang_len = 0; - lang_key_len = 0; + lang_len = 0; + lang_key_len = 0; } else #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; + /* 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_warning(png_ptr, "iTXt chunk not supported."); - continue; + png_warning(png_ptr, "iTXt chunk not supported."); + continue; } #endif @@ -787,7 +794,7 @@ png_set_text_2(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, { text_length = 0; #ifdef PNG_iTXt_SUPPORTED - if(text_ptr[i].compression > 0) + if (text_ptr[i].compression > 0) textp->compression = PNG_ITXT_COMPRESSION_NONE; else #endif @@ -800,26 +807,27 @@ 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_uint_32)(key_len + text_length + lang_len + lang_key_len + 4)); + (png_uint_32) + (key_len + text_length + lang_len + lang_key_len + 4)); if (textp->key == NULL) - return(1); - png_debug2(2, "Allocated %lu bytes at %x in png_set_text\n", - (png_uint_32)(key_len + lang_len + lang_key_len + text_length + 4), - (int)textp->key); + return(1); + png_debug2(2, "Allocated %lu bytes at %x in png_set_text", + (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'; + 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; + textp->lang = textp->key + key_len + 1; png_memcpy(textp->lang, text_ptr[i].lang, lang_len); - *(textp->lang+lang_len) = '\0'; - textp->lang_key=textp->lang + lang_len + 1; + *(textp->lang + lang_len) = '\0'; + textp->lang_key = textp->lang + lang_len + 1; png_memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len); - *(textp->lang_key+lang_key_len) = '\0'; - textp->text=textp->lang_key + lang_key_len + 1; + *(textp->lang_key + lang_key_len) = '\0'; + textp->text = textp->lang_key + lang_key_len + 1; } else #endif @@ -828,15 +836,15 @@ png_set_text_2(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, textp->lang=NULL; textp->lang_key=NULL; #endif - textp->text=textp->key + key_len + 1; + textp->text = textp->key + key_len + 1; } - if(text_length) + if (text_length) png_memcpy(textp->text, text_ptr[i].text, (png_size_t)(text_length)); - *(textp->text+text_length) = '\0'; + *(textp->text + text_length) = '\0'; #ifdef PNG_iTXt_SUPPORTED - if(textp->compression > 0) + if (textp->compression > 0) { textp->text_length = 0; textp->itxt_length = text_length; @@ -849,9 +857,8 @@ png_set_text_2(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, textp->itxt_length = 0; #endif } - info_ptr->text[info_ptr->num_text]= *textp; info_ptr->num_text++; - png_debug1(3, "transferred text chunk %d\n", info_ptr->num_text); + png_debug1(3, "transferred text chunk %d", info_ptr->num_text); } return(0); } @@ -861,12 +868,12 @@ png_set_text_2(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr, void PNGAPI png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_timep mod_time) { - png_debug1(1, "in %s storage function\n", "tIME"); + png_debug1(1, "in %s storage function", "tIME"); if (png_ptr == NULL || info_ptr == NULL || (png_ptr->mode & PNG_WROTE_tIME)) return; - png_memcpy(&(info_ptr->mod_time), mod_time, png_sizeof (png_time)); + png_memcpy(&(info_ptr->mod_time), mod_time, png_sizeof(png_time)); info_ptr->valid |= PNG_INFO_tIME; } #endif @@ -876,7 +883,7 @@ void PNGAPI png_set_tRNS(png_structp png_ptr, png_infop info_ptr, png_bytep trans, int num_trans, png_color_16p trans_values) { - png_debug1(1, "in %s storage function\n", "tRNS"); + png_debug1(1, "in %s storage function", "tRNS"); if (png_ptr == NULL || info_ptr == NULL) return; @@ -887,29 +894,45 @@ png_set_tRNS(png_structp png_ptr, png_infop info_ptr, * we do it for backward compatibility with the way the png_handle_tRNS * function used to do the allocation. */ + #ifdef PNG_FREE_ME_SUPPORTED png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0); #endif - /* Changed from num_trans to 256 in version 1.2.1 */ + + /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */ png_ptr->trans = info_ptr->trans = (png_bytep)png_malloc(png_ptr, - (png_uint_32)256); - png_memcpy(info_ptr->trans, trans, (png_size_t)num_trans); -#ifdef PNG_FREE_ME_SUPPORTED - info_ptr->free_me |= PNG_FREE_TRNS; -#else - png_ptr->flags |= PNG_FLAG_FREE_TRNS; -#endif + (png_uint_32)PNG_MAX_PALETTE_LENGTH); + if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH) + png_memcpy(info_ptr->trans, trans, (png_size_t)num_trans); } if (trans_values != NULL) { + int sample_max = (1 << info_ptr->bit_depth); + if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY && + (int)trans_values->gray > sample_max) || + (info_ptr->color_type == PNG_COLOR_TYPE_RGB && + ((int)trans_values->red > sample_max || + (int)trans_values->green > sample_max || + (int)trans_values->blue > sample_max))) + png_warning(png_ptr, + "tRNS chunk has out-of-range samples for bit_depth"); png_memcpy(&(info_ptr->trans_values), trans_values, png_sizeof(png_color_16)); if (num_trans == 0) - num_trans = 1; + num_trans = 1; } + info_ptr->num_trans = (png_uint_16)num_trans; - info_ptr->valid |= PNG_INFO_tRNS; + if (num_trans != 0) + { + info_ptr->valid |= PNG_INFO_tRNS; +#ifdef PNG_FREE_ME_SUPPORTED + info_ptr->free_me |= PNG_FREE_TRNS; +#else + png_ptr->flags |= PNG_FLAG_FREE_TRNS; +#endif + } } #endif @@ -917,46 +940,70 @@ png_set_tRNS(png_structp png_ptr, png_infop info_ptr, void PNGAPI png_set_sPLT(png_structp png_ptr, png_infop info_ptr, png_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. + */ { - png_sPLT_tp np; - int i; + png_sPLT_tp np; + int i; - np = (png_sPLT_tp)png_malloc_warn(png_ptr, - (info_ptr->splt_palettes_num + nentries) * png_sizeof(png_sPLT_t)); - if (np == NULL) - { - png_warning(png_ptr, "No memory for sPLT palettes."); + if (png_ptr == NULL || info_ptr == NULL) return; - } - 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; + np = (png_sPLT_tp)png_malloc_warn(png_ptr, + (info_ptr->splt_palettes_num + nentries) * + (png_uint_32)png_sizeof(png_sPLT_t)); + if (np == NULL) + { + png_warning(png_ptr, "No memory for sPLT palettes."); + return; + } - for (i = 0; i < nentries; i++) - { - png_sPLT_tp to = np + info_ptr->splt_palettes_num + i; - png_sPLT_tp from = entries + i; + 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; - to->name = (png_charp)png_malloc(png_ptr, - png_strlen(from->name) + 1); - /* TODO: use png_malloc_warn */ - png_strcpy(to->name, from->name); - to->entries = (png_sPLT_entryp)png_malloc(png_ptr, - from->nentries * png_sizeof(png_sPLT_t)); - /* TODO: use png_malloc_warn */ - png_memcpy(to->entries, from->entries, - from->nentries * png_sizeof(png_sPLT_t)); - to->nentries = from->nentries; - to->depth = from->depth; - } + for (i = 0; i < nentries; i++) + { + png_sPLT_tp to = np + info_ptr->splt_palettes_num + i; + png_sPLT_tp from = entries + i; + png_uint_32 length; - info_ptr->splt_palettes = np; - info_ptr->splt_palettes_num += nentries; - info_ptr->valid |= PNG_INFO_sPLT; + length = png_strlen(from->name) + 1; + to->name = (png_charp)png_malloc_warn(png_ptr, length); + if (to->name == NULL) + { + png_warning(png_ptr, + "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_uint_32)(from->nentries * png_sizeof(png_sPLT_entry))); + if (to->entries == NULL) + { + png_warning(png_ptr, + "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; + } + + info_ptr->splt_palettes = np; + info_ptr->splt_palettes_num += nentries; + info_ptr->valid |= PNG_INFO_sPLT; #ifdef PNG_FREE_ME_SUPPORTED - info_ptr->free_me |= PNG_FREE_SPLT; + info_ptr->free_me |= PNG_FREE_SPLT; #endif } #endif /* PNG_sPLT_SUPPORTED */ @@ -966,84 +1013,96 @@ void PNGAPI png_set_unknown_chunks(png_structp png_ptr, png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns) { - png_unknown_chunkp np; - int i; + png_unknown_chunkp np; + int i; - if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0) - return; + if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0) + return; - np = (png_unknown_chunkp)png_malloc_warn(png_ptr, - (info_ptr->unknown_chunks_num + num_unknowns) * - png_sizeof(png_unknown_chunk)); - if (np == NULL) - { - png_warning(png_ptr, "Out of memory while processing unknown chunk."); - return; - } + np = (png_unknown_chunkp)png_malloc_warn(png_ptr, + (png_uint_32)((info_ptr->unknown_chunks_num + num_unknowns) * + png_sizeof(png_unknown_chunk))); + if (np == NULL) + { + png_warning(png_ptr, + "Out of memory while processing unknown chunk."); + return; + } - png_memcpy(np, info_ptr->unknown_chunks, - info_ptr->unknown_chunks_num * png_sizeof(png_unknown_chunk)); - png_free(png_ptr, info_ptr->unknown_chunks); - info_ptr->unknown_chunks=NULL; + png_memcpy(np, info_ptr->unknown_chunks, + 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; + 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_strncpy((png_charp)to->name, (png_charp)from->name, 5); - to->data = (png_bytep)png_malloc_warn(png_ptr, from->size); - if (to->data == NULL) - { - png_warning(png_ptr, "Out of memory processing unknown chunk."); - } - else - { - png_memcpy(to->data, from->data, from->size); - to->size = from->size; + png_memcpy((png_charp)to->name, + (png_charp)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); - /* 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_uint_32)from->size); + if (to->data == NULL) + { + png_warning(png_ptr, + "Out of memory while processing unknown chunk."); + to->size = 0; + } + else + png_memcpy(to->data, from->data, from->size); + } + } - info_ptr->unknown_chunks = np; - info_ptr->unknown_chunks_num += num_unknowns; + info_ptr->unknown_chunks = np; + info_ptr->unknown_chunks_num += num_unknowns; #ifdef PNG_FREE_ME_SUPPORTED - info_ptr->free_me |= PNG_FREE_UNKN; + info_ptr->free_me |= PNG_FREE_UNKN; #endif } void PNGAPI png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr, int chunk, int location) { - if(png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk < + if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk < (int)info_ptr->unknown_chunks_num) info_ptr->unknown_chunks[chunk].location = (png_byte)location; } #endif +#if defined(PNG_1_0_X) || defined(PNG_1_2_X) #if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \ defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) void PNGAPI png_permit_empty_plte (png_structp png_ptr, int empty_plte_permitted) { /* This function is deprecated in favor of png_permit_mng_features() - and will be removed from libpng-2.0.0 */ - png_debug(1, "in png_permit_empty_plte, DEPRECATED.\n"); + and will be removed from libpng-1.3.0 */ + png_debug(1, "in png_permit_empty_plte, DEPRECATED."); if (png_ptr == NULL) return; png_ptr->mng_features_permitted = (png_byte) - ((png_ptr->mng_features_permitted & (~(PNG_FLAG_MNG_EMPTY_PLTE))) | + ((png_ptr->mng_features_permitted & (~PNG_FLAG_MNG_EMPTY_PLTE)) | ((empty_plte_permitted & PNG_FLAG_MNG_EMPTY_PLTE))); } #endif +#endif #if defined(PNG_MNG_FEATURES_SUPPORTED) png_uint_32 PNGAPI png_permit_mng_features (png_structp png_ptr, png_uint_32 mng_features) { - png_debug(1, "in png_permit_mng_features\n"); + png_debug(1, "in png_permit_mng_features"); if (png_ptr == NULL) return (png_uint_32)0; png_ptr->mng_features_permitted = @@ -1057,41 +1116,44 @@ void PNGAPI png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_bytep chunk_list, int num_chunks) { - png_bytep new_list, p; - int i, old_num_chunks; - if (num_chunks == 0) - { - if(keep == PNG_HANDLE_CHUNK_ALWAYS || keep == PNG_HANDLE_CHUNK_IF_SAFE) - png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_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; + png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS; - if(keep == PNG_HANDLE_CHUNK_ALWAYS) - png_ptr->flags |= PNG_FLAG_KEEP_UNSAFE_CHUNKS; + if (keep == PNG_HANDLE_CHUNK_ALWAYS) + png_ptr->flags |= PNG_FLAG_KEEP_UNSAFE_CHUNKS; else - png_ptr->flags &= ~PNG_FLAG_KEEP_UNSAFE_CHUNKS; + png_ptr->flags &= ~PNG_FLAG_KEEP_UNSAFE_CHUNKS; return; - } - if (chunk_list == NULL) + } + if (chunk_list == NULL) return; - old_num_chunks=png_ptr->num_chunk_list; - new_list=(png_bytep)png_malloc(png_ptr, - (png_uint_32)(5*(num_chunks+old_num_chunks))); - if(png_ptr->chunk_list != NULL) - { - png_memcpy(new_list, png_ptr->chunk_list, - (png_size_t)(5*old_num_chunks)); - 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; + old_num_chunks = png_ptr->num_chunk_list; + new_list=(png_bytep)png_malloc(png_ptr, + (png_uint_32) + (5*(num_chunks + old_num_chunks))); + if (png_ptr->chunk_list != NULL) + { + png_memcpy(new_list, png_ptr->chunk_list, + (png_size_t)(5*old_num_chunks)); + 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; #ifdef PNG_FREE_ME_SUPPORTED - png_ptr->free_me |= PNG_FREE_LIST; + png_ptr->free_me |= PNG_FREE_LIST; #endif } #endif @@ -1101,7 +1163,9 @@ 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_debug(1, "in png_set_read_user_chunk_fn\n"); + png_debug(1, "in png_set_read_user_chunk_fn"); + if (png_ptr == NULL) + return; png_ptr->read_user_chunk_fn = read_user_chunk_fn; png_ptr->user_chunk_ptr = user_chunk_ptr; } @@ -1111,25 +1175,27 @@ png_set_read_user_chunk_fn(png_structp png_ptr, png_voidp user_chunk_ptr, void PNGAPI png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers) { - png_debug1(1, "in %s storage function\n", "rows"); + png_debug1(1, "in %s storage function", "rows"); if (png_ptr == NULL || info_ptr == NULL) return; - if(info_ptr->row_pointers && (info_ptr->row_pointers != 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) + if (row_pointers) info_ptr->valid |= PNG_INFO_IDAT; } #endif #ifdef PNG_WRITE_SUPPORTED void PNGAPI -png_set_compression_buffer_size(png_structp png_ptr, png_uint_32 size) +png_set_compression_buffer_size(png_structp png_ptr, + png_uint_32 size) { - if(png_ptr->zbuf) - png_free(png_ptr, png_ptr->zbuf); + if (png_ptr == NULL) + return; + png_free(png_ptr, png_ptr->zbuf); png_ptr->zbuf_size = (png_size_t)size; png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size); png_ptr->zstream.next_out = png_ptr->zbuf; @@ -1141,79 +1207,53 @@ void PNGAPI png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask) { if (png_ptr && info_ptr) - info_ptr->valid &= ~(mask); + info_ptr->valid &= ~mask; } #ifndef PNG_1_0_X #ifdef PNG_ASSEMBLER_CODE_SUPPORTED -/* this function was added to libpng 1.2.0 and should always exist by default */ +/* Function was added to libpng 1.2.0 and should always exist by default */ void PNGAPI png_set_asm_flags (png_structp png_ptr, png_uint_32 asm_flags) { - png_uint_32 settable_asm_flags; - png_uint_32 settable_mmx_flags; - - settable_mmx_flags = -#ifdef PNG_HAVE_ASSEMBLER_COMBINE_ROW - PNG_ASM_FLAG_MMX_READ_COMBINE_ROW | -#endif -#ifdef PNG_HAVE_ASSEMBLER_READ_INTERLACE - PNG_ASM_FLAG_MMX_READ_INTERLACE | -#endif -#ifdef PNG_HAVE_ASSEMBLER_READ_FILTER_ROW - PNG_ASM_FLAG_MMX_READ_FILTER_SUB | - PNG_ASM_FLAG_MMX_READ_FILTER_UP | - PNG_ASM_FLAG_MMX_READ_FILTER_AVG | - PNG_ASM_FLAG_MMX_READ_FILTER_PAETH | -#endif - 0; - - /* could be some non-MMX ones in the future, but not currently: */ - settable_asm_flags = settable_mmx_flags; - - if (!(png_ptr->asm_flags & PNG_ASM_FLAG_MMX_SUPPORT_COMPILED) || - !(png_ptr->asm_flags & PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU)) - { - /* clear all MMX flags if MMX isn't supported */ - settable_asm_flags &= ~settable_mmx_flags; - png_ptr->asm_flags &= ~settable_mmx_flags; - } - - /* we're replacing the settable bits with those passed in by the user, - * so first zero them out of the master copy, then logical-OR in the - * allowed subset that was requested */ - - png_ptr->asm_flags &= ~settable_asm_flags; /* zero them */ - png_ptr->asm_flags |= (asm_flags & settable_asm_flags); /* set them */ +/* Obsolete as of libpng-1.2.20 and will be removed from libpng-1.4.0 */ + if (png_ptr != NULL) + png_ptr->asm_flags = 0; + asm_flags = asm_flags; /* Quiet the compiler */ } -#endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */ -#ifdef PNG_ASSEMBLER_CODE_SUPPORTED -/* this function was added to libpng 1.2.0 */ +/* This function was added to libpng 1.2.0 */ void PNGAPI png_set_mmx_thresholds (png_structp png_ptr, png_byte mmx_bitdepth_threshold, png_uint_32 mmx_rowbytes_threshold) { - png_ptr->mmx_bitdepth_threshold = mmx_bitdepth_threshold; - png_ptr->mmx_rowbytes_threshold = mmx_rowbytes_threshold; +/* Obsolete as of libpng-1.2.20 and will be removed from libpng-1.4.0 */ + if (png_ptr == NULL) + return; + /* Quiet the compiler */ + mmx_bitdepth_threshold = mmx_bitdepth_threshold; + mmx_rowbytes_threshold = mmx_rowbytes_threshold; } #endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */ #ifdef PNG_SET_USER_LIMITS_SUPPORTED -/* this function was added to libpng 1.2.6 */ +/* 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_uint_32 user_height_max) { - /* Images with dimensions larger than these limits will be - * rejected by png_set_IHDR(). To accept any PNG datastream - * regardless of dimensions, set both limits to 0x7ffffffL. - */ - png_ptr->user_width_max = user_width_max; - png_ptr->user_height_max = user_height_max; + /* Images with dimensions larger than these limits will be + * rejected by png_set_IHDR(). To accept any PNG datastream + * regardless of dimensions, set both limits to 0x7ffffffL. + */ + if (png_ptr == NULL) + return; + png_ptr->user_width_max = user_width_max; + png_ptr->user_height_max = user_height_max; } #endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */ #endif /* ?PNG_1_0_X */ +#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ diff --git a/3rdparty/wxWidgets/src/png/pngtest.c b/3rdparty/wxWidgets/src/png/pngtest.c index 431c85dd35..f6c3e340c0 100644 --- a/3rdparty/wxWidgets/src/png/pngtest.c +++ b/3rdparty/wxWidgets/src/png/pngtest.c @@ -1,12 +1,15 @@ /* pngtest.c - a simple test program to test libpng * - * libpng 1.2.7 - September 12, 2004 - * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2004 Glenn Randers-Pehrson + * Last changed in libpng 1.2.37 [June 4, 2009] + * Copyright (c) 1998-2009 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. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * * This program reads in a PNG image, writes it out again, and then * compares the two files. If the files are identical, this shows that * the basic chunk handling, filtering, and (de)compression code is working @@ -37,18 +40,17 @@ # include # include # define READFILE(file, data, length, check) \ - if (ReadFile(file, data, length, &check,NULL)) check = 0 + if (ReadFile(file, data, length, &check, NULL)) check = 0 # define WRITEFILE(file, data, length, check)) \ if (WriteFile(file, data, length, &check, NULL)) check = 0 # define FCLOSE(file) CloseHandle(file) #else # include # include -# include # define READFILE(file, data, length, check) \ - check=(png_size_t)fread(data,(png_size_t)1,length,file) + check=(png_size_t)fread(data, (png_size_t)1, length, file) # define WRITEFILE(file, data, length, check) \ - check=(png_size_t)fwrite(data,(png_size_t)1, length, file) + check=(png_size_t)fwrite(data, (png_size_t)1, length, file) # define FCLOSE(file) fclose(file) #endif @@ -66,7 +68,7 @@ #endif #if !PNG_DEBUG -# define SINGLE_ROWBUF_ALLOC /* makes buffer overruns easier to nail */ +# define SINGLE_ROWBUF_ALLOC /* Makes buffer overruns easier to nail */ #endif /* Turn on CPU timing @@ -82,21 +84,10 @@ static float t_start, t_stop, t_decode, t_encode, t_misc; #include #endif -/* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */ -#ifndef png_jmpbuf -# define png_jmpbuf(png_ptr) png_ptr->jmpbuf -#endif - -#ifdef PNGTEST_TIMING -static float t_start, t_stop, t_decode, t_encode, t_misc; -#if !defined(PNG_tIME_SUPPORTED) -#include -#endif -#endif - #if defined(PNG_TIME_RFC1123_SUPPORTED) -static int tIME_chunk_present=0; -static char tIME_string[30] = "no tIME chunk present in file"; +#define PNG_tIME_STRING_LENGTH 29 +static int tIME_chunk_present = 0; +static char tIME_string[PNG_tIME_STRING_LENGTH] = "tIME chunk is not present"; #endif static int verbose = 0; @@ -107,14 +98,24 @@ int test_one_file PNGARG((PNG_CONST char *inname, PNG_CONST char *outname)); #include #endif -/* defined so I can write to a file on gui/windowing platforms */ +/* Defined so I can write to a file on gui/windowing platforms */ /* #define STDERR stderr */ -#define STDERR stdout /* for DOS */ +#define STDERR stdout /* For DOS */ -/* example of using row callbacks to make a simple progress meter */ -static int status_pass=1; -static int status_dots_requested=0; -static int status_dots=1; +/* In case a system header (e.g., on AIX) defined jmpbuf */ +#ifdef jmpbuf +# undef jmpbuf +#endif + +/* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */ +#ifndef png_jmpbuf +# define png_jmpbuf(png_ptr) png_ptr->jmpbuf +#endif + +/* Example of using row callbacks to make a simple progress meter */ +static int status_pass = 1; +static int status_dots_requested = 0; +static int status_dots = 1; void #ifdef PNG_1_0_X @@ -127,20 +128,21 @@ PNGAPI #endif read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass) { - if(png_ptr == NULL || row_number > PNG_UINT_31_MAX) return; - if(status_pass != pass) - { - fprintf(stdout,"\n Pass %d: ",pass); - status_pass = pass; - status_dots = 31; - } - status_dots--; - if(status_dots == 0) - { - fprintf(stdout, "\n "); - status_dots=30; - } - fprintf(stdout, "r"); + if (png_ptr == NULL || row_number > PNG_UINT_31_MAX) + return; + if (status_pass != pass) + { + fprintf(stdout, "\n Pass %d: ", pass); + status_pass = pass; + status_dots = 31; + } + status_dots--; + if (status_dots == 0) + { + fprintf(stdout, "\n "); + status_dots=30; + } + fprintf(stdout, "r"); } void @@ -154,15 +156,17 @@ PNGAPI #endif write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass) { - if(png_ptr == NULL || row_number > PNG_UINT_31_MAX || pass > 7) return; - fprintf(stdout, "w"); + if (png_ptr == NULL || row_number > PNG_UINT_31_MAX || pass > 7) + return; + fprintf(stdout, "w"); } #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) /* Example of using user transform callback (we don't transform anything, - but merely examine the row filters. We set this to 256 rather than - 5 in case illegal filter values are present.) */ + * but merely examine the row filters. We set this to 256 rather than + * 5 in case illegal filter values are present.) + */ static png_uint_32 filters_used[256]; void #ifdef PNG_1_0_X @@ -175,14 +179,15 @@ PNGAPI #endif count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data) { - if(png_ptr != NULL && row_info != NULL) - ++filters_used[*(data-1)]; + if (png_ptr != NULL && row_info != NULL) + ++filters_used[*(data - 1)]; } #endif #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) -/* example of using user transform callback (we don't transform anything, - but merely count the zero samples) */ +/* Example of using user transform callback (we don't transform anything, + * but merely count the zero samples) + */ static png_uint_32 zero_samples; @@ -198,9 +203,9 @@ PNGAPI count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data) { png_bytep dp = data; - if(png_ptr == NULL)return; + if (png_ptr == NULL)return; - /* contents of row_info: + /* Contents of 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 @@ -209,74 +214,81 @@ count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data) * png_byte pixel_depth bits per pixel (depth*channels) */ + /* Counts the number of zero samples (or zero pixels if color_type is 3 */ - /* counts the number of zero samples (or zero pixels if color_type is 3 */ - - if(row_info->color_type == 0 || row_info->color_type == 3) + if (row_info->color_type == 0 || row_info->color_type == 3) { - int pos=0; + int pos = 0; png_uint_32 n, nstop; - for (n=0, nstop=row_info->width; nwidth; nbit_depth == 1) + if (row_info->bit_depth == 1) { - if(((*dp << pos++ ) & 0x80) == 0) zero_samples++; - if(pos == 8) + if (((*dp << pos++ ) & 0x80) == 0) + zero_samples++; + if (pos == 8) { pos = 0; dp++; } } - if(row_info->bit_depth == 2) + if (row_info->bit_depth == 2) { - if(((*dp << (pos+=2)) & 0xc0) == 0) zero_samples++; - if(pos == 8) + if (((*dp << (pos+=2)) & 0xc0) == 0) + zero_samples++; + if (pos == 8) { pos = 0; dp++; } } - if(row_info->bit_depth == 4) + if (row_info->bit_depth == 4) { - if(((*dp << (pos+=4)) & 0xf0) == 0) zero_samples++; - if(pos == 8) + if (((*dp << (pos+=4)) & 0xf0) == 0) + zero_samples++; + if (pos == 8) { pos = 0; dp++; } } - if(row_info->bit_depth == 8) - if(*dp++ == 0) zero_samples++; - if(row_info->bit_depth == 16) + if (row_info->bit_depth == 8) + if (*dp++ == 0) + zero_samples++; + if (row_info->bit_depth == 16) { - if((*dp | *(dp+1)) == 0) zero_samples++; + if ((*dp | *(dp+1)) == 0) + zero_samples++; dp+=2; } } } - else /* other color types */ + else /* Other color types */ { png_uint_32 n, nstop; int channel; int color_channels = row_info->channels; - if(row_info->color_type > 3)color_channels--; + if (row_info->color_type > 3)color_channels--; - for (n=0, nstop=row_info->width; nwidth; nbit_depth == 8) - if(*dp++ == 0) zero_samples++; - if(row_info->bit_depth == 16) + if (row_info->bit_depth == 8) + if (*dp++ == 0) + zero_samples++; + if (row_info->bit_depth == 16) { - if((*dp | *(dp+1)) == 0) zero_samples++; + if ((*dp | *(dp+1)) == 0) + zero_samples++; dp+=2; } } - if(row_info->color_type > 3) + if (row_info->color_type > 3) { dp++; - if(row_info->bit_depth == 16)dp++; + if (row_info->bit_depth == 16) + dp++; } } } @@ -287,12 +299,13 @@ static int wrote_question = 0; #if defined(PNG_NO_STDIO) /* START of code to validate stdio-free compilation */ -/* These copies of the default read/write functions come from pngrio.c and */ -/* pngwio.c. They allow "don't include stdio" testing of the library. */ -/* This is the function that does the actual reading of data. If you are - not reading from a standard C stream, you should create a replacement - read_data function and use it at run time with png_set_read_fn(), rather - than changing the library. */ +/* These copies of the default read/write functions come from pngrio.c and + * pngwio.c. They allow "don't include stdio" testing of the library. + * This is the function that does the actual reading of data. If you are + * not reading from a standard C stream, you should create a replacement + * read_data function and use it at run time with png_set_read_fn(), rather + * than changing the library. + */ #ifndef USE_FAR_KEYWORD static void @@ -311,7 +324,7 @@ pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length) } } #else -/* this is the model-independent version. Since the standard I/O library +/* 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. */ @@ -343,8 +356,8 @@ pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length) { read = MIN(NEAR_BUF_SIZE, remaining); READFILE(io_ptr, buf, 1, err); - png_memcpy(data, buf, read); /* copy far buffer to near buffer */ - if(err != read) + png_memcpy(data, buf, read); /* Copy far buffer to near buffer */ + if (err != read) break; else check += err; @@ -354,9 +367,7 @@ pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length) while (remaining != 0); } if (check != length) - { png_error(png_ptr, "read Error"); - } } #endif /* USE_FAR_KEYWORD */ @@ -364,19 +375,16 @@ pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length) static void pngtest_flush(png_structp png_ptr) { -#if !defined(_WIN32_WCE) - png_FILE_p io_ptr; - io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr)); - if (io_ptr != NULL) - fflush(io_ptr); -#endif + /* Do nothing; fflush() is said to be just a waste of energy. */ + png_ptr = png_ptr; /* Stifle compiler warning */ } #endif /* This is the function that does the actual writing of data. If you are - not writing to a standard C stream, you should create a replacement - write_data function and use it at run time with png_set_write_fn(), rather - than changing the library. */ + * not writing to a standard C stream, you should create a replacement + * write_data function and use it at run time with png_set_write_fn(), rather + * than changing the library. + */ #ifndef USE_FAR_KEYWORD static void pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length) @@ -390,7 +398,7 @@ pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length) } } #else -/* this is the model-independent version. Since the standard I/O library +/* 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. */ @@ -421,7 +429,7 @@ pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length) do { written = MIN(NEAR_BUF_SIZE, remaining); - png_memcpy(buf, data, written); /* copy far buffer to near buffer */ + png_memcpy(buf, data, written); /* Copy far buffer to near buffer */ WRITEFILE(io_ptr, buf, written, err); if (err != written) break; @@ -437,7 +445,6 @@ pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length) png_error(png_ptr, "Write Error"); } } - #endif /* USE_FAR_KEYWORD */ /* This function is called when there is a warning, but the library thinks @@ -464,7 +471,8 @@ pngtest_error(png_structp png_ptr, png_const_charp message) { pngtest_warning(png_ptr, message); /* We can return because png_error calls the default handler, which is - * actually OK in this case. */ + * actually OK in this case. + */ } #endif /* PNG_NO_STDIO */ /* END of code to validate stdio-free compilation */ @@ -473,13 +481,14 @@ pngtest_error(png_structp png_ptr, png_const_charp message) #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG /* Allocate memory. For reasonable files, size should never exceed - 64K. However, zlib may allocate more then 64K if you don't tell - it not to. See zconf.h and png.h for more information. zlib does - need to allocate exactly 64K, so whatever you call here must - have the ability to do that. - - This piece of code can be compiled to validate max 64K allocations - by setting MAXSEG_64K in zlib zconf.h *or* PNG_MAX_MALLOC_64K. */ + * 64K. However, zlib may allocate more then 64K if you don't tell + * it not to. See zconf.h and png.h for more information. zlib does + * need to allocate exactly 64K, so whatever you call here must + * have the ability to do that. + * + * This piece of code can be compiled to validate max 64K allocations + * by setting MAXSEG_64K in zlib zconf.h *or* PNG_MAX_MALLOC_64K. + */ typedef struct memory_information { png_uint_32 size; @@ -502,7 +511,8 @@ png_debug_malloc(png_structp png_ptr, png_uint_32 size) { /* png_malloc has already tested for NULL; png_create_struct calls - png_debug_malloc directly, with png_ptr == NULL which is OK */ + * png_debug_malloc directly, with png_ptr == NULL which is OK + */ if (size == 0) return (NULL); @@ -514,7 +524,7 @@ png_debug_malloc(png_structp png_ptr, png_uint_32 size) memory_infop pinfo; png_set_mem_fn(png_ptr, NULL, NULL, NULL); pinfo = (memory_infop)png_malloc(png_ptr, - (png_uint_32)png_sizeof (*pinfo)); + (png_uint_32)png_sizeof(*pinfo)); pinfo->size = size; current_allocation += size; total_allocation += size; @@ -523,8 +533,9 @@ png_debug_malloc(png_structp png_ptr, png_uint_32 size) maximum_allocation = current_allocation; pinfo->pointer = (png_voidp)png_malloc(png_ptr, size); /* Restore malloc_fn and free_fn */ - png_set_mem_fn(png_ptr, png_voidp_NULL, (png_malloc_ptr)png_debug_malloc, - (png_free_ptr)png_debug_free); + png_set_mem_fn(png_ptr, + png_voidp_NULL, (png_malloc_ptr)png_debug_malloc, + (png_free_ptr)png_debug_free); if (size != 0 && pinfo->pointer == NULL) { current_allocation -= size; @@ -536,9 +547,9 @@ png_debug_malloc(png_structp png_ptr, png_uint_32 size) pinformation = pinfo; /* Make sure the caller isn't assuming zeroed memory. */ png_memset(pinfo->pointer, 0xdd, pinfo->size); - if(verbose) - printf("png_malloc %lu bytes at %x\n",size,pinfo->pointer); - assert(pinfo->size != 12345678); + if (verbose) + printf("png_malloc %lu bytes at %x\n", (unsigned long)size, + pinfo->pointer); return (png_voidp)(pinfo->pointer); } } @@ -573,7 +584,7 @@ png_debug_free(png_structp png_ptr, png_voidp ptr) the memory that is to be freed. */ png_memset(ptr, 0x55, pinfo->size); png_free_default(png_ptr, pinfo); - pinfo=NULL; + pinfo = NULL; break; } if (pinfo->next == NULL) @@ -586,14 +597,82 @@ png_debug_free(png_structp png_ptr, png_voidp ptr) } /* Finally free the data. */ - if(verbose) - printf("Freeing %x\n",ptr); + if (verbose) + printf("Freeing %x\n", ptr); png_free_default(png_ptr, ptr); - ptr=NULL; + ptr = NULL; } #endif /* PNG_USER_MEM_SUPPORTED && PNG_DEBUG */ /* END of code to test memory allocation/deallocation */ + +/* Demonstration of user chunk support of the sTER and vpAg chunks */ +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) + +/* (sTER is a public chunk not yet known by libpng. vpAg is a private +chunk used in ImageMagick to store "virtual page" size). */ + +static png_uint_32 user_chunk_data[4]; + + /* 0: sTER mode + 1 + * 1: vpAg width + * 2: vpAg height + * 3: vpAg units + */ + +static int read_user_chunk_callback(png_struct *png_ptr, + png_unknown_chunkp chunk) +{ + png_uint_32 + *my_user_chunk_data; + + /* Return one of the following: + * return (-n); chunk had an error + * return (0); did not recognize + * return (n); success + * + * The unknown chunk structure contains the chunk data: + * png_byte name[5]; + * png_byte *data; + * png_size_t size; + * + * Note that libpng has already taken care of the CRC handling. + */ + + if (chunk->name[0] == 115 && chunk->name[1] == 84 && /* s T */ + chunk->name[2] == 69 && chunk->name[3] == 82) /* E R */ + { + /* Found sTER chunk */ + if (chunk->size != 1) + return (-1); /* Error return */ + if (chunk->data[0] != 0 && chunk->data[0] != 1) + return (-1); /* Invalid mode */ + my_user_chunk_data=(png_uint_32 *) png_get_user_chunk_ptr(png_ptr); + my_user_chunk_data[0]=chunk->data[0]+1; + return (1); + } + + if (chunk->name[0] != 118 || chunk->name[1] != 112 || /* v p */ + chunk->name[2] != 65 || chunk->name[3] != 103) /* A g */ + return (0); /* Did not recognize */ + + /* Found ImageMagick vpAg chunk */ + + if (chunk->size != 9) + return (-1); /* Error return */ + + my_user_chunk_data=(png_uint_32 *) png_get_user_chunk_ptr(png_ptr); + + my_user_chunk_data[1]=png_get_uint_31(png_ptr, chunk->data); + my_user_chunk_data[2]=png_get_uint_31(png_ptr, chunk->data + 4); + my_user_chunk_data[3]=(png_uint_32)chunk->data[8]; + + return (1); + +} +#endif +/* END of code to demonstrate user chunk support */ + /* Test one file */ int test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) @@ -652,26 +731,40 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) return (1); } - png_debug(0, "Allocating read and write structures\n"); + png_debug(0, "Allocating read and write structures"); #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - read_ptr = png_create_read_struct_2(PNG_LIBPNG_VER_STRING, png_voidp_NULL, + read_ptr = + png_create_read_struct_2(PNG_LIBPNG_VER_STRING, png_voidp_NULL, png_error_ptr_NULL, png_error_ptr_NULL, png_voidp_NULL, (png_malloc_ptr)png_debug_malloc, (png_free_ptr)png_debug_free); #else - read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, png_voidp_NULL, + read_ptr = + png_create_read_struct(PNG_LIBPNG_VER_STRING, png_voidp_NULL, png_error_ptr_NULL, png_error_ptr_NULL); #endif #if defined(PNG_NO_STDIO) png_set_error_fn(read_ptr, (png_voidp)inname, pngtest_error, pngtest_warning); #endif + +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) + user_chunk_data[0] = 0; + user_chunk_data[1] = 0; + user_chunk_data[2] = 0; + user_chunk_data[3] = 0; + png_set_read_user_chunk_fn(read_ptr, user_chunk_data, + read_user_chunk_callback); + +#endif #ifdef PNG_WRITE_SUPPORTED #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG - write_ptr = png_create_write_struct_2(PNG_LIBPNG_VER_STRING, png_voidp_NULL, + write_ptr = + png_create_write_struct_2(PNG_LIBPNG_VER_STRING, png_voidp_NULL, png_error_ptr_NULL, png_error_ptr_NULL, png_voidp_NULL, (png_malloc_ptr)png_debug_malloc, (png_free_ptr)png_debug_free); #else - write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, png_voidp_NULL, + write_ptr = + png_create_write_struct(PNG_LIBPNG_VER_STRING, png_voidp_NULL, png_error_ptr_NULL, png_error_ptr_NULL); #endif #if defined(PNG_NO_STDIO) @@ -679,7 +772,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) pngtest_warning); #endif #endif - png_debug(0, "Allocating read_info, write_info and end_info structures\n"); + png_debug(0, "Allocating read_info, write_info and end_info structures"); read_info_ptr = png_create_info_struct(read_ptr); end_info_ptr = png_create_info_struct(read_ptr); #ifdef PNG_WRITE_SUPPORTED @@ -688,7 +781,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) #endif #ifdef PNG_SETJMP_SUPPORTED - png_debug(0, "Setting jmpbuf for read struct\n"); + png_debug(0, "Setting jmpbuf for read struct"); #ifdef USE_FAR_KEYWORD if (setjmp(jmpbuf)) #else @@ -696,8 +789,8 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) #endif { fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname); - if (row_buf) - png_free(read_ptr, row_buf); + png_free(read_ptr, row_buf); + row_buf = NULL; png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); #ifdef PNG_WRITE_SUPPORTED png_destroy_info_struct(write_ptr, &write_end_info_ptr); @@ -708,11 +801,11 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) return (1); } #ifdef USE_FAR_KEYWORD - png_memcpy(png_jmpbuf(read_ptr),jmpbuf,png_sizeof(jmp_buf)); + png_memcpy(png_jmpbuf(read_ptr), jmpbuf, png_sizeof(jmp_buf)); #endif #ifdef PNG_WRITE_SUPPORTED - png_debug(0, "Setting jmpbuf for write struct\n"); + png_debug(0, "Setting jmpbuf for write struct"); #ifdef USE_FAR_KEYWORD if (setjmp(jmpbuf)) #else @@ -730,12 +823,12 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) return (1); } #ifdef USE_FAR_KEYWORD - png_memcpy(png_jmpbuf(write_ptr),jmpbuf,png_sizeof(jmp_buf)); + png_memcpy(png_jmpbuf(write_ptr), jmpbuf, png_sizeof(jmp_buf)); #endif #endif #endif - png_debug(0, "Initializing input and output streams\n"); + png_debug(0, "Initializing input and output streams"); #if !defined(PNG_NO_STDIO) png_init_io(read_ptr, fpin); # ifdef PNG_WRITE_SUPPORTED @@ -752,7 +845,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) # endif # endif #endif - if(status_dots_requested == 1) + if (status_dots_requested == 1) { #ifdef PNG_WRITE_SUPPORTED png_set_write_status_fn(write_ptr, write_row_callback); @@ -769,14 +862,14 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) { - int i; - for(i=0; i<256; i++) - filters_used[i]=0; - png_set_read_user_transform_fn(read_ptr, count_filters); + int i; + for (i = 0; i<256; i++) + filters_used[i] = 0; + png_set_read_user_transform_fn(read_ptr, count_filters); } #endif #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) - zero_samples=0; + zero_samples = 0; png_set_write_user_transform_fn(write_ptr, count_zero_samples); #endif @@ -795,10 +888,10 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) png_bytep_NULL, 0); #endif - png_debug(0, "Reading info struct\n"); + png_debug(0, "Reading info struct"); png_read_info(read_ptr, read_info_ptr); - png_debug(0, "Transferring info struct\n"); + png_debug(0, "Transferring info struct"); { int interlace_type, compression_type, filter_type; @@ -831,9 +924,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) png_fixed_point gamma; if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma)) - { png_set_gAMA_fixed(write_ptr, write_info_ptr, gamma); - } } #endif #else /* Use floating point versions */ @@ -855,13 +946,11 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) double gamma; if (png_get_gAMA(read_ptr, read_info_ptr, &gamma)) - { png_set_gAMA(write_ptr, write_info_ptr, gamma); - } } #endif -#endif /* floating point */ -#endif /* fixed point */ +#endif /* Floating point */ +#endif /* Fixed point */ #if defined(PNG_iCCP_SUPPORTED) { png_charp name; @@ -882,9 +971,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) int intent; if (png_get_sRGB(read_ptr, read_info_ptr, &intent)) - { png_set_sRGB(write_ptr, write_info_ptr, intent); - } } #endif { @@ -892,9 +979,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) int num_palette; if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette)) - { png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette); - } } #if defined(PNG_bKGD_SUPPORTED) { @@ -911,9 +996,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) png_uint_16p hist; if (png_get_hIST(read_ptr, read_info_ptr, &hist)) - { png_set_hIST(write_ptr, write_info_ptr, hist); - } } #endif #if defined(PNG_oFFs_SUPPORTED) @@ -921,7 +1004,8 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) png_int_32 offset_x, offset_y; int unit_type; - if (png_get_oFFs(read_ptr, read_info_ptr,&offset_x,&offset_y,&unit_type)) + if (png_get_oFFs(read_ptr, read_info_ptr, &offset_x, &offset_y, + &unit_type)) { png_set_oFFs(write_ptr, write_info_ptr, offset_x, offset_y, unit_type); } @@ -948,9 +1032,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) int unit_type; if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y, &unit_type)) - { png_set_pHYs(write_ptr, write_info_ptr, res_x, res_y, unit_type); - } } #endif #if defined(PNG_sBIT_SUPPORTED) @@ -958,9 +1040,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) png_color_8p sig_bit; if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit)) - { png_set_sBIT(write_ptr, write_info_ptr, sig_bit); - } } #endif #if defined(PNG_sCAL_SUPPORTED) @@ -997,7 +1077,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) if (png_get_text(read_ptr, read_info_ptr, &text_ptr, &num_text) > 0) { - png_debug1(0, "Handling %d iTXt/tEXt/zTXt chunks\n", num_text); + png_debug1(0, "Handling %d iTXt/tEXt/zTXt chunks", num_text); png_set_text(write_ptr, write_info_ptr, text_ptr, num_text); } } @@ -1010,10 +1090,14 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) { png_set_tIME(write_ptr, write_info_ptr, mod_time); #if defined(PNG_TIME_RFC1123_SUPPORTED) - /* we have to use png_strcpy instead of "=" because the string - pointed to by png_convert_to_rfc1123() gets free'ed before - we use it */ - png_strcpy(tIME_string,png_convert_to_rfc1123(read_ptr, mod_time)); + /* We have to use png_memcpy instead of "=" because the string + * pointed to by png_convert_to_rfc1123() gets free'ed before + * we use it. + */ + png_memcpy(tIME_string, + png_convert_to_rfc1123(read_ptr, mod_time), + png_sizeof(tIME_string)); + tIME_string[png_sizeof(tIME_string) - 1] = '\0'; tIME_chunk_present++; #endif /* PNG_TIME_RFC1123_SUPPORTED */ } @@ -1028,8 +1112,16 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) if (png_get_tRNS(read_ptr, read_info_ptr, &trans, &num_trans, &trans_values)) { - png_set_tRNS(write_ptr, write_info_ptr, trans, num_trans, - trans_values); + int sample_max = (1 << read_info_ptr->bit_depth); + /* libpng doesn't reject a tRNS chunk with out-of-range samples */ + if (!((read_info_ptr->color_type == PNG_COLOR_TYPE_GRAY && + (int)trans_values->gray > sample_max) || + (read_info_ptr->color_type == PNG_COLOR_TYPE_RGB && + ((int)trans_values->red > sample_max || + (int)trans_values->green > sample_max || + (int)trans_values->blue > sample_max)))) + png_set_tRNS(write_ptr, write_info_ptr, trans, num_trans, + trans_values); } } #endif @@ -1043,9 +1135,10 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) png_size_t i; png_set_unknown_chunks(write_ptr, write_info_ptr, unknowns, num_unknowns); - /* copy the locations from the read_info_ptr. The automatically - generated locations in write_info_ptr are wrong because we - haven't written anything yet */ + /* Copy the locations from the read_info_ptr. The automatically + * generated locations in write_info_ptr are wrong because we + * haven't written anything yet. + */ for (i = 0; i < (png_size_t)num_unknowns; i++) png_set_unknown_chunk_location(write_ptr, write_info_ptr, i, unknowns[i].location); @@ -1054,21 +1147,55 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) #endif #ifdef PNG_WRITE_SUPPORTED - png_debug(0, "\nWriting info struct\n"); + png_debug(0, "Writing info struct"); /* If we wanted, we could write info in two steps: - png_write_info_before_PLTE(write_ptr, write_info_ptr); + * png_write_info_before_PLTE(write_ptr, write_info_ptr); */ png_write_info(write_ptr, write_info_ptr); + +#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) + if (user_chunk_data[0] != 0) + { + png_byte png_sTER[5] = {115, 84, 69, 82, '\0'}; + + unsigned char + ster_chunk_data[1]; + + if (verbose) + fprintf(STDERR, "\n stereo mode = %lu\n", + (unsigned long)(user_chunk_data[0] - 1)); + ster_chunk_data[0]=(unsigned char)(user_chunk_data[0] - 1); + png_write_chunk(write_ptr, png_sTER, ster_chunk_data, 1); + } + if (user_chunk_data[1] != 0 || user_chunk_data[2] != 0) + { + png_byte png_vpAg[5] = {118, 112, 65, 103, '\0'}; + + unsigned char + vpag_chunk_data[9]; + + if (verbose) + fprintf(STDERR, " vpAg = %lu x %lu, units = %lu\n", + (unsigned long)user_chunk_data[1], + (unsigned long)user_chunk_data[2], + (unsigned long)user_chunk_data[3]); + png_save_uint_32(vpag_chunk_data, user_chunk_data[1]); + png_save_uint_32(vpag_chunk_data + 4, user_chunk_data[2]); + vpag_chunk_data[8] = (unsigned char)(user_chunk_data[3] & 0xff); + png_write_chunk(write_ptr, png_vpAg, vpag_chunk_data, 9); + } + +#endif #endif #ifdef SINGLE_ROWBUF_ALLOC - png_debug(0, "\nAllocating row buffer..."); + png_debug(0, "Allocating row buffer..."); row_buf = (png_bytep)png_malloc(read_ptr, png_get_rowbytes(read_ptr, read_info_ptr)); - png_debug1(0, "0x%08lx\n\n", (unsigned long)row_buf); + png_debug1(0, "0x%08lx", (unsigned long)row_buf); #endif /* SINGLE_ROWBUF_ALLOC */ - png_debug(0, "Writing row data\n"); + png_debug(0, "Writing row data"); #if defined(PNG_READ_INTERLACING_SUPPORTED) || \ defined(PNG_WRITE_INTERLACING_SUPPORTED) @@ -1077,7 +1204,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) png_set_interlace_handling(write_ptr); # endif #else - num_pass=1; + num_pass = 1; #endif #ifdef PNGTEST_TIMING @@ -1087,14 +1214,14 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) #endif for (pass = 0; pass < num_pass; pass++) { - png_debug1(0, "Writing row data for pass %d\n",pass); + png_debug1(0, "Writing row data for pass %d", pass); for (y = 0; y < height; y++) { #ifndef SINGLE_ROWBUF_ALLOC - png_debug2(0, "\nAllocating row buffer (pass %d, y = %ld)...", pass,y); + png_debug2(0, "Allocating row buffer (pass %d, y = %ld)...", pass, y); row_buf = (png_bytep)png_malloc(read_ptr, png_get_rowbytes(read_ptr, read_info_ptr)); - png_debug2(0, "0x%08lx (%ld bytes)\n", (unsigned long)row_buf, + png_debug2(0, "0x%08lx (%ld bytes)", (unsigned long)row_buf, png_get_rowbytes(read_ptr, read_info_ptr)); #endif /* !SINGLE_ROWBUF_ALLOC */ png_read_rows(read_ptr, (png_bytepp)&row_buf, png_bytepp_NULL, 1); @@ -1114,8 +1241,9 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) #endif /* PNG_WRITE_SUPPORTED */ #ifndef SINGLE_ROWBUF_ALLOC - png_debug2(0, "Freeing row buffer (pass %d, y = %ld)\n\n", pass, y); + png_debug2(0, "Freeing row buffer (pass %d, y = %ld)", pass, y); png_free(read_ptr, row_buf); + row_buf = NULL; #endif /* !SINGLE_ROWBUF_ALLOC */ } } @@ -1127,7 +1255,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) png_free_data(write_ptr, write_info_ptr, PNG_FREE_UNKN, -1); #endif - png_debug(0, "Reading and writing end_info data\n"); + png_debug(0, "Reading and writing end_info data"); png_read_end(read_ptr, end_info_ptr); #if defined(PNG_TEXT_SUPPORTED) @@ -1137,7 +1265,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) if (png_get_text(read_ptr, end_info_ptr, &text_ptr, &num_text) > 0) { - png_debug1(0, "Handling %d iTXt/tEXt/zTXt chunks\n", num_text); + png_debug1(0, "Handling %d iTXt/tEXt/zTXt chunks", num_text); png_set_text(write_ptr, write_end_info_ptr, text_ptr, num_text); } } @@ -1150,10 +1278,13 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) { png_set_tIME(write_ptr, write_end_info_ptr, mod_time); #if defined(PNG_TIME_RFC1123_SUPPORTED) - /* we have to use png_strcpy instead of "=" because the string + /* We have to use png_memcpy instead of "=" because the string pointed to by png_convert_to_rfc1123() gets free'ed before we use it */ - png_strcpy(tIME_string,png_convert_to_rfc1123(read_ptr, mod_time)); + png_memcpy(tIME_string, + png_convert_to_rfc1123(read_ptr, mod_time), + png_sizeof(tIME_string)); + tIME_string[png_sizeof(tIME_string) - 1] = '\0'; tIME_chunk_present++; #endif /* PNG_TIME_RFC1123_SUPPORTED */ } @@ -1170,9 +1301,10 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) png_size_t i; png_set_unknown_chunks(write_ptr, write_end_info_ptr, unknowns, num_unknowns); - /* copy the locations from the read_info_ptr. The automatically - generated locations in write_end_info_ptr are wrong because we - haven't written the end_info yet */ + /* Copy the locations from the read_info_ptr. The automatically + * generated locations in write_end_info_ptr are wrong because we + * haven't written the end_info yet. + */ for (i = 0; i < (png_size_t)num_unknowns; i++) png_set_unknown_chunk_location(write_ptr, write_end_info_ptr, i, unknowns[i].location); @@ -1184,36 +1316,36 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) #endif #ifdef PNG_EASY_ACCESS_SUPPORTED - if(verbose) + if (verbose) { png_uint_32 iwidth, iheight; iwidth = png_get_image_width(write_ptr, write_info_ptr); iheight = png_get_image_height(write_ptr, write_info_ptr); - fprintf(STDERR, "Image width = %lu, height = %lu\n", - iwidth, iheight); + fprintf(STDERR, "\n Image width = %lu, height = %lu\n", + (unsigned long)iwidth, (unsigned long)iheight); } #endif - png_debug(0, "Destroying data structs\n"); + png_debug(0, "Destroying data structs"); #ifdef SINGLE_ROWBUF_ALLOC - png_debug(1, "destroying row_buf for read_ptr\n"); + png_debug(1, "destroying row_buf for read_ptr"); png_free(read_ptr, row_buf); - row_buf=NULL; + row_buf = NULL; #endif /* SINGLE_ROWBUF_ALLOC */ - png_debug(1, "destroying read_ptr, read_info_ptr, end_info_ptr\n"); + png_debug(1, "destroying read_ptr, read_info_ptr, end_info_ptr"); png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); #ifdef PNG_WRITE_SUPPORTED - png_debug(1, "destroying write_end_info_ptr\n"); + png_debug(1, "destroying write_end_info_ptr"); png_destroy_info_struct(write_ptr, &write_end_info_ptr); - png_debug(1, "destroying write_ptr, write_info_ptr\n"); + png_debug(1, "destroying write_ptr, write_info_ptr"); png_destroy_write_struct(&write_ptr, &write_info_ptr); #endif - png_debug(0, "Destruction complete.\n"); + png_debug(0, "Destruction complete."); FCLOSE(fpin); FCLOSE(fpout); - png_debug(0, "Opening files for comparison\n"); + png_debug(0, "Opening files for comparison"); #if defined(_WIN32_WCE) MultiByteToWideChar(CP_ACP, 0, inname, -1, path, MAX_PATH); if ((fpin = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) @@ -1237,28 +1369,28 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) return (1); } - for(;;) + for (;;) { png_size_t num_in, num_out; - READFILE(fpin, inbuf, 1, num_in); - READFILE(fpout, outbuf, 1, num_out); + READFILE(fpin, inbuf, 1, num_in); + READFILE(fpout, outbuf, 1, num_out); if (num_in != num_out) { fprintf(STDERR, "\nFiles %s and %s are of a different size\n", inname, outname); - if(wrote_question == 0) + if (wrote_question == 0) { fprintf(STDERR, " Was %s written with the same maximum IDAT chunk size (%d bytes),", - inname,PNG_ZBUF_SIZE); + inname, PNG_ZBUF_SIZE); fprintf(STDERR, "\n filtering heuristic (libpng default), compression"); fprintf(STDERR, " level (zlib default),\n and zlib version (%s)?\n\n", ZLIB_VERSION); - wrote_question=1; + wrote_question = 1; } FCLOSE(fpin); FCLOSE(fpout); @@ -1271,17 +1403,17 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) if (png_memcmp(inbuf, outbuf, num_in)) { fprintf(STDERR, "\nFiles %s and %s are different\n", inname, outname); - if(wrote_question == 0) + if (wrote_question == 0) { fprintf(STDERR, " Was %s written with the same maximum IDAT chunk size (%d bytes),", - inname,PNG_ZBUF_SIZE); + inname, PNG_ZBUF_SIZE); fprintf(STDERR, "\n filtering heuristic (libpng default), compression"); fprintf(STDERR, " level (zlib default),\n and zlib version (%s)?\n\n", ZLIB_VERSION); - wrote_question=1; + wrote_question = 1; } FCLOSE(fpin); FCLOSE(fpout); @@ -1295,7 +1427,7 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) return (0); } -/* input and output filenames */ +/* Input and output filenames */ #ifdef RISCOS static PNG_CONST char *inname = "pngtest/png"; static PNG_CONST char *outname = "pngout/png"; @@ -1310,22 +1442,24 @@ main(int argc, char *argv[]) int multiple = 0; int ierror = 0; - fprintf(STDERR, "Testing libpng version %s\n", PNG_LIBPNG_VER_STRING); + fprintf(STDERR, "\n Testing libpng version %s\n", PNG_LIBPNG_VER_STRING); fprintf(STDERR, " with zlib version %s\n", ZLIB_VERSION); - fprintf(STDERR,"%s",png_get_copyright(NULL)); + fprintf(STDERR, "%s", png_get_copyright(NULL)); /* Show the version of libpng used in building the library */ - fprintf(STDERR," library (%lu):%s", png_access_version_number(), + fprintf(STDERR, " library (%lu):%s", + (unsigned long)png_access_version_number(), png_get_header_version(NULL)); /* Show the version of libpng used in building the application */ - fprintf(STDERR," pngtest (%lu):%s", (unsigned long)PNG_LIBPNG_VER, + fprintf(STDERR, " pngtest (%lu):%s", (unsigned long)PNG_LIBPNG_VER, PNG_HEADER_VERSION_STRING); - fprintf(STDERR," png_sizeof(png_struct)=%ld, png_sizeof(png_info)=%ld\n", + fprintf(STDERR, " sizeof(png_struct)=%ld, sizeof(png_info)=%ld\n", (long)png_sizeof(png_struct), (long)png_sizeof(png_info)); /* Do some consistency checking on the memory allocation settings, I'm - not sure this matters, but it is nice to know, the first of these - tests should be impossible because of the way the macros are set - in pngconf.h */ + * not sure this matters, but it is nice to know, the first of these + * tests should be impossible because of the way the macros are set + * in pngconf.h + */ #if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K) fprintf(STDERR, " NOTE: Zlib compiled for max 64k, libpng not\n"); #endif @@ -1370,10 +1504,10 @@ main(int argc, char *argv[]) } } - if (!multiple && argc == 3+verbose) - outname = argv[2+verbose]; + if (!multiple && argc == 3 + verbose) + outname = argv[2 + verbose]; - if ((!multiple && argc > 3+verbose) || (multiple && argc < 2)) + if ((!multiple && argc > 3 + verbose) || (multiple && argc < 2)) { fprintf(STDERR, "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n", @@ -1397,24 +1531,25 @@ main(int argc, char *argv[]) int k; #endif int kerror; - fprintf(STDERR, "Testing %s:",argv[i]); + fprintf(STDERR, "\n Testing %s:", argv[i]); kerror = test_one_file(argv[i], outname); if (kerror == 0) { #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) - fprintf(STDERR, "\n PASS (%lu zero samples)\n",zero_samples); + fprintf(STDERR, "\n PASS (%lu zero samples)\n", + (unsigned long)zero_samples); #else fprintf(STDERR, " PASS\n"); #endif #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) - for (k=0; k<256; k++) - if(filters_used[k]) + for (k = 0; k<256; k++) + if (filters_used[k]) fprintf(STDERR, " Filter %d was used %lu times\n", - k,filters_used[k]); + k, (unsigned long)filters_used[k]); #endif #if defined(PNG_TIME_RFC1123_SUPPORTED) - if(tIME_chunk_present != 0) - fprintf(STDERR, " tIME = %s\n",tIME_string); + if (tIME_chunk_present != 0) + fprintf(STDERR, " tIME = %s\n", tIME_string); tIME_chunk_present = 0; #endif /* PNG_TIME_RFC1123_SUPPORTED */ } @@ -1426,7 +1561,7 @@ main(int argc, char *argv[]) #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG if (allocation_now != current_allocation) fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n", - current_allocation-allocation_now); + current_allocation - allocation_now); if (current_allocation != 0) { memory_infop pinfo = pinformation; @@ -1435,7 +1570,8 @@ main(int argc, char *argv[]) current_allocation); while (pinfo != NULL) { - fprintf(STDERR, " %lu bytes at %x\n", pinfo->size, + fprintf(STDERR, " %lu bytes at %x\n", + (unsigned long)pinfo->size, (unsigned int) pinfo->pointer); pinfo = pinfo->next; } @@ -1456,52 +1592,54 @@ main(int argc, char *argv[]) else { int i; - for (i=0; i<3; ++i) + for (i = 0; i<3; ++i) { int kerror; #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG int allocation_now = current_allocation; #endif if (i == 1) status_dots_requested = 1; - else if(verbose == 0)status_dots_requested = 0; + else if (verbose == 0)status_dots_requested = 0; if (i == 0 || verbose == 1 || ierror != 0) - fprintf(STDERR, "Testing %s:",inname); + fprintf(STDERR, "\n Testing %s:", inname); kerror = test_one_file(inname, outname); - if(kerror == 0) + if (kerror == 0) { - if(verbose == 1 || i == 2) + if (verbose == 1 || i == 2) { #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) int k; #endif #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) - fprintf(STDERR, "\n PASS (%lu zero samples)\n",zero_samples); + fprintf(STDERR, "\n PASS (%lu zero samples)\n", + (unsigned long)zero_samples); #else fprintf(STDERR, " PASS\n"); #endif #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) - for (k=0; k<256; k++) - if(filters_used[k]) + for (k = 0; k<256; k++) + if (filters_used[k]) fprintf(STDERR, " Filter %d was used %lu times\n", - k,filters_used[k]); + k, + (unsigned long)filters_used[k]); #endif #if defined(PNG_TIME_RFC1123_SUPPORTED) - if(tIME_chunk_present != 0) - fprintf(STDERR, " tIME = %s\n",tIME_string); + if (tIME_chunk_present != 0) + fprintf(STDERR, " tIME = %s\n", tIME_string); #endif /* PNG_TIME_RFC1123_SUPPORTED */ } } else { - if(verbose == 0 && i != 2) - fprintf(STDERR, "Testing %s:",inname); + if (verbose == 0 && i != 2) + fprintf(STDERR, "\n Testing %s:", inname); fprintf(STDERR, " FAIL\n"); ierror += kerror; } #if defined(PNG_USER_MEM_SUPPORTED) && PNG_DEBUG if (allocation_now != current_allocation) fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n", - current_allocation-allocation_now); + current_allocation - allocation_now); if (current_allocation != 0) { memory_infop pinfo = pinformation; @@ -1510,8 +1648,8 @@ main(int argc, char *argv[]) current_allocation); while (pinfo != NULL) { - fprintf(STDERR," %lu bytes at %x\n", - pinfo->size, (unsigned int)pinfo->pointer); + fprintf(STDERR, " %lu bytes at %x\n", + (unsigned long)pinfo->size, (unsigned int)pinfo->pointer); pinfo = pinfo->next; } } @@ -1533,22 +1671,22 @@ main(int argc, char *argv[]) t_stop = (float)clock(); t_misc += (t_stop - t_start); t_start = t_stop; - fprintf(STDERR," CPU time used = %.3f seconds", + fprintf(STDERR, " CPU time used = %.3f seconds", (t_misc+t_decode+t_encode)/(float)CLOCKS_PER_SEC); - fprintf(STDERR," (decoding %.3f,\n", + fprintf(STDERR, " (decoding %.3f,\n", t_decode/(float)CLOCKS_PER_SEC); - fprintf(STDERR," encoding %.3f ,", + fprintf(STDERR, " encoding %.3f ,", t_encode/(float)CLOCKS_PER_SEC); - fprintf(STDERR," other %.3f seconds)\n\n", + fprintf(STDERR, " other %.3f seconds)\n\n", t_misc/(float)CLOCKS_PER_SEC); #endif if (ierror == 0) - fprintf(STDERR, "libpng passes test\n"); + fprintf(STDERR, " libpng passes test\n"); else - fprintf(STDERR, "libpng FAILS test\n"); + fprintf(STDERR, " libpng FAILS test\n"); return (int)(ierror != 0); } /* Generate a compiler error if there is an old png.h in the search path. */ -typedef version_1_2_7 your_png_h_is_not_version_1_2_7; +typedef version_1_2_39 your_png_h_is_not_version_1_2_39; diff --git a/3rdparty/wxWidgets/src/png/pngtrans.c b/3rdparty/wxWidgets/src/png/pngtrans.c index f279f9e790..6e1870c596 100644 --- a/3rdparty/wxWidgets/src/png/pngtrans.c +++ b/3rdparty/wxWidgets/src/png/pngtrans.c @@ -1,43 +1,53 @@ /* pngtrans.c - transforms the data in a row (used by both readers and writers) * - * libpng 1.2.7 - September 12, 2004 - * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2004 Glenn Randers-Pehrson + * Last changed in libpng 1.2.36 [May 14, 2009] + * Copyright (c) 1998-2009 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. + * For conditions of distribution and use, see the disclaimer + * and license in png.h */ #define PNG_INTERNAL #include "png.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 */ +/* Turn on BGR-to-RGB mapping */ void PNGAPI png_set_bgr(png_structp png_ptr) { - png_debug(1, "in png_set_bgr\n"); + png_debug(1, "in png_set_bgr"); + if (png_ptr == NULL) + return; png_ptr->transformations |= PNG_BGR; } #endif #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) -/* turn on 16 bit byte swapping */ +/* Turn on 16 bit byte swapping */ void PNGAPI png_set_swap(png_structp png_ptr) { - png_debug(1, "in png_set_swap\n"); + png_debug(1, "in png_set_swap"); + if (png_ptr == NULL) + return; if (png_ptr->bit_depth == 16) png_ptr->transformations |= PNG_SWAP_BYTES; } #endif #if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) -/* turn on pixel packing */ +/* Turn on pixel packing */ void PNGAPI png_set_packing(png_structp png_ptr) { - png_debug(1, "in png_set_packing\n"); + png_debug(1, "in png_set_packing"); + if (png_ptr == NULL) + return; if (png_ptr->bit_depth < 8) { png_ptr->transformations |= PNG_PACK; @@ -47,11 +57,13 @@ png_set_packing(png_structp png_ptr) #endif #if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED) -/* turn on packed pixel swapping */ +/* Turn on packed pixel swapping */ void PNGAPI png_set_packswap(png_structp png_ptr) { - png_debug(1, "in png_set_packswap\n"); + png_debug(1, "in png_set_packswap"); + if (png_ptr == NULL) + return; if (png_ptr->bit_depth < 8) png_ptr->transformations |= PNG_PACKSWAP; } @@ -61,7 +73,9 @@ png_set_packswap(png_structp png_ptr) void PNGAPI png_set_shift(png_structp png_ptr, png_color_8p true_bits) { - png_debug(1, "in png_set_shift\n"); + png_debug(1, "in png_set_shift"); + if (png_ptr == NULL) + return; png_ptr->transformations |= PNG_SHIFT; png_ptr->shift = *true_bits; } @@ -72,8 +86,8 @@ png_set_shift(png_structp png_ptr, png_color_8p true_bits) int PNGAPI png_set_interlace_handling(png_structp png_ptr) { - png_debug(1, "in png_set_interlace handling\n"); - if (png_ptr->interlaced) + png_debug(1, "in png_set_interlace handling"); + if (png_ptr && png_ptr->interlaced) { png_ptr->transformations |= PNG_INTERLACE; return (7); @@ -92,7 +106,9 @@ png_set_interlace_handling(png_structp png_ptr) void PNGAPI png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc) { - png_debug(1, "in png_set_filler\n"); + png_debug(1, "in png_set_filler"); + if (png_ptr == NULL) + return; png_ptr->transformations |= PNG_FILLER; png_ptr->filler = (png_byte)filler; if (filler_loc == PNG_FILLER_AFTER) @@ -124,7 +140,9 @@ png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc) void PNGAPI png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc) { - png_debug(1, "in png_set_add_alpha\n"); + png_debug(1, "in png_set_add_alpha"); + if (png_ptr == NULL) + return; png_set_filler(png_ptr, filler, filler_loc); png_ptr->transformations |= PNG_ADD_ALPHA; } @@ -137,7 +155,9 @@ png_set_add_alpha(png_structp png_ptr, png_uint_32 filler, int filler_loc) void PNGAPI png_set_swap_alpha(png_structp png_ptr) { - png_debug(1, "in png_set_swap_alpha\n"); + png_debug(1, "in png_set_swap_alpha"); + if (png_ptr == NULL) + return; png_ptr->transformations |= PNG_SWAP_ALPHA; } #endif @@ -147,7 +167,9 @@ png_set_swap_alpha(png_structp png_ptr) void PNGAPI png_set_invert_alpha(png_structp png_ptr) { - png_debug(1, "in png_set_invert_alpha\n"); + png_debug(1, "in png_set_invert_alpha"); + if (png_ptr == NULL) + return; png_ptr->transformations |= PNG_INVERT_ALPHA; } #endif @@ -156,15 +178,17 @@ png_set_invert_alpha(png_structp png_ptr) void PNGAPI png_set_invert_mono(png_structp png_ptr) { - png_debug(1, "in png_set_invert_mono\n"); + png_debug(1, "in png_set_invert_mono"); + if (png_ptr == NULL) + return; png_ptr->transformations |= PNG_INVERT_MONO; } -/* invert monochrome grayscale data */ +/* Invert monochrome grayscale data */ void /* PRIVATE */ png_do_invert(png_row_infop row_info, png_bytep row) { - png_debug(1, "in png_do_invert\n"); + png_debug(1, "in png_do_invert"); /* This test removed from libpng version 1.0.13 and 1.2.0: * if (row_info->bit_depth == 1 && */ @@ -215,11 +239,11 @@ png_do_invert(png_row_infop row_info, png_bytep row) #endif #if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED) -/* swaps byte order on 16 bit depth images */ +/* Swaps byte order on 16 bit depth images */ void /* PRIVATE */ png_do_swap(png_row_infop row_info, png_bytep row) { - png_debug(1, "in png_do_swap\n"); + png_debug(1, "in png_do_swap"); if ( #if defined(PNG_USELESS_TESTS_SUPPORTED) row != NULL && row_info != NULL && @@ -241,7 +265,7 @@ png_do_swap(png_row_infop row_info, png_bytep row) #endif #if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED) -static png_byte onebppswaptable[256] = { +static PNG_CONST png_byte onebppswaptable[256] = { 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, @@ -276,7 +300,7 @@ static png_byte onebppswaptable[256] = { 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF }; -static png_byte twobppswaptable[256] = { +static PNG_CONST png_byte twobppswaptable[256] = { 0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0, 0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0, 0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4, @@ -311,7 +335,7 @@ static png_byte twobppswaptable[256] = { 0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF }; -static png_byte fourbppswaptable[256] = { +static PNG_CONST png_byte fourbppswaptable[256] = { 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0, 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, @@ -346,11 +370,11 @@ static png_byte fourbppswaptable[256] = { 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF }; -/* swaps pixel packing order within bytes */ +/* Swaps pixel packing order within bytes */ void /* PRIVATE */ png_do_packswap(png_row_infop row_info, png_bytep row) { - png_debug(1, "in png_do_packswap\n"); + png_debug(1, "in png_do_packswap"); if ( #if defined(PNG_USELESS_TESTS_SUPPORTED) row != NULL && row_info != NULL && @@ -362,11 +386,11 @@ png_do_packswap(png_row_infop row_info, png_bytep row) end = row + row_info->rowbytes; if (row_info->bit_depth == 1) - table = onebppswaptable; + table = (png_bytep)onebppswaptable; else if (row_info->bit_depth == 2) - table = twobppswaptable; + table = (png_bytep)twobppswaptable; else if (row_info->bit_depth == 4) - table = fourbppswaptable; + table = (png_bytep)fourbppswaptable; else return; @@ -378,11 +402,11 @@ png_do_packswap(png_row_infop row_info, png_bytep row) #if defined(PNG_WRITE_FILLER_SUPPORTED) || \ defined(PNG_READ_STRIP_ALPHA_SUPPORTED) -/* remove filler or alpha byte(s) */ +/* Remove filler or alpha byte(s) */ void /* PRIVATE */ png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags) { - png_debug(1, "in png_do_strip_filler\n"); + png_debug(1, "in png_do_strip_filler"); #if defined(PNG_USELESS_TESTS_SUPPORTED) if (row != NULL && row_info != NULL) #endif @@ -392,8 +416,10 @@ png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags) png_uint_32 row_width=row_info->width; png_uint_32 i; - if (row_info->color_type == PNG_COLOR_TYPE_RGB && - row_info->channels == 4) + if ((row_info->color_type == PNG_COLOR_TYPE_RGB || + (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA && + (flags & PNG_FLAG_STRIP_ALPHA))) && + row_info->channels == 4) { if (row_info->bit_depth == 8) { @@ -471,7 +497,9 @@ png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags) } row_info->channels = 3; } - else if (row_info->color_type == PNG_COLOR_TYPE_GRAY && + else if ((row_info->color_type == PNG_COLOR_TYPE_GRAY || + (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && + (flags & PNG_FLAG_STRIP_ALPHA))) && row_info->channels == 2) { if (row_info->bit_depth == 8) @@ -525,16 +553,18 @@ png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags) } row_info->channels = 1; } + if (flags & PNG_FLAG_STRIP_ALPHA) + row_info->color_type &= ~PNG_COLOR_MASK_ALPHA; } } #endif #if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED) -/* swaps red and blue bytes within a pixel */ +/* Swaps red and blue bytes within a pixel */ void /* PRIVATE */ png_do_bgr(png_row_infop row_info, png_bytep row) { - png_debug(1, "in png_do_bgr\n"); + png_debug(1, "in png_do_bgr"); if ( #if defined(PNG_USELESS_TESTS_SUPPORTED) row != NULL && row_info != NULL && @@ -607,19 +637,21 @@ png_do_bgr(png_row_infop row_info, png_bytep row) #endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */ #if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \ - defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \ - defined(PNG_LEGACY_SUPPORTED) + defined(PNG_LEGACY_SUPPORTED) || \ + defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) void PNGAPI png_set_user_transform_info(png_structp png_ptr, png_voidp user_transform_ptr, int user_transform_depth, int user_transform_channels) { - png_debug(1, "in png_set_user_transform_info\n"); + png_debug(1, "in png_set_user_transform_info"); + if (png_ptr == NULL) + return; #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) png_ptr->user_transform_ptr = user_transform_ptr; png_ptr->user_transform_depth = (png_byte)user_transform_depth; png_ptr->user_transform_channels = (png_byte)user_transform_channels; #else - if(user_transform_ptr || user_transform_depth || user_transform_channels) + if (user_transform_ptr || user_transform_depth || user_transform_channels) png_warning(png_ptr, "This version of libpng does not support user transform info"); #endif @@ -634,11 +666,12 @@ png_set_user_transform_info(png_structp png_ptr, png_voidp png_voidp PNGAPI png_get_user_transform_ptr(png_structp png_ptr) { + if (png_ptr == NULL) + return (NULL); #if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) return ((png_voidp)png_ptr->user_transform_ptr); #else - if(png_ptr) - return (NULL); return (NULL); #endif } +#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ diff --git a/3rdparty/wxWidgets/src/png/pngvcrd.c b/3rdparty/wxWidgets/src/png/pngvcrd.c deleted file mode 100644 index b6fea2e35f..0000000000 --- a/3rdparty/wxWidgets/src/png/pngvcrd.c +++ /dev/null @@ -1,3903 +0,0 @@ -/* pngvcrd.c - mixed C/assembler version of utilities to read a PNG file - * - * For Intel x86 CPU and Microsoft Visual C++ compiler - * - * libpng version 1.2.7 - September 12, 2004 - * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2004 Glenn Randers-Pehrson - * Copyright (c) 1998, Intel Corporation - * - * Contributed by Nirav Chhatrapati, Intel Corporation, 1998 - * Interface to libpng contributed by Gilles Vollant, 1999 - * - * - * In png_do_read_interlace() in libpng versions 1.0.3a through 1.0.4d, - * a sign error in the post-MMX cleanup code for each pixel_depth resulted - * in bad pixels at the beginning of some rows of some images, and also - * (due to out-of-range memory reads and writes) caused heap corruption - * when compiled with MSVC 6.0. The error was fixed in version 1.0.4e. - * - * [png_read_filter_row_mmx_avg() bpp == 2 bugfix, GRR 20000916] - * - * [runtime MMX configuration, GRR 20010102] - * - */ - -#define PNG_INTERNAL -#include "png.h" - -#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_USE_PNGVCRD) - -static int mmx_supported=2; - - -int PNGAPI -png_mmx_support(void) -{ - int mmx_supported_local = 0; - _asm { - push ebx /*CPUID will trash these */ - push ecx - push edx - - pushfd /*Save Eflag to stack */ - pop eax /*Get Eflag from stack into eax */ - mov ecx, eax /*Make another copy of Eflag in ecx */ - xor eax, 0x200000 /*Toggle ID bit in Eflag [i.e. bit(21)] */ - push eax /*Save modified Eflag back to stack */ - - popfd /*Restored modified value back to Eflag reg */ - pushfd /*Save Eflag to stack */ - pop eax /*Get Eflag from stack */ - push ecx /* save original Eflag to stack */ - popfd /* restore original Eflag */ - xor eax, ecx /*Compare the new Eflag with the original Eflag */ - jz NOT_SUPPORTED /*If the same, CPUID instruction is not supported, */ - /*skip following instructions and jump to */ - /*NOT_SUPPORTED label */ - - xor eax, eax /*Set eax to zero */ - - _asm _emit 0x0f /*CPUID instruction (two bytes opcode) */ - _asm _emit 0xa2 - - cmp eax, 1 /*make sure eax return non-zero value */ - jl NOT_SUPPORTED /*If eax is zero, mmx not supported */ - - xor eax, eax /*set eax to zero */ - inc eax /*Now increment eax to 1. This instruction is */ - /*faster than the instruction "mov eax, 1" */ - - _asm _emit 0x0f /*CPUID instruction */ - _asm _emit 0xa2 - - and edx, 0x00800000 /*mask out all bits but mmx bit(24) */ - cmp edx, 0 /* 0 = mmx not supported */ - jz NOT_SUPPORTED /* non-zero = Yes, mmx IS supported */ - - mov mmx_supported_local, 1 /*set return value to 1 */ - -NOT_SUPPORTED: - mov eax, mmx_supported_local /*move return value to eax */ - pop edx /*CPUID trashed these */ - pop ecx - pop ebx - } - - /*mmx_supported_local=0; // test code for force don't support MMX */ - /*printf("MMX : %u (1=MMX supported)\n",mmx_supported_local); */ - - mmx_supported = mmx_supported_local; - return mmx_supported_local; -} - -/* Combines the row recently read in with the previous 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. */ - -/* Use this routine for x86 platform - uses faster MMX routine if machine - supports MMX */ - -void /* PRIVATE */ -png_combine_row(png_structp png_ptr, png_bytep row, int mask) -{ -#ifdef PNG_USE_LOCAL_ARRAYS - const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; -#endif - - png_debug(1,"in png_combine_row_asm\n"); - - if (mmx_supported == 2) { -#if !defined(PNG_1_0_X) - /* this should have happened in png_init_mmx_flags() already */ - png_warning(png_ptr, "asm_flags may not have been initialized"); -#endif - png_mmx_support(); - } - - if (mask == 0xff) - { - png_memcpy(row, png_ptr->row_buf + 1, - (png_size_t)PNG_ROWBYTES(png_ptr->row_info.pixel_depth, - png_ptr->width)); - } - /* GRR: add "else if (mask == 0)" case? - * or does png_combine_row() not even get called in that case? */ - else - { - switch (png_ptr->row_info.pixel_depth) - { - case 1: - { - png_bytep sp; - png_bytep dp; - int s_inc, s_start, s_end; - int m; - int shift; - png_uint_32 i; - - sp = png_ptr->row_buf + 1; - dp = row; - m = 0x80; -#if defined(PNG_READ_PACKSWAP_SUPPORTED) - if (png_ptr->transformations & PNG_PACKSWAP) - { - s_start = 0; - s_end = 7; - s_inc = 1; - } - else -#endif - { - s_start = 7; - s_end = 0; - s_inc = -1; - } - - shift = s_start; - - for (i = 0; i < png_ptr->width; i++) - { - if (m & mask) - { - int value; - - value = (*sp >> shift) & 0x1; - *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff); - *dp |= (png_byte)(value << shift); - } - - if (shift == s_end) - { - shift = s_start; - sp++; - dp++; - } - else - shift += s_inc; - - if (m == 1) - m = 0x80; - else - m >>= 1; - } - break; - } - - case 2: - { - png_bytep sp; - png_bytep dp; - int s_start, s_end, s_inc; - int m; - int shift; - png_uint_32 i; - int value; - - sp = png_ptr->row_buf + 1; - dp = row; - m = 0x80; -#if defined(PNG_READ_PACKSWAP_SUPPORTED) - if (png_ptr->transformations & PNG_PACKSWAP) - { - s_start = 0; - s_end = 6; - s_inc = 2; - } - else -#endif - { - s_start = 6; - s_end = 0; - s_inc = -2; - } - - shift = s_start; - - for (i = 0; i < png_ptr->width; i++) - { - if (m & mask) - { - value = (*sp >> shift) & 0x3; - *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); - *dp |= (png_byte)(value << shift); - } - - if (shift == s_end) - { - shift = s_start; - sp++; - dp++; - } - else - shift += s_inc; - if (m == 1) - m = 0x80; - else - m >>= 1; - } - break; - } - - case 4: - { - png_bytep sp; - png_bytep dp; - int s_start, s_end, s_inc; - int m; - int shift; - png_uint_32 i; - int value; - - sp = png_ptr->row_buf + 1; - dp = row; - m = 0x80; -#if defined(PNG_READ_PACKSWAP_SUPPORTED) - if (png_ptr->transformations & PNG_PACKSWAP) - { - s_start = 0; - s_end = 4; - s_inc = 4; - } - else -#endif - { - s_start = 4; - s_end = 0; - s_inc = -4; - } - shift = s_start; - - for (i = 0; i < png_ptr->width; i++) - { - if (m & mask) - { - value = (*sp >> shift) & 0xf; - *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); - *dp |= (png_byte)(value << shift); - } - - if (shift == s_end) - { - shift = s_start; - sp++; - dp++; - } - else - shift += s_inc; - if (m == 1) - m = 0x80; - else - m >>= 1; - } - break; - } - - case 8: - { - png_bytep srcptr; - png_bytep dstptr; - png_uint_32 len; - int m; - int diff, unmask; - - __int64 mask0=0x0102040810204080; - -#if !defined(PNG_1_0_X) - if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) - /* && mmx_supported */ ) -#else - if (mmx_supported) -#endif - { - srcptr = png_ptr->row_buf + 1; - dstptr = row; - m = 0x80; - unmask = ~mask; - len = png_ptr->width &~7; /*reduce to multiple of 8 */ - diff = png_ptr->width & 7; /*amount lost */ - - _asm - { - movd mm7, unmask /*load bit pattern */ - psubb mm6,mm6 /*zero mm6 */ - punpcklbw mm7,mm7 - punpcklwd mm7,mm7 - punpckldq mm7,mm7 /*fill register with 8 masks */ - - movq mm0,mask0 - - pand mm0,mm7 /*nonzero if keep byte */ - pcmpeqb mm0,mm6 /*zeros->1s, v versa */ - - mov ecx,len /*load length of line (pixels) */ - mov esi,srcptr /*load source */ - mov ebx,dstptr /*load dest */ - cmp ecx,0 /*lcr */ - je mainloop8end - -mainloop8: - movq mm4,[esi] - pand mm4,mm0 - movq mm6,mm0 - pandn mm6,[ebx] - por mm4,mm6 - movq [ebx],mm4 - - add esi,8 /*inc by 8 bytes processed */ - add ebx,8 - sub ecx,8 /*dec by 8 pixels processed */ - - ja mainloop8 -mainloop8end: - - mov ecx,diff - cmp ecx,0 - jz end8 - - mov edx,mask - sal edx,24 /*make low byte the high byte */ - -secondloop8: - sal edx,1 /*move high bit to CF */ - jnc skip8 /*if CF = 0 */ - mov al,[esi] - mov [ebx],al -skip8: - inc esi - inc ebx - - dec ecx - jnz secondloop8 -end8: - emms - } - } - else /* mmx not supported - use modified C routine */ - { - register unsigned int incr1, initial_val, final_val; - png_size_t pixel_bytes; - png_uint_32 i; - register int disp = png_pass_inc[png_ptr->pass]; - int offset_table[7] = {0, 4, 0, 2, 0, 1, 0}; - - pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); - srcptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]* - pixel_bytes; - dstptr = row + offset_table[png_ptr->pass]*pixel_bytes; - initial_val = offset_table[png_ptr->pass]*pixel_bytes; - final_val = png_ptr->width*pixel_bytes; - incr1 = (disp)*pixel_bytes; - for (i = initial_val; i < final_val; i += incr1) - { - png_memcpy(dstptr, srcptr, pixel_bytes); - srcptr += incr1; - dstptr += incr1; - } - } /* end of else */ - - break; - } /* end 8 bpp */ - - case 16: - { - png_bytep srcptr; - png_bytep dstptr; - png_uint_32 len; - int unmask, diff; - __int64 mask1=0x0101020204040808, - mask0=0x1010202040408080; - -#if !defined(PNG_1_0_X) - if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) - /* && mmx_supported */ ) -#else - if (mmx_supported) -#endif - { - srcptr = png_ptr->row_buf + 1; - dstptr = row; - - unmask = ~mask; - len = (png_ptr->width)&~7; - diff = (png_ptr->width)&7; - _asm - { - movd mm7, unmask /*load bit pattern */ - psubb mm6,mm6 /*zero mm6 */ - punpcklbw mm7,mm7 - punpcklwd mm7,mm7 - punpckldq mm7,mm7 /*fill register with 8 masks */ - - movq mm0,mask0 - movq mm1,mask1 - - pand mm0,mm7 - pand mm1,mm7 - - pcmpeqb mm0,mm6 - pcmpeqb mm1,mm6 - - mov ecx,len /*load length of line */ - mov esi,srcptr /*load source */ - mov ebx,dstptr /*load dest */ - cmp ecx,0 /*lcr */ - jz mainloop16end - -mainloop16: - movq mm4,[esi] - pand mm4,mm0 - movq mm6,mm0 - movq mm7,[ebx] - pandn mm6,mm7 - por mm4,mm6 - movq [ebx],mm4 - - movq mm5,[esi+8] - pand mm5,mm1 - movq mm7,mm1 - movq mm6,[ebx+8] - pandn mm7,mm6 - por mm5,mm7 - movq [ebx+8],mm5 - - add esi,16 /*inc by 16 bytes processed */ - add ebx,16 - sub ecx,8 /*dec by 8 pixels processed */ - - ja mainloop16 - -mainloop16end: - mov ecx,diff - cmp ecx,0 - jz end16 - - mov edx,mask - sal edx,24 /*make low byte the high byte */ -secondloop16: - sal edx,1 /*move high bit to CF */ - jnc skip16 /*if CF = 0 */ - mov ax,[esi] - mov [ebx],ax -skip16: - add esi,2 - add ebx,2 - - dec ecx - jnz secondloop16 -end16: - emms - } - } - else /* mmx not supported - use modified C routine */ - { - register unsigned int incr1, initial_val, final_val; - png_size_t pixel_bytes; - png_uint_32 i; - register int disp = png_pass_inc[png_ptr->pass]; - int offset_table[7] = {0, 4, 0, 2, 0, 1, 0}; - - pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); - srcptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]* - pixel_bytes; - dstptr = row + offset_table[png_ptr->pass]*pixel_bytes; - initial_val = offset_table[png_ptr->pass]*pixel_bytes; - final_val = png_ptr->width*pixel_bytes; - incr1 = (disp)*pixel_bytes; - for (i = initial_val; i < final_val; i += incr1) - { - png_memcpy(dstptr, srcptr, pixel_bytes); - srcptr += incr1; - dstptr += incr1; - } - } /* end of else */ - - break; - } /* end 16 bpp */ - - case 24: - { - png_bytep srcptr; - png_bytep dstptr; - png_uint_32 len; - int unmask, diff; - - __int64 mask2=0x0101010202020404, /*24bpp */ - mask1=0x0408080810101020, - mask0=0x2020404040808080; - - srcptr = png_ptr->row_buf + 1; - dstptr = row; - - unmask = ~mask; - len = (png_ptr->width)&~7; - diff = (png_ptr->width)&7; - -#if !defined(PNG_1_0_X) - if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) - /* && mmx_supported */ ) -#else - if (mmx_supported) -#endif - { - _asm - { - movd mm7, unmask /*load bit pattern */ - psubb mm6,mm6 /*zero mm6 */ - punpcklbw mm7,mm7 - punpcklwd mm7,mm7 - punpckldq mm7,mm7 /*fill register with 8 masks */ - - movq mm0,mask0 - movq mm1,mask1 - movq mm2,mask2 - - pand mm0,mm7 - pand mm1,mm7 - pand mm2,mm7 - - pcmpeqb mm0,mm6 - pcmpeqb mm1,mm6 - pcmpeqb mm2,mm6 - - mov ecx,len /*load length of line */ - mov esi,srcptr /*load source */ - mov ebx,dstptr /*load dest */ - cmp ecx,0 - jz mainloop24end - -mainloop24: - movq mm4,[esi] - pand mm4,mm0 - movq mm6,mm0 - movq mm7,[ebx] - pandn mm6,mm7 - por mm4,mm6 - movq [ebx],mm4 - - - movq mm5,[esi+8] - pand mm5,mm1 - movq mm7,mm1 - movq mm6,[ebx+8] - pandn mm7,mm6 - por mm5,mm7 - movq [ebx+8],mm5 - - movq mm6,[esi+16] - pand mm6,mm2 - movq mm4,mm2 - movq mm7,[ebx+16] - pandn mm4,mm7 - por mm6,mm4 - movq [ebx+16],mm6 - - add esi,24 /*inc by 24 bytes processed */ - add ebx,24 - sub ecx,8 /*dec by 8 pixels processed */ - - ja mainloop24 - -mainloop24end: - mov ecx,diff - cmp ecx,0 - jz end24 - - mov edx,mask - sal edx,24 /*make low byte the high byte */ -secondloop24: - sal edx,1 /*move high bit to CF */ - jnc skip24 /*if CF = 0 */ - mov ax,[esi] - mov [ebx],ax - xor eax,eax - mov al,[esi+2] - mov [ebx+2],al -skip24: - add esi,3 - add ebx,3 - - dec ecx - jnz secondloop24 - -end24: - emms - } - } - else /* mmx not supported - use modified C routine */ - { - register unsigned int incr1, initial_val, final_val; - png_size_t pixel_bytes; - png_uint_32 i; - register int disp = png_pass_inc[png_ptr->pass]; - int offset_table[7] = {0, 4, 0, 2, 0, 1, 0}; - - pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); - srcptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]* - pixel_bytes; - dstptr = row + offset_table[png_ptr->pass]*pixel_bytes; - initial_val = offset_table[png_ptr->pass]*pixel_bytes; - final_val = png_ptr->width*pixel_bytes; - incr1 = (disp)*pixel_bytes; - for (i = initial_val; i < final_val; i += incr1) - { - png_memcpy(dstptr, srcptr, pixel_bytes); - srcptr += incr1; - dstptr += incr1; - } - } /* end of else */ - - break; - } /* end 24 bpp */ - - case 32: - { - png_bytep srcptr; - png_bytep dstptr; - png_uint_32 len; - int unmask, diff; - - __int64 mask3=0x0101010102020202, /*32bpp */ - mask2=0x0404040408080808, - mask1=0x1010101020202020, - mask0=0x4040404080808080; - - srcptr = png_ptr->row_buf + 1; - dstptr = row; - - unmask = ~mask; - len = (png_ptr->width)&~7; - diff = (png_ptr->width)&7; - -#if !defined(PNG_1_0_X) - if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) - /* && mmx_supported */ ) -#else - if (mmx_supported) -#endif - { - _asm - { - movd mm7, unmask /*load bit pattern */ - psubb mm6,mm6 /*zero mm6 */ - punpcklbw mm7,mm7 - punpcklwd mm7,mm7 - punpckldq mm7,mm7 /*fill register with 8 masks */ - - movq mm0,mask0 - movq mm1,mask1 - movq mm2,mask2 - movq mm3,mask3 - - pand mm0,mm7 - pand mm1,mm7 - pand mm2,mm7 - pand mm3,mm7 - - pcmpeqb mm0,mm6 - pcmpeqb mm1,mm6 - pcmpeqb mm2,mm6 - pcmpeqb mm3,mm6 - - mov ecx,len /*load length of line */ - mov esi,srcptr /*load source */ - mov ebx,dstptr /*load dest */ - - cmp ecx,0 /*lcr */ - jz mainloop32end - -mainloop32: - movq mm4,[esi] - pand mm4,mm0 - movq mm6,mm0 - movq mm7,[ebx] - pandn mm6,mm7 - por mm4,mm6 - movq [ebx],mm4 - - movq mm5,[esi+8] - pand mm5,mm1 - movq mm7,mm1 - movq mm6,[ebx+8] - pandn mm7,mm6 - por mm5,mm7 - movq [ebx+8],mm5 - - movq mm6,[esi+16] - pand mm6,mm2 - movq mm4,mm2 - movq mm7,[ebx+16] - pandn mm4,mm7 - por mm6,mm4 - movq [ebx+16],mm6 - - movq mm7,[esi+24] - pand mm7,mm3 - movq mm5,mm3 - movq mm4,[ebx+24] - pandn mm5,mm4 - por mm7,mm5 - movq [ebx+24],mm7 - - add esi,32 /*inc by 32 bytes processed */ - add ebx,32 - sub ecx,8 /*dec by 8 pixels processed */ - - ja mainloop32 - -mainloop32end: - mov ecx,diff - cmp ecx,0 - jz end32 - - mov edx,mask - sal edx,24 /*make low byte the high byte */ -secondloop32: - sal edx,1 /*move high bit to CF */ - jnc skip32 /*if CF = 0 */ - mov eax,[esi] - mov [ebx],eax -skip32: - add esi,4 - add ebx,4 - - dec ecx - jnz secondloop32 - -end32: - emms - } - } - else /* mmx _not supported - Use modified C routine */ - { - register unsigned int incr1, initial_val, final_val; - png_size_t pixel_bytes; - png_uint_32 i; - register int disp = png_pass_inc[png_ptr->pass]; - int offset_table[7] = {0, 4, 0, 2, 0, 1, 0}; - - pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); - srcptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]* - pixel_bytes; - dstptr = row + offset_table[png_ptr->pass]*pixel_bytes; - initial_val = offset_table[png_ptr->pass]*pixel_bytes; - final_val = png_ptr->width*pixel_bytes; - incr1 = (disp)*pixel_bytes; - for (i = initial_val; i < final_val; i += incr1) - { - png_memcpy(dstptr, srcptr, pixel_bytes); - srcptr += incr1; - dstptr += incr1; - } - } /* end of else */ - - break; - } /* end 32 bpp */ - - case 48: - { - png_bytep srcptr; - png_bytep dstptr; - png_uint_32 len; - int unmask, diff; - - __int64 mask5=0x0101010101010202, - mask4=0x0202020204040404, - mask3=0x0404080808080808, - mask2=0x1010101010102020, - mask1=0x2020202040404040, - mask0=0x4040808080808080; - -#if !defined(PNG_1_0_X) - if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) - /* && mmx_supported */ ) -#else - if (mmx_supported) -#endif - { - srcptr = png_ptr->row_buf + 1; - dstptr = row; - - unmask = ~mask; - len = (png_ptr->width)&~7; - diff = (png_ptr->width)&7; - _asm - { - movd mm7, unmask /*load bit pattern */ - psubb mm6,mm6 /*zero mm6 */ - punpcklbw mm7,mm7 - punpcklwd mm7,mm7 - punpckldq mm7,mm7 /*fill register with 8 masks */ - - movq mm0,mask0 - movq mm1,mask1 - movq mm2,mask2 - movq mm3,mask3 - movq mm4,mask4 - movq mm5,mask5 - - pand mm0,mm7 - pand mm1,mm7 - pand mm2,mm7 - pand mm3,mm7 - pand mm4,mm7 - pand mm5,mm7 - - pcmpeqb mm0,mm6 - pcmpeqb mm1,mm6 - pcmpeqb mm2,mm6 - pcmpeqb mm3,mm6 - pcmpeqb mm4,mm6 - pcmpeqb mm5,mm6 - - mov ecx,len /*load length of line */ - mov esi,srcptr /*load source */ - mov ebx,dstptr /*load dest */ - - cmp ecx,0 - jz mainloop48end - -mainloop48: - movq mm7,[esi] - pand mm7,mm0 - movq mm6,mm0 - pandn mm6,[ebx] - por mm7,mm6 - movq [ebx],mm7 - - movq mm6,[esi+8] - pand mm6,mm1 - movq mm7,mm1 - pandn mm7,[ebx+8] - por mm6,mm7 - movq [ebx+8],mm6 - - movq mm6,[esi+16] - pand mm6,mm2 - movq mm7,mm2 - pandn mm7,[ebx+16] - por mm6,mm7 - movq [ebx+16],mm6 - - movq mm7,[esi+24] - pand mm7,mm3 - movq mm6,mm3 - pandn mm6,[ebx+24] - por mm7,mm6 - movq [ebx+24],mm7 - - movq mm6,[esi+32] - pand mm6,mm4 - movq mm7,mm4 - pandn mm7,[ebx+32] - por mm6,mm7 - movq [ebx+32],mm6 - - movq mm7,[esi+40] - pand mm7,mm5 - movq mm6,mm5 - pandn mm6,[ebx+40] - por mm7,mm6 - movq [ebx+40],mm7 - - add esi,48 /*inc by 32 bytes processed */ - add ebx,48 - sub ecx,8 /*dec by 8 pixels processed */ - - ja mainloop48 -mainloop48end: - - mov ecx,diff - cmp ecx,0 - jz end48 - - mov edx,mask - sal edx,24 /*make low byte the high byte */ - -secondloop48: - sal edx,1 /*move high bit to CF */ - jnc skip48 /*if CF = 0 */ - mov eax,[esi] - mov [ebx],eax -skip48: - add esi,4 - add ebx,4 - - dec ecx - jnz secondloop48 - -end48: - emms - } - } - else /* mmx _not supported - Use modified C routine */ - { - register unsigned int incr1, initial_val, final_val; - png_size_t pixel_bytes; - png_uint_32 i; - register int disp = png_pass_inc[png_ptr->pass]; - int offset_table[7] = {0, 4, 0, 2, 0, 1, 0}; - - pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); - srcptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]* - pixel_bytes; - dstptr = row + offset_table[png_ptr->pass]*pixel_bytes; - initial_val = offset_table[png_ptr->pass]*pixel_bytes; - final_val = png_ptr->width*pixel_bytes; - incr1 = (disp)*pixel_bytes; - for (i = initial_val; i < final_val; i += incr1) - { - png_memcpy(dstptr, srcptr, pixel_bytes); - srcptr += incr1; - dstptr += incr1; - } - } /* end of else */ - - break; - } /* end 48 bpp */ - - default: - { - png_bytep sptr; - png_bytep dp; - png_size_t pixel_bytes; - int offset_table[7] = {0, 4, 0, 2, 0, 1, 0}; - unsigned int i; - register int disp = png_pass_inc[png_ptr->pass]; /* get the offset */ - register unsigned int incr1, initial_val, final_val; - - pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); - sptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]* - pixel_bytes; - dp = row + offset_table[png_ptr->pass]*pixel_bytes; - initial_val = offset_table[png_ptr->pass]*pixel_bytes; - final_val = png_ptr->width*pixel_bytes; - incr1 = (disp)*pixel_bytes; - for (i = initial_val; i < final_val; i += incr1) - { - png_memcpy(dp, sptr, pixel_bytes); - sptr += incr1; - dp += incr1; - } - break; - } - } /* end switch (png_ptr->row_info.pixel_depth) */ - } /* end if (non-trivial mask) */ - -} /* end png_combine_row() */ - - -#if defined(PNG_READ_INTERLACING_SUPPORTED) - -void /* PRIVATE */ -png_do_read_interlace(png_structp png_ptr) -{ - png_row_infop row_info = &(png_ptr->row_info); - png_bytep row = png_ptr->row_buf + 1; - int pass = png_ptr->pass; - png_uint_32 transformations = png_ptr->transformations; -#ifdef PNG_USE_LOCAL_ARRAYS - const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; -#endif - - png_debug(1,"in png_do_read_interlace\n"); - - if (mmx_supported == 2) { -#if !defined(PNG_1_0_X) - /* this should have happened in png_init_mmx_flags() already */ - png_warning(png_ptr, "asm_flags may not have been initialized"); -#endif - png_mmx_support(); - } - - if (row != NULL && row_info != NULL) - { - png_uint_32 final_width; - - final_width = row_info->width * png_pass_inc[pass]; - - switch (row_info->pixel_depth) - { - case 1: - { - png_bytep sp, dp; - int sshift, dshift; - int s_start, s_end, s_inc; - png_byte v; - png_uint_32 i; - int j; - - sp = row + (png_size_t)((row_info->width - 1) >> 3); - dp = row + (png_size_t)((final_width - 1) >> 3); -#if defined(PNG_READ_PACKSWAP_SUPPORTED) - if (transformations & PNG_PACKSWAP) - { - sshift = (int)((row_info->width + 7) & 7); - dshift = (int)((final_width + 7) & 7); - s_start = 7; - s_end = 0; - s_inc = -1; - } - else -#endif - { - sshift = 7 - (int)((row_info->width + 7) & 7); - dshift = 7 - (int)((final_width + 7) & 7); - s_start = 0; - s_end = 7; - s_inc = 1; - } - - for (i = row_info->width; i; i--) - { - v = (png_byte)((*sp >> sshift) & 0x1); - for (j = 0; j < png_pass_inc[pass]; j++) - { - *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, dp; - int sshift, dshift; - int s_start, s_end, s_inc; - png_uint_32 i; - - sp = row + (png_size_t)((row_info->width - 1) >> 2); - dp = row + (png_size_t)((final_width - 1) >> 2); -#if defined(PNG_READ_PACKSWAP_SUPPORTED) - if (transformations & PNG_PACKSWAP) - { - sshift = (png_size_t)(((row_info->width + 3) & 3) << 1); - dshift = (png_size_t)(((final_width + 3) & 3) << 1); - s_start = 6; - s_end = 0; - s_inc = -2; - } - else -#endif - { - sshift = (png_size_t)((3 - ((row_info->width + 3) & 3)) << 1); - dshift = (png_size_t)((3 - ((final_width + 3) & 3)) << 1); - s_start = 0; - s_end = 6; - s_inc = 2; - } - - for (i = row_info->width; i; i--) - { - png_byte v; - int j; - - v = (png_byte)((*sp >> sshift) & 0x3); - for (j = 0; j < png_pass_inc[pass]; j++) - { - *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, dp; - int sshift, dshift; - int s_start, s_end, s_inc; - png_uint_32 i; - - sp = row + (png_size_t)((row_info->width - 1) >> 1); - dp = row + (png_size_t)((final_width - 1) >> 1); -#if defined(PNG_READ_PACKSWAP_SUPPORTED) - if (transformations & PNG_PACKSWAP) - { - sshift = (png_size_t)(((row_info->width + 1) & 1) << 2); - dshift = (png_size_t)(((final_width + 1) & 1) << 2); - s_start = 4; - s_end = 0; - s_inc = -4; - } - else -#endif - { - sshift = (png_size_t)((1 - ((row_info->width + 1) & 1)) << 2); - dshift = (png_size_t)((1 - ((final_width + 1) & 1)) << 2); - s_start = 0; - s_end = 4; - s_inc = 4; - } - - for (i = row_info->width; i; i--) - { - png_byte v; - int j; - - v = (png_byte)((*sp >> sshift) & 0xf); - for (j = 0; j < png_pass_inc[pass]; j++) - { - *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; - } - break; - } - - default: /* This is the place where the routine is modified */ - { - __int64 const4 = 0x0000000000FFFFFF; - /* __int64 const5 = 0x000000FFFFFF0000; // unused... */ - __int64 const6 = 0x00000000000000FF; - png_bytep sptr, dp; - png_uint_32 i; - png_size_t pixel_bytes; - int width = row_info->width; - - pixel_bytes = (row_info->pixel_depth >> 3); - - sptr = row + (width - 1) * pixel_bytes; - dp = row + (final_width - 1) * pixel_bytes; - /* New code by Nirav Chhatrapati - Intel Corporation */ - /* sign fix by GRR */ - /* NOTE: there is NO MMX code for 48-bit and 64-bit images */ - - // use MMX routine if machine supports it -#if !defined(PNG_1_0_X) - if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_INTERLACE) - /* && mmx_supported */ ) -#else - if (mmx_supported) -#endif - { - if (pixel_bytes == 3) - { - if (((pass == 0) || (pass == 1)) && width) - { - _asm - { - mov esi, sptr - mov edi, dp - mov ecx, width - sub edi, 21 /* (png_pass_inc[pass] - 1)*pixel_bytes */ -loop_pass0: - movd mm0, [esi] ; X X X X X v2 v1 v0 - pand mm0, const4 ; 0 0 0 0 0 v2 v1 v0 - movq mm1, mm0 ; 0 0 0 0 0 v2 v1 v0 - psllq mm0, 16 ; 0 0 0 v2 v1 v0 0 0 - movq mm2, mm0 ; 0 0 0 v2 v1 v0 0 0 - psllq mm0, 24 ; v2 v1 v0 0 0 0 0 0 - psrlq mm1, 8 ; 0 0 0 0 0 0 v2 v1 - por mm0, mm2 ; v2 v1 v0 v2 v1 v0 0 0 - por mm0, mm1 ; v2 v1 v0 v2 v1 v0 v2 v1 - movq mm3, mm0 ; v2 v1 v0 v2 v1 v0 v2 v1 - psllq mm0, 16 ; v0 v2 v1 v0 v2 v1 0 0 - movq mm4, mm3 ; v2 v1 v0 v2 v1 v0 v2 v1 - punpckhdq mm3, mm0 ; v0 v2 v1 v0 v2 v1 v0 v2 - movq [edi+16] , mm4 - psrlq mm0, 32 ; 0 0 0 0 v0 v2 v1 v0 - movq [edi+8] , mm3 - punpckldq mm0, mm4 ; v1 v0 v2 v1 v0 v2 v1 v0 - sub esi, 3 - movq [edi], mm0 - sub edi, 24 - /*sub esi, 3 */ - dec ecx - jnz loop_pass0 - EMMS - } - } - else if (((pass == 2) || (pass == 3)) && width) - { - _asm - { - mov esi, sptr - mov edi, dp - mov ecx, width - sub edi, 9 /* (png_pass_inc[pass] - 1)*pixel_bytes */ -loop_pass2: - movd mm0, [esi] ; X X X X X v2 v1 v0 - pand mm0, const4 ; 0 0 0 0 0 v2 v1 v0 - movq mm1, mm0 ; 0 0 0 0 0 v2 v1 v0 - psllq mm0, 16 ; 0 0 0 v2 v1 v0 0 0 - movq mm2, mm0 ; 0 0 0 v2 v1 v0 0 0 - psllq mm0, 24 ; v2 v1 v0 0 0 0 0 0 - psrlq mm1, 8 ; 0 0 0 0 0 0 v2 v1 - por mm0, mm2 ; v2 v1 v0 v2 v1 v0 0 0 - por mm0, mm1 ; v2 v1 v0 v2 v1 v0 v2 v1 - movq [edi+4], mm0 ; move to memory - psrlq mm0, 16 ; 0 0 v2 v1 v0 v2 v1 v0 - movd [edi], mm0 ; move to memory - sub esi, 3 - sub edi, 12 - dec ecx - jnz loop_pass2 - EMMS - } - } - else if (width) /* && ((pass == 4) || (pass == 5)) */ - { - int width_mmx = ((width >> 1) << 1) - 8; - if (width_mmx < 0) - width_mmx = 0; - width -= width_mmx; /* 8 or 9 pix, 24 or 27 bytes */ - if (width_mmx) - { - _asm - { - mov esi, sptr - mov edi, dp - mov ecx, width_mmx - sub esi, 3 - sub edi, 9 -loop_pass4: - movq mm0, [esi] ; X X v2 v1 v0 v5 v4 v3 - movq mm7, mm0 ; X X v2 v1 v0 v5 v4 v3 - movq mm6, mm0 ; X X v2 v1 v0 v5 v4 v3 - psllq mm0, 24 ; v1 v0 v5 v4 v3 0 0 0 - pand mm7, const4 ; 0 0 0 0 0 v5 v4 v3 - psrlq mm6, 24 ; 0 0 0 X X v2 v1 v0 - por mm0, mm7 ; v1 v0 v5 v4 v3 v5 v4 v3 - movq mm5, mm6 ; 0 0 0 X X v2 v1 v0 - psllq mm6, 8 ; 0 0 X X v2 v1 v0 0 - movq [edi], mm0 ; move quad to memory - psrlq mm5, 16 ; 0 0 0 0 0 X X v2 - pand mm5, const6 ; 0 0 0 0 0 0 0 v2 - por mm6, mm5 ; 0 0 X X v2 v1 v0 v2 - movd [edi+8], mm6 ; move double to memory - sub esi, 6 - sub edi, 12 - sub ecx, 2 - jnz loop_pass4 - EMMS - } - } - - sptr -= width_mmx*3; - dp -= width_mmx*6; - for (i = width; i; i--) - { - png_byte v[8]; - int j; - - png_memcpy(v, sptr, 3); - for (j = 0; j < png_pass_inc[pass]; j++) - { - png_memcpy(dp, v, 3); - dp -= 3; - } - sptr -= 3; - } - } - } /* end of pixel_bytes == 3 */ - - else if (pixel_bytes == 1) - { - if (((pass == 0) || (pass == 1)) && width) - { - int width_mmx = ((width >> 2) << 2); - width -= width_mmx; - if (width_mmx) - { - _asm - { - mov esi, sptr - mov edi, dp - mov ecx, width_mmx - sub edi, 31 - sub esi, 3 -loop1_pass0: - movd mm0, [esi] ; X X X X v0 v1 v2 v3 - movq mm1, mm0 ; X X X X v0 v1 v2 v3 - punpcklbw mm0, mm0 ; v0 v0 v1 v1 v2 v2 v3 v3 - movq mm2, mm0 ; v0 v0 v1 v1 v2 v2 v3 v3 - punpcklwd mm0, mm0 ; v2 v2 v2 v2 v3 v3 v3 v3 - movq mm3, mm0 ; v2 v2 v2 v2 v3 v3 v3 v3 - punpckldq mm0, mm0 ; v3 v3 v3 v3 v3 v3 v3 v3 - punpckhdq mm3, mm3 ; v2 v2 v2 v2 v2 v2 v2 v2 - movq [edi], mm0 ; move to memory v3 - punpckhwd mm2, mm2 ; v0 v0 v0 v0 v1 v1 v1 v1 - movq [edi+8], mm3 ; move to memory v2 - movq mm4, mm2 ; v0 v0 v0 v0 v1 v1 v1 v1 - punpckldq mm2, mm2 ; v1 v1 v1 v1 v1 v1 v1 v1 - punpckhdq mm4, mm4 ; v0 v0 v0 v0 v0 v0 v0 v0 - movq [edi+16], mm2 ; move to memory v1 - movq [edi+24], mm4 ; move to memory v0 - sub esi, 4 - sub edi, 32 - sub ecx, 4 - jnz loop1_pass0 - EMMS - } - } - - sptr -= width_mmx; - dp -= width_mmx*8; - for (i = width; i; i--) - { - int j; - - /* I simplified this part in version 1.0.4e - * here and in several other instances where - * pixel_bytes == 1 -- GR-P - * - * Original code: - * - * png_byte v[8]; - * png_memcpy(v, sptr, pixel_bytes); - * for (j = 0; j < png_pass_inc[pass]; j++) - * { - * png_memcpy(dp, v, pixel_bytes); - * dp -= pixel_bytes; - * } - * sptr -= pixel_bytes; - * - * Replacement code is in the next three lines: - */ - - for (j = 0; j < png_pass_inc[pass]; j++) - *dp-- = *sptr; - sptr--; - } - } - else if (((pass == 2) || (pass == 3)) && width) - { - int width_mmx = ((width >> 2) << 2); - width -= width_mmx; - if (width_mmx) - { - _asm - { - mov esi, sptr - mov edi, dp - mov ecx, width_mmx - sub edi, 15 - sub esi, 3 -loop1_pass2: - movd mm0, [esi] ; X X X X v0 v1 v2 v3 - punpcklbw mm0, mm0 ; v0 v0 v1 v1 v2 v2 v3 v3 - movq mm1, mm0 ; v0 v0 v1 v1 v2 v2 v3 v3 - punpcklwd mm0, mm0 ; v2 v2 v2 v2 v3 v3 v3 v3 - punpckhwd mm1, mm1 ; v0 v0 v0 v0 v1 v1 v1 v1 - movq [edi], mm0 ; move to memory v2 and v3 - sub esi, 4 - movq [edi+8], mm1 ; move to memory v1 and v0 - sub edi, 16 - sub ecx, 4 - jnz loop1_pass2 - EMMS - } - } - - sptr -= width_mmx; - dp -= width_mmx*4; - for (i = width; i; i--) - { - int j; - - for (j = 0; j < png_pass_inc[pass]; j++) - { - *dp-- = *sptr; - } - sptr --; - } - } - else if (width) /* && ((pass == 4) || (pass == 5))) */ - { - int width_mmx = ((width >> 3) << 3); - width -= width_mmx; - if (width_mmx) - { - _asm - { - mov esi, sptr - mov edi, dp - mov ecx, width_mmx - sub edi, 15 - sub esi, 7 -loop1_pass4: - movq mm0, [esi] ; v0 v1 v2 v3 v4 v5 v6 v7 - movq mm1, mm0 ; v0 v1 v2 v3 v4 v5 v6 v7 - punpcklbw mm0, mm0 ; v4 v4 v5 v5 v6 v6 v7 v7 - /*movq mm1, mm0 ; v0 v0 v1 v1 v2 v2 v3 v3 */ - punpckhbw mm1, mm1 ;v0 v0 v1 v1 v2 v2 v3 v3 - movq [edi+8], mm1 ; move to memory v0 v1 v2 and v3 - sub esi, 8 - movq [edi], mm0 ; move to memory v4 v5 v6 and v7 - /*sub esi, 4 */ - sub edi, 16 - sub ecx, 8 - jnz loop1_pass4 - EMMS - } - } - - sptr -= width_mmx; - dp -= width_mmx*2; - for (i = width; i; i--) - { - int j; - - for (j = 0; j < png_pass_inc[pass]; j++) - { - *dp-- = *sptr; - } - sptr --; - } - } - } /* end of pixel_bytes == 1 */ - - else if (pixel_bytes == 2) - { - if (((pass == 0) || (pass == 1)) && width) - { - int width_mmx = ((width >> 1) << 1); - width -= width_mmx; - if (width_mmx) - { - _asm - { - mov esi, sptr - mov edi, dp - mov ecx, width_mmx - sub esi, 2 - sub edi, 30 -loop2_pass0: - movd mm0, [esi] ; X X X X v1 v0 v3 v2 - punpcklwd mm0, mm0 ; v1 v0 v1 v0 v3 v2 v3 v2 - movq mm1, mm0 ; v1 v0 v1 v0 v3 v2 v3 v2 - punpckldq mm0, mm0 ; v3 v2 v3 v2 v3 v2 v3 v2 - punpckhdq mm1, mm1 ; v1 v0 v1 v0 v1 v0 v1 v0 - movq [edi], mm0 - movq [edi + 8], mm0 - movq [edi + 16], mm1 - movq [edi + 24], mm1 - sub esi, 4 - sub edi, 32 - sub ecx, 2 - jnz loop2_pass0 - EMMS - } - } - - sptr -= (width_mmx*2 - 2); /* sign fixed */ - dp -= (width_mmx*16 - 2); /* sign fixed */ - for (i = width; i; i--) - { - png_byte v[8]; - int j; - sptr -= 2; - png_memcpy(v, sptr, 2); - for (j = 0; j < png_pass_inc[pass]; j++) - { - dp -= 2; - png_memcpy(dp, v, 2); - } - } - } - else if (((pass == 2) || (pass == 3)) && width) - { - int width_mmx = ((width >> 1) << 1) ; - width -= width_mmx; - if (width_mmx) - { - _asm - { - mov esi, sptr - mov edi, dp - mov ecx, width_mmx - sub esi, 2 - sub edi, 14 -loop2_pass2: - movd mm0, [esi] ; X X X X v1 v0 v3 v2 - punpcklwd mm0, mm0 ; v1 v0 v1 v0 v3 v2 v3 v2 - movq mm1, mm0 ; v1 v0 v1 v0 v3 v2 v3 v2 - punpckldq mm0, mm0 ; v3 v2 v3 v2 v3 v2 v3 v2 - punpckhdq mm1, mm1 ; v1 v0 v1 v0 v1 v0 v1 v0 - movq [edi], mm0 - sub esi, 4 - movq [edi + 8], mm1 - /*sub esi, 4 */ - sub edi, 16 - sub ecx, 2 - jnz loop2_pass2 - EMMS - } - } - - sptr -= (width_mmx*2 - 2); /* sign fixed */ - dp -= (width_mmx*8 - 2); /* sign fixed */ - for (i = width; i; i--) - { - png_byte v[8]; - int j; - sptr -= 2; - png_memcpy(v, sptr, 2); - for (j = 0; j < png_pass_inc[pass]; j++) - { - dp -= 2; - png_memcpy(dp, v, 2); - } - } - } - else if (width) /* pass == 4 or 5 */ - { - int width_mmx = ((width >> 1) << 1) ; - width -= width_mmx; - if (width_mmx) - { - _asm - { - mov esi, sptr - mov edi, dp - mov ecx, width_mmx - sub esi, 2 - sub edi, 6 -loop2_pass4: - movd mm0, [esi] ; X X X X v1 v0 v3 v2 - punpcklwd mm0, mm0 ; v1 v0 v1 v0 v3 v2 v3 v2 - sub esi, 4 - movq [edi], mm0 - sub edi, 8 - sub ecx, 2 - jnz loop2_pass4 - EMMS - } - } - - sptr -= (width_mmx*2 - 2); /* sign fixed */ - dp -= (width_mmx*4 - 2); /* sign fixed */ - for (i = width; i; i--) - { - png_byte v[8]; - int j; - sptr -= 2; - png_memcpy(v, sptr, 2); - for (j = 0; j < png_pass_inc[pass]; j++) - { - dp -= 2; - png_memcpy(dp, v, 2); - } - } - } - } /* end of pixel_bytes == 2 */ - - else if (pixel_bytes == 4) - { - if (((pass == 0) || (pass == 1)) && width) - { - int width_mmx = ((width >> 1) << 1) ; - width -= width_mmx; - if (width_mmx) - { - _asm - { - mov esi, sptr - mov edi, dp - mov ecx, width_mmx - sub esi, 4 - sub edi, 60 -loop4_pass0: - movq mm0, [esi] ; v3 v2 v1 v0 v7 v6 v5 v4 - movq mm1, mm0 ; v3 v2 v1 v0 v7 v6 v5 v4 - punpckldq mm0, mm0 ; v7 v6 v5 v4 v7 v6 v5 v4 - punpckhdq mm1, mm1 ; v3 v2 v1 v0 v3 v2 v1 v0 - movq [edi], mm0 - movq [edi + 8], mm0 - movq [edi + 16], mm0 - movq [edi + 24], mm0 - movq [edi+32], mm1 - movq [edi + 40], mm1 - movq [edi+ 48], mm1 - sub esi, 8 - movq [edi + 56], mm1 - sub edi, 64 - sub ecx, 2 - jnz loop4_pass0 - EMMS - } - } - - sptr -= (width_mmx*4 - 4); /* sign fixed */ - dp -= (width_mmx*32 - 4); /* sign fixed */ - for (i = width; i; i--) - { - png_byte v[8]; - int j; - sptr -= 4; - png_memcpy(v, sptr, 4); - for (j = 0; j < png_pass_inc[pass]; j++) - { - dp -= 4; - png_memcpy(dp, v, 4); - } - } - } - else if (((pass == 2) || (pass == 3)) && width) - { - int width_mmx = ((width >> 1) << 1) ; - width -= width_mmx; - if (width_mmx) - { - _asm - { - mov esi, sptr - mov edi, dp - mov ecx, width_mmx - sub esi, 4 - sub edi, 28 -loop4_pass2: - movq mm0, [esi] ; v3 v2 v1 v0 v7 v6 v5 v4 - movq mm1, mm0 ; v3 v2 v1 v0 v7 v6 v5 v4 - punpckldq mm0, mm0 ; v7 v6 v5 v4 v7 v6 v5 v4 - punpckhdq mm1, mm1 ; v3 v2 v1 v0 v3 v2 v1 v0 - movq [edi], mm0 - movq [edi + 8], mm0 - movq [edi+16], mm1 - movq [edi + 24], mm1 - sub esi, 8 - sub edi, 32 - sub ecx, 2 - jnz loop4_pass2 - EMMS - } - } - - sptr -= (width_mmx*4 - 4); /* sign fixed */ - dp -= (width_mmx*16 - 4); /* sign fixed */ - for (i = width; i; i--) - { - png_byte v[8]; - int j; - sptr -= 4; - png_memcpy(v, sptr, 4); - for (j = 0; j < png_pass_inc[pass]; j++) - { - dp -= 4; - png_memcpy(dp, v, 4); - } - } - } - else if (width) /* pass == 4 or 5 */ - { - int width_mmx = ((width >> 1) << 1) ; - width -= width_mmx; - if (width_mmx) - { - _asm - { - mov esi, sptr - mov edi, dp - mov ecx, width_mmx - sub esi, 4 - sub edi, 12 -loop4_pass4: - movq mm0, [esi] ; v3 v2 v1 v0 v7 v6 v5 v4 - movq mm1, mm0 ; v3 v2 v1 v0 v7 v6 v5 v4 - punpckldq mm0, mm0 ; v7 v6 v5 v4 v7 v6 v5 v4 - punpckhdq mm1, mm1 ; v3 v2 v1 v0 v3 v2 v1 v0 - movq [edi], mm0 - sub esi, 8 - movq [edi + 8], mm1 - sub edi, 16 - sub ecx, 2 - jnz loop4_pass4 - EMMS - } - } - - sptr -= (width_mmx*4 - 4); /* sign fixed */ - dp -= (width_mmx*8 - 4); /* sign fixed */ - for (i = width; i; i--) - { - png_byte v[8]; - int j; - sptr -= 4; - png_memcpy(v, sptr, 4); - for (j = 0; j < png_pass_inc[pass]; j++) - { - dp -= 4; - png_memcpy(dp, v, 4); - } - } - } - - } /* end of pixel_bytes == 4 */ - - else if (pixel_bytes == 6) - { - for (i = width; i; i--) - { - png_byte v[8]; - int j; - png_memcpy(v, sptr, 6); - for (j = 0; j < png_pass_inc[pass]; j++) - { - png_memcpy(dp, v, 6); - dp -= 6; - } - sptr -= 6; - } - } /* end of pixel_bytes == 6 */ - - else - { - for (i = width; i; i--) - { - png_byte v[8]; - int j; - png_memcpy(v, sptr, pixel_bytes); - for (j = 0; j < png_pass_inc[pass]; j++) - { - png_memcpy(dp, v, pixel_bytes); - dp -= pixel_bytes; - } - sptr-= pixel_bytes; - } - } - } /* end of mmx_supported */ - - else /* MMX not supported: use modified C code - takes advantage - * of inlining of memcpy for a constant */ - { - if (pixel_bytes == 1) - { - for (i = width; i; i--) - { - int j; - for (j = 0; j < png_pass_inc[pass]; j++) - *dp-- = *sptr; - sptr--; - } - } - else if (pixel_bytes == 3) - { - for (i = width; i; i--) - { - png_byte v[8]; - int j; - png_memcpy(v, sptr, pixel_bytes); - for (j = 0; j < png_pass_inc[pass]; j++) - { - png_memcpy(dp, v, pixel_bytes); - dp -= pixel_bytes; - } - sptr -= pixel_bytes; - } - } - else if (pixel_bytes == 2) - { - for (i = width; i; i--) - { - png_byte v[8]; - int j; - png_memcpy(v, sptr, pixel_bytes); - for (j = 0; j < png_pass_inc[pass]; j++) - { - png_memcpy(dp, v, pixel_bytes); - dp -= pixel_bytes; - } - sptr -= pixel_bytes; - } - } - else if (pixel_bytes == 4) - { - for (i = width; i; i--) - { - png_byte v[8]; - int j; - png_memcpy(v, sptr, pixel_bytes); - for (j = 0; j < png_pass_inc[pass]; j++) - { - png_memcpy(dp, v, pixel_bytes); - dp -= pixel_bytes; - } - sptr -= pixel_bytes; - } - } - else if (pixel_bytes == 6) - { - for (i = width; i; i--) - { - png_byte v[8]; - int j; - png_memcpy(v, sptr, pixel_bytes); - for (j = 0; j < png_pass_inc[pass]; j++) - { - png_memcpy(dp, v, pixel_bytes); - dp -= pixel_bytes; - } - sptr -= pixel_bytes; - } - } - else - { - for (i = width; i; i--) - { - png_byte v[8]; - int j; - png_memcpy(v, sptr, pixel_bytes); - for (j = 0; j < png_pass_inc[pass]; j++) - { - png_memcpy(dp, v, pixel_bytes); - dp -= pixel_bytes; - } - sptr -= pixel_bytes; - } - } - - } /* end of MMX not supported */ - break; - } - } /* end switch (row_info->pixel_depth) */ - - row_info->width = final_width; - - row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,final_width); - } - -} - -#endif /* PNG_READ_INTERLACING_SUPPORTED */ - - -/* These variables are utilized in the functions below. They are declared */ -/* globally here to ensure alignment on 8-byte boundaries. */ - -union uAll { - __int64 use; - double align; -} LBCarryMask = {0x0101010101010101}, - HBClearMask = {0x7f7f7f7f7f7f7f7f}, - ActiveMask, ActiveMask2, ActiveMaskEnd, ShiftBpp, ShiftRem; - - -/* Optimized code for PNG Average filter decoder */ -void /* PRIVATE */ -png_read_filter_row_mmx_avg(png_row_infop row_info, png_bytep row - , png_bytep prev_row) -{ - int bpp; - png_uint_32 FullLength; - png_uint_32 MMXLength; - /*png_uint_32 len; */ - int diff; - - bpp = (row_info->pixel_depth + 7) >> 3; /* Get # bytes per pixel */ - FullLength = row_info->rowbytes; /* # of bytes to filter */ - _asm { - /* Init address pointers and offset */ - mov edi, row /* edi ==> Avg(x) */ - xor ebx, ebx /* ebx ==> x */ - mov edx, edi - mov esi, prev_row /* esi ==> Prior(x) */ - sub edx, bpp /* edx ==> Raw(x-bpp) */ - - xor eax, eax - /* Compute the Raw value for the first bpp bytes */ - /* Raw(x) = Avg(x) + (Prior(x)/2) */ -davgrlp: - mov al, [esi + ebx] /* Load al with Prior(x) */ - inc ebx - shr al, 1 /* divide by 2 */ - add al, [edi+ebx-1] /* Add Avg(x); -1 to offset inc ebx */ - cmp ebx, bpp - mov [edi+ebx-1], al /* Write back Raw(x); */ - /* mov does not affect flags; -1 to offset inc ebx */ - jb davgrlp - /* get # of bytes to alignment */ - mov diff, edi /* take start of row */ - add diff, ebx /* add bpp */ - add diff, 0xf /* add 7 + 8 to incr past alignment boundary */ - and diff, 0xfffffff8 /* mask to alignment boundary */ - sub diff, edi /* subtract from start ==> value ebx at alignment */ - jz davggo - /* fix alignment */ - /* Compute the Raw value for the bytes upto the alignment boundary */ - /* Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2) */ - xor ecx, ecx -davglp1: - xor eax, eax - mov cl, [esi + ebx] /* load cl with Prior(x) */ - mov al, [edx + ebx] /* load al with Raw(x-bpp) */ - add ax, cx - inc ebx - shr ax, 1 /* divide by 2 */ - add al, [edi+ebx-1] /* Add Avg(x); -1 to offset inc ebx */ - cmp ebx, diff /* Check if at alignment boundary */ - mov [edi+ebx-1], al /* Write back Raw(x); */ - /* mov does not affect flags; -1 to offset inc ebx */ - jb davglp1 /* Repeat until at alignment boundary */ -davggo: - mov eax, FullLength - mov ecx, eax - sub eax, ebx /* subtract alignment fix */ - and eax, 0x00000007 /* calc bytes over mult of 8 */ - sub ecx, eax /* drop over bytes from original length */ - mov MMXLength, ecx - } /* end _asm block */ - /* Now do the math for the rest of the row */ - switch ( bpp ) - { - case 3: - { - ActiveMask.use = 0x0000000000ffffff; - ShiftBpp.use = 24; /* == 3 * 8 */ - ShiftRem.use = 40; /* == 64 - 24 */ - _asm { - /* Re-init address pointers and offset */ - movq mm7, ActiveMask - mov ebx, diff /* ebx ==> x = offset to alignment boundary */ - movq mm5, LBCarryMask - mov edi, row /* edi ==> Avg(x) */ - movq mm4, HBClearMask - mov esi, prev_row /* esi ==> Prior(x) */ - /* PRIME the pump (load the first Raw(x-bpp) data set */ - movq mm2, [edi + ebx - 8] /* Load previous aligned 8 bytes */ - /* (we correct position in loop below) */ -davg3lp: - movq mm0, [edi + ebx] /* Load mm0 with Avg(x) */ - /* Add (Prev_row/2) to Average */ - movq mm3, mm5 - psrlq mm2, ShiftRem /* Correct position Raw(x-bpp) data */ - movq mm1, [esi + ebx] /* Load mm1 with Prior(x) */ - movq mm6, mm7 - pand mm3, mm1 /* get lsb for each prev_row byte */ - psrlq mm1, 1 /* divide prev_row bytes by 2 */ - pand mm1, mm4 /* clear invalid bit 7 of each byte */ - paddb mm0, mm1 /* add (Prev_row/2) to Avg for each byte */ - /* Add 1st active group (Raw(x-bpp)/2) to Average with LBCarry */ - movq mm1, mm3 /* now use mm1 for getting LBCarrys */ - pand mm1, mm2 /* get LBCarrys for each byte where both */ - /* lsb's were == 1 (Only valid for active group) */ - psrlq mm2, 1 /* divide raw bytes by 2 */ - pand mm2, mm4 /* clear invalid bit 7 of each byte */ - paddb mm2, mm1 /* add LBCarrys to (Raw(x-bpp)/2) for each byte */ - pand mm2, mm6 /* Leave only Active Group 1 bytes to add to Avg */ - paddb mm0, mm2 /* add (Raw/2) + LBCarrys to Avg for each Active */ - /* byte */ - /* Add 2nd active group (Raw(x-bpp)/2) to Average with LBCarry */ - psllq mm6, ShiftBpp /* shift the mm6 mask to cover bytes 3-5 */ - movq mm2, mm0 /* mov updated Raws to mm2 */ - psllq mm2, ShiftBpp /* shift data to position correctly */ - movq mm1, mm3 /* now use mm1 for getting LBCarrys */ - pand mm1, mm2 /* get LBCarrys for each byte where both */ - /* lsb's were == 1 (Only valid for active group) */ - psrlq mm2, 1 /* divide raw bytes by 2 */ - pand mm2, mm4 /* clear invalid bit 7 of each byte */ - paddb mm2, mm1 /* add LBCarrys to (Raw(x-bpp)/2) for each byte */ - pand mm2, mm6 /* Leave only Active Group 2 bytes to add to Avg */ - paddb mm0, mm2 /* add (Raw/2) + LBCarrys to Avg for each Active */ - /* byte */ - - /* Add 3rd active group (Raw(x-bpp)/2) to Average with LBCarry */ - psllq mm6, ShiftBpp /* shift the mm6 mask to cover the last two */ - /* bytes */ - movq mm2, mm0 /* mov updated Raws to mm2 */ - psllq mm2, ShiftBpp /* shift data to position correctly */ - /* Data only needs to be shifted once here to */ - /* get the correct x-bpp offset. */ - movq mm1, mm3 /* now use mm1 for getting LBCarrys */ - pand mm1, mm2 /* get LBCarrys for each byte where both */ - /* lsb's were == 1 (Only valid for active group) */ - psrlq mm2, 1 /* divide raw bytes by 2 */ - pand mm2, mm4 /* clear invalid bit 7 of each byte */ - paddb mm2, mm1 /* add LBCarrys to (Raw(x-bpp)/2) for each byte */ - pand mm2, mm6 /* Leave only Active Group 2 bytes to add to Avg */ - add ebx, 8 - paddb mm0, mm2 /* add (Raw/2) + LBCarrys to Avg for each Active */ - /* byte */ - - /* Now ready to write back to memory */ - movq [edi + ebx - 8], mm0 - /* Move updated Raw(x) to use as Raw(x-bpp) for next loop */ - cmp ebx, MMXLength - movq mm2, mm0 /* mov updated Raw(x) to mm2 */ - jb davg3lp - } /* end _asm block */ - } - break; - - case 6: - case 4: - case 7: - case 5: - { - ActiveMask.use = 0xffffffffffffffff; /* use shift below to clear */ - /* appropriate inactive bytes */ - ShiftBpp.use = bpp << 3; - ShiftRem.use = 64 - ShiftBpp.use; - _asm { - movq mm4, HBClearMask - /* Re-init address pointers and offset */ - mov ebx, diff /* ebx ==> x = offset to alignment boundary */ - /* Load ActiveMask and clear all bytes except for 1st active group */ - movq mm7, ActiveMask - mov edi, row /* edi ==> Avg(x) */ - psrlq mm7, ShiftRem - mov esi, prev_row /* esi ==> Prior(x) */ - movq mm6, mm7 - movq mm5, LBCarryMask - psllq mm6, ShiftBpp /* Create mask for 2nd active group */ - /* PRIME the pump (load the first Raw(x-bpp) data set */ - movq mm2, [edi + ebx - 8] /* Load previous aligned 8 bytes */ - /* (we correct position in loop below) */ -davg4lp: - movq mm0, [edi + ebx] - psrlq mm2, ShiftRem /* shift data to position correctly */ - movq mm1, [esi + ebx] - /* Add (Prev_row/2) to Average */ - movq mm3, mm5 - pand mm3, mm1 /* get lsb for each prev_row byte */ - psrlq mm1, 1 /* divide prev_row bytes by 2 */ - pand mm1, mm4 /* clear invalid bit 7 of each byte */ - paddb mm0, mm1 /* add (Prev_row/2) to Avg for each byte */ - /* Add 1st active group (Raw(x-bpp)/2) to Average with LBCarry */ - movq mm1, mm3 /* now use mm1 for getting LBCarrys */ - pand mm1, mm2 /* get LBCarrys for each byte where both */ - /* lsb's were == 1 (Only valid for active group) */ - psrlq mm2, 1 /* divide raw bytes by 2 */ - pand mm2, mm4 /* clear invalid bit 7 of each byte */ - paddb mm2, mm1 /* add LBCarrys to (Raw(x-bpp)/2) for each byte */ - pand mm2, mm7 /* Leave only Active Group 1 bytes to add to Avg */ - paddb mm0, mm2 /* add (Raw/2) + LBCarrys to Avg for each Active */ - /* byte */ - /* Add 2nd active group (Raw(x-bpp)/2) to Average with LBCarry */ - movq mm2, mm0 /* mov updated Raws to mm2 */ - psllq mm2, ShiftBpp /* shift data to position correctly */ - add ebx, 8 - movq mm1, mm3 /* now use mm1 for getting LBCarrys */ - pand mm1, mm2 /* get LBCarrys for each byte where both */ - /* lsb's were == 1 (Only valid for active group) */ - psrlq mm2, 1 /* divide raw bytes by 2 */ - pand mm2, mm4 /* clear invalid bit 7 of each byte */ - paddb mm2, mm1 /* add LBCarrys to (Raw(x-bpp)/2) for each byte */ - pand mm2, mm6 /* Leave only Active Group 2 bytes to add to Avg */ - paddb mm0, mm2 /* add (Raw/2) + LBCarrys to Avg for each Active */ - /* byte */ - cmp ebx, MMXLength - /* Now ready to write back to memory */ - movq [edi + ebx - 8], mm0 - /* Prep Raw(x-bpp) for next loop */ - movq mm2, mm0 /* mov updated Raws to mm2 */ - jb davg4lp - } /* end _asm block */ - } - break; - case 2: - { - ActiveMask.use = 0x000000000000ffff; - ShiftBpp.use = 16; /* == 2 * 8 [BUGFIX] */ - ShiftRem.use = 48; /* == 64 - 16 [BUGFIX] */ - _asm { - /* Load ActiveMask */ - movq mm7, ActiveMask - /* Re-init address pointers and offset */ - mov ebx, diff /* ebx ==> x = offset to alignment boundary */ - movq mm5, LBCarryMask - mov edi, row /* edi ==> Avg(x) */ - movq mm4, HBClearMask - mov esi, prev_row /* esi ==> Prior(x) */ - /* PRIME the pump (load the first Raw(x-bpp) data set */ - movq mm2, [edi + ebx - 8] /* Load previous aligned 8 bytes */ - /* (we correct position in loop below) */ -davg2lp: - movq mm0, [edi + ebx] - psrlq mm2, ShiftRem /* shift data to position correctly [BUGFIX] */ - movq mm1, [esi + ebx] - /* Add (Prev_row/2) to Average */ - movq mm3, mm5 - pand mm3, mm1 /* get lsb for each prev_row byte */ - psrlq mm1, 1 /* divide prev_row bytes by 2 */ - pand mm1, mm4 /* clear invalid bit 7 of each byte */ - movq mm6, mm7 - paddb mm0, mm1 /* add (Prev_row/2) to Avg for each byte */ - /* Add 1st active group (Raw(x-bpp)/2) to Average with LBCarry */ - movq mm1, mm3 /* now use mm1 for getting LBCarrys */ - pand mm1, mm2 /* get LBCarrys for each byte where both */ - /* lsb's were == 1 (Only valid for active group) */ - psrlq mm2, 1 /* divide raw bytes by 2 */ - pand mm2, mm4 /* clear invalid bit 7 of each byte */ - paddb mm2, mm1 /* add LBCarrys to (Raw(x-bpp)/2) for each byte */ - pand mm2, mm6 /* Leave only Active Group 1 bytes to add to Avg */ - paddb mm0, mm2 /* add (Raw/2) + LBCarrys to Avg for each Active byte */ - /* Add 2nd active group (Raw(x-bpp)/2) to Average with LBCarry */ - psllq mm6, ShiftBpp /* shift the mm6 mask to cover bytes 2 & 3 */ - movq mm2, mm0 /* mov updated Raws to mm2 */ - psllq mm2, ShiftBpp /* shift data to position correctly */ - movq mm1, mm3 /* now use mm1 for getting LBCarrys */ - pand mm1, mm2 /* get LBCarrys for each byte where both */ - /* lsb's were == 1 (Only valid for active group) */ - psrlq mm2, 1 /* divide raw bytes by 2 */ - pand mm2, mm4 /* clear invalid bit 7 of each byte */ - paddb mm2, mm1 /* add LBCarrys to (Raw(x-bpp)/2) for each byte */ - pand mm2, mm6 /* Leave only Active Group 2 bytes to add to Avg */ - paddb mm0, mm2 /* add (Raw/2) + LBCarrys to Avg for each Active byte */ - - /* Add rdd active group (Raw(x-bpp)/2) to Average with LBCarry */ - psllq mm6, ShiftBpp /* shift the mm6 mask to cover bytes 4 & 5 */ - movq mm2, mm0 /* mov updated Raws to mm2 */ - psllq mm2, ShiftBpp /* shift data to position correctly */ - /* Data only needs to be shifted once here to */ - /* get the correct x-bpp offset. */ - movq mm1, mm3 /* now use mm1 for getting LBCarrys */ - pand mm1, mm2 /* get LBCarrys for each byte where both */ - /* lsb's were == 1 (Only valid for active group) */ - psrlq mm2, 1 /* divide raw bytes by 2 */ - pand mm2, mm4 /* clear invalid bit 7 of each byte */ - paddb mm2, mm1 /* add LBCarrys to (Raw(x-bpp)/2) for each byte */ - pand mm2, mm6 /* Leave only Active Group 2 bytes to add to Avg */ - paddb mm0, mm2 /* add (Raw/2) + LBCarrys to Avg for each Active byte */ - - /* Add 4th active group (Raw(x-bpp)/2) to Average with LBCarry */ - psllq mm6, ShiftBpp /* shift the mm6 mask to cover bytes 6 & 7 */ - movq mm2, mm0 /* mov updated Raws to mm2 */ - psllq mm2, ShiftBpp /* shift data to position correctly */ - /* Data only needs to be shifted once here to */ - /* get the correct x-bpp offset. */ - add ebx, 8 - movq mm1, mm3 /* now use mm1 for getting LBCarrys */ - pand mm1, mm2 /* get LBCarrys for each byte where both */ - /* lsb's were == 1 (Only valid for active group) */ - psrlq mm2, 1 /* divide raw bytes by 2 */ - pand mm2, mm4 /* clear invalid bit 7 of each byte */ - paddb mm2, mm1 /* add LBCarrys to (Raw(x-bpp)/2) for each byte */ - pand mm2, mm6 /* Leave only Active Group 2 bytes to add to Avg */ - paddb mm0, mm2 /* add (Raw/2) + LBCarrys to Avg for each Active byte */ - - cmp ebx, MMXLength - /* Now ready to write back to memory */ - movq [edi + ebx - 8], mm0 - /* Prep Raw(x-bpp) for next loop */ - movq mm2, mm0 /* mov updated Raws to mm2 */ - jb davg2lp - } /* end _asm block */ - } - break; - - case 1: /* bpp == 1 */ - { - _asm { - /* Re-init address pointers and offset */ - mov ebx, diff /* ebx ==> x = offset to alignment boundary */ - mov edi, row /* edi ==> Avg(x) */ - cmp ebx, FullLength /* Test if offset at end of array */ - jnb davg1end - /* Do Paeth decode for remaining bytes */ - mov esi, prev_row /* esi ==> Prior(x) */ - mov edx, edi - xor ecx, ecx /* zero ecx before using cl & cx in loop below */ - sub edx, bpp /* edx ==> Raw(x-bpp) */ -davg1lp: - /* Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2) */ - xor eax, eax - mov cl, [esi + ebx] /* load cl with Prior(x) */ - mov al, [edx + ebx] /* load al with Raw(x-bpp) */ - add ax, cx - inc ebx - shr ax, 1 /* divide by 2 */ - add al, [edi+ebx-1] /* Add Avg(x); -1 to offset inc ebx */ - cmp ebx, FullLength /* Check if at end of array */ - mov [edi+ebx-1], al /* Write back Raw(x); */ - /* mov does not affect flags; -1 to offset inc ebx */ - jb davg1lp -davg1end: - } /* end _asm block */ - } - return; - - case 8: /* bpp == 8 */ - { - _asm { - /* Re-init address pointers and offset */ - mov ebx, diff /* ebx ==> x = offset to alignment boundary */ - movq mm5, LBCarryMask - mov edi, row /* edi ==> Avg(x) */ - movq mm4, HBClearMask - mov esi, prev_row /* esi ==> Prior(x) */ - /* PRIME the pump (load the first Raw(x-bpp) data set */ - movq mm2, [edi + ebx - 8] /* Load previous aligned 8 bytes */ - /* (NO NEED to correct position in loop below) */ -davg8lp: - movq mm0, [edi + ebx] - movq mm3, mm5 - movq mm1, [esi + ebx] - add ebx, 8 - pand mm3, mm1 /* get lsb for each prev_row byte */ - psrlq mm1, 1 /* divide prev_row bytes by 2 */ - pand mm3, mm2 /* get LBCarrys for each byte where both */ - /* lsb's were == 1 */ - psrlq mm2, 1 /* divide raw bytes by 2 */ - pand mm1, mm4 /* clear invalid bit 7 of each byte */ - paddb mm0, mm3 /* add LBCarrys to Avg for each byte */ - pand mm2, mm4 /* clear invalid bit 7 of each byte */ - paddb mm0, mm1 /* add (Prev_row/2) to Avg for each byte */ - paddb mm0, mm2 /* add (Raw/2) to Avg for each byte */ - cmp ebx, MMXLength - movq [edi + ebx - 8], mm0 - movq mm2, mm0 /* reuse as Raw(x-bpp) */ - jb davg8lp - } /* end _asm block */ - } - break; - default: /* bpp greater than 8 */ - { - _asm { - movq mm5, LBCarryMask - /* Re-init address pointers and offset */ - mov ebx, diff /* ebx ==> x = offset to alignment boundary */ - mov edi, row /* edi ==> Avg(x) */ - movq mm4, HBClearMask - mov edx, edi - mov esi, prev_row /* esi ==> Prior(x) */ - sub edx, bpp /* edx ==> Raw(x-bpp) */ -davgAlp: - movq mm0, [edi + ebx] - movq mm3, mm5 - movq mm1, [esi + ebx] - pand mm3, mm1 /* get lsb for each prev_row byte */ - movq mm2, [edx + ebx] - psrlq mm1, 1 /* divide prev_row bytes by 2 */ - pand mm3, mm2 /* get LBCarrys for each byte where both */ - /* lsb's were == 1 */ - psrlq mm2, 1 /* divide raw bytes by 2 */ - pand mm1, mm4 /* clear invalid bit 7 of each byte */ - paddb mm0, mm3 /* add LBCarrys to Avg for each byte */ - pand mm2, mm4 /* clear invalid bit 7 of each byte */ - paddb mm0, mm1 /* add (Prev_row/2) to Avg for each byte */ - add ebx, 8 - paddb mm0, mm2 /* add (Raw/2) to Avg for each byte */ - cmp ebx, MMXLength - movq [edi + ebx - 8], mm0 - jb davgAlp - } /* end _asm block */ - } - break; - } /* end switch ( bpp ) */ - - _asm { - /* MMX acceleration complete now do clean-up */ - /* Check if any remaining bytes left to decode */ - mov ebx, MMXLength /* ebx ==> x = offset bytes remaining after MMX */ - mov edi, row /* edi ==> Avg(x) */ - cmp ebx, FullLength /* Test if offset at end of array */ - jnb davgend - /* Do Paeth decode for remaining bytes */ - mov esi, prev_row /* esi ==> Prior(x) */ - mov edx, edi - xor ecx, ecx /* zero ecx before using cl & cx in loop below */ - sub edx, bpp /* edx ==> Raw(x-bpp) */ -davglp2: - /* Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2) */ - xor eax, eax - mov cl, [esi + ebx] /* load cl with Prior(x) */ - mov al, [edx + ebx] /* load al with Raw(x-bpp) */ - add ax, cx - inc ebx - shr ax, 1 /* divide by 2 */ - add al, [edi+ebx-1] /* Add Avg(x); -1 to offset inc ebx */ - cmp ebx, FullLength /* Check if at end of array */ - mov [edi+ebx-1], al /* Write back Raw(x); */ - /* mov does not affect flags; -1 to offset inc ebx */ - jb davglp2 -davgend: - emms /* End MMX instructions; prep for possible FP instrs. */ - } /* end _asm block */ -} - -/* Optimized code for PNG Paeth filter decoder */ -void /* PRIVATE */ -png_read_filter_row_mmx_paeth(png_row_infop row_info, png_bytep row, - png_bytep prev_row) -{ - png_uint_32 FullLength; - png_uint_32 MMXLength; - /*png_uint_32 len; */ - int bpp; - int diff; - /*int ptemp; */ - int patemp, pbtemp, pctemp; - - bpp = (row_info->pixel_depth + 7) >> 3; /* Get # bytes per pixel */ - FullLength = row_info->rowbytes; /* # of bytes to filter */ - _asm - { - xor ebx, ebx /* ebx ==> x offset */ - mov edi, row - xor edx, edx /* edx ==> x-bpp offset */ - mov esi, prev_row - xor eax, eax - - /* Compute the Raw value for the first bpp bytes */ - /* Note: the formula works out to be always */ - /* Paeth(x) = Raw(x) + Prior(x) where x < bpp */ -dpthrlp: - mov al, [edi + ebx] - add al, [esi + ebx] - inc ebx - cmp ebx, bpp - mov [edi + ebx - 1], al - jb dpthrlp - /* get # of bytes to alignment */ - mov diff, edi /* take start of row */ - add diff, ebx /* add bpp */ - xor ecx, ecx - add diff, 0xf /* add 7 + 8 to incr past alignment boundary */ - and diff, 0xfffffff8 /* mask to alignment boundary */ - sub diff, edi /* subtract from start ==> value ebx at alignment */ - jz dpthgo - /* fix alignment */ -dpthlp1: - xor eax, eax - /* pav = p - a = (a + b - c) - a = b - c */ - mov al, [esi + ebx] /* load Prior(x) into al */ - mov cl, [esi + edx] /* load Prior(x-bpp) into cl */ - sub eax, ecx /* subtract Prior(x-bpp) */ - mov patemp, eax /* Save pav for later use */ - xor eax, eax - /* pbv = p - b = (a + b - c) - b = a - c */ - mov al, [edi + edx] /* load Raw(x-bpp) into al */ - sub eax, ecx /* subtract Prior(x-bpp) */ - mov ecx, eax - /* pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv */ - add eax, patemp /* pcv = pav + pbv */ - /* pc = abs(pcv) */ - test eax, 0x80000000 - jz dpthpca - neg eax /* reverse sign of neg values */ -dpthpca: - mov pctemp, eax /* save pc for later use */ - /* pb = abs(pbv) */ - test ecx, 0x80000000 - jz dpthpba - neg ecx /* reverse sign of neg values */ -dpthpba: - mov pbtemp, ecx /* save pb for later use */ - /* pa = abs(pav) */ - mov eax, patemp - test eax, 0x80000000 - jz dpthpaa - neg eax /* reverse sign of neg values */ -dpthpaa: - mov patemp, eax /* save pa for later use */ - /* test if pa <= pb */ - cmp eax, ecx - jna dpthabb - /* pa > pb; now test if pb <= pc */ - cmp ecx, pctemp - jna dpthbbc - /* pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp) */ - mov cl, [esi + edx] /* load Prior(x-bpp) into cl */ - jmp dpthpaeth -dpthbbc: - /* pb <= pc; Raw(x) = Paeth(x) + Prior(x) */ - mov cl, [esi + ebx] /* load Prior(x) into cl */ - jmp dpthpaeth -dpthabb: - /* pa <= pb; now test if pa <= pc */ - cmp eax, pctemp - jna dpthabc - /* pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp) */ - mov cl, [esi + edx] /* load Prior(x-bpp) into cl */ - jmp dpthpaeth -dpthabc: - /* pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp) */ - mov cl, [edi + edx] /* load Raw(x-bpp) into cl */ -dpthpaeth: - inc ebx - inc edx - /* Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256 */ - add [edi + ebx - 1], cl - cmp ebx, diff - jb dpthlp1 -dpthgo: - mov ecx, FullLength - mov eax, ecx - sub eax, ebx /* subtract alignment fix */ - and eax, 0x00000007 /* calc bytes over mult of 8 */ - sub ecx, eax /* drop over bytes from original length */ - mov MMXLength, ecx - } /* end _asm block */ - /* Now do the math for the rest of the row */ - switch ( bpp ) - { - case 3: - { - ActiveMask.use = 0x0000000000ffffff; - ActiveMaskEnd.use = 0xffff000000000000; - ShiftBpp.use = 24; /* == bpp(3) * 8 */ - ShiftRem.use = 40; /* == 64 - 24 */ - _asm - { - mov ebx, diff - mov edi, row - mov esi, prev_row - pxor mm0, mm0 - /* PRIME the pump (load the first Raw(x-bpp) data set */ - movq mm1, [edi+ebx-8] -dpth3lp: - psrlq mm1, ShiftRem /* shift last 3 bytes to 1st 3 bytes */ - movq mm2, [esi + ebx] /* load b=Prior(x) */ - punpcklbw mm1, mm0 /* Unpack High bytes of a */ - movq mm3, [esi+ebx-8] /* Prep c=Prior(x-bpp) bytes */ - punpcklbw mm2, mm0 /* Unpack High bytes of b */ - psrlq mm3, ShiftRem /* shift last 3 bytes to 1st 3 bytes */ - /* pav = p - a = (a + b - c) - a = b - c */ - movq mm4, mm2 - punpcklbw mm3, mm0 /* Unpack High bytes of c */ - /* pbv = p - b = (a + b - c) - b = a - c */ - movq mm5, mm1 - psubw mm4, mm3 - pxor mm7, mm7 - /* pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv */ - movq mm6, mm4 - psubw mm5, mm3 - - /* pa = abs(p-a) = abs(pav) */ - /* pb = abs(p-b) = abs(pbv) */ - /* pc = abs(p-c) = abs(pcv) */ - pcmpgtw mm0, mm4 /* Create mask pav bytes < 0 */ - paddw mm6, mm5 - pand mm0, mm4 /* Only pav bytes < 0 in mm7 */ - pcmpgtw mm7, mm5 /* Create mask pbv bytes < 0 */ - psubw mm4, mm0 - pand mm7, mm5 /* Only pbv bytes < 0 in mm0 */ - psubw mm4, mm0 - psubw mm5, mm7 - pxor mm0, mm0 - pcmpgtw mm0, mm6 /* Create mask pcv bytes < 0 */ - pand mm0, mm6 /* Only pav bytes < 0 in mm7 */ - psubw mm5, mm7 - psubw mm6, mm0 - /* test pa <= pb */ - movq mm7, mm4 - psubw mm6, mm0 - pcmpgtw mm7, mm5 /* pa > pb? */ - movq mm0, mm7 - /* use mm7 mask to merge pa & pb */ - pand mm5, mm7 - /* use mm0 mask copy to merge a & b */ - pand mm2, mm0 - pandn mm7, mm4 - pandn mm0, mm1 - paddw mm7, mm5 - paddw mm0, mm2 - /* test ((pa <= pb)? pa:pb) <= pc */ - pcmpgtw mm7, mm6 /* pab > pc? */ - pxor mm1, mm1 - pand mm3, mm7 - pandn mm7, mm0 - paddw mm7, mm3 - pxor mm0, mm0 - packuswb mm7, mm1 - movq mm3, [esi + ebx] /* load c=Prior(x-bpp) */ - pand mm7, ActiveMask - movq mm2, mm3 /* load b=Prior(x) step 1 */ - paddb mm7, [edi + ebx] /* add Paeth predictor with Raw(x) */ - punpcklbw mm3, mm0 /* Unpack High bytes of c */ - movq [edi + ebx], mm7 /* write back updated value */ - movq mm1, mm7 /* Now mm1 will be used as Raw(x-bpp) */ - /* Now do Paeth for 2nd set of bytes (3-5) */ - psrlq mm2, ShiftBpp /* load b=Prior(x) step 2 */ - punpcklbw mm1, mm0 /* Unpack High bytes of a */ - pxor mm7, mm7 - punpcklbw mm2, mm0 /* Unpack High bytes of b */ - /* pbv = p - b = (a + b - c) - b = a - c */ - movq mm5, mm1 - /* pav = p - a = (a + b - c) - a = b - c */ - movq mm4, mm2 - psubw mm5, mm3 - psubw mm4, mm3 - /* pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = */ - /* pav + pbv = pbv + pav */ - movq mm6, mm5 - paddw mm6, mm4 - - /* pa = abs(p-a) = abs(pav) */ - /* pb = abs(p-b) = abs(pbv) */ - /* pc = abs(p-c) = abs(pcv) */ - pcmpgtw mm0, mm5 /* Create mask pbv bytes < 0 */ - pcmpgtw mm7, mm4 /* Create mask pav bytes < 0 */ - pand mm0, mm5 /* Only pbv bytes < 0 in mm0 */ - pand mm7, mm4 /* Only pav bytes < 0 in mm7 */ - psubw mm5, mm0 - psubw mm4, mm7 - psubw mm5, mm0 - psubw mm4, mm7 - pxor mm0, mm0 - pcmpgtw mm0, mm6 /* Create mask pcv bytes < 0 */ - pand mm0, mm6 /* Only pav bytes < 0 in mm7 */ - psubw mm6, mm0 - /* test pa <= pb */ - movq mm7, mm4 - psubw mm6, mm0 - pcmpgtw mm7, mm5 /* pa > pb? */ - movq mm0, mm7 - /* use mm7 mask to merge pa & pb */ - pand mm5, mm7 - /* use mm0 mask copy to merge a & b */ - pand mm2, mm0 - pandn mm7, mm4 - pandn mm0, mm1 - paddw mm7, mm5 - paddw mm0, mm2 - /* test ((pa <= pb)? pa:pb) <= pc */ - pcmpgtw mm7, mm6 /* pab > pc? */ - movq mm2, [esi + ebx] /* load b=Prior(x) */ - pand mm3, mm7 - pandn mm7, mm0 - pxor mm1, mm1 - paddw mm7, mm3 - pxor mm0, mm0 - packuswb mm7, mm1 - movq mm3, mm2 /* load c=Prior(x-bpp) step 1 */ - pand mm7, ActiveMask - punpckhbw mm2, mm0 /* Unpack High bytes of b */ - psllq mm7, ShiftBpp /* Shift bytes to 2nd group of 3 bytes */ - /* pav = p - a = (a + b - c) - a = b - c */ - movq mm4, mm2 - paddb mm7, [edi + ebx] /* add Paeth predictor with Raw(x) */ - psllq mm3, ShiftBpp /* load c=Prior(x-bpp) step 2 */ - movq [edi + ebx], mm7 /* write back updated value */ - movq mm1, mm7 - punpckhbw mm3, mm0 /* Unpack High bytes of c */ - psllq mm1, ShiftBpp /* Shift bytes */ - /* Now mm1 will be used as Raw(x-bpp) */ - /* Now do Paeth for 3rd, and final, set of bytes (6-7) */ - pxor mm7, mm7 - punpckhbw mm1, mm0 /* Unpack High bytes of a */ - psubw mm4, mm3 - /* pbv = p - b = (a + b - c) - b = a - c */ - movq mm5, mm1 - /* pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv */ - movq mm6, mm4 - psubw mm5, mm3 - pxor mm0, mm0 - paddw mm6, mm5 - - /* pa = abs(p-a) = abs(pav) */ - /* pb = abs(p-b) = abs(pbv) */ - /* pc = abs(p-c) = abs(pcv) */ - pcmpgtw mm0, mm4 /* Create mask pav bytes < 0 */ - pcmpgtw mm7, mm5 /* Create mask pbv bytes < 0 */ - pand mm0, mm4 /* Only pav bytes < 0 in mm7 */ - pand mm7, mm5 /* Only pbv bytes < 0 in mm0 */ - psubw mm4, mm0 - psubw mm5, mm7 - psubw mm4, mm0 - psubw mm5, mm7 - pxor mm0, mm0 - pcmpgtw mm0, mm6 /* Create mask pcv bytes < 0 */ - pand mm0, mm6 /* Only pav bytes < 0 in mm7 */ - psubw mm6, mm0 - /* test pa <= pb */ - movq mm7, mm4 - psubw mm6, mm0 - pcmpgtw mm7, mm5 /* pa > pb? */ - movq mm0, mm7 - /* use mm0 mask copy to merge a & b */ - pand mm2, mm0 - /* use mm7 mask to merge pa & pb */ - pand mm5, mm7 - pandn mm0, mm1 - pandn mm7, mm4 - paddw mm0, mm2 - paddw mm7, mm5 - /* test ((pa <= pb)? pa:pb) <= pc */ - pcmpgtw mm7, mm6 /* pab > pc? */ - pand mm3, mm7 - pandn mm7, mm0 - paddw mm7, mm3 - pxor mm1, mm1 - packuswb mm1, mm7 - /* Step ebx to next set of 8 bytes and repeat loop til done */ - add ebx, 8 - pand mm1, ActiveMaskEnd - paddb mm1, [edi + ebx - 8] /* add Paeth predictor with Raw(x) */ - - cmp ebx, MMXLength - pxor mm0, mm0 /* pxor does not affect flags */ - movq [edi + ebx - 8], mm1 /* write back updated value */ - /* mm1 will be used as Raw(x-bpp) next loop */ - /* mm3 ready to be used as Prior(x-bpp) next loop */ - jb dpth3lp - } /* end _asm block */ - } - break; - - case 6: - case 7: - case 5: - { - ActiveMask.use = 0x00000000ffffffff; - ActiveMask2.use = 0xffffffff00000000; - ShiftBpp.use = bpp << 3; /* == bpp * 8 */ - ShiftRem.use = 64 - ShiftBpp.use; - _asm - { - mov ebx, diff - mov edi, row - mov esi, prev_row - /* PRIME the pump (load the first Raw(x-bpp) data set */ - movq mm1, [edi+ebx-8] - pxor mm0, mm0 -dpth6lp: - /* Must shift to position Raw(x-bpp) data */ - psrlq mm1, ShiftRem - /* Do first set of 4 bytes */ - movq mm3, [esi+ebx-8] /* read c=Prior(x-bpp) bytes */ - punpcklbw mm1, mm0 /* Unpack Low bytes of a */ - movq mm2, [esi + ebx] /* load b=Prior(x) */ - punpcklbw mm2, mm0 /* Unpack Low bytes of b */ - /* Must shift to position Prior(x-bpp) data */ - psrlq mm3, ShiftRem - /* pav = p - a = (a + b - c) - a = b - c */ - movq mm4, mm2 - punpcklbw mm3, mm0 /* Unpack Low bytes of c */ - /* pbv = p - b = (a + b - c) - b = a - c */ - movq mm5, mm1 - psubw mm4, mm3 - pxor mm7, mm7 - /* pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv */ - movq mm6, mm4 - psubw mm5, mm3 - /* pa = abs(p-a) = abs(pav) */ - /* pb = abs(p-b) = abs(pbv) */ - /* pc = abs(p-c) = abs(pcv) */ - pcmpgtw mm0, mm4 /* Create mask pav bytes < 0 */ - paddw mm6, mm5 - pand mm0, mm4 /* Only pav bytes < 0 in mm7 */ - pcmpgtw mm7, mm5 /* Create mask pbv bytes < 0 */ - psubw mm4, mm0 - pand mm7, mm5 /* Only pbv bytes < 0 in mm0 */ - psubw mm4, mm0 - psubw mm5, mm7 - pxor mm0, mm0 - pcmpgtw mm0, mm6 /* Create mask pcv bytes < 0 */ - pand mm0, mm6 /* Only pav bytes < 0 in mm7 */ - psubw mm5, mm7 - psubw mm6, mm0 - /* test pa <= pb */ - movq mm7, mm4 - psubw mm6, mm0 - pcmpgtw mm7, mm5 /* pa > pb? */ - movq mm0, mm7 - /* use mm7 mask to merge pa & pb */ - pand mm5, mm7 - /* use mm0 mask copy to merge a & b */ - pand mm2, mm0 - pandn mm7, mm4 - pandn mm0, mm1 - paddw mm7, mm5 - paddw mm0, mm2 - /* test ((pa <= pb)? pa:pb) <= pc */ - pcmpgtw mm7, mm6 /* pab > pc? */ - pxor mm1, mm1 - pand mm3, mm7 - pandn mm7, mm0 - paddw mm7, mm3 - pxor mm0, mm0 - packuswb mm7, mm1 - movq mm3, [esi + ebx - 8] /* load c=Prior(x-bpp) */ - pand mm7, ActiveMask - psrlq mm3, ShiftRem - movq mm2, [esi + ebx] /* load b=Prior(x) step 1 */ - paddb mm7, [edi + ebx] /* add Paeth predictor with Raw(x) */ - movq mm6, mm2 - movq [edi + ebx], mm7 /* write back updated value */ - movq mm1, [edi+ebx-8] - psllq mm6, ShiftBpp - movq mm5, mm7 - psrlq mm1, ShiftRem - por mm3, mm6 - psllq mm5, ShiftBpp - punpckhbw mm3, mm0 /* Unpack High bytes of c */ - por mm1, mm5 - /* Do second set of 4 bytes */ - punpckhbw mm2, mm0 /* Unpack High bytes of b */ - punpckhbw mm1, mm0 /* Unpack High bytes of a */ - /* pav = p - a = (a + b - c) - a = b - c */ - movq mm4, mm2 - /* pbv = p - b = (a + b - c) - b = a - c */ - movq mm5, mm1 - psubw mm4, mm3 - pxor mm7, mm7 - /* pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv */ - movq mm6, mm4 - psubw mm5, mm3 - /* pa = abs(p-a) = abs(pav) */ - /* pb = abs(p-b) = abs(pbv) */ - /* pc = abs(p-c) = abs(pcv) */ - pcmpgtw mm0, mm4 /* Create mask pav bytes < 0 */ - paddw mm6, mm5 - pand mm0, mm4 /* Only pav bytes < 0 in mm7 */ - pcmpgtw mm7, mm5 /* Create mask pbv bytes < 0 */ - psubw mm4, mm0 - pand mm7, mm5 /* Only pbv bytes < 0 in mm0 */ - psubw mm4, mm0 - psubw mm5, mm7 - pxor mm0, mm0 - pcmpgtw mm0, mm6 /* Create mask pcv bytes < 0 */ - pand mm0, mm6 /* Only pav bytes < 0 in mm7 */ - psubw mm5, mm7 - psubw mm6, mm0 - /* test pa <= pb */ - movq mm7, mm4 - psubw mm6, mm0 - pcmpgtw mm7, mm5 /* pa > pb? */ - movq mm0, mm7 - /* use mm7 mask to merge pa & pb */ - pand mm5, mm7 - /* use mm0 mask copy to merge a & b */ - pand mm2, mm0 - pandn mm7, mm4 - pandn mm0, mm1 - paddw mm7, mm5 - paddw mm0, mm2 - /* test ((pa <= pb)? pa:pb) <= pc */ - pcmpgtw mm7, mm6 /* pab > pc? */ - pxor mm1, mm1 - pand mm3, mm7 - pandn mm7, mm0 - pxor mm1, mm1 - paddw mm7, mm3 - pxor mm0, mm0 - /* Step ex to next set of 8 bytes and repeat loop til done */ - add ebx, 8 - packuswb mm1, mm7 - paddb mm1, [edi + ebx - 8] /* add Paeth predictor with Raw(x) */ - cmp ebx, MMXLength - movq [edi + ebx - 8], mm1 /* write back updated value */ - /* mm1 will be used as Raw(x-bpp) next loop */ - jb dpth6lp - } /* end _asm block */ - } - break; - - case 4: - { - ActiveMask.use = 0x00000000ffffffff; - _asm { - mov ebx, diff - mov edi, row - mov esi, prev_row - pxor mm0, mm0 - /* PRIME the pump (load the first Raw(x-bpp) data set */ - movq mm1, [edi+ebx-8] /* Only time should need to read */ - /* a=Raw(x-bpp) bytes */ -dpth4lp: - /* Do first set of 4 bytes */ - movq mm3, [esi+ebx-8] /* read c=Prior(x-bpp) bytes */ - punpckhbw mm1, mm0 /* Unpack Low bytes of a */ - movq mm2, [esi + ebx] /* load b=Prior(x) */ - punpcklbw mm2, mm0 /* Unpack High bytes of b */ - /* pav = p - a = (a + b - c) - a = b - c */ - movq mm4, mm2 - punpckhbw mm3, mm0 /* Unpack High bytes of c */ - /* pbv = p - b = (a + b - c) - b = a - c */ - movq mm5, mm1 - psubw mm4, mm3 - pxor mm7, mm7 - /* pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv */ - movq mm6, mm4 - psubw mm5, mm3 - /* pa = abs(p-a) = abs(pav) */ - /* pb = abs(p-b) = abs(pbv) */ - /* pc = abs(p-c) = abs(pcv) */ - pcmpgtw mm0, mm4 /* Create mask pav bytes < 0 */ - paddw mm6, mm5 - pand mm0, mm4 /* Only pav bytes < 0 in mm7 */ - pcmpgtw mm7, mm5 /* Create mask pbv bytes < 0 */ - psubw mm4, mm0 - pand mm7, mm5 /* Only pbv bytes < 0 in mm0 */ - psubw mm4, mm0 - psubw mm5, mm7 - pxor mm0, mm0 - pcmpgtw mm0, mm6 /* Create mask pcv bytes < 0 */ - pand mm0, mm6 /* Only pav bytes < 0 in mm7 */ - psubw mm5, mm7 - psubw mm6, mm0 - /* test pa <= pb */ - movq mm7, mm4 - psubw mm6, mm0 - pcmpgtw mm7, mm5 /* pa > pb? */ - movq mm0, mm7 - /* use mm7 mask to merge pa & pb */ - pand mm5, mm7 - /* use mm0 mask copy to merge a & b */ - pand mm2, mm0 - pandn mm7, mm4 - pandn mm0, mm1 - paddw mm7, mm5 - paddw mm0, mm2 - /* test ((pa <= pb)? pa:pb) <= pc */ - pcmpgtw mm7, mm6 /* pab > pc? */ - pxor mm1, mm1 - pand mm3, mm7 - pandn mm7, mm0 - paddw mm7, mm3 - pxor mm0, mm0 - packuswb mm7, mm1 - movq mm3, [esi + ebx] /* load c=Prior(x-bpp) */ - pand mm7, ActiveMask - movq mm2, mm3 /* load b=Prior(x) step 1 */ - paddb mm7, [edi + ebx] /* add Paeth predictor with Raw(x) */ - punpcklbw mm3, mm0 /* Unpack High bytes of c */ - movq [edi + ebx], mm7 /* write back updated value */ - movq mm1, mm7 /* Now mm1 will be used as Raw(x-bpp) */ - /* Do second set of 4 bytes */ - punpckhbw mm2, mm0 /* Unpack Low bytes of b */ - punpcklbw mm1, mm0 /* Unpack Low bytes of a */ - /* pav = p - a = (a + b - c) - a = b - c */ - movq mm4, mm2 - /* pbv = p - b = (a + b - c) - b = a - c */ - movq mm5, mm1 - psubw mm4, mm3 - pxor mm7, mm7 - /* pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv */ - movq mm6, mm4 - psubw mm5, mm3 - /* pa = abs(p-a) = abs(pav) */ - /* pb = abs(p-b) = abs(pbv) */ - /* pc = abs(p-c) = abs(pcv) */ - pcmpgtw mm0, mm4 /* Create mask pav bytes < 0 */ - paddw mm6, mm5 - pand mm0, mm4 /* Only pav bytes < 0 in mm7 */ - pcmpgtw mm7, mm5 /* Create mask pbv bytes < 0 */ - psubw mm4, mm0 - pand mm7, mm5 /* Only pbv bytes < 0 in mm0 */ - psubw mm4, mm0 - psubw mm5, mm7 - pxor mm0, mm0 - pcmpgtw mm0, mm6 /* Create mask pcv bytes < 0 */ - pand mm0, mm6 /* Only pav bytes < 0 in mm7 */ - psubw mm5, mm7 - psubw mm6, mm0 - /* test pa <= pb */ - movq mm7, mm4 - psubw mm6, mm0 - pcmpgtw mm7, mm5 /* pa > pb? */ - movq mm0, mm7 - /* use mm7 mask to merge pa & pb */ - pand mm5, mm7 - /* use mm0 mask copy to merge a & b */ - pand mm2, mm0 - pandn mm7, mm4 - pandn mm0, mm1 - paddw mm7, mm5 - paddw mm0, mm2 - /* test ((pa <= pb)? pa:pb) <= pc */ - pcmpgtw mm7, mm6 /* pab > pc? */ - pxor mm1, mm1 - pand mm3, mm7 - pandn mm7, mm0 - pxor mm1, mm1 - paddw mm7, mm3 - pxor mm0, mm0 - /* Step ex to next set of 8 bytes and repeat loop til done */ - add ebx, 8 - packuswb mm1, mm7 - paddb mm1, [edi + ebx - 8] /* add Paeth predictor with Raw(x) */ - cmp ebx, MMXLength - movq [edi + ebx - 8], mm1 /* write back updated value */ - /* mm1 will be used as Raw(x-bpp) next loop */ - jb dpth4lp - } /* end _asm block */ - } - break; - case 8: /* bpp == 8 */ - { - ActiveMask.use = 0x00000000ffffffff; - _asm { - mov ebx, diff - mov edi, row - mov esi, prev_row - pxor mm0, mm0 - /* PRIME the pump (load the first Raw(x-bpp) data set */ - movq mm1, [edi+ebx-8] /* Only time should need to read */ - /* a=Raw(x-bpp) bytes */ -dpth8lp: - /* Do first set of 4 bytes */ - movq mm3, [esi+ebx-8] /* read c=Prior(x-bpp) bytes */ - punpcklbw mm1, mm0 /* Unpack Low bytes of a */ - movq mm2, [esi + ebx] /* load b=Prior(x) */ - punpcklbw mm2, mm0 /* Unpack Low bytes of b */ - /* pav = p - a = (a + b - c) - a = b - c */ - movq mm4, mm2 - punpcklbw mm3, mm0 /* Unpack Low bytes of c */ - /* pbv = p - b = (a + b - c) - b = a - c */ - movq mm5, mm1 - psubw mm4, mm3 - pxor mm7, mm7 - /* pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv */ - movq mm6, mm4 - psubw mm5, mm3 - /* pa = abs(p-a) = abs(pav) */ - /* pb = abs(p-b) = abs(pbv) */ - /* pc = abs(p-c) = abs(pcv) */ - pcmpgtw mm0, mm4 /* Create mask pav bytes < 0 */ - paddw mm6, mm5 - pand mm0, mm4 /* Only pav bytes < 0 in mm7 */ - pcmpgtw mm7, mm5 /* Create mask pbv bytes < 0 */ - psubw mm4, mm0 - pand mm7, mm5 /* Only pbv bytes < 0 in mm0 */ - psubw mm4, mm0 - psubw mm5, mm7 - pxor mm0, mm0 - pcmpgtw mm0, mm6 /* Create mask pcv bytes < 0 */ - pand mm0, mm6 /* Only pav bytes < 0 in mm7 */ - psubw mm5, mm7 - psubw mm6, mm0 - /* test pa <= pb */ - movq mm7, mm4 - psubw mm6, mm0 - pcmpgtw mm7, mm5 /* pa > pb? */ - movq mm0, mm7 - /* use mm7 mask to merge pa & pb */ - pand mm5, mm7 - /* use mm0 mask copy to merge a & b */ - pand mm2, mm0 - pandn mm7, mm4 - pandn mm0, mm1 - paddw mm7, mm5 - paddw mm0, mm2 - /* test ((pa <= pb)? pa:pb) <= pc */ - pcmpgtw mm7, mm6 /* pab > pc? */ - pxor mm1, mm1 - pand mm3, mm7 - pandn mm7, mm0 - paddw mm7, mm3 - pxor mm0, mm0 - packuswb mm7, mm1 - movq mm3, [esi+ebx-8] /* read c=Prior(x-bpp) bytes */ - pand mm7, ActiveMask - movq mm2, [esi + ebx] /* load b=Prior(x) */ - paddb mm7, [edi + ebx] /* add Paeth predictor with Raw(x) */ - punpckhbw mm3, mm0 /* Unpack High bytes of c */ - movq [edi + ebx], mm7 /* write back updated value */ - movq mm1, [edi+ebx-8] /* read a=Raw(x-bpp) bytes */ - - /* Do second set of 4 bytes */ - punpckhbw mm2, mm0 /* Unpack High bytes of b */ - punpckhbw mm1, mm0 /* Unpack High bytes of a */ - /* pav = p - a = (a + b - c) - a = b - c */ - movq mm4, mm2 - /* pbv = p - b = (a + b - c) - b = a - c */ - movq mm5, mm1 - psubw mm4, mm3 - pxor mm7, mm7 - /* pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv */ - movq mm6, mm4 - psubw mm5, mm3 - /* pa = abs(p-a) = abs(pav) */ - /* pb = abs(p-b) = abs(pbv) */ - /* pc = abs(p-c) = abs(pcv) */ - pcmpgtw mm0, mm4 /* Create mask pav bytes < 0 */ - paddw mm6, mm5 - pand mm0, mm4 /* Only pav bytes < 0 in mm7 */ - pcmpgtw mm7, mm5 /* Create mask pbv bytes < 0 */ - psubw mm4, mm0 - pand mm7, mm5 /* Only pbv bytes < 0 in mm0 */ - psubw mm4, mm0 - psubw mm5, mm7 - pxor mm0, mm0 - pcmpgtw mm0, mm6 /* Create mask pcv bytes < 0 */ - pand mm0, mm6 /* Only pav bytes < 0 in mm7 */ - psubw mm5, mm7 - psubw mm6, mm0 - /* test pa <= pb */ - movq mm7, mm4 - psubw mm6, mm0 - pcmpgtw mm7, mm5 /* pa > pb? */ - movq mm0, mm7 - /* use mm7 mask to merge pa & pb */ - pand mm5, mm7 - /* use mm0 mask copy to merge a & b */ - pand mm2, mm0 - pandn mm7, mm4 - pandn mm0, mm1 - paddw mm7, mm5 - paddw mm0, mm2 - /* test ((pa <= pb)? pa:pb) <= pc */ - pcmpgtw mm7, mm6 /* pab > pc? */ - pxor mm1, mm1 - pand mm3, mm7 - pandn mm7, mm0 - pxor mm1, mm1 - paddw mm7, mm3 - pxor mm0, mm0 - /* Step ex to next set of 8 bytes and repeat loop til done */ - add ebx, 8 - packuswb mm1, mm7 - paddb mm1, [edi + ebx - 8] /* add Paeth predictor with Raw(x) */ - cmp ebx, MMXLength - movq [edi + ebx - 8], mm1 /* write back updated value */ - /* mm1 will be used as Raw(x-bpp) next loop */ - jb dpth8lp - } /* end _asm block */ - } - break; - - case 1: /* bpp = 1 */ - case 2: /* bpp = 2 */ - default: /* bpp > 8 */ - { - _asm { - mov ebx, diff - cmp ebx, FullLength - jnb dpthdend - mov edi, row - mov esi, prev_row - /* Do Paeth decode for remaining bytes */ - mov edx, ebx - xor ecx, ecx /* zero ecx before using cl & cx in loop below */ - sub edx, bpp /* Set edx = ebx - bpp */ -dpthdlp: - xor eax, eax - /* pav = p - a = (a + b - c) - a = b - c */ - mov al, [esi + ebx] /* load Prior(x) into al */ - mov cl, [esi + edx] /* load Prior(x-bpp) into cl */ - sub eax, ecx /* subtract Prior(x-bpp) */ - mov patemp, eax /* Save pav for later use */ - xor eax, eax - /* pbv = p - b = (a + b - c) - b = a - c */ - mov al, [edi + edx] /* load Raw(x-bpp) into al */ - sub eax, ecx /* subtract Prior(x-bpp) */ - mov ecx, eax - /* pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv */ - add eax, patemp /* pcv = pav + pbv */ - /* pc = abs(pcv) */ - test eax, 0x80000000 - jz dpthdpca - neg eax /* reverse sign of neg values */ -dpthdpca: - mov pctemp, eax /* save pc for later use */ - /* pb = abs(pbv) */ - test ecx, 0x80000000 - jz dpthdpba - neg ecx /* reverse sign of neg values */ -dpthdpba: - mov pbtemp, ecx /* save pb for later use */ - /* pa = abs(pav) */ - mov eax, patemp - test eax, 0x80000000 - jz dpthdpaa - neg eax /* reverse sign of neg values */ -dpthdpaa: - mov patemp, eax /* save pa for later use */ - /* test if pa <= pb */ - cmp eax, ecx - jna dpthdabb - /* pa > pb; now test if pb <= pc */ - cmp ecx, pctemp - jna dpthdbbc - /* pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp) */ - mov cl, [esi + edx] /* load Prior(x-bpp) into cl */ - jmp dpthdpaeth -dpthdbbc: - /* pb <= pc; Raw(x) = Paeth(x) + Prior(x) */ - mov cl, [esi + ebx] /* load Prior(x) into cl */ - jmp dpthdpaeth -dpthdabb: - /* pa <= pb; now test if pa <= pc */ - cmp eax, pctemp - jna dpthdabc - /* pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp) */ - mov cl, [esi + edx] /* load Prior(x-bpp) into cl */ - jmp dpthdpaeth -dpthdabc: - /* pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp) */ - mov cl, [edi + edx] /* load Raw(x-bpp) into cl */ -dpthdpaeth: - inc ebx - inc edx - /* Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256 */ - add [edi + ebx - 1], cl - cmp ebx, FullLength - jb dpthdlp -dpthdend: - } /* end _asm block */ - } - return; /* No need to go further with this one */ - } /* end switch ( bpp ) */ - _asm - { - /* MMX acceleration complete now do clean-up */ - /* Check if any remaining bytes left to decode */ - mov ebx, MMXLength - cmp ebx, FullLength - jnb dpthend - mov edi, row - mov esi, prev_row - /* Do Paeth decode for remaining bytes */ - mov edx, ebx - xor ecx, ecx /* zero ecx before using cl & cx in loop below */ - sub edx, bpp /* Set edx = ebx - bpp */ -dpthlp2: - xor eax, eax - /* pav = p - a = (a + b - c) - a = b - c */ - mov al, [esi + ebx] /* load Prior(x) into al */ - mov cl, [esi + edx] /* load Prior(x-bpp) into cl */ - sub eax, ecx /* subtract Prior(x-bpp) */ - mov patemp, eax /* Save pav for later use */ - xor eax, eax - /* pbv = p - b = (a + b - c) - b = a - c */ - mov al, [edi + edx] /* load Raw(x-bpp) into al */ - sub eax, ecx /* subtract Prior(x-bpp) */ - mov ecx, eax - /* pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv */ - add eax, patemp /* pcv = pav + pbv */ - /* pc = abs(pcv) */ - test eax, 0x80000000 - jz dpthpca2 - neg eax /* reverse sign of neg values */ -dpthpca2: - mov pctemp, eax /* save pc for later use */ - /* pb = abs(pbv) */ - test ecx, 0x80000000 - jz dpthpba2 - neg ecx /* reverse sign of neg values */ -dpthpba2: - mov pbtemp, ecx /* save pb for later use */ - /* pa = abs(pav) */ - mov eax, patemp - test eax, 0x80000000 - jz dpthpaa2 - neg eax /* reverse sign of neg values */ -dpthpaa2: - mov patemp, eax /* save pa for later use */ - /* test if pa <= pb */ - cmp eax, ecx - jna dpthabb2 - /* pa > pb; now test if pb <= pc */ - cmp ecx, pctemp - jna dpthbbc2 - /* pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp) */ - mov cl, [esi + edx] /* load Prior(x-bpp) into cl */ - jmp dpthpaeth2 -dpthbbc2: - /* pb <= pc; Raw(x) = Paeth(x) + Prior(x) */ - mov cl, [esi + ebx] /* load Prior(x) into cl */ - jmp dpthpaeth2 -dpthabb2: - /* pa <= pb; now test if pa <= pc */ - cmp eax, pctemp - jna dpthabc2 - /* pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp) */ - mov cl, [esi + edx] /* load Prior(x-bpp) into cl */ - jmp dpthpaeth2 -dpthabc2: - /* pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp) */ - mov cl, [edi + edx] /* load Raw(x-bpp) into cl */ -dpthpaeth2: - inc ebx - inc edx - /* Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256 */ - add [edi + ebx - 1], cl - cmp ebx, FullLength - jb dpthlp2 -dpthend: - emms /* End MMX instructions; prep for possible FP instrs. */ - } /* end _asm block */ -} - -/* Optimized code for PNG Sub filter decoder */ -void /* PRIVATE */ -png_read_filter_row_mmx_sub(png_row_infop row_info, png_bytep row) -{ - /*int test; */ - int bpp; - png_uint_32 FullLength; - png_uint_32 MMXLength; - int diff; - - bpp = (row_info->pixel_depth + 7) >> 3; /* Get # bytes per pixel */ - FullLength = row_info->rowbytes - bpp; /* # of bytes to filter */ - _asm { - mov edi, row - mov esi, edi /* lp = row */ - add edi, bpp /* rp = row + bpp */ - xor eax, eax - /* get # of bytes to alignment */ - mov diff, edi /* take start of row */ - add diff, 0xf /* add 7 + 8 to incr past */ - /* alignment boundary */ - xor ebx, ebx - and diff, 0xfffffff8 /* mask to alignment boundary */ - sub diff, edi /* subtract from start ==> value */ - /* ebx at alignment */ - jz dsubgo - /* fix alignment */ -dsublp1: - mov al, [esi+ebx] - add [edi+ebx], al - inc ebx - cmp ebx, diff - jb dsublp1 -dsubgo: - mov ecx, FullLength - mov edx, ecx - sub edx, ebx /* subtract alignment fix */ - and edx, 0x00000007 /* calc bytes over mult of 8 */ - sub ecx, edx /* drop over bytes from length */ - mov MMXLength, ecx - } /* end _asm block */ - - /* Now do the math for the rest of the row */ - switch ( bpp ) - { - case 3: - { - ActiveMask.use = 0x0000ffffff000000; - ShiftBpp.use = 24; /* == 3 * 8 */ - ShiftRem.use = 40; /* == 64 - 24 */ - _asm { - mov edi, row - movq mm7, ActiveMask /* Load ActiveMask for 2nd active byte group */ - mov esi, edi /* lp = row */ - add edi, bpp /* rp = row + bpp */ - movq mm6, mm7 - mov ebx, diff - psllq mm6, ShiftBpp /* Move mask in mm6 to cover 3rd active */ - /* byte group */ - /* PRIME the pump (load the first Raw(x-bpp) data set */ - movq mm1, [edi+ebx-8] -dsub3lp: - psrlq mm1, ShiftRem /* Shift data for adding 1st bpp bytes */ - /* no need for mask; shift clears inactive bytes */ - /* Add 1st active group */ - movq mm0, [edi+ebx] - paddb mm0, mm1 - /* Add 2nd active group */ - movq mm1, mm0 /* mov updated Raws to mm1 */ - psllq mm1, ShiftBpp /* shift data to position correctly */ - pand mm1, mm7 /* mask to use only 2nd active group */ - paddb mm0, mm1 - /* Add 3rd active group */ - movq mm1, mm0 /* mov updated Raws to mm1 */ - psllq mm1, ShiftBpp /* shift data to position correctly */ - pand mm1, mm6 /* mask to use only 3rd active group */ - add ebx, 8 - paddb mm0, mm1 - cmp ebx, MMXLength - movq [edi+ebx-8], mm0 /* Write updated Raws back to array */ - /* Prep for doing 1st add at top of loop */ - movq mm1, mm0 - jb dsub3lp - } /* end _asm block */ - } - break; - - case 1: - { - /* Placed here just in case this is a duplicate of the */ - /* non-MMX code for the SUB filter in png_read_filter_row below */ - // - /* png_bytep rp; */ - /* png_bytep lp; */ - /* png_uint_32 i; */ - /* bpp = (row_info->pixel_depth + 7) >> 3; */ - /* for (i = (png_uint_32)bpp, rp = row + bpp, lp = row; */ - /* i < row_info->rowbytes; i++, rp++, lp++) */ - /* { */ - /* *rp = (png_byte)(((int)(*rp) + (int)(*lp)) & 0xff); */ - /* } */ - _asm { - mov ebx, diff - mov edi, row - cmp ebx, FullLength - jnb dsub1end - mov esi, edi /* lp = row */ - xor eax, eax - add edi, bpp /* rp = row + bpp */ -dsub1lp: - mov al, [esi+ebx] - add [edi+ebx], al - inc ebx - cmp ebx, FullLength - jb dsub1lp -dsub1end: - } /* end _asm block */ - } - return; - - case 6: - case 7: - case 4: - case 5: - { - ShiftBpp.use = bpp << 3; - ShiftRem.use = 64 - ShiftBpp.use; - _asm { - mov edi, row - mov ebx, diff - mov esi, edi /* lp = row */ - add edi, bpp /* rp = row + bpp */ - /* PRIME the pump (load the first Raw(x-bpp) data set */ - movq mm1, [edi+ebx-8] -dsub4lp: - psrlq mm1, ShiftRem /* Shift data for adding 1st bpp bytes */ - /* no need for mask; shift clears inactive bytes */ - movq mm0, [edi+ebx] - paddb mm0, mm1 - /* Add 2nd active group */ - movq mm1, mm0 /* mov updated Raws to mm1 */ - psllq mm1, ShiftBpp /* shift data to position correctly */ - /* there is no need for any mask */ - /* since shift clears inactive bits/bytes */ - add ebx, 8 - paddb mm0, mm1 - cmp ebx, MMXLength - movq [edi+ebx-8], mm0 - movq mm1, mm0 /* Prep for doing 1st add at top of loop */ - jb dsub4lp - } /* end _asm block */ - } - break; - - case 2: - { - ActiveMask.use = 0x00000000ffff0000; - ShiftBpp.use = 16; /* == 2 * 8 */ - ShiftRem.use = 48; /* == 64 - 16 */ - _asm { - movq mm7, ActiveMask /* Load ActiveMask for 2nd active byte group */ - mov ebx, diff - movq mm6, mm7 - mov edi, row - psllq mm6, ShiftBpp /* Move mask in mm6 to cover 3rd active */ - /* byte group */ - mov esi, edi /* lp = row */ - movq mm5, mm6 - add edi, bpp /* rp = row + bpp */ - psllq mm5, ShiftBpp /* Move mask in mm5 to cover 4th active */ - /* byte group */ - /* PRIME the pump (load the first Raw(x-bpp) data set */ - movq mm1, [edi+ebx-8] -dsub2lp: - /* Add 1st active group */ - psrlq mm1, ShiftRem /* Shift data for adding 1st bpp bytes */ - /* no need for mask; shift clears inactive */ - /* bytes */ - movq mm0, [edi+ebx] - paddb mm0, mm1 - /* Add 2nd active group */ - movq mm1, mm0 /* mov updated Raws to mm1 */ - psllq mm1, ShiftBpp /* shift data to position correctly */ - pand mm1, mm7 /* mask to use only 2nd active group */ - paddb mm0, mm1 - /* Add 3rd active group */ - movq mm1, mm0 /* mov updated Raws to mm1 */ - psllq mm1, ShiftBpp /* shift data to position correctly */ - pand mm1, mm6 /* mask to use only 3rd active group */ - paddb mm0, mm1 - /* Add 4th active group */ - movq mm1, mm0 /* mov updated Raws to mm1 */ - psllq mm1, ShiftBpp /* shift data to position correctly */ - pand mm1, mm5 /* mask to use only 4th active group */ - add ebx, 8 - paddb mm0, mm1 - cmp ebx, MMXLength - movq [edi+ebx-8], mm0 /* Write updated Raws back to array */ - movq mm1, mm0 /* Prep for doing 1st add at top of loop */ - jb dsub2lp - } /* end _asm block */ - } - break; - case 8: - { - _asm { - mov edi, row - mov ebx, diff - mov esi, edi /* lp = row */ - add edi, bpp /* rp = row + bpp */ - mov ecx, MMXLength - movq mm7, [edi+ebx-8] /* PRIME the pump (load the first */ - /* Raw(x-bpp) data set */ - and ecx, 0x0000003f /* calc bytes over mult of 64 */ -dsub8lp: - movq mm0, [edi+ebx] /* Load Sub(x) for 1st 8 bytes */ - paddb mm0, mm7 - movq mm1, [edi+ebx+8] /* Load Sub(x) for 2nd 8 bytes */ - movq [edi+ebx], mm0 /* Write Raw(x) for 1st 8 bytes */ - /* Now mm0 will be used as Raw(x-bpp) for */ - /* the 2nd group of 8 bytes. This will be */ - /* repeated for each group of 8 bytes with */ - /* the 8th group being used as the Raw(x-bpp) */ - /* for the 1st group of the next loop. */ - paddb mm1, mm0 - movq mm2, [edi+ebx+16] /* Load Sub(x) for 3rd 8 bytes */ - movq [edi+ebx+8], mm1 /* Write Raw(x) for 2nd 8 bytes */ - paddb mm2, mm1 - movq mm3, [edi+ebx+24] /* Load Sub(x) for 4th 8 bytes */ - movq [edi+ebx+16], mm2 /* Write Raw(x) for 3rd 8 bytes */ - paddb mm3, mm2 - movq mm4, [edi+ebx+32] /* Load Sub(x) for 5th 8 bytes */ - movq [edi+ebx+24], mm3 /* Write Raw(x) for 4th 8 bytes */ - paddb mm4, mm3 - movq mm5, [edi+ebx+40] /* Load Sub(x) for 6th 8 bytes */ - movq [edi+ebx+32], mm4 /* Write Raw(x) for 5th 8 bytes */ - paddb mm5, mm4 - movq mm6, [edi+ebx+48] /* Load Sub(x) for 7th 8 bytes */ - movq [edi+ebx+40], mm5 /* Write Raw(x) for 6th 8 bytes */ - paddb mm6, mm5 - movq mm7, [edi+ebx+56] /* Load Sub(x) for 8th 8 bytes */ - movq [edi+ebx+48], mm6 /* Write Raw(x) for 7th 8 bytes */ - add ebx, 64 - paddb mm7, mm6 - cmp ebx, ecx - movq [edi+ebx-8], mm7 /* Write Raw(x) for 8th 8 bytes */ - jb dsub8lp - cmp ebx, MMXLength - jnb dsub8lt8 -dsub8lpA: - movq mm0, [edi+ebx] - add ebx, 8 - paddb mm0, mm7 - cmp ebx, MMXLength - movq [edi+ebx-8], mm0 /* use -8 to offset early add to ebx */ - movq mm7, mm0 /* Move calculated Raw(x) data to mm1 to */ - /* be the new Raw(x-bpp) for the next loop */ - jb dsub8lpA -dsub8lt8: - } /* end _asm block */ - } - break; - - default: /* bpp greater than 8 bytes */ - { - _asm { - mov ebx, diff - mov edi, row - mov esi, edi /* lp = row */ - add edi, bpp /* rp = row + bpp */ -dsubAlp: - movq mm0, [edi+ebx] - movq mm1, [esi+ebx] - add ebx, 8 - paddb mm0, mm1 - cmp ebx, MMXLength - movq [edi+ebx-8], mm0 /* mov does not affect flags; -8 to offset */ - /* add ebx */ - jb dsubAlp - } /* end _asm block */ - } - break; - - } /* end switch ( bpp ) */ - - _asm { - mov ebx, MMXLength - mov edi, row - cmp ebx, FullLength - jnb dsubend - mov esi, edi /* lp = row */ - xor eax, eax - add edi, bpp /* rp = row + bpp */ -dsublp2: - mov al, [esi+ebx] - add [edi+ebx], al - inc ebx - cmp ebx, FullLength - jb dsublp2 -dsubend: - emms /* End MMX instructions; prep for possible FP instrs. */ - } /* end _asm block */ -} - -/* Optimized code for PNG Up filter decoder */ -void /* PRIVATE */ -png_read_filter_row_mmx_up(png_row_infop row_info, png_bytep row, - png_bytep prev_row) -{ - png_uint_32 len; - len = row_info->rowbytes; /* # of bytes to filter */ - _asm { - mov edi, row - /* get # of bytes to alignment */ - mov ecx, edi - xor ebx, ebx - add ecx, 0x7 - xor eax, eax - and ecx, 0xfffffff8 - mov esi, prev_row - sub ecx, edi - jz dupgo - /* fix alignment */ -duplp1: - mov al, [edi+ebx] - add al, [esi+ebx] - inc ebx - cmp ebx, ecx - mov [edi + ebx-1], al /* mov does not affect flags; -1 to offset inc ebx */ - jb duplp1 -dupgo: - mov ecx, len - mov edx, ecx - sub edx, ebx /* subtract alignment fix */ - and edx, 0x0000003f /* calc bytes over mult of 64 */ - sub ecx, edx /* drop over bytes from length */ - /* Unrolled loop - use all MMX registers and interleave to reduce */ - /* number of branch instructions (loops) and reduce partial stalls */ -duploop: - movq mm1, [esi+ebx] - movq mm0, [edi+ebx] - movq mm3, [esi+ebx+8] - paddb mm0, mm1 - movq mm2, [edi+ebx+8] - movq [edi+ebx], mm0 - paddb mm2, mm3 - movq mm5, [esi+ebx+16] - movq [edi+ebx+8], mm2 - movq mm4, [edi+ebx+16] - movq mm7, [esi+ebx+24] - paddb mm4, mm5 - movq mm6, [edi+ebx+24] - movq [edi+ebx+16], mm4 - paddb mm6, mm7 - movq mm1, [esi+ebx+32] - movq [edi+ebx+24], mm6 - movq mm0, [edi+ebx+32] - movq mm3, [esi+ebx+40] - paddb mm0, mm1 - movq mm2, [edi+ebx+40] - movq [edi+ebx+32], mm0 - paddb mm2, mm3 - movq mm5, [esi+ebx+48] - movq [edi+ebx+40], mm2 - movq mm4, [edi+ebx+48] - movq mm7, [esi+ebx+56] - paddb mm4, mm5 - movq mm6, [edi+ebx+56] - movq [edi+ebx+48], mm4 - add ebx, 64 - paddb mm6, mm7 - cmp ebx, ecx - movq [edi+ebx-8], mm6 /* (+56)movq does not affect flags; */ - /* -8 to offset add ebx */ - jb duploop - - cmp edx, 0 /* Test for bytes over mult of 64 */ - jz dupend - - - /* 2 lines added by lcreeve@netins.net */ - /* (mail 11 Jul 98 in png-implement list) */ - cmp edx, 8 /*test for less than 8 bytes */ - jb duplt8 - - - add ecx, edx - and edx, 0x00000007 /* calc bytes over mult of 8 */ - sub ecx, edx /* drop over bytes from length */ - jz duplt8 - /* Loop using MMX registers mm0 & mm1 to update 8 bytes simultaneously */ -duplpA: - movq mm1, [esi+ebx] - movq mm0, [edi+ebx] - add ebx, 8 - paddb mm0, mm1 - cmp ebx, ecx - movq [edi+ebx-8], mm0 /* movq does not affect flags; -8 to offset add ebx */ - jb duplpA - cmp edx, 0 /* Test for bytes over mult of 8 */ - jz dupend -duplt8: - xor eax, eax - add ecx, edx /* move over byte count into counter */ - /* Loop using x86 registers to update remaining bytes */ -duplp2: - mov al, [edi + ebx] - add al, [esi + ebx] - inc ebx - cmp ebx, ecx - mov [edi + ebx-1], al /* mov does not affect flags; -1 to offset inc ebx */ - jb duplp2 -dupend: - /* Conversion of filtered row completed */ - emms /* End MMX instructions; prep for possible FP instrs. */ - } /* end _asm block */ -} - - -/* Optimized png_read_filter_row routines */ -void /* PRIVATE */ -png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep - row, png_bytep prev_row, int filter) -{ -#ifdef PNG_DEBUG - char filnm[10]; -#endif - - if (mmx_supported == 2) { -#if !defined(PNG_1_0_X) - /* this should have happened in png_init_mmx_flags() already */ - png_warning(png_ptr, "asm_flags may not have been initialized"); -#endif - png_mmx_support(); - } - -#ifdef PNG_DEBUG - png_debug(1, "in png_read_filter_row\n"); - switch (filter) - { - case 0: sprintf(filnm, "none"); - break; -#if !defined(PNG_1_0_X) - case 1: sprintf(filnm, "sub-%s", - (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_SUB)? "MMX" : "x86"); - break; - case 2: sprintf(filnm, "up-%s", - (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_UP)? "MMX" : "x86"); - break; - case 3: sprintf(filnm, "avg-%s", - (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_AVG)? "MMX" : "x86"); - break; - case 4: sprintf(filnm, "Paeth-%s", - (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_PAETH)? "MMX":"x86"); - break; -#else - case 1: sprintf(filnm, "sub"); - break; - case 2: sprintf(filnm, "up"); - break; - case 3: sprintf(filnm, "avg"); - break; - case 4: sprintf(filnm, "Paeth"); - break; -#endif - default: sprintf(filnm, "unknw"); - break; - } - png_debug2(0,"row=%5d, %s, ", png_ptr->row_number, filnm); - png_debug2(0, "pd=%2d, b=%d, ", (int)row_info->pixel_depth, - (int)((row_info->pixel_depth + 7) >> 3)); - png_debug1(0,"len=%8d, ", row_info->rowbytes); -#endif /* PNG_DEBUG */ - - switch (filter) - { - case PNG_FILTER_VALUE_NONE: - break; - - case PNG_FILTER_VALUE_SUB: - { -#if !defined(PNG_1_0_X) - if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_SUB) && - (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && - (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) -#else - if (mmx_supported) -#endif - { - png_read_filter_row_mmx_sub(row_info, row); - } - else - { - png_uint_32 i; - png_uint_32 istop = row_info->rowbytes; - png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; - png_bytep rp = row + bpp; - png_bytep lp = row; - - for (i = bpp; i < istop; i++) - { - *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff); - rp++; - } - } - break; - } - - case PNG_FILTER_VALUE_UP: - { -#if !defined(PNG_1_0_X) - if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_UP) && - (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && - (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) -#else - if (mmx_supported) -#endif - { - png_read_filter_row_mmx_up(row_info, row, prev_row); - } - else - { - png_uint_32 i; - png_uint_32 istop = row_info->rowbytes; - png_bytep rp = row; - png_bytep pp = prev_row; - - for (i = 0; i < istop; ++i) - { - *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); - rp++; - } - } - break; - } - - case PNG_FILTER_VALUE_AVG: - { -#if !defined(PNG_1_0_X) - if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_AVG) && - (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && - (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) -#else - if (mmx_supported) -#endif - { - png_read_filter_row_mmx_avg(row_info, row, prev_row); - } - else - { - png_uint_32 i; - png_bytep rp = row; - png_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; - - for (i = 0; i < bpp; i++) - { - *rp = (png_byte)(((int)(*rp) + - ((int)(*pp++) >> 1)) & 0xff); - rp++; - } - - for (i = 0; i < istop; i++) - { - *rp = (png_byte)(((int)(*rp) + - ((int)(*pp++ + *lp++) >> 1)) & 0xff); - rp++; - } - } - break; - } - - case PNG_FILTER_VALUE_PAETH: - { -#if !defined(PNG_1_0_X) - if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_PAETH) && - (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) && - (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold)) -#else - if (mmx_supported) -#endif - { - png_read_filter_row_mmx_paeth(row_info, row, prev_row); - } - else - { - png_uint_32 i; - png_bytep rp = row; - png_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; - - for (i = 0; i < bpp; i++) - { - *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); - rp++; - } - - for (i = 0; i < istop; i++) /* use leftover rp,pp */ - { - int a, b, c, pa, pb, pc, p; - - a = *lp++; - b = *pp++; - c = *cp++; - - p = b - c; - pc = a - c; - -#ifdef PNG_USE_ABS - pa = abs(p); - pb = abs(pc); - pc = abs(p + pc); -#else - pa = p < 0 ? -p : p; - pb = pc < 0 ? -pc : pc; - pc = (p + pc) < 0 ? -(p + pc) : p + pc; -#endif - - /* - if (pa <= pb && pa <= pc) - p = a; - else if (pb <= pc) - p = b; - else - p = c; - */ - - p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c; - - *rp = (png_byte)(((int)(*rp) + p) & 0xff); - rp++; - } - } - break; - } - - default: - png_warning(png_ptr, "Ignoring bad row filter type"); - *row=0; - break; - } -} - -#endif /* PNG_ASSEMBLER_CODE_SUPPORTED && PNG_USE_PNGVCRD */ diff --git a/3rdparty/wxWidgets/src/png/pngwio.c b/3rdparty/wxWidgets/src/png/pngwio.c index adc57b3091..f77b2dbd96 100644 --- a/3rdparty/wxWidgets/src/png/pngwio.c +++ b/3rdparty/wxWidgets/src/png/pngwio.c @@ -1,12 +1,15 @@ /* pngwio.c - functions for data output * - * libpng 1.2.7 - September 12, 2004 - * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2004 Glenn Randers-Pehrson + * Last changed in libpng 1.2.37 [June 4, 2009] + * Copyright (c) 1998-2009 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. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + * * This file provides a location for all output. Users who need * special handling are expected to write functions that have the same * arguments as these and perform similar functions, but that possibly @@ -20,10 +23,11 @@ #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 - buffering if you are using unbuffered writes. This should never be asked - to write more than 64K on a 16 bit machine. */ + * writes to a file pointer. Note that this routine sometimes gets called + * with very small lengths, so you should implement some kind of simple + * buffering if you are using unbuffered writes. This should never be asked + * to write more than 64K on a 16 bit machine. + */ void /* PRIVATE */ png_write_data(png_structp png_ptr, png_bytep data, png_size_t length) @@ -36,15 +40,18 @@ png_write_data(png_structp png_ptr, png_bytep data, png_size_t length) #if !defined(PNG_NO_STDIO) /* This is the function that does the actual writing of data. If you are - not writing to a standard C stream, you should create a replacement - write_data function and use it at run time with png_set_write_fn(), rather - than changing the library. */ + * not writing to a standard C stream, you should create a replacement + * write_data function and use it at run time with png_set_write_fn(), rather + * than changing the library. + */ #ifndef USE_FAR_KEYWORD void PNGAPI png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) { png_uint_32 check; + if (png_ptr == NULL) + return; #if defined(_WIN32_WCE) if ( !WriteFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) ) check = 0; @@ -55,10 +62,10 @@ png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) png_error(png_ptr, "Write Error"); } #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. -*/ +/* 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. + */ #define NEAR_BUF_SIZE 1024 #define MIN(a,b) (a <= b ? a : b) @@ -70,6 +77,8 @@ png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */ png_FILE_p io_ptr; + 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); @@ -91,7 +100,7 @@ png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) do { written = MIN(NEAR_BUF_SIZE, remaining); - png_memcpy(buf, data, written); /* copy far buffer to near buffer */ + png_memcpy(buf, data, written); /* Copy far buffer to near buffer */ #if defined(_WIN32_WCE) if ( !WriteFile(io_ptr, buf, written, &err, NULL) ) err = 0; @@ -100,8 +109,10 @@ png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) #endif if (err != written) break; + else check += err; + data += written; remaining -= written; } @@ -115,8 +126,9 @@ png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length) #endif /* This function is called to output any data pending writing (normally - to disk). After png_flush is called, there should be no data pending - writing in any buffers. */ + * to disk). After png_flush is called, there should be no data pending + * writing in any buffers. + */ #if defined(PNG_WRITE_FLUSH_SUPPORTED) void /* PRIVATE */ png_flush(png_structp png_ptr) @@ -131,45 +143,59 @@ png_default_flush(png_structp png_ptr) { #if !defined(_WIN32_WCE) png_FILE_p io_ptr; +#endif + if (png_ptr == NULL) + return; +#if !defined(_WIN32_WCE) io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr)); - if (io_ptr != NULL) - fflush(io_ptr); + fflush(io_ptr); #endif } #endif #endif /* This function allows the application to supply new output functions for - libpng if standard C streams aren't being used. - - This function takes as its arguments: - png_ptr - pointer to a png output data structure - io_ptr - pointer to user supplied structure containing info about - the output functions. May be NULL. - write_data_fn - pointer to a new output function that takes as its - arguments a pointer to a png_struct, a pointer to - data to be written, and a 32-bit unsigned int that is - the number of bytes to be written. The new write - function should call png_error(png_ptr, "Error msg") - to exit and output any fatal error messages. - flush_data_fn - pointer to a new flush function that takes as its - arguments a pointer to a png_struct. After a call to - the flush function, there should be no data in any buffers - or pending transmission. If the output method doesn't do - any buffering of ouput, a function prototype must still be - supplied although it doesn't have to do anything. If - PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile - time, output_flush_fn will be ignored, although it must be - supplied for compatibility. */ + * libpng if standard C streams aren't being used. + * + * This function takes as its arguments: + * png_ptr - pointer to a png output data structure + * io_ptr - pointer to user supplied structure containing info about + * the output functions. May be NULL. + * write_data_fn - pointer to a new output function that takes as its + * arguments a pointer to a png_struct, a pointer to + * data to be written, and a 32-bit unsigned int that is + * the number of bytes to be written. The new write + * function should call png_error(png_ptr, "Error msg") + * to exit and output any fatal error messages. May be + * NULL, in which case libpng's default function will + * be used. + * flush_data_fn - pointer to a new flush function that takes as its + * arguments a pointer to a png_struct. After a call to + * the flush function, there should be no data in any buffers + * or pending transmission. If the output method doesn't do + * any buffering of ouput, a function prototype must still be + * supplied although it doesn't have to do anything. If + * PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile + * time, output_flush_fn will be ignored, although it must be + * supplied for compatibility. May be NULL, in which case + * libpng's default function will be used, if + * PNG_WRITE_FLUSH_SUPPORTED is defined. This is not + * a good idea if io_ptr does not point to a standard + * *FILE structure. + */ 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) { + if (png_ptr == NULL) + return; + png_ptr->io_ptr = io_ptr; #if !defined(PNG_NO_STDIO) if (write_data_fn != NULL) png_ptr->write_data_fn = write_data_fn; + else png_ptr->write_data_fn = png_default_write_data; #else @@ -180,6 +206,7 @@ png_set_write_fn(png_structp png_ptr, png_voidp io_ptr, #if !defined(PNG_NO_STDIO) if (output_flush_fn != NULL) png_ptr->output_flush_fn = output_flush_fn; + else png_ptr->output_flush_fn = png_default_flush; #else @@ -200,27 +227,31 @@ png_set_write_fn(png_structp png_ptr, png_voidp io_ptr, #if defined(USE_FAR_KEYWORD) #if defined(_MSC_VER) -void *png_far_to_near(png_structp png_ptr,png_voidp ptr, int check) +void *png_far_to_near(png_structp png_ptr, png_voidp ptr, int check) { void *near_ptr; void FAR *far_ptr; FP_OFF(near_ptr) = FP_OFF(ptr); far_ptr = (void FAR *)near_ptr; - if(check != 0) - if(FP_SEG(ptr) != FP_SEG(far_ptr)) - png_error(png_ptr,"segment lost in conversion"); + + if (check != 0) + if (FP_SEG(ptr) != FP_SEG(far_ptr)) + png_error(png_ptr, "segment lost in conversion"); + return(near_ptr); } # else -void *png_far_to_near(png_structp png_ptr,png_voidp ptr, int check) +void *png_far_to_near(png_structp png_ptr, png_voidp ptr, int check) { void *near_ptr; void FAR *far_ptr; near_ptr = (void FAR *)ptr; far_ptr = (void FAR *)near_ptr; - if(check != 0) - if(far_ptr != ptr) - png_error(png_ptr,"segment lost in conversion"); + + if (check != 0) + if (far_ptr != ptr) + png_error(png_ptr, "segment lost in conversion"); + return(near_ptr); } # endif diff --git a/3rdparty/wxWidgets/src/png/pngwrite.c b/3rdparty/wxWidgets/src/png/pngwrite.c index f422173bf2..0987612d1f 100644 --- a/3rdparty/wxWidgets/src/png/pngwrite.c +++ b/3rdparty/wxWidgets/src/png/pngwrite.c @@ -1,14 +1,17 @@ /* pngwrite.c - general routines to write a PNG file * - * libpng 1.2.7 - September 12, 2004 - * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2004 Glenn Randers-Pehrson + * Last changed in libpng 1.2.37 [June 4, 2009] + * Copyright (c) 1998-2009 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. + * For conditions of distribution and use, see the disclaimer + * and license in png.h */ -/* get internal access to png.h */ +/* Get internal access to png.h */ #define PNG_INTERNAL #include "png.h" #ifdef PNG_WRITE_SUPPORTED @@ -25,18 +28,20 @@ void PNGAPI png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr) { - png_debug(1, "in png_write_info_before_PLTE\n"); + png_debug(1, "in png_write_info_before_PLTE"); + if (png_ptr == NULL || info_ptr == NULL) + return; if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE)) { - png_write_sig(png_ptr); /* write PNG signature */ + png_write_sig(png_ptr); /* Write PNG signature */ #if defined(PNG_MNG_FEATURES_SUPPORTED) - if((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)&&(png_ptr->mng_features_permitted)) + if ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)&&(png_ptr->mng_features_permitted)) { - png_warning(png_ptr,"MNG features are not allowed in a PNG datastream\n"); + png_warning(png_ptr, "MNG features are not allowed in a PNG datastream"); png_ptr->mng_features_permitted=0; } #endif - /* write IHDR information. */ + /* 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, @@ -45,8 +50,9 @@ png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr) #else 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. */ + /* The rest of these check to see if the valid field has the appropriate + * flag set, and if it does, writes the chunk. + */ #if defined(PNG_WRITE_gAMA_SUPPORTED) if (info_ptr->valid & PNG_INFO_gAMA) { @@ -95,14 +101,14 @@ png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr) #if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) if (info_ptr->unknown_chunks_num) { - png_unknown_chunk *up; + png_unknown_chunk *up; - png_debug(5, "writing extra chunks\n"); + png_debug(5, "writing extra chunks"); - for (up = info_ptr->unknown_chunks; - up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; - up++) - { + for (up = info_ptr->unknown_chunks; + up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; + up++) + { int keep=png_handle_as_unknown(png_ptr, up->name); if (keep != PNG_HANDLE_CHUNK_NEVER && up->location && !(up->location & PNG_HAVE_PLTE) && @@ -110,9 +116,11 @@ png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr) ((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); } - } + } } #endif png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE; @@ -126,7 +134,10 @@ png_write_info(png_structp png_ptr, png_infop info_ptr) int i; #endif - png_debug(1, "in png_write_info\n"); + png_debug(1, "in png_write_info"); + + if (png_ptr == NULL || info_ptr == NULL) + return; png_write_info_before_PLTE(png_ptr, info_ptr); @@ -134,24 +145,24 @@ png_write_info(png_structp png_ptr, png_infop info_ptr) png_write_PLTE(png_ptr, info_ptr->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\n"); + png_error(png_ptr, "Valid palette required for paletted images"); #if defined(PNG_WRITE_tRNS_SUPPORTED) if (info_ptr->valid & PNG_INFO_tRNS) - { + { #if defined(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) - { - int j; - for (j=0; j<(int)info_ptr->num_trans; j++) - info_ptr->trans[j] = (png_byte)(255 - info_ptr->trans[j]); - } + /* Invert the alpha channel (in tRNS) */ + if ((png_ptr->transformations & PNG_INVERT_ALPHA) && + info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) + { + int j; + for (j=0; j<(int)info_ptr->num_trans; j++) + info_ptr->trans[j] = (png_byte)(255 - info_ptr->trans[j]); + } #endif png_write_tRNS(png_ptr, info_ptr->trans, &(info_ptr->trans_values), info_ptr->num_trans, info_ptr->color_type); - } + } #endif #if defined(PNG_WRITE_bKGD_SUPPORTED) if (info_ptr->valid & PNG_INFO_bKGD) @@ -172,49 +183,56 @@ png_write_info(png_structp png_ptr, png_infop info_ptr) info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams, info_ptr->pcal_units, info_ptr->pcal_params); #endif -#if defined(PNG_WRITE_sCAL_SUPPORTED) + +#if defined(PNG_sCAL_SUPPORTED) if (info_ptr->valid & PNG_INFO_sCAL) +#if defined(PNG_WRITE_sCAL_SUPPORTED) #if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO) png_write_sCAL(png_ptr, (int)info_ptr->scal_unit, info_ptr->scal_pixel_width, info_ptr->scal_pixel_height); -#else +#else /* !FLOATING_POINT */ #ifdef PNG_FIXED_POINT_SUPPORTED png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit, info_ptr->scal_s_width, info_ptr->scal_s_height); -#else +#endif /* FIXED_POINT */ +#endif /* FLOATING_POINT */ +#else /* !WRITE_sCAL */ png_warning(png_ptr, - "png_write_sCAL not supported; sCAL chunk not written.\n"); -#endif -#endif -#endif + "png_write_sCAL not supported; sCAL chunk not written."); +#endif /* WRITE_sCAL */ +#endif /* sCAL */ + #if defined(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); -#endif +#endif /* pHYs */ + #if defined(PNG_WRITE_tIME_SUPPORTED) if (info_ptr->valid & PNG_INFO_tIME) { png_write_tIME(png_ptr, &(info_ptr->mod_time)); png_ptr->mode |= PNG_WROTE_tIME; } -#endif +#endif /* tIME */ + #if defined(PNG_WRITE_sPLT_SUPPORTED) if (info_ptr->valid & PNG_INFO_sPLT) for (i = 0; i < (int)info_ptr->splt_palettes_num; i++) png_write_sPLT(png_ptr, info_ptr->splt_palettes + i); -#endif +#endif /* sPLT */ + #if defined(PNG_WRITE_TEXT_SUPPORTED) /* Check to see if we need to write text chunks */ for (i = 0; i < info_ptr->num_text; i++) { - png_debug2(2, "Writing header text chunk %d, type %d\n", i, + png_debug2(2, "Writing header text chunk %d, type %d", i, info_ptr->text[i].compression); - /* an internationalized chunk? */ + /* An internationalized chunk? */ if (info_ptr->text[i].compression > 0) { #if defined(PNG_WRITE_iTXt_SUPPORTED) - /* write international chunk */ + /* Write international chunk */ png_write_iTXt(png_ptr, info_ptr->text[i].compression, info_ptr->text[i].key, @@ -222,7 +240,7 @@ png_write_info(png_structp png_ptr, png_infop info_ptr) info_ptr->text[i].lang_key, info_ptr->text[i].text); #else - png_warning(png_ptr, "Unable to write international text\n"); + 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; @@ -231,12 +249,12 @@ png_write_info(png_structp png_ptr, png_infop info_ptr) else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_zTXt) { #if defined(PNG_WRITE_zTXt_SUPPORTED) - /* write compressed chunk */ + /* Write compressed chunk */ png_write_zTXt(png_ptr, info_ptr->text[i].key, info_ptr->text[i].text, 0, info_ptr->text[i].compression); #else - png_warning(png_ptr, "Unable to write compressed text\n"); + 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; @@ -244,24 +262,26 @@ png_write_info(png_structp png_ptr, png_infop info_ptr) else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) { #if defined(PNG_WRITE_tEXt_SUPPORTED) - /* write uncompressed chunk */ + /* Write uncompressed chunk */ png_write_tEXt(png_ptr, info_ptr->text[i].key, info_ptr->text[i].text, 0); -#else - png_warning(png_ptr, "Unable to write uncompressed text\n"); -#endif /* Mark this chunk as written */ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR; +#else + /* Can't get here */ + png_warning(png_ptr, "Unable to write uncompressed text"); +#endif } } -#endif +#endif /* tEXt */ + #if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) if (info_ptr->unknown_chunks_num) { png_unknown_chunk *up; - png_debug(5, "writing extra chunks\n"); + png_debug(5, "writing extra chunks"); for (up = info_ptr->unknown_chunks; up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; @@ -289,33 +309,35 @@ png_write_info(png_structp png_ptr, png_infop info_ptr) void PNGAPI png_write_end(png_structp png_ptr, png_infop info_ptr) { - png_debug(1, "in png_write_end\n"); + png_debug(1, "in png_write_end"); + if (png_ptr == NULL) + return; if (!(png_ptr->mode & PNG_HAVE_IDAT)) png_error(png_ptr, "No IDATs written into file"); - /* see if user wants us to write information chunks */ + /* See if user wants us to write information chunks */ if (info_ptr != NULL) { #if defined(PNG_WRITE_TEXT_SUPPORTED) - int i; /* local index variable */ + int i; /* Local index variable */ #endif #if defined(PNG_WRITE_tIME_SUPPORTED) - /* check to see if user has supplied a time chunk */ + /* Check to see if user has supplied a time chunk */ if ((info_ptr->valid & PNG_INFO_tIME) && !(png_ptr->mode & PNG_WROTE_tIME)) png_write_tIME(png_ptr, &(info_ptr->mod_time)); #endif #if defined(PNG_WRITE_TEXT_SUPPORTED) - /* loop through comment chunks */ + /* Loop through comment chunks */ for (i = 0; i < info_ptr->num_text; i++) { - png_debug2(2, "Writing trailer text chunk %d, type %d\n", i, + png_debug2(2, "Writing trailer text chunk %d, type %d", i, info_ptr->text[i].compression); - /* an internationalized chunk? */ + /* An internationalized chunk? */ if (info_ptr->text[i].compression > 0) { #if defined(PNG_WRITE_iTXt_SUPPORTED) - /* write international chunk */ + /* Write international chunk */ png_write_iTXt(png_ptr, info_ptr->text[i].compression, info_ptr->text[i].key, @@ -323,7 +345,7 @@ png_write_end(png_structp png_ptr, png_infop info_ptr) info_ptr->text[i].lang_key, info_ptr->text[i].text); #else - png_warning(png_ptr, "Unable to write international text\n"); + 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; @@ -331,12 +353,12 @@ png_write_end(png_structp png_ptr, png_infop info_ptr) else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt) { #if defined(PNG_WRITE_zTXt_SUPPORTED) - /* write compressed chunk */ + /* Write compressed chunk */ png_write_zTXt(png_ptr, info_ptr->text[i].key, info_ptr->text[i].text, 0, info_ptr->text[i].compression); #else - png_warning(png_ptr, "Unable to write compressed text\n"); + 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; @@ -344,11 +366,11 @@ png_write_end(png_structp png_ptr, png_infop info_ptr) else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE) { #if defined(PNG_WRITE_tEXt_SUPPORTED) - /* write uncompressed chunk */ + /* Write uncompressed chunk */ png_write_tEXt(png_ptr, info_ptr->text[i].key, info_ptr->text[i].text, 0); #else - png_warning(png_ptr, "Unable to write uncompressed text\n"); + png_warning(png_ptr, "Unable to write uncompressed text"); #endif /* Mark this chunk as written */ @@ -361,7 +383,7 @@ png_write_end(png_structp png_ptr, png_infop info_ptr) { png_unknown_chunk *up; - png_debug(5, "writing extra chunks\n"); + png_debug(5, "writing extra chunks"); for (up = info_ptr->unknown_chunks; up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num; @@ -382,11 +404,18 @@ png_write_end(png_structp png_ptr, png_infop info_ptr) png_ptr->mode |= PNG_AFTER_IDAT; - /* write end of PNG file */ + /* Write end of PNG file */ png_write_IEND(png_ptr); -#if 0 -/* This flush, added in libpng-1.0.8, causes some applications to crash - because they do not set png_ptr->output_flush_fn */ + /* This flush, added in libpng-1.0.8, removed from libpng-1.0.9beta03, + * and restored again in libpng-1.2.30, may cause some applications that + * do not set png_ptr->output_flush_fn to crash. If your application + * experiences a problem, please try building libpng with + * PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED defined, and report the event to + * png-mng-implement at lists.sf.net . This kludge will be removed + * from libpng-1.4.0. + */ +#if defined(PNG_WRITE_FLUSH_SUPPORTED) && \ + defined(PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED) png_flush(png_ptr); #endif } @@ -397,7 +426,7 @@ png_write_end(png_structp png_ptr, png_infop info_ptr) void PNGAPI png_convert_from_struct_tm(png_timep ptime, struct tm FAR * ttime) { - png_debug(1, "in png_convert_from_struct_tm\n"); + png_debug(1, "in png_convert_from_struct_tm"); ptime->year = (png_uint_16)(1900 + ttime->tm_year); ptime->month = (png_byte)(ttime->tm_mon + 1); ptime->day = (png_byte)ttime->tm_mday; @@ -411,7 +440,7 @@ png_convert_from_time_t(png_timep ptime, time_t ttime) { struct tm *tbuf; - png_debug(1, "in png_convert_from_time_t\n"); + png_debug(1, "in png_convert_from_time_t"); tbuf = gmtime(&ttime); png_convert_from_struct_tm(ptime, tbuf); } @@ -435,14 +464,17 @@ png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn) { #endif /* PNG_USER_MEM_SUPPORTED */ - png_structp png_ptr; +#ifdef PNG_SETJMP_SUPPORTED + volatile +#endif + png_structp png_ptr; #ifdef PNG_SETJMP_SUPPORTED #ifdef USE_FAR_KEYWORD jmp_buf jmpbuf; #endif #endif int i; - png_debug(1, "in png_create_write_struct\n"); + png_debug(1, "in png_create_write_struct"); #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); @@ -452,13 +484,7 @@ png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, if (png_ptr == NULL) return (NULL); -#if !defined(PNG_1_0_X) -#ifdef PNG_ASSEMBLER_CODE_SUPPORTED - png_init_mmx_flags(png_ptr); /* 1.2.0 addition */ -#endif -#endif /* PNG_1_0_X */ - - /* added at libpng-1.2.6 */ + /* Added at libpng-1.2.6 */ #ifdef PNG_SET_USER_LIMITS_SUPPORTED png_ptr->user_width_max=PNG_USER_WIDTH_MAX; png_ptr->user_height_max=PNG_USER_HEIGHT_MAX; @@ -472,12 +498,12 @@ png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, #endif { png_free(png_ptr, png_ptr->zbuf); - png_ptr->zbuf=NULL; + png_ptr->zbuf=NULL; png_destroy_struct(png_ptr); return (NULL); } #ifdef USE_FAR_KEYWORD - png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf)); + png_memcpy(png_ptr->jmpbuf, jmpbuf, png_sizeof(jmp_buf)); #endif #endif @@ -486,12 +512,15 @@ png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, #endif /* PNG_USER_MEM_SUPPORTED */ png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn); - i=0; - do + if (user_png_ver) { - if(user_png_ver[i] != png_libpng_ver[i]) - png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; - } while (png_libpng_ver[i++]); + i=0; + do + { + if (user_png_ver[i] != png_libpng_ver[i]) + png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH; + } while (png_libpng_ver[i++]); + } if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH) { @@ -508,11 +537,13 @@ png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, char msg[80]; if (user_png_ver) { - sprintf(msg, "Application was compiled with png.h from libpng-%.20s", + png_snprintf(msg, 80, + "Application was compiled with png.h from libpng-%.20s", user_png_ver); png_warning(png_ptr, msg); } - sprintf(msg, "Application is running with png.c from libpng-%.20s", + png_snprintf(msg, 80, + "Application is running with png.c from libpng-%.20s", png_libpng_ver); png_warning(png_ptr, msg); #endif @@ -524,7 +555,7 @@ png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, } } - /* initialize zbuf - compression buffer */ + /* Initialize zbuf - compression buffer */ png_ptr->zbuf_size = PNG_ZBUF_SIZE; png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, (png_uint_32)png_ptr->zbuf_size); @@ -544,7 +575,7 @@ png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, #ifdef USE_FAR_KEYWORD if (setjmp(jmpbuf)) PNG_ABORT(); - png_memcpy(png_ptr->jmpbuf,jmpbuf,png_sizeof(jmp_buf)); + png_memcpy(png_ptr->jmpbuf, jmpbuf, png_sizeof(jmp_buf)); #else if (setjmp(png_ptr->jmpbuf)) PNG_ABORT(); @@ -554,6 +585,8 @@ png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, } /* Initialize png_ptr structure, and allocate any memory needed */ +#if defined(PNG_1_0_X) || defined(PNG_1_2_X) +/* Deprecated. */ #undef png_write_init void PNGAPI png_write_init(png_structp png_ptr) @@ -567,24 +600,27 @@ png_write_init_2(png_structp png_ptr, png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t png_info_size) { /* We only come here via pre-1.0.12-compiled applications */ + if (png_ptr == NULL) return; #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) - if(png_sizeof(png_struct) > png_struct_size || + if (png_sizeof(png_struct) > png_struct_size || png_sizeof(png_info) > png_info_size) { char msg[80]; png_ptr->warning_fn=NULL; if (user_png_ver) { - sprintf(msg, "Application was compiled with png.h from libpng-%.20s", + png_snprintf(msg, 80, + "Application was compiled with png.h from libpng-%.20s", user_png_ver); png_warning(png_ptr, msg); } - sprintf(msg, "Application is running with png.c from libpng-%.20s", + png_snprintf(msg, 80, + "Application is running with png.c from libpng-%.20s", png_libpng_ver); png_warning(png_ptr, msg); } #endif - if(png_sizeof(png_struct) > png_struct_size) + if (png_sizeof(png_struct) > png_struct_size) { png_ptr->error_fn=NULL; #ifdef PNG_ERROR_NUMBERS_SUPPORTED @@ -593,7 +629,7 @@ png_write_init_2(png_structp png_ptr, png_const_charp user_png_ver, png_error(png_ptr, "The png struct allocated by the application for writing is too small."); } - if(png_sizeof(png_info) > png_info_size) + if (png_sizeof(png_info) > png_info_size) { png_ptr->error_fn=NULL; #ifdef PNG_ERROR_NUMBERS_SUPPORTED @@ -604,6 +640,7 @@ png_write_init_2(png_structp png_ptr, png_const_charp user_png_ver, } png_write_init_3(&png_ptr, user_png_ver, png_struct_size); } +#endif /* PNG_1_0_X || PNG_1_2_X */ void PNGAPI @@ -612,9 +649,14 @@ png_write_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver, { png_structp png_ptr=*ptr_ptr; #ifdef PNG_SETJMP_SUPPORTED - jmp_buf tmp_jmp; /* to save current jump buffer */ + jmp_buf tmp_jmp; /* To save current jump buffer */ #endif + int i = 0; + + if (png_ptr == NULL) + return; + do { if (user_png_ver[i] != png_libpng_ver[i]) @@ -624,17 +666,17 @@ png_write_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver, #else png_ptr->warning_fn=NULL; png_warning(png_ptr, - "Application uses deprecated png_write_init() and should be recompiled."); + "Application uses deprecated png_write_init() and should be recompiled."); break; #endif } } while (png_libpng_ver[i++]); - png_debug(1, "in png_write_init_3\n"); + png_debug(1, "in png_write_init_3"); #ifdef PNG_SETJMP_SUPPORTED - /* save jump buffer and error functions */ - png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf)); + /* Save jump buffer and error functions */ + png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof(jmp_buf)); #endif if (png_sizeof(png_struct) > png_struct_size) @@ -644,30 +686,24 @@ png_write_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver, *ptr_ptr = png_ptr; } - /* reset all variables to 0 */ - png_memset(png_ptr, 0, png_sizeof (png_struct)); + /* Reset all variables to 0 */ + png_memset(png_ptr, 0, png_sizeof(png_struct)); - /* added at libpng-1.2.6 */ + /* Added at libpng-1.2.6 */ #ifdef PNG_SET_USER_LIMITS_SUPPORTED png_ptr->user_width_max=PNG_USER_WIDTH_MAX; png_ptr->user_height_max=PNG_USER_HEIGHT_MAX; #endif -#if !defined(PNG_1_0_X) -#ifdef PNG_ASSEMBLER_CODE_SUPPORTED - png_init_mmx_flags(png_ptr); /* 1.2.0 addition */ -#endif -#endif /* PNG_1_0_X */ - #ifdef PNG_SETJMP_SUPPORTED - /* restore jump buffer */ - png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof (jmp_buf)); + /* Restore jump buffer */ + png_memcpy(png_ptr->jmpbuf, tmp_jmp, png_sizeof(jmp_buf)); #endif png_set_write_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL, png_flush_ptr_NULL); - /* initialize zbuf - compression buffer */ + /* Initialize zbuf - compression buffer */ png_ptr->zbuf_size = PNG_ZBUF_SIZE; png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, (png_uint_32)png_ptr->zbuf_size); @@ -687,11 +723,15 @@ void PNGAPI png_write_rows(png_structp png_ptr, png_bytepp row, png_uint_32 num_rows) { - png_uint_32 i; /* row counter */ - png_bytepp rp; /* row pointer */ + png_uint_32 i; /* Row counter */ + png_bytepp rp; /* Row pointer */ - png_debug(1, "in png_write_rows\n"); - /* loop through the rows */ + png_debug(1, "in png_write_rows"); + + if (png_ptr == NULL) + return; + + /* Loop through the rows */ for (i = 0, rp = row; i < num_rows; i++, rp++) { png_write_row(png_ptr, *rp); @@ -704,22 +744,26 @@ png_write_rows(png_structp png_ptr, png_bytepp row, void PNGAPI png_write_image(png_structp png_ptr, png_bytepp image) { - png_uint_32 i; /* row index */ - int pass, num_pass; /* pass variables */ - png_bytepp rp; /* points to current row */ + png_uint_32 i; /* Row index */ + int pass, num_pass; /* Pass variables */ + png_bytepp rp; /* Points to current row */ - png_debug(1, "in png_write_image\n"); + if (png_ptr == NULL) + return; + + png_debug(1, "in png_write_image"); #if defined(PNG_WRITE_INTERLACING_SUPPORTED) - /* intialize interlace handling. If image is not interlaced, - this will set pass to 1 */ + /* Initialize interlace handling. If image is not interlaced, + * this will set pass to 1 + */ num_pass = png_set_interlace_handling(png_ptr); #else num_pass = 1; #endif - /* loop through passes */ + /* Loop through passes */ for (pass = 0; pass < num_pass; pass++) { - /* loop through image */ + /* Loop through image */ for (i = 0, rp = image; i < png_ptr->height; i++, rp++) { png_write_row(png_ptr, *rp); @@ -727,55 +771,58 @@ png_write_image(png_structp png_ptr, png_bytepp image) } } -/* called by user to write a row of image data */ +/* Called by user to write a row of image data */ void PNGAPI png_write_row(png_structp png_ptr, png_bytep row) { - png_debug2(1, "in png_write_row (row %ld, pass %d)\n", + if (png_ptr == NULL) + return; + png_debug2(1, "in png_write_row (row %ld, pass %d)", png_ptr->row_number, png_ptr->pass); - /* initialize transformations and other stuff if first time */ + + /* Initialize transformations and other stuff if first time */ if (png_ptr->row_number == 0 && png_ptr->pass == 0) { - /* 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."); + /* 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."); - /* check for transforms that have been set but were defined out */ + /* 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."); + 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."); + if (png_ptr->transformations & PNG_FILLER) + png_warning(png_ptr, "PNG_WRITE_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_WRITE_PACKSWAP_SUPPORTED is not defined."); + if (png_ptr->transformations & PNG_PACKSWAP) + 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."); + 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."); + 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."); + 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."); + if (png_ptr->transformations & PNG_SWAP_BYTES) + png_warning(png_ptr, "PNG_WRITE_SWAP_SUPPORTED is not defined."); #endif png_write_start_row(png_ptr); } #if defined(PNG_WRITE_INTERLACING_SUPPORTED) - /* if interlaced and not interested in row, return */ + /* If interlaced and not interested in row, return */ if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) { switch (png_ptr->pass) @@ -833,7 +880,7 @@ png_write_row(png_structp png_ptr, png_bytep row) } #endif - /* set up row info for transformations */ + /* Set up row info for transformations */ png_ptr->row_info.color_type = png_ptr->color_type; png_ptr->row_info.width = png_ptr->usr_width; png_ptr->row_info.channels = png_ptr->usr_channels; @@ -844,25 +891,25 @@ png_write_row(png_structp png_ptr, png_bytep row) png_ptr->row_info.rowbytes = PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->row_info.width); - png_debug1(3, "row_info->color_type = %d\n", png_ptr->row_info.color_type); - png_debug1(3, "row_info->width = %lu\n", png_ptr->row_info.width); - png_debug1(3, "row_info->channels = %d\n", png_ptr->row_info.channels); - png_debug1(3, "row_info->bit_depth = %d\n", png_ptr->row_info.bit_depth); - png_debug1(3, "row_info->pixel_depth = %d\n", png_ptr->row_info.pixel_depth); - png_debug1(3, "row_info->rowbytes = %lu\n", png_ptr->row_info.rowbytes); + 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->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); /* Copy user's row into buffer, leaving room for filter byte. */ png_memcpy_check(png_ptr, png_ptr->row_buf + 1, row, png_ptr->row_info.rowbytes); #if defined(PNG_WRITE_INTERLACING_SUPPORTED) - /* handle interlacing */ + /* Handle interlacing */ if (png_ptr->interlaced && png_ptr->pass < 6 && (png_ptr->transformations & PNG_INTERLACE)) { png_do_write_interlace(&(png_ptr->row_info), png_ptr->row_buf + 1, png_ptr->pass); - /* this should always get caught above, but still ... */ + /* This should always get caught above, but still ... */ if (!(png_ptr->row_info.width)) { png_write_finish_row(png_ptr); @@ -871,7 +918,7 @@ png_write_row(png_structp png_ptr, png_bytep row) } #endif - /* handle other transformations */ + /* Handle other transformations */ if (png_ptr->transformations) png_do_write_transformations(png_ptr); @@ -885,7 +932,7 @@ png_write_row(png_structp png_ptr, png_bytep row) * 4. The filter_method is 64 and * 5. The color_type is RGB or RGBA */ - if((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && + if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING)) { /* Intrapixel differencing */ @@ -905,30 +952,34 @@ png_write_row(png_structp png_ptr, png_bytep row) void PNGAPI png_set_flush(png_structp png_ptr, int nrows) { - png_debug(1, "in png_set_flush\n"); + png_debug(1, "in png_set_flush"); + if (png_ptr == NULL) + return; png_ptr->flush_dist = (nrows < 0 ? 0 : nrows); } -/* flush the current output buffers now */ +/* Flush the current output buffers now */ void PNGAPI png_write_flush(png_structp png_ptr) { int wrote_IDAT; - png_debug(1, "in png_write_flush\n"); + png_debug(1, "in png_write_flush"); + if (png_ptr == NULL) + return; /* We have already written out all of the data */ if (png_ptr->row_number >= png_ptr->num_rows) - return; + return; do { int ret; - /* compress the data */ + /* Compress the data */ ret = deflate(&png_ptr->zstream, Z_SYNC_FLUSH); wrote_IDAT = 0; - /* check for compression errors */ + /* Check for compression errors */ if (ret != Z_OK) { if (png_ptr->zstream.msg != NULL) @@ -939,7 +990,7 @@ png_write_flush(png_structp png_ptr) if (!(png_ptr->zstream.avail_out)) { - /* write the IDAT and reset the zlib output buffer */ + /* Write the IDAT and reset the zlib output buffer */ png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); png_ptr->zstream.next_out = png_ptr->zbuf; @@ -951,7 +1002,7 @@ png_write_flush(png_structp png_ptr) /* 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 */ + /* 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->zstream.next_out = png_ptr->zbuf; @@ -962,7 +1013,7 @@ png_write_flush(png_structp png_ptr) } #endif /* PNG_WRITE_FLUSH_SUPPORTED */ -/* free all memory used by the write */ +/* Free all memory used by the write */ void PNGAPI png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr) { @@ -973,7 +1024,7 @@ png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr) png_voidp mem_ptr = NULL; #endif - png_debug(1, "in png_destroy_write_struct\n"); + png_debug(1, "in png_destroy_write_struct"); if (png_ptr_ptr != NULL) { png_ptr = *png_ptr_ptr; @@ -983,21 +1034,32 @@ png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr) #endif } +#ifdef PNG_USER_MEM_SUPPORTED + if (png_ptr != NULL) + { + free_fn = png_ptr->free_fn; + mem_ptr = png_ptr->mem_ptr; + } +#endif + if (info_ptr_ptr != NULL) info_ptr = *info_ptr_ptr; if (info_ptr != NULL) { - png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); + if (png_ptr != NULL) + { + png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1); #if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED) - if (png_ptr->num_chunk_list) - { - png_free(png_ptr, png_ptr->chunk_list); - png_ptr->chunk_list=NULL; - png_ptr->num_chunk_list=0; - } + if (png_ptr->num_chunk_list) + { + png_free(png_ptr, png_ptr->chunk_list); + png_ptr->chunk_list=NULL; + 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, @@ -1027,7 +1089,7 @@ void /* PRIVATE */ png_write_destroy(png_structp png_ptr) { #ifdef PNG_SETJMP_SUPPORTED - jmp_buf tmp_jmp; /* save jump buffer */ + jmp_buf tmp_jmp; /* Save jump buffer */ #endif png_error_ptr error_fn; png_error_ptr warning_fn; @@ -1036,18 +1098,20 @@ png_write_destroy(png_structp png_ptr) png_free_ptr free_fn; #endif - png_debug(1, "in png_write_destroy\n"); - /* free any memory zlib uses */ + png_debug(1, "in png_write_destroy"); + /* Free any memory zlib uses */ deflateEnd(&png_ptr->zstream); - /* free our memory. png_free checks NULL for us. */ + /* Free our memory. png_free checks NULL for us. */ png_free(png_ptr, png_ptr->zbuf); png_free(png_ptr, png_ptr->row_buf); +#ifndef PNG_NO_WRITE_FILTER png_free(png_ptr, png_ptr->prev_row); png_free(png_ptr, png_ptr->sub_row); png_free(png_ptr, png_ptr->up_row); png_free(png_ptr, png_ptr->avg_row); png_free(png_ptr, png_ptr->paeth_row); +#endif #if defined(PNG_TIME_RFC1123_SUPPORTED) png_free(png_ptr, png_ptr->time_buffer); @@ -1062,8 +1126,8 @@ png_write_destroy(png_structp png_ptr) #endif #ifdef PNG_SETJMP_SUPPORTED - /* reset structure */ - png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof (jmp_buf)); + /* Reset structure */ + png_memcpy(tmp_jmp, png_ptr->jmpbuf, png_sizeof(jmp_buf)); #endif error_fn = png_ptr->error_fn; @@ -1073,7 +1137,7 @@ png_write_destroy(png_structp png_ptr) free_fn = png_ptr->free_fn; #endif - png_memset(png_ptr, 0, png_sizeof (png_struct)); + png_memset(png_ptr, 0, png_sizeof(png_struct)); png_ptr->error_fn = error_fn; png_ptr->warning_fn = warning_fn; @@ -1083,7 +1147,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->jmpbuf, tmp_jmp, png_sizeof(jmp_buf)); #endif } @@ -1091,9 +1155,11 @@ png_write_destroy(png_structp png_ptr) void PNGAPI png_set_filter(png_structp png_ptr, int method, int filters) { - png_debug(1, "in png_set_filter\n"); + png_debug(1, "in png_set_filter"); + if (png_ptr == NULL) + return; #if defined(PNG_MNG_FEATURES_SUPPORTED) - if((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && + if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) && (method == PNG_INTRAPIXEL_DIFFERENCING)) method = PNG_FILTER_TYPE_BASE; #endif @@ -1101,15 +1167,26 @@ png_set_filter(png_structp png_ptr, int method, int filters) { switch (filters & (PNG_ALL_FILTERS | 0x07)) { +#ifndef PNG_NO_WRITE_FILTER case 5: case 6: case 7: png_warning(png_ptr, "Unknown row filter for method 0"); - case PNG_FILTER_VALUE_NONE: png_ptr->do_filter=PNG_FILTER_NONE; break; - case PNG_FILTER_VALUE_SUB: png_ptr->do_filter=PNG_FILTER_SUB; break; - case PNG_FILTER_VALUE_UP: png_ptr->do_filter=PNG_FILTER_UP; break; - case PNG_FILTER_VALUE_AVG: png_ptr->do_filter=PNG_FILTER_AVG; break; - case PNG_FILTER_VALUE_PAETH: png_ptr->do_filter=PNG_FILTER_PAETH;break; +#endif /* PNG_NO_WRITE_FILTER */ + case PNG_FILTER_VALUE_NONE: + png_ptr->do_filter=PNG_FILTER_NONE; break; +#ifndef PNG_NO_WRITE_FILTER + case PNG_FILTER_VALUE_SUB: + png_ptr->do_filter=PNG_FILTER_SUB; break; + case PNG_FILTER_VALUE_UP: + png_ptr->do_filter=PNG_FILTER_UP; break; + case PNG_FILTER_VALUE_AVG: + 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; +#else + default: png_warning(png_ptr, "Unknown row filter for method 0"); +#endif /* PNG_NO_WRITE_FILTER */ } /* If we have allocated the row_buf, this means we have already started @@ -1123,6 +1200,7 @@ png_set_filter(png_structp png_ptr, int method, int filters) */ if (png_ptr->row_buf != NULL) { +#ifndef PNG_NO_WRITE_FILTER if ((png_ptr->do_filter & PNG_FILTER_SUB) && png_ptr->sub_row == NULL) { png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, @@ -1177,6 +1255,7 @@ png_set_filter(png_structp png_ptr, int method, int filters) } if (png_ptr->do_filter == PNG_NO_FILTERS) +#endif /* PNG_NO_WRITE_FILTER */ png_ptr->do_filter = PNG_FILTER_NONE; } } @@ -1199,7 +1278,9 @@ png_set_filter_heuristics(png_structp png_ptr, int heuristic_method, { int i; - png_debug(1, "in png_set_filter_heuristics\n"); + png_debug(1, "in png_set_filter_heuristics"); + if (png_ptr == NULL) + return; if (heuristic_method >= PNG_FILTER_HEURISTIC_LAST) { png_warning(png_ptr, "Unknown filter heuristic method"); @@ -1311,7 +1392,9 @@ png_set_filter_heuristics(png_structp png_ptr, int heuristic_method, void PNGAPI png_set_compression_level(png_structp png_ptr, int level) { - png_debug(1, "in png_set_compression_level\n"); + png_debug(1, "in png_set_compression_level"); + if (png_ptr == NULL) + return; png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_LEVEL; png_ptr->zlib_level = level; } @@ -1319,7 +1402,9 @@ png_set_compression_level(png_structp png_ptr, int level) void PNGAPI png_set_compression_mem_level(png_structp png_ptr, int mem_level) { - png_debug(1, "in png_set_compression_mem_level\n"); + png_debug(1, "in png_set_compression_mem_level"); + if (png_ptr == NULL) + return; png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL; png_ptr->zlib_mem_level = mem_level; } @@ -1327,7 +1412,9 @@ png_set_compression_mem_level(png_structp png_ptr, int mem_level) void PNGAPI png_set_compression_strategy(png_structp png_ptr, int strategy) { - png_debug(1, "in png_set_compression_strategy\n"); + png_debug(1, "in png_set_compression_strategy"); + if (png_ptr == NULL) + return; png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY; png_ptr->zlib_strategy = strategy; } @@ -1335,12 +1422,14 @@ png_set_compression_strategy(png_structp png_ptr, int strategy) void PNGAPI 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 */ + /* Avoid libpng bug with 256-byte windows */ if (window_bits == 8) { png_warning(png_ptr, "Compression window is being reset to 512"); @@ -1354,7 +1443,9 @@ png_set_compression_window_bits(png_structp png_ptr, int window_bits) void PNGAPI png_set_compression_method(png_structp png_ptr, int method) { - png_debug(1, "in png_set_compression_method\n"); + png_debug(1, "in png_set_compression_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; @@ -1364,6 +1455,8 @@ png_set_compression_method(png_structp png_ptr, int method) void PNGAPI 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; } @@ -1372,7 +1465,9 @@ void PNGAPI png_set_write_user_transform_fn(png_structp png_ptr, png_user_transform_ptr write_user_transform_fn) { - png_debug(1, "in png_set_write_user_transform_fn\n"); + 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; } @@ -1384,10 +1479,12 @@ void PNGAPI png_write_png(png_structp png_ptr, png_infop info_ptr, int transforms, voidp params) { + if (png_ptr == NULL || info_ptr == NULL) + return; #if defined(PNG_WRITE_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 /* Write the file header information. */ @@ -1396,9 +1493,9 @@ png_write_png(png_structp png_ptr, png_infop info_ptr, /* ------ these transformations don't touch the info structure ------- */ #if defined(PNG_WRITE_INVERT_SUPPORTED) - /* invert monochrome pixels */ + /* Invert monochrome pixels */ if (transforms & PNG_TRANSFORM_INVERT_MONO) - png_set_invert_mono(png_ptr); + png_set_invert_mono(png_ptr); #endif #if defined(PNG_WRITE_SHIFT_SUPPORTED) @@ -1407,58 +1504,58 @@ png_write_png(png_structp png_ptr, png_infop info_ptr, */ if ((transforms & PNG_TRANSFORM_SHIFT) && (info_ptr->valid & PNG_INFO_sBIT)) - png_set_shift(png_ptr, &info_ptr->sig_bit); + png_set_shift(png_ptr, &info_ptr->sig_bit); #endif #if defined(PNG_WRITE_PACK_SUPPORTED) - /* pack pixels into bytes */ + /* Pack pixels into bytes */ if (transforms & PNG_TRANSFORM_PACKING) png_set_packing(png_ptr); #endif #if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED) - /* swap location of alpha bytes from ARGB to RGBA */ + /* Swap location of alpha bytes from ARGB to RGBA */ if (transforms & PNG_TRANSFORM_SWAP_ALPHA) - png_set_swap_alpha(png_ptr); + png_set_swap_alpha(png_ptr); #endif #if defined(PNG_WRITE_FILLER_SUPPORTED) - /* Get rid of filler (OR ALPHA) bytes, pack XRGB/RGBX/ARGB/RGBA into - * RGB (4 channels -> 3 channels). The second parameter is not used. - */ - if (transforms & PNG_TRANSFORM_STRIP_FILLER) - png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); + /* 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 #if defined(PNG_WRITE_BGR_SUPPORTED) - /* flip BGR pixels to RGB */ + /* Flip BGR pixels to RGB */ if (transforms & PNG_TRANSFORM_BGR) - png_set_bgr(png_ptr); + png_set_bgr(png_ptr); #endif #if defined(PNG_WRITE_SWAP_SUPPORTED) - /* swap bytes of 16-bit files to most significant byte first */ + /* Swap bytes of 16-bit files to most significant byte first */ if (transforms & PNG_TRANSFORM_SWAP_ENDIAN) - png_set_swap(png_ptr); + png_set_swap(png_ptr); #endif #if defined(PNG_WRITE_PACKSWAP_SUPPORTED) - /* swap bits of 1, 2, 4 bit packed pixel formats */ + /* Swap bits of 1, 2, 4 bit packed pixel formats */ if (transforms & PNG_TRANSFORM_PACKSWAP) - png_set_packswap(png_ptr); + png_set_packswap(png_ptr); #endif /* ----------------------- end of transformations ------------------- */ - /* write the bits */ + /* Write the bits */ if (info_ptr->valid & PNG_INFO_IDAT) png_write_image(png_ptr, info_ptr->row_pointers); /* It is REQUIRED to call this to finish writing the rest of the file */ png_write_end(png_ptr, info_ptr); - if(transforms == 0 || params == NULL) - /* quiet compiler warnings */ return; + transforms = transforms; /* Quiet compiler warnings */ + params = params; } #endif #endif /* PNG_WRITE_SUPPORTED */ diff --git a/3rdparty/wxWidgets/src/png/pngwtran.c b/3rdparty/wxWidgets/src/png/pngwtran.c index 94d8ecc1ce..88a7d3cbf3 100644 --- a/3rdparty/wxWidgets/src/png/pngwtran.c +++ b/3rdparty/wxWidgets/src/png/pngwtran.c @@ -1,11 +1,14 @@ /* pngwtran.c - transforms the data in a row for PNG writers * - * libpng version 1.2.7 - September 12, 2004 - * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2004 Glenn Randers-Pehrson + * Last changed in libpng 1.2.37 [June 4, 2009] + * Copyright (c) 1998-2009 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. + * For conditions of distribution and use, see the disclaimer + * and license in png.h */ #define PNG_INTERNAL @@ -18,15 +21,15 @@ void /* PRIVATE */ png_do_write_transformations(png_structp png_ptr) { - png_debug(1, "in png_do_write_transformations\n"); + png_debug(1, "in png_do_write_transformations"); if (png_ptr == NULL) return; #if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) if (png_ptr->transformations & PNG_USER_TRANSFORM) - if(png_ptr->write_user_transform_fn != NULL) - (*(png_ptr->write_user_transform_fn)) /* user write transform function */ + if (png_ptr->write_user_transform_fn != NULL) + (*(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 */ @@ -60,14 +63,14 @@ png_do_write_transformations(png_structp png_ptr) png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1, &(png_ptr->shift)); #endif -#if defined(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 #if defined(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 +#if defined(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 #if defined(PNG_WRITE_BGR_SUPPORTED) if (png_ptr->transformations & PNG_BGR) png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1); @@ -86,7 +89,7 @@ png_do_write_transformations(png_structp png_ptr) void /* PRIVATE */ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth) { - png_debug(1, "in png_do_pack\n"); + png_debug(1, "in png_do_pack"); if (row_info->bit_depth == 8 && #if defined(PNG_USELESS_TESTS_SUPPORTED) row != NULL && row_info != NULL && @@ -212,7 +215,7 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth) void /* PRIVATE */ png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth) { - png_debug(1, "in png_do_shift\n"); + png_debug(1, "in png_do_shift"); #if defined(PNG_USELESS_TESTS_SUPPORTED) if (row != NULL && row_info != NULL && #else @@ -248,7 +251,7 @@ png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth) channels++; } - /* with low row depths, could only be grayscale, so one channel */ + /* With low row depths, could only be grayscale, so one channel */ if (row_info->bit_depth < 8) { png_bytep bp = row; @@ -336,7 +339,7 @@ png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth) void /* PRIVATE */ png_do_write_swap_alpha(png_row_infop row_info, png_bytep row) { - png_debug(1, "in png_do_write_swap_alpha\n"); + png_debug(1, "in png_do_write_swap_alpha"); #if defined(PNG_USELESS_TESTS_SUPPORTED) if (row != NULL && row_info != NULL) #endif @@ -424,7 +427,7 @@ png_do_write_swap_alpha(png_row_infop row_info, png_bytep row) void /* PRIVATE */ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row) { - png_debug(1, "in png_do_write_invert_alpha\n"); + png_debug(1, "in png_do_write_invert_alpha"); #if defined(PNG_USELESS_TESTS_SUPPORTED) if (row != NULL && row_info != NULL) #endif @@ -439,9 +442,12 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row) png_uint_32 row_width = row_info->width; for (i = 0, sp = dp = row; i < row_width; i++) { + /* Does nothing *(dp++) = *(sp++); *(dp++) = *(sp++); *(dp++) = *(sp++); + */ + sp+=3; dp = sp; *(dp++) = (png_byte)(255 - *(sp++)); } } @@ -454,12 +460,15 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row) for (i = 0, sp = dp = row; i < row_width; i++) { + /* Does nothing *(dp++) = *(sp++); *(dp++) = *(sp++); *(dp++) = *(sp++); *(dp++) = *(sp++); *(dp++) = *(sp++); *(dp++) = *(sp++); + */ + sp+=6; dp = sp; *(dp++) = (png_byte)(255 - *(sp++)); *(dp++) = (png_byte)(255 - *(sp++)); } @@ -489,8 +498,11 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row) for (i = 0, sp = dp = row; i < row_width; i++) { + /* Does nothing *(dp++) = *(sp++); *(dp++) = *(sp++); + */ + sp+=2; dp = sp; *(dp++) = (png_byte)(255 - *(sp++)); *(dp++) = (png_byte)(255 - *(sp++)); } @@ -501,11 +513,11 @@ png_do_write_invert_alpha(png_row_infop row_info, png_bytep row) #endif #if defined(PNG_MNG_FEATURES_SUPPORTED) -/* undoes intrapixel differencing */ +/* Undoes intrapixel differencing */ void /* PRIVATE */ png_do_write_intrapixel(png_row_infop row_info, png_bytep row) { - png_debug(1, "in png_do_write_intrapixel\n"); + png_debug(1, "in png_do_write_intrapixel"); if ( #if defined(PNG_USELESS_TESTS_SUPPORTED) row != NULL && row_info != NULL && @@ -549,8 +561,8 @@ png_do_write_intrapixel(png_row_infop row_info, png_bytep row) 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); + 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); diff --git a/3rdparty/wxWidgets/src/png/pngwutil.c b/3rdparty/wxWidgets/src/png/pngwutil.c index 17938d2278..aed280e38d 100644 --- a/3rdparty/wxWidgets/src/png/pngwutil.c +++ b/3rdparty/wxWidgets/src/png/pngwutil.c @@ -1,11 +1,14 @@ /* pngwutil.c - utilities to write a PNG file * - * libpng version 1.2.7 - September 12, 2004 - * For conditions of distribution and use, see copyright notice in png.h - * Copyright (c) 1998-2004 Glenn Randers-Pehrson + * Last changed in libpng 1.2.39 [August 13, 2009] + * Copyright (c) 1998-2009 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. + * For conditions of distribution and use, see the disclaimer + * and license in png.h */ #define PNG_INTERNAL @@ -16,7 +19,7 @@ * with unsigned numbers for convenience, although one supported * ancillary chunk uses signed (two's complement) numbers. */ -void /* PRIVATE */ +void PNGAPI png_save_uint_32(png_bytep buf, png_uint_32 i) { buf[0] = (png_byte)((i >> 24) & 0xff); @@ -25,12 +28,11 @@ png_save_uint_32(png_bytep buf, png_uint_32 i) buf[3] = (png_byte)(i & 0xff); } -#if defined(PNG_WRITE_pCAL_SUPPORTED) || defined(PNG_WRITE_oFFs_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. */ -void /* PRIVATE */ +void PNGAPI png_save_int_32(png_bytep buf, png_int_32 i) { buf[0] = (png_byte)((i >> 24) & 0xff); @@ -38,19 +40,36 @@ png_save_int_32(png_bytep buf, png_int_32 i) buf[2] = (png_byte)((i >> 8) & 0xff); buf[3] = (png_byte)(i & 0xff); } -#endif /* Place a 16-bit number into a buffer in PNG byte order. * The parameter is declared unsigned int, not png_uint_16, * just to avoid potential problems on pre-ANSI C compilers. */ -void /* PRIVATE */ +void PNGAPI png_save_uint_16(png_bytep buf, unsigned int i) { buf[0] = (png_byte)((i >> 8) & 0xff); buf[1] = (png_byte)(i & 0xff); } +/* Simple function to write the signature. If we have already written + * the magic bytes of the signature, or more likely, the PNG stream is + * being embedded into another stream and doesn't need its own signature, + * we should call png_set_sig_bytes() to tell libpng how many of the + * bytes have already been written. + */ +void /* PRIVATE */ +png_write_sig(png_structp png_ptr) +{ + png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; + + /* Write the rest of the 8 byte signature */ + png_write_data(png_ptr, &png_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; +} + /* Write a PNG chunk all at once. The type is an array of ASCII characters * representing the chunk name. The array must be at least 4 bytes in * length, and does not need to be null terminated. To be safe, pass the @@ -64,8 +83,10 @@ void PNGAPI png_write_chunk(png_structp png_ptr, png_bytep chunk_name, png_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, length); + png_write_chunk_data(png_ptr, data, (png_size_t)length); png_write_chunk_end(png_ptr); } @@ -77,16 +98,20 @@ void PNGAPI png_write_chunk_start(png_structp png_ptr, png_bytep chunk_name, png_uint_32 length) { - png_byte buf[4]; - png_debug2(0, "Writing %s chunk (%lu bytes)\n", chunk_name, length); + png_byte buf[8]; - /* write the length */ + png_debug2(0, "Writing %s chunk, length = %lu", chunk_name, + (unsigned long)length); + if (png_ptr == NULL) + return; + + /* Write the length and the chunk name */ png_save_uint_32(buf, length); - png_write_data(png_ptr, buf, (png_size_t)4); - - /* write the chunk name */ - png_write_data(png_ptr, chunk_name, (png_size_t)4); - /* reset the crc and run it over the chunk name */ + 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, (png_size_t)4); } @@ -99,11 +124,16 @@ png_write_chunk_start(png_structp png_ptr, png_bytep chunk_name, void PNGAPI png_write_chunk_data(png_structp png_ptr, png_bytep data, png_size_t length) { - /* write the data, and run the CRC over it */ + /* Write the data, and run the CRC over it */ + if (png_ptr == NULL) + return; if (data != NULL && length > 0) { - png_calculate_crc(png_ptr, data, length); png_write_data(png_ptr, data, length); + /* Update the CRC after writing the data, + * in case that the user I/O routine alters it. + */ + png_calculate_crc(png_ptr, data, length); } } @@ -113,32 +143,16 @@ png_write_chunk_end(png_structp png_ptr) { png_byte buf[4]; - /* write the crc */ + if (png_ptr == NULL) return; + + /* Write the crc in a single operation */ png_save_uint_32(buf, png_ptr->crc); png_write_data(png_ptr, buf, (png_size_t)4); } -/* Simple function to write the signature. If we have already written - * the magic bytes of the signature, or more likely, the PNG stream is - * being embedded into another stream and doesn't need its own signature, - * we should call png_set_sig_bytes() to tell libpng how many of the - * bytes have already been written. - */ -void /* PRIVATE */ -png_write_sig(png_structp png_ptr) -{ - png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; - /* write the rest of the 8 byte signature */ - png_write_data(png_ptr, &png_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; -} - #if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_iCCP_SUPPORTED) -/* - * This pair of functions encapsulates the operation of (a) compressing a +/* This pair of functions encapsulates the operation of (a) compressing a * text string, and (b) issuing it later as a series of chunk data writes. * The compression_state structure is shared context for these functions * set up by the caller in order to make the whole mess thread-safe. @@ -146,14 +160,14 @@ png_write_sig(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 */ + char *input; /* The uncompressed input data */ + int input_len; /* Its length */ + int num_output_ptr; /* Number of output pointers used */ + int max_output_ptr; /* Size of output_ptr */ + png_charpp output_ptr; /* Array of pointers to output */ } compression_state; -/* compress given text into storage in the png_ptr structure */ +/* 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, @@ -161,11 +175,13 @@ png_text_compress(png_structp png_ptr, { int ret; - comp->num_output_ptr = comp->max_output_ptr = 0; + comp->num_output_ptr = 0; + comp->max_output_ptr = 0; comp->output_ptr = NULL; comp->input = NULL; + comp->input_len = 0; - /* we may just want to pass the text right through */ + /* We may just want to pass the text right through */ if (compression == PNG_TEXT_COMPRESSION_NONE) { comp->input = text; @@ -177,7 +193,7 @@ png_text_compress(png_structp png_ptr, { #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) char msg[50]; - sprintf(msg, "Unknown compression type %d", compression); + png_snprintf(msg, 50, "Unknown compression type %d", compression); png_warning(png_ptr, msg); #else png_warning(png_ptr, "Unknown compression type"); @@ -199,29 +215,29 @@ png_text_compress(png_structp png_ptr, * wouldn't cause a failure, just a slowdown due to swapping). */ - /* set up the compression buffers */ + /* Set up the compression buffers */ png_ptr->zstream.avail_in = (uInt)text_len; png_ptr->zstream.next_in = (Bytef *)text; png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; png_ptr->zstream.next_out = (Bytef *)png_ptr->zbuf; - /* this is the same compression loop as in png_write_row() */ + /* This is the same compression loop as in png_write_row() */ do { - /* compress the data */ + /* Compress the data */ ret = deflate(&png_ptr->zstream, Z_NO_FLUSH); if (ret != Z_OK) { - /* error */ + /* Error */ if (png_ptr->zstream.msg != NULL) png_error(png_ptr, png_ptr->zstream.msg); else png_error(png_ptr, "zlib error"); } - /* check to see if we need more room */ - if (!png_ptr->zstream.avail_out && png_ptr->zstream.avail_in) + /* Check to see if we need more room */ + if (!(png_ptr->zstream.avail_out)) { - /* make sure the output array has room */ + /* Make sure the output array has room */ if (comp->num_output_ptr >= comp->max_output_ptr) { int old_max; @@ -234,20 +250,21 @@ png_text_compress(png_structp png_ptr, old_ptr = comp->output_ptr; comp->output_ptr = (png_charpp)png_malloc(png_ptr, - (png_uint_32)(comp->max_output_ptr * - png_sizeof (png_charpp))); + (png_uint_32) + (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_uint_32)(comp->max_output_ptr * - png_sizeof (png_charp))); + (png_uint_32) + (comp->max_output_ptr * png_sizeof(png_charp))); } - /* save the data */ - comp->output_ptr[comp->num_output_ptr] = (png_charp)png_malloc(png_ptr, + /* Save the data */ + comp->output_ptr[comp->num_output_ptr] = + (png_charp)png_malloc(png_ptr, (png_uint_32)png_ptr->zbuf_size); png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf, png_ptr->zbuf_size); @@ -257,21 +274,21 @@ png_text_compress(png_structp png_ptr, png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; png_ptr->zstream.next_out = png_ptr->zbuf; } - /* continue until we don't have any more to compress */ + /* Continue until we don't have any more to compress */ } while (png_ptr->zstream.avail_in); - /* finish the compression */ + /* Finish the compression */ do { - /* tell zlib we are finished */ + /* Tell zlib we are finished */ ret = deflate(&png_ptr->zstream, Z_FINISH); if (ret == Z_OK) { - /* check to see if we need more room */ + /* Check to see if we need more room */ if (!(png_ptr->zstream.avail_out)) { - /* check to make sure our output array has room */ + /* Check to make sure our output array has room */ if (comp->num_output_ptr >= comp->max_output_ptr) { int old_max; @@ -286,20 +303,21 @@ png_text_compress(png_structp png_ptr, /* This could be optimized to realloc() */ comp->output_ptr = (png_charpp)png_malloc(png_ptr, (png_uint_32)(comp->max_output_ptr * - png_sizeof (png_charpp))); + 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_uint_32)(comp->max_output_ptr * - png_sizeof (png_charp))); + png_sizeof(png_charp))); } - /* save off the data */ + /* Save the data */ comp->output_ptr[comp->num_output_ptr] = - (png_charp)png_malloc(png_ptr, (png_uint_32)png_ptr->zbuf_size); + (png_charp)png_malloc(png_ptr, + (png_uint_32)png_ptr->zbuf_size); png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf, png_ptr->zbuf_size); comp->num_output_ptr++; @@ -311,7 +329,7 @@ png_text_compress(png_structp png_ptr, } else if (ret != Z_STREAM_END) { - /* we got an error */ + /* We got an error */ if (png_ptr->zstream.msg != NULL) png_error(png_ptr, png_ptr->zstream.msg); else @@ -319,7 +337,7 @@ png_text_compress(png_structp png_ptr, } } while (ret != Z_STREAM_END); - /* text length is number of buffers plus last buffer */ + /* 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; @@ -327,39 +345,39 @@ png_text_compress(png_structp png_ptr, return((int)text_len); } -/* ship the compressed text out via chunk writes */ +/* Ship the compressed text out via chunk writes */ static void /* PRIVATE */ png_write_compressed_data_out(png_structp png_ptr, compression_state *comp) { int i; - /* handle the no-compression case */ + /* Handle the no-compression case */ if (comp->input) { - png_write_chunk_data(png_ptr, (png_bytep)comp->input, + png_write_chunk_data(png_ptr, (png_bytep)comp->input, (png_size_t)comp->input_len); - return; + return; } - /* write saved output buffers, if any */ + /* Write saved output buffers, if any */ for (i = 0; i < comp->num_output_ptr; i++) { - png_write_chunk_data(png_ptr,(png_bytep)comp->output_ptr[i], - png_ptr->zbuf_size); + png_write_chunk_data(png_ptr, (png_bytep)comp->output_ptr[i], + (png_size_t)png_ptr->zbuf_size); png_free(png_ptr, comp->output_ptr[i]); - comp->output_ptr[i]=NULL; + comp->output_ptr[i]=NULL; } if (comp->max_output_ptr != 0) png_free(png_ptr, comp->output_ptr); - comp->output_ptr=NULL; - /* write anything left in zbuf */ + comp->output_ptr=NULL; + /* Write anything left in zbuf */ if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size) png_write_chunk_data(png_ptr, png_ptr->zbuf, - png_ptr->zbuf_size - png_ptr->zstream.avail_out); + (png_size_t)(png_ptr->zbuf_size - png_ptr->zstream.avail_out)); - /* reset zlib for another zTXt/iTXt or the image data */ + /* Reset zlib for another zTXt/iTXt or image data */ deflateReset(&png_ptr->zstream); - + png_ptr->zstream.data_type = Z_BINARY; } #endif @@ -375,9 +393,11 @@ png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height, #ifdef PNG_USE_LOCAL_ARRAYS PNG_IHDR; #endif - png_byte buf[13]; /* buffer to store the IHDR info */ + int ret; - png_debug(1, "in png_write_IHDR\n"); + png_byte buf[13]; /* Buffer to store the IHDR info */ + + png_debug(1, "in png_write_IHDR"); /* Check that we have valid input data from the application info */ switch (color_type) { @@ -389,7 +409,7 @@ png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height, case 4: case 8: case 16: png_ptr->channels = 1; break; - default: png_error(png_ptr,"Invalid bit depth for grayscale image"); + default: png_error(png_ptr, "Invalid bit depth for grayscale image"); } break; case PNG_COLOR_TYPE_RGB: @@ -461,7 +481,7 @@ png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height, interlace_type=PNG_INTERLACE_NONE; #endif - /* save off the relevent information */ + /* Save the relevent information */ png_ptr->bit_depth = (png_byte)bit_depth; png_ptr->color_type = (png_byte)color_type; png_ptr->interlaced = (png_byte)interlace_type; @@ -474,12 +494,12 @@ png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height, png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels); png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width); - /* set the usr info, so any transformations can modify it */ + /* Set the usr info, so any transformations can modify it */ png_ptr->usr_width = png_ptr->width; png_ptr->usr_bit_depth = png_ptr->bit_depth; png_ptr->usr_channels = png_ptr->channels; - /* pack the header information into the buffer */ + /* Pack the header information into the buffer */ png_save_uint_32(buf, width); png_save_uint_32(buf + 4, height); buf[8] = (png_byte)bit_depth; @@ -488,10 +508,10 @@ png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height, buf[11] = (png_byte)filter_type; buf[12] = (png_byte)interlace_type; - /* write the chunk */ + /* Write the chunk */ png_write_chunk(png_ptr, (png_bytep)png_IHDR, buf, (png_size_t)13); - /* initialize zlib with PNG info */ + /* Initialize zlib with PNG info */ png_ptr->zstream.zalloc = png_zalloc; png_ptr->zstream.zfree = png_zfree; png_ptr->zstream.opaque = (voidpf)png_ptr; @@ -518,16 +538,29 @@ png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height, png_ptr->zlib_window_bits = 15; if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_METHOD)) png_ptr->zlib_method = 8; - 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); + 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); + 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"); + 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 */ + png_ptr->zstream.data_type = Z_BINARY; png_ptr->mode = PNG_HAVE_IHDR; } -/* write the palette. We are careful not to trust png_color to be in the +/* Write the palette. We are careful not to trust png_color to be in the * correct order for PNG, so people can redefine it to any convenient * structure. */ @@ -541,7 +574,7 @@ png_write_PLTE(png_structp png_ptr, png_colorp palette, png_uint_32 num_pal) png_colorp pal_ptr; png_byte buf[3]; - png_debug(1, "in png_write_PLTE\n"); + png_debug(1, "in png_write_PLTE"); if (( #if defined(PNG_MNG_FEATURES_SUPPORTED) !(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) && @@ -567,9 +600,10 @@ png_write_PLTE(png_structp png_ptr, png_colorp palette, png_uint_32 num_pal) } png_ptr->num_palette = (png_uint_16)num_pal; - png_debug1(3, "num_palette = %d\n", png_ptr->num_palette); + png_debug1(3, "num_palette = %d", png_ptr->num_palette); - png_write_chunk_start(png_ptr, (png_bytep)png_PLTE, num_pal * 3); + png_write_chunk_start(png_ptr, (png_bytep)png_PLTE, + (png_uint_32)(num_pal * 3)); #ifndef PNG_NO_POINTER_INDEXING for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++) { @@ -593,14 +627,14 @@ png_write_PLTE(png_structp png_ptr, png_colorp palette, png_uint_32 num_pal) png_ptr->mode |= PNG_HAVE_PLTE; } -/* write an IDAT chunk */ +/* Write an IDAT chunk */ void /* PRIVATE */ png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length) { #ifdef PNG_USE_LOCAL_ARRAYS PNG_IDAT; #endif - png_debug(1, "in png_write_IDAT\n"); + png_debug(1, "in png_write_IDAT"); /* Optimize the CMF field in the zlib stream. */ /* This hack of the zlib stream is compliant to the stream specification. */ @@ -610,9 +644,11 @@ png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length) unsigned int z_cmf = data[0]; /* zlib compression method and flags */ if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70) { - /* Avoid memory underflows and multiplication overflows. */ - /* The conditions below are practically always satisfied; - however, they still must be checked. */ + /* Avoid memory underflows and multiplication overflows. + * + * The conditions below are practically always satisfied; + * however, they still must be checked. + */ if (length >= 2 && png_ptr->height < 16384 && png_ptr->width < 16384) { @@ -645,21 +681,21 @@ png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length) png_ptr->mode |= PNG_HAVE_IDAT; } -/* write an IEND chunk */ +/* Write an IEND chunk */ void /* PRIVATE */ png_write_IEND(png_structp png_ptr) { #ifdef PNG_USE_LOCAL_ARRAYS PNG_IEND; #endif - png_debug(1, "in png_write_IEND\n"); + png_debug(1, "in png_write_IEND"); png_write_chunk(png_ptr, (png_bytep)png_IEND, png_bytep_NULL, (png_size_t)0); png_ptr->mode |= PNG_HAVE_IEND; } #if defined(PNG_WRITE_gAMA_SUPPORTED) -/* write a gAMA chunk */ +/* Write a gAMA chunk */ #ifdef PNG_FLOATING_POINT_SUPPORTED void /* PRIVATE */ png_write_gAMA(png_structp png_ptr, double file_gamma) @@ -670,7 +706,7 @@ png_write_gAMA(png_structp png_ptr, double file_gamma) png_uint_32 igamma; png_byte buf[4]; - png_debug(1, "in png_write_gAMA\n"); + 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); @@ -686,7 +722,7 @@ png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma) #endif png_byte buf[4]; - png_debug(1, "in png_write_gAMA\n"); + png_debug(1, "in png_write_gAMA"); /* 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); @@ -695,7 +731,7 @@ png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma) #endif #if defined(PNG_WRITE_sRGB_SUPPORTED) -/* write a sRGB chunk */ +/* Write a sRGB chunk */ void /* PRIVATE */ png_write_sRGB(png_structp png_ptr, int srgb_intent) { @@ -704,8 +740,8 @@ png_write_sRGB(png_structp png_ptr, int srgb_intent) #endif png_byte buf[1]; - png_debug(1, "in png_write_sRGB\n"); - if(srgb_intent >= PNG_sRGB_INTENT_LAST) + png_debug(1, "in png_write_sRGB"); + if (srgb_intent >= PNG_sRGB_INTENT_LAST) png_warning(png_ptr, "Invalid sRGB rendering intent specified"); buf[0]=(png_byte)srgb_intent; @@ -714,7 +750,7 @@ png_write_sRGB(png_structp png_ptr, int srgb_intent) #endif #if defined(PNG_WRITE_iCCP_SUPPORTED) -/* write an iCCP chunk */ +/* 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) @@ -725,14 +761,19 @@ png_write_iCCP(png_structp png_ptr, png_charp name, int compression_type, png_size_t name_len; png_charp new_name; compression_state comp; + int embedded_profile_len = 0; - png_debug(1, "in png_write_iCCP\n"); - if (name == NULL || (name_len = png_check_keyword(png_ptr, name, + png_debug(1, "in png_write_iCCP"); + + comp.num_output_ptr = 0; + comp.max_output_ptr = 0; + comp.output_ptr = NULL; + comp.input = NULL; + comp.input_len = 0; + + if ((name_len = png_check_keyword(png_ptr, name, &new_name)) == 0) - { - png_warning(png_ptr, "Empty keyword in iCCP chunk"); return; - } if (compression_type != PNG_COMPRESSION_TYPE_BASE) png_warning(png_ptr, "Unknown compression type in iCCP chunk"); @@ -740,15 +781,46 @@ png_write_iCCP(png_structp png_ptr, png_charp name, int compression_type, if (profile == NULL) profile_len = 0; - if (profile_len) - profile_len = png_text_compress(png_ptr, profile, (png_size_t)profile_len, - PNG_COMPRESSION_TYPE_BASE, &comp); + 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)) ); - /* make sure we include the NULL after the name and the compression type */ + if (embedded_profile_len < 0) + { + png_warning(png_ptr, + "Embedded profile length in iCCP chunk is negative"); + png_free(png_ptr, new_name); + return; + } + + if (profile_len < embedded_profile_len) + { + png_warning(png_ptr, + "Embedded profile length too large in iCCP chunk"); + png_free(png_ptr, new_name); + return; + } + + if (profile_len > embedded_profile_len) + { + png_warning(png_ptr, + "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); + + /* 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); - new_name[name_len+1]=0x00; - png_write_chunk_data(png_ptr, (png_bytep)new_name, name_len + 2); + (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)); if (profile_len) png_write_compressed_data_out(png_ptr, &comp); @@ -759,7 +831,7 @@ png_write_iCCP(png_structp png_ptr, png_charp name, int compression_type, #endif #if defined(PNG_WRITE_sPLT_SUPPORTED) -/* write a sPLT chunk */ +/* Write a sPLT chunk */ void /* PRIVATE */ png_write_sPLT(png_structp png_ptr, png_sPLT_tp spalette) { @@ -776,63 +848,60 @@ png_write_sPLT(png_structp png_ptr, png_sPLT_tp spalette) int i; #endif - png_debug(1, "in png_write_sPLT\n"); - if (spalette->name == NULL || (name_len = png_check_keyword(png_ptr, - spalette->name, &new_name))==0) - { - png_warning(png_ptr, "Empty keyword in sPLT chunk"); + png_debug(1, "in png_write_sPLT"); + if ((name_len = png_check_keyword(png_ptr,spalette->name, &new_name))==0) return; - } - /* make sure we include the NULL after the name */ + /* 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_data(png_ptr, (png_bytep)new_name, name_len + 1); - png_write_chunk_data(png_ptr, (png_bytep)&spalette->depth, 1); + (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); - /* loop through each palette entry, writing appropriately */ + /* Loop through each palette entry, writing appropriately */ #ifndef PNG_NO_POINTER_INDEXING - for (ep = spalette->entries; epentries+spalette->nentries; ep++) + for (ep = spalette->entries; epentries + spalette->nentries; ep++) { - if (spalette->depth == 8) - { - entrybuf[0] = (png_byte)ep->red; - entrybuf[1] = (png_byte)ep->green; - entrybuf[2] = (png_byte)ep->blue; - entrybuf[3] = (png_byte)ep->alpha; - png_save_uint_16(entrybuf + 4, ep->frequency); - } - else - { - png_save_uint_16(entrybuf + 0, ep->red); - png_save_uint_16(entrybuf + 2, ep->green); - png_save_uint_16(entrybuf + 4, ep->blue); - png_save_uint_16(entrybuf + 6, ep->alpha); - png_save_uint_16(entrybuf + 8, ep->frequency); - } - png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size); + if (spalette->depth == 8) + { + entrybuf[0] = (png_byte)ep->red; + entrybuf[1] = (png_byte)ep->green; + entrybuf[2] = (png_byte)ep->blue; + entrybuf[3] = (png_byte)ep->alpha; + png_save_uint_16(entrybuf + 4, ep->frequency); + } + else + { + png_save_uint_16(entrybuf + 0, ep->red); + png_save_uint_16(entrybuf + 2, ep->green); + png_save_uint_16(entrybuf + 4, ep->blue); + png_save_uint_16(entrybuf + 6, ep->alpha); + png_save_uint_16(entrybuf + 8, ep->frequency); + } + png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size); } #else ep=spalette->entries; 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); - } - 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_write_chunk_data(png_ptr, entrybuf, entry_size); + 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); + } + 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_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size); } #endif @@ -842,7 +911,7 @@ png_write_sPLT(png_structp png_ptr, png_sPLT_tp spalette) #endif #if defined(PNG_WRITE_sBIT_SUPPORTED) -/* write the sBIT chunk */ +/* Write the sBIT chunk */ void /* PRIVATE */ png_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type) { @@ -852,8 +921,8 @@ png_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type) png_byte buf[4]; png_size_t size; - png_debug(1, "in png_write_sBIT\n"); - /* make sure we don't depend upon the order of PNG_COLOR_8 */ + png_debug(1, "in png_write_sBIT"); + /* Make sure we don't depend upon the order of PNG_COLOR_8 */ if (color_type & PNG_COLOR_MASK_COLOR) { png_byte maxbits; @@ -898,7 +967,7 @@ png_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type) #endif #if defined(PNG_WRITE_cHRM_SUPPORTED) -/* write the cHRM chunk */ +/* Write the cHRM chunk */ #ifdef PNG_FLOATING_POINT_SUPPORTED void /* PRIVATE */ png_write_cHRM(png_structp png_ptr, double white_x, double white_y, @@ -909,58 +978,42 @@ png_write_cHRM(png_structp png_ptr, double white_x, double white_y, PNG_cHRM; #endif png_byte buf[32]; - png_uint_32 itemp; - png_debug(1, "in png_write_cHRM\n"); - /* each value is saved in 1/100,000ths */ - if (white_x < 0 || white_x > 0.8 || white_y < 0 || white_y > 0.8 || - white_x + white_y > 1.0) - { - png_warning(png_ptr, "Invalid cHRM white point specified"); -#if !defined(PNG_NO_CONSOLE_IO) - fprintf(stderr,"white_x=%f, white_y=%f\n",white_x, white_y); + 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); + +#if !defined(PNG_NO_CHECK_cHRM) + 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 - return; - } - itemp = (png_uint_32)(white_x * 100000.0 + 0.5); - png_save_uint_32(buf, itemp); - itemp = (png_uint_32)(white_y * 100000.0 + 0.5); - png_save_uint_32(buf + 4, itemp); - - if (red_x < 0 || red_x > 0.8 || red_y < 0 || red_y > 0.8 || - red_x + red_y > 1.0) { - png_warning(png_ptr, "Invalid cHRM red point specified"); - return; - } - itemp = (png_uint_32)(red_x * 100000.0 + 0.5); - png_save_uint_32(buf + 8, itemp); - itemp = (png_uint_32)(red_y * 100000.0 + 0.5); - png_save_uint_32(buf + 12, itemp); + /* Each value is saved in 1/100,000ths */ - if (green_x < 0 || green_x > 0.8 || green_y < 0 || green_y > 0.8 || - green_x + green_y > 1.0) - { - png_warning(png_ptr, "Invalid cHRM green point specified"); - return; - } - itemp = (png_uint_32)(green_x * 100000.0 + 0.5); - png_save_uint_32(buf + 16, itemp); - itemp = (png_uint_32)(green_y * 100000.0 + 0.5); - png_save_uint_32(buf + 20, itemp); + png_save_uint_32(buf, int_white_x); + png_save_uint_32(buf + 4, int_white_y); - if (blue_x < 0 || blue_x > 0.8 || blue_y < 0 || blue_y > 0.8 || - blue_x + blue_y > 1.0) - { - png_warning(png_ptr, "Invalid cHRM blue point specified"); - return; - } - itemp = (png_uint_32)(blue_x * 100000.0 + 0.5); - png_save_uint_32(buf + 24, itemp); - itemp = (png_uint_32)(blue_y * 100000.0 + 0.5); - png_save_uint_32(buf + 28, itemp); + png_save_uint_32(buf + 8, int_red_x); + png_save_uint_32(buf + 12, int_red_y); - png_write_chunk(png_ptr, (png_bytep)png_cHRM, buf, (png_size_t)32); + 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 @@ -975,50 +1028,33 @@ png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x, #endif png_byte buf[32]; - png_debug(1, "in png_write_cHRM\n"); - /* each value is saved in 1/100,000ths */ - if (white_x > 80000L || white_y > 80000L || white_x + white_y > 100000L) - { - png_warning(png_ptr, "Invalid fixed cHRM white point specified"); -#if !defined(PNG_NO_CONSOLE_IO) - fprintf(stderr,"white_x=%ld, white_y=%ld\n",white_x, white_y); + png_debug(1, "in png_write_cHRM"); + /* Each value is saved in 1/100,000ths */ +#if !defined(PNG_NO_CHECK_cHRM) + if (png_check_cHRM_fixed(png_ptr, white_x, white_y, red_x, red_y, + green_x, green_y, blue_x, blue_y)) #endif - return; - } - png_save_uint_32(buf, (png_uint_32)white_x); - png_save_uint_32(buf + 4, (png_uint_32)white_y); - - if (red_x > 80000L || red_y > 80000L || red_x + red_y > 100000L) { - png_warning(png_ptr, "Invalid cHRM fixed red point specified"); - return; - } - png_save_uint_32(buf + 8, (png_uint_32)red_x); - png_save_uint_32(buf + 12, (png_uint_32)red_y); + png_save_uint_32(buf, (png_uint_32)white_x); + png_save_uint_32(buf + 4, (png_uint_32)white_y); - if (green_x > 80000L || green_y > 80000L || green_x + green_y > 100000L) - { - png_warning(png_ptr, "Invalid fixed cHRM green point specified"); - return; - } - png_save_uint_32(buf + 16, (png_uint_32)green_x); - png_save_uint_32(buf + 20, (png_uint_32)green_y); + png_save_uint_32(buf + 8, (png_uint_32)red_x); + png_save_uint_32(buf + 12, (png_uint_32)red_y); - if (blue_x > 80000L || blue_y > 80000L || blue_x + blue_y > 100000L) - { - png_warning(png_ptr, "Invalid fixed cHRM blue point specified"); - return; - } - png_save_uint_32(buf + 24, (png_uint_32)blue_x); - png_save_uint_32(buf + 28, (png_uint_32)blue_y); + png_save_uint_32(buf + 16, (png_uint_32)green_x); + png_save_uint_32(buf + 20, (png_uint_32)green_y); - png_write_chunk(png_ptr, (png_bytep)png_cHRM, buf, (png_size_t)32); + 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); + } } #endif #endif #if defined(PNG_WRITE_tRNS_SUPPORTED) -/* write the tRNS chunk */ +/* Write the tRNS chunk */ void /* PRIVATE */ png_write_tRNS(png_structp png_ptr, png_bytep trans, png_color_16p tran, int num_trans, int color_type) @@ -1028,21 +1064,22 @@ png_write_tRNS(png_structp png_ptr, png_bytep trans, png_color_16p tran, #endif png_byte buf[6]; - png_debug(1, "in png_write_tRNS\n"); + png_debug(1, "in png_write_tRNS"); if (color_type == PNG_COLOR_TYPE_PALETTE) { if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette) { - png_warning(png_ptr,"Invalid number of transparent colors specified"); + 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, (png_size_t)num_trans); + /* Write the chunk out as it is */ + png_write_chunk(png_ptr, (png_bytep)png_tRNS, trans, + (png_size_t)num_trans); } else if (color_type == PNG_COLOR_TYPE_GRAY) { - /* one 16 bit value */ - if(tran->gray >= (1 << png_ptr->bit_depth)) + /* 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"); @@ -1053,16 +1090,16 @@ png_write_tRNS(png_structp png_ptr, png_bytep trans, png_color_16p tran, } else if (color_type == PNG_COLOR_TYPE_RGB) { - /* three 16 bit values */ + /* 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); - if(png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4])) - { - png_warning(png_ptr, - "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8"); - return; - } + if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4])) + { + 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); } else @@ -1073,7 +1110,7 @@ png_write_tRNS(png_structp png_ptr, png_bytep trans, png_color_16p tran, #endif #if defined(PNG_WRITE_bKGD_SUPPORTED) -/* write the background chunk */ +/* Write the background chunk */ void /* PRIVATE */ png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type) { @@ -1082,7 +1119,7 @@ png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type) #endif png_byte buf[6]; - png_debug(1, "in png_write_bKGD\n"); + png_debug(1, "in png_write_bKGD"); if (color_type == PNG_COLOR_TYPE_PALETTE) { if ( @@ -1090,7 +1127,7 @@ png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type) (png_ptr->num_palette || (!(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE))) && #endif - back->index > png_ptr->num_palette) + back->index >= png_ptr->num_palette) { png_warning(png_ptr, "Invalid background palette index"); return; @@ -1103,17 +1140,17 @@ png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type) png_save_uint_16(buf, back->red); png_save_uint_16(buf + 2, back->green); png_save_uint_16(buf + 4, back->blue); - if(png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4])) - { - png_warning(png_ptr, - "Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8"); - return; - } + if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4])) + { + png_warning(png_ptr, + "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); } else { - if(back->gray >= (1 << png_ptr->bit_depth)) + if (back->gray >= (1 << png_ptr->bit_depth)) { png_warning(png_ptr, "Ignoring attempt to write bKGD chunk out-of-range for bit_depth"); @@ -1126,7 +1163,7 @@ png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type) #endif #if defined(PNG_WRITE_hIST_SUPPORTED) -/* write the histogram */ +/* Write the histogram */ void /* PRIVATE */ png_write_hIST(png_structp png_ptr, png_uint_16p hist, int num_hist) { @@ -1136,16 +1173,17 @@ png_write_hIST(png_structp png_ptr, png_uint_16p hist, int num_hist) int i; png_byte buf[3]; - png_debug(1, "in png_write_hIST\n"); + png_debug(1, "in png_write_hIST"); if (num_hist > (int)png_ptr->num_palette) { - png_debug2(3, "num_hist = %d, num_palette = %d\n", num_hist, + png_debug2(3, "num_hist = %d, num_palette = %d", num_hist, 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_bytep)png_hIST, + (png_uint_32)(num_hist * 2)); for (i = 0; i < num_hist; i++) { png_save_uint_16(buf, hist[i]); @@ -1175,7 +1213,7 @@ png_check_keyword(png_structp png_ptr, png_charp key, png_charpp new_key) int kflag; int kwarn=0; - png_debug(1, "in png_check_keyword\n"); + png_debug(1, "in png_check_keyword"); *new_key = NULL; if (key == NULL || (key_len = png_strlen(key)) == 0) @@ -1184,7 +1222,7 @@ png_check_keyword(png_structp png_ptr, png_charp key, png_charpp new_key) return ((png_size_t)0); } - png_debug1(2, "Keyword to be checked is '%s'\n", 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) @@ -1196,12 +1234,14 @@ 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++) { - if (*kp < 0x20 || (*kp > 0x7E && (png_byte)*kp < 0xA1)) + if ((png_byte)*kp < 0x20 || + ((png_byte)*kp > 0x7E && (png_byte)*kp < 0xA1)) { #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) char msg[40]; - sprintf(msg, "invalid keyword character 0x%02X", *kp); + png_snprintf(msg, 40, + "invalid keyword character 0x%02X", (png_byte)*kp); png_warning(png_ptr, msg); #else png_warning(png_ptr, "invalid character in keyword"); @@ -1223,8 +1263,8 @@ png_check_keyword(png_structp png_ptr, png_charp key, png_charpp new_key) while (*kp == ' ') { - *(kp--) = '\0'; - key_len--; + *(kp--) = '\0'; + key_len--; } } @@ -1236,12 +1276,12 @@ png_check_keyword(png_structp png_ptr, png_charp key, png_charpp new_key) while (*kp == ' ') { - kp++; - key_len--; + kp++; + key_len--; } } - png_debug1(2, "Checking for multiple internal spaces in '%s'\n", kp); + png_debug1(2, "Checking for multiple internal spaces in '%s'", kp); /* Remove multiple internal spaces. */ for (kflag = 0, dp = *new_key; *kp != '\0'; kp++) @@ -1263,20 +1303,20 @@ png_check_keyword(png_structp png_ptr, png_charp key, png_charpp new_key) } } *dp = '\0'; - if(kwarn) + if (kwarn) png_warning(png_ptr, "extra interior spaces removed from keyword"); if (key_len == 0) { png_free(png_ptr, *new_key); - *new_key=NULL; + *new_key=NULL; png_warning(png_ptr, "Zero length keyword"); } if (key_len > 79) { png_warning(png_ptr, "keyword length must be 1 - 79 characters"); - new_key[79] = '\0'; + (*new_key)[79] = '\0'; key_len = 79; } @@ -1285,7 +1325,7 @@ png_check_keyword(png_structp png_ptr, png_charp key, png_charpp new_key) #endif #if defined(PNG_WRITE_tEXt_SUPPORTED) -/* write a tEXt chunk */ +/* Write a tEXt chunk */ void /* PRIVATE */ png_write_tEXt(png_structp png_ptr, png_charp key, png_charp text, png_size_t text_len) @@ -1296,29 +1336,28 @@ png_write_tEXt(png_structp png_ptr, png_charp key, png_charp text, png_size_t key_len; png_charp new_key; - png_debug(1, "in png_write_tEXt\n"); - if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0) - { - png_warning(png_ptr, "Empty keyword in tEXt chunk"); + png_debug(1, "in png_write_tEXt"); + if ((key_len = png_check_keyword(png_ptr, key, &new_key))==0) return; - } 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); + /* 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)); /* * We leave it to the application to meet PNG-1.0 requirements on the * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them. * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. */ - png_write_chunk_data(png_ptr, (png_bytep)new_key, key_len + 1); + png_write_chunk_data(png_ptr, (png_bytep)new_key, + (png_size_t)(key_len + 1)); if (text_len) - png_write_chunk_data(png_ptr, (png_bytep)text, text_len); + png_write_chunk_data(png_ptr, (png_bytep)text, (png_size_t)text_len); png_write_chunk_end(png_ptr); png_free(png_ptr, new_key); @@ -1326,7 +1365,7 @@ png_write_tEXt(png_structp png_ptr, png_charp key, png_charp text, #endif #if defined(PNG_WRITE_zTXt_SUPPORTED) -/* write a compressed text chunk */ +/* 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) @@ -1339,11 +1378,17 @@ png_write_zTXt(png_structp png_ptr, png_charp key, png_charp text, png_charp new_key; compression_state comp; - png_debug(1, "in png_write_zTXt\n"); + png_debug(1, "in png_write_zTXt"); - if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0) + comp.num_output_ptr = 0; + comp.max_output_ptr = 0; + comp.output_ptr = NULL; + comp.input = NULL; + comp.input_len = 0; + + if ((key_len = png_check_keyword(png_ptr, key, &new_key))==0) { - png_warning(png_ptr, "Empty keyword in zTXt chunk"); + png_free(png_ptr, new_key); return; } @@ -1356,30 +1401,31 @@ png_write_zTXt(png_structp png_ptr, png_charp key, png_charp text, text_len = png_strlen(text); - png_free(png_ptr, new_key); - - /* compute the compressed data; do it now for the length */ + /* Compute the compressed data; do it now for the length */ text_len = png_text_compress(png_ptr, text, text_len, compression, &comp); - /* write start of chunk */ - png_write_chunk_start(png_ptr, (png_bytep)png_zTXt, (png_uint_32) - (key_len+text_len+2)); - /* write key */ - png_write_chunk_data(png_ptr, (png_bytep)key, key_len + 1); + /* Write start of chunk */ + png_write_chunk_start(png_ptr, (png_bytep)png_zTXt, + (png_uint_32)(key_len+text_len + 2)); + /* Write key */ + png_write_chunk_data(png_ptr, (png_bytep)new_key, + (png_size_t)(key_len + 1)); + png_free(png_ptr, new_key); + buf[0] = (png_byte)compression; - /* write compression */ + /* Write compression */ png_write_chunk_data(png_ptr, (png_bytep)buf, (png_size_t)1); - /* write the compressed data */ + /* Write the compressed data */ png_write_compressed_data_out(png_ptr, &comp); - /* close the chunk */ + /* Close the chunk */ png_write_chunk_end(png_ptr); } #endif #if defined(PNG_WRITE_iTXt_SUPPORTED) -/* write an iTXt chunk */ +/* 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) @@ -1388,18 +1434,22 @@ png_write_iTXt(png_structp png_ptr, int compression, png_charp key, PNG_iTXt; #endif png_size_t lang_len, key_len, lang_key_len, text_len; - png_charp new_lang, new_key; + png_charp new_lang; + png_charp new_key = NULL; png_byte cbuf[2]; compression_state comp; - png_debug(1, "in png_write_iTXt\n"); + png_debug(1, "in png_write_iTXt"); - if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0) - { - png_warning(png_ptr, "Empty keyword in iTXt chunk"); + comp.num_output_ptr = 0; + comp.max_output_ptr = 0; + comp.output_ptr = NULL; + comp.input = NULL; + + if ((key_len = png_check_keyword(png_ptr, key, &new_key))==0) return; - } - if (lang == NULL || (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; @@ -1407,21 +1457,21 @@ png_write_iTXt(png_structp png_ptr, int compression, png_charp key, } if (lang_key == NULL) - lang_key_len = 0; + lang_key_len = 0; else - lang_key_len = png_strlen(lang_key); + lang_key_len = png_strlen(lang_key); if (text == NULL) text_len = 0; else - text_len = png_strlen(text); + text_len = png_strlen(text); - /* compute the compressed data; do it now for the length */ + /* Compute the compressed data; do it now for the length */ text_len = png_text_compress(png_ptr, text, text_len, compression-2, &comp); - /* make sure we include the compression flag, the compression byte, + /* Make sure we include the compression flag, the compression byte, * and the NULs after the key, lang, and lang_key parts */ png_write_chunk_start(png_ptr, (png_bytep)png_iTXt, @@ -1432,38 +1482,39 @@ png_write_iTXt(png_structp png_ptr, int compression, png_charp key, + lang_key_len + text_len)); - /* - * We leave it to the application to meet PNG-1.0 requirements on the + /* We leave it to the application to meet PNG-1.0 requirements on the * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them. * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG. */ - png_write_chunk_data(png_ptr, (png_bytep)new_key, key_len + 1); + png_write_chunk_data(png_ptr, (png_bytep)new_key, + (png_size_t)(key_len + 1)); - /* set the compression flag */ + /* Set the compression flag */ if (compression == PNG_ITXT_COMPRESSION_NONE || \ compression == PNG_TEXT_COMPRESSION_NONE) cbuf[0] = 0; else /* compression == PNG_ITXT_COMPRESSION_zTXt */ cbuf[0] = 1; - /* set the compression method */ + /* Set the compression method */ cbuf[1] = 0; - png_write_chunk_data(png_ptr, cbuf, 2); + 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), lang_len + 1); - png_write_chunk_data(png_ptr, (lang_key ? (png_bytep)lang_key : cbuf), lang_key_len + 1); + 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_compressed_data_out(png_ptr, &comp); png_write_chunk_end(png_ptr); png_free(png_ptr, new_key); - if (new_lang) - png_free(png_ptr, new_lang); + png_free(png_ptr, new_lang); } #endif #if defined(PNG_WRITE_oFFs_SUPPORTED) -/* write the oFFs chunk */ +/* 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) @@ -1473,7 +1524,7 @@ png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset, #endif png_byte buf[9]; - png_debug(1, "in png_write_oFFs\n"); + png_debug(1, "in png_write_oFFs"); if (unit_type >= PNG_OFFSET_LAST) png_warning(png_ptr, "Unrecognized unit type for oFFs chunk"); @@ -1484,9 +1535,8 @@ png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset, png_write_chunk(png_ptr, (png_bytep)png_oFFs, buf, (png_size_t)9); } #endif - #if defined(PNG_WRITE_pCAL_SUPPORTED) -/* write the pCAL chunk (described in the PNG extensions document) */ +/* 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) @@ -1500,31 +1550,33 @@ png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0, png_charp new_purpose; int i; - png_debug1(1, "in png_write_pCAL (%d parameters)\n", nparams); + png_debug1(1, "in png_write_pCAL (%d parameters)", nparams); if (type >= PNG_EQUATION_LAST) png_warning(png_ptr, "Unrecognized equation type for pCAL chunk"); purpose_len = png_check_keyword(png_ptr, purpose, &new_purpose) + 1; - png_debug1(3, "pCAL purpose length = %d\n", (int)purpose_len); + png_debug1(3, "pCAL purpose length = %d", (int)purpose_len); units_len = png_strlen(units) + (nparams == 0 ? 0 : 1); - png_debug1(3, "pCAL units length = %d\n", (int)units_len); + png_debug1(3, "pCAL units length = %d", (int)units_len); total_len = purpose_len + units_len + 10; - params_len = (png_uint_32p)png_malloc(png_ptr, (png_uint_32)(nparams - *png_sizeof(png_uint_32))); + params_len = (png_uint_32p)png_malloc(png_ptr, + (png_uint_32)(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. */ 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\n", i, params_len[i]); + png_debug2(3, "pCAL parameter %d length = %lu", i, + (unsigned long) params_len[i]); total_len += (png_size_t)params_len[i]; } - png_debug1(3, "pCAL total length = %d\n", (int)total_len); + 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, purpose_len); + png_write_chunk_data(png_ptr, (png_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; @@ -1546,42 +1598,44 @@ png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0, #endif #if defined(PNG_WRITE_sCAL_SUPPORTED) -/* write the sCAL chunk */ +/* Write the sCAL chunk */ #if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO) void /* PRIVATE */ -png_write_sCAL(png_structp png_ptr, int unit, double width,double height) +png_write_sCAL(png_structp png_ptr, int unit, double width, double height) { #ifdef PNG_USE_LOCAL_ARRAYS PNG_sCAL; #endif + char buf[64]; png_size_t total_len; - char wbuf[32], hbuf[32]; - png_byte bunit = unit; - png_debug(1, "in png_write_sCAL\n"); + png_debug(1, "in png_write_sCAL"); + buf[0] = (char)unit; #if defined(_WIN32_WCE) /* sprintf() function is not supported on WindowsCE */ { wchar_t wc_buf[32]; + size_t wc_len; swprintf(wc_buf, TEXT("%12.12e"), width); - WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, wbuf, 32, NULL, NULL); + wc_len = wcslen(wc_buf); + WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, buf + 1, wc_len, NULL, NULL); + total_len = wc_len + 2; swprintf(wc_buf, TEXT("%12.12e"), height); - WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, hbuf, 32, NULL, NULL); + wc_len = wcslen(wc_buf); + WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, buf + total_len, wc_len, + NULL, NULL); + total_len += wc_len; } #else - sprintf(wbuf, "%12.12e", width); - sprintf(hbuf, "%12.12e", height); + 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); #endif - total_len = 1 + png_strlen(wbuf)+1 + png_strlen(hbuf); - png_debug1(3, "sCAL total length = %d\n", (int)total_len); - png_write_chunk_start(png_ptr, (png_bytep)png_sCAL, (png_uint_32)total_len); - png_write_chunk_data(png_ptr, (png_bytep)&bunit, 1); - png_write_chunk_data(png_ptr, (png_bytep)wbuf, png_strlen(wbuf)+1); - png_write_chunk_data(png_ptr, (png_bytep)hbuf, png_strlen(hbuf)); - - png_write_chunk_end(png_ptr); + 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 @@ -1592,30 +1646,33 @@ png_write_sCAL_s(png_structp png_ptr, int unit, png_charp width, #ifdef PNG_USE_LOCAL_ARRAYS PNG_sCAL; #endif - png_size_t total_len; - char wbuf[32], hbuf[32]; - png_byte bunit = unit; + png_byte buf[64]; + png_size_t wlen, hlen, total_len; - png_debug(1, "in png_write_sCAL_s\n"); + png_debug(1, "in png_write_sCAL_s"); - png_strcpy(wbuf,(const char *)width); - png_strcpy(hbuf,(const char *)height); - total_len = 1 + png_strlen(wbuf)+1 + png_strlen(hbuf); + 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)"); + return; + } - png_debug1(3, "sCAL total length = %d\n", total_len); - png_write_chunk_start(png_ptr, (png_bytep)png_sCAL, (png_uint_32)total_len); - png_write_chunk_data(png_ptr, (png_bytep)&bunit, 1); - png_write_chunk_data(png_ptr, (png_bytep)wbuf, png_strlen(wbuf)+1); - png_write_chunk_data(png_ptr, (png_bytep)hbuf, png_strlen(hbuf)); + buf[0] = (png_byte)unit; + png_memcpy(buf + 1, width, wlen + 1); /* Append the '\0' here */ + png_memcpy(buf + wlen + 2, height, hlen); /* Do NOT append the '\0' here */ - png_write_chunk_end(png_ptr); + png_debug1(3, "sCAL total length = %u", (unsigned int)total_len); + png_write_chunk(png_ptr, (png_bytep)png_sCAL, buf, total_len); } #endif #endif #endif #if defined(PNG_WRITE_pHYs_SUPPORTED) -/* write the pHYs chunk */ +/* 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, @@ -1626,7 +1683,7 @@ png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit, #endif png_byte buf[9]; - png_debug(1, "in png_write_pHYs\n"); + png_debug(1, "in png_write_pHYs"); if (unit_type >= PNG_RESOLUTION_LAST) png_warning(png_ptr, "Unrecognized unit type for pHYs chunk"); @@ -1650,7 +1707,7 @@ png_write_tIME(png_structp png_ptr, png_timep mod_time) #endif png_byte buf[7]; - png_debug(1, "in png_write_tIME\n"); + png_debug(1, "in png_write_tIME"); if (mod_time->month > 12 || mod_time->month < 1 || mod_time->day > 31 || mod_time->day < 1 || mod_time->hour > 23 || mod_time->second > 60) @@ -1670,75 +1727,81 @@ png_write_tIME(png_structp png_ptr, png_timep mod_time) } #endif -/* initializes the row writing capability of libpng */ +/* Initializes the row writing capability of libpng */ void /* PRIVATE */ png_write_start_row(png_structp png_ptr) { +#ifdef PNG_WRITE_INTERLACING_SUPPORTED #ifdef PNG_USE_LOCAL_ARRAYS - /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - /* start of interlace block */ + /* Start of interlace block */ int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; - /* offset to next interlace block */ + /* Offset to next interlace block */ int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; - /* start of interlace block in the y direction */ + /* Start of interlace block in the y direction */ int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; - /* offset to next interlace block in the y direction */ + /* Offset to next interlace block in the y direction */ int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; +#endif #endif png_size_t buf_size; - png_debug(1, "in png_write_start_row\n"); + 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_uint_32)buf_size); + /* Set up row buffer */ + png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, + (png_uint_32)buf_size); png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE; - /* set up filtering buffer, if using this filter */ +#ifndef PNG_NO_WRITE_FILTER + /* 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_ptr->rowbytes + 1)); + (png_uint_32)(png_ptr->rowbytes + 1)); png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB; } /* We only need to keep the previous row if we are using one of these. */ if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH)) { - /* set up previous row buffer */ - png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)buf_size); - png_memset(png_ptr->prev_row, 0, buf_size); + /* Set up previous row buffer */ + png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, + (png_uint_32)buf_size); + png_memset(png_ptr->prev_row, 0, buf_size); if (png_ptr->do_filter & PNG_FILTER_UP) { - png_ptr->up_row = (png_bytep )png_malloc(png_ptr, - (png_ptr->rowbytes + 1)); + png_ptr->up_row = (png_bytep)png_malloc(png_ptr, + (png_uint_32)(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_ptr->rowbytes + 1)); + (png_uint_32)(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_ptr->rowbytes + 1)); + png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr, + (png_uint_32)(png_ptr->rowbytes + 1)); png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH; } } +#endif /* PNG_NO_WRITE_FILTER */ #ifdef PNG_WRITE_INTERLACING_SUPPORTED - /* if interlaced, we need to set up width and height of pass */ + /* If interlaced, we need to set up width and height of pass */ if (png_ptr->interlaced) { if (!(png_ptr->transformations & PNG_INTERLACE)) @@ -1768,34 +1831,36 @@ png_write_start_row(png_structp png_ptr) void /* PRIVATE */ png_write_finish_row(png_structp png_ptr) { +#ifdef PNG_WRITE_INTERLACING_SUPPORTED #ifdef PNG_USE_LOCAL_ARRAYS - /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - /* start of interlace block */ + /* Start of interlace block */ int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; - /* offset to next interlace block */ + /* Offset to next interlace block */ int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; - /* start of interlace block in the y direction */ + /* Start of interlace block in the y direction */ int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; - /* offset to next interlace block in the y direction */ + /* Offset to next interlace block in the y direction */ int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; +#endif #endif int ret; - png_debug(1, "in png_write_finish_row\n"); - /* next row */ + png_debug(1, "in png_write_finish_row"); + /* Next row */ png_ptr->row_number++; - /* see if we are done */ + /* See if we are done */ if (png_ptr->row_number < png_ptr->num_rows) return; #ifdef PNG_WRITE_INTERLACING_SUPPORTED - /* if interlaced, go to next pass */ + /* If interlaced, go to next pass */ if (png_ptr->interlaced) { png_ptr->row_number = 0; @@ -1805,7 +1870,7 @@ png_write_finish_row(png_structp png_ptr) } else { - /* loop until we find a non-zero width or height pass */ + /* Loop until we find a non-zero width or height pass */ do { png_ptr->pass++; @@ -1825,28 +1890,28 @@ png_write_finish_row(png_structp png_ptr) } - /* reset the row above the image for the next pass */ + /* Reset the row above the image for the next pass */ if (png_ptr->pass < 7) { 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_ptr->usr_bit_depth, png_ptr->width)) + 1); return; } } #endif - /* if we get here, we've just written the last row, so we need + /* If we get here, we've just written the last row, so we need to flush the compressor */ do { - /* tell the compressor we are done */ + /* Tell the compressor we are done */ ret = deflate(&png_ptr->zstream, Z_FINISH); - /* check for an error */ + /* Check for an error */ if (ret == Z_OK) { - /* check to see if we need more room */ + /* Check to see if we need more room */ if (!(png_ptr->zstream.avail_out)) { png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); @@ -1863,7 +1928,7 @@ png_write_finish_row(png_structp png_ptr) } } while (ret != Z_STREAM_END); - /* write any extra space */ + /* Write any extra space */ if (png_ptr->zstream.avail_out < png_ptr->zbuf_size) { png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size - @@ -1871,6 +1936,7 @@ png_write_finish_row(png_structp png_ptr) } deflateReset(&png_ptr->zstream); + png_ptr->zstream.data_type = Z_BINARY; } #if defined(PNG_WRITE_INTERLACING_SUPPORTED) @@ -1885,24 +1951,24 @@ void /* PRIVATE */ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) { #ifdef PNG_USE_LOCAL_ARRAYS - /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */ + /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - /* start of interlace block */ + /* Start of interlace block */ int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; - /* offset to next interlace block */ + /* Offset to next interlace block */ int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; #endif - png_debug(1, "in png_do_write_interlace\n"); - /* we don't have to do anything on the last pass (6) */ + png_debug(1, "in png_do_write_interlace"); + /* We don't have to do anything on the last pass (6) */ #if defined(PNG_USELESS_TESTS_SUPPORTED) if (row != NULL && row_info != NULL && pass < 6) #else if (pass < 6) #endif { - /* each pixel depth is handled separately */ + /* Each pixel depth is handled separately */ switch (row_info->pixel_depth) { case 1: @@ -2013,27 +2079,27 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) png_uint_32 row_width = row_info->width; png_size_t pixel_bytes; - /* start at the beginning */ + /* Start at the beginning */ dp = row; - /* find out how many bytes each pixel takes up */ + /* 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 + /* 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 */ + /* Find out where the original pixel is */ sp = row + (png_size_t)i * pixel_bytes; - /* move the pixel */ + /* Move the pixel */ if (dp != sp) png_memcpy(dp, sp, pixel_bytes); - /* next pixel */ + /* Next pixel */ dp += pixel_bytes; } break; } } - /* set new row width */ + /* Set new row width */ row_info->width = (row_info->width + png_pass_inc[pass] - 1 - png_pass_start[pass]) / @@ -2048,27 +2114,35 @@ png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass) * been specified by the application, and then writes the row out with the * chosen filter. */ -#define PNG_MAXSUM (~((png_uint_32)0) >> 1) +#define PNG_MAXSUM (((png_uint_32)(-1)) >> 1) #define PNG_HISHIFT 10 #define PNG_LOMASK ((png_uint_32)0xffffL) #define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT)) void /* PRIVATE */ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) { - png_bytep prev_row, best_row, row_buf; + png_bytep best_row; +#ifndef PNG_NO_WRITE_FILTER + 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; -#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) +#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED int num_p_filters = (int)png_ptr->num_prev_filters; -#endif +#endif - png_debug(1, "in png_write_find_filter\n"); - /* find out how many bytes offset each pixel is */ + png_debug(1, "in png_write_find_filter"); + + + png_debug(1, "in png_write_find_filter"); + /* Find out how many bytes offset each pixel is */ bpp = (row_info->pixel_depth + 7) >> 3; prev_row = png_ptr->prev_row; - best_row = row_buf = png_ptr->row_buf; +#endif + best_row = png_ptr->row_buf; +#ifndef PNG_NO_WRITE_FILTER + row_buf = best_row; mins = PNG_MAXSUM; /* The prediction method we use is to find which method provides the @@ -2148,9 +2222,9 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) mins = sum; } - /* sub filter */ + /* Sub filter */ if (filter_to_do == PNG_FILTER_SUB) - /* it's the only filter so no testing is needed */ + /* It's the only filter so no testing is needed */ { png_bytep rp, lp, dp; png_uint_32 i; @@ -2265,7 +2339,7 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) } } - /* up filter */ + /* Up filter */ if (filter_to_do == PNG_FILTER_UP) { png_bytep rp, dp, pp; @@ -2368,7 +2442,7 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) } } - /* avg filter */ + /* Avg filter */ if (filter_to_do == PNG_FILTER_AVG) { png_bytep rp, dp, pp, lp; @@ -2643,11 +2717,12 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) best_row = png_ptr->paeth_row; } } - +#endif /* PNG_NO_WRITE_FILTER */ /* Do the actual writing of the filtered row data from the chosen filter. */ png_write_filtered_row(png_ptr, best_row); +#ifndef PNG_NO_WRITE_FILTER #if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) /* Save the type of filter we picked this time for future calculations */ if (png_ptr->num_prev_filters > 0) @@ -2660,6 +2735,7 @@ png_write_find_filter(png_structp png_ptr, png_row_infop row_info) png_ptr->prev_filters[j] = best_row[0]; } #endif +#endif /* PNG_NO_WRITE_FILTER */ } @@ -2667,20 +2743,20 @@ 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_debug(1, "in png_write_filtered_row\n"); - png_debug1(2, "filter = %d\n", filtered_row[0]); - /* set up the zlib input buffer */ + 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; - /* repeat until we have compressed all the data */ + /* Repeat until we have compressed all the data */ do { - int ret; /* return of zlib */ + int ret; /* Return of zlib */ - /* compress the data */ + /* Compress the data */ ret = deflate(&png_ptr->zstream, Z_NO_FLUSH); - /* check for compression errors */ + /* Check for compression errors */ if (ret != Z_OK) { if (png_ptr->zstream.msg != NULL) @@ -2689,18 +2765,18 @@ png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row) png_error(png_ptr, "zlib error"); } - /* see if it is time to write another IDAT */ + /* See if it is time to write another IDAT */ if (!(png_ptr->zstream.avail_out)) { - /* write the IDAT and reset the zlib output buffer */ + /* Write the IDAT and reset the zlib output buffer */ 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; } - /* repeat until all data has been compressed */ + /* Repeat until all data has been compressed */ } while (png_ptr->zstream.avail_in); - /* swap the current and previous rows */ + /* Swap the current and previous rows */ if (png_ptr->prev_row != NULL) { png_bytep tptr; @@ -2710,7 +2786,7 @@ png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row) png_ptr->row_buf = tptr; } - /* finish row - updates counters and flushes zlib if last row */ + /* Finish row - updates counters and flushes zlib if last row */ png_write_finish_row(png_ptr); #if defined(PNG_WRITE_FLUSH_SUPPORTED)