From f671d863fe45e837a8fa58be506a733213c49d7d Mon Sep 17 00:00:00 2001 From: Glenn Randers-Pehrson Date: Mon, 8 Oct 2001 20:32:33 -0500 Subject: [PATCH] Imported from pngcrush-1.5.7.tar --- Makefile.msc | 2 +- README.txt | 43 +++-- png.c | 65 +++++++- png.h | 108 ++++++++++--- pngasmrd.h | 2 +- pngconf.h | 30 +--- pngcrush.c | 194 ++++++++++++----------- pngcrush.h | 5 + pngerror.c | 3 +- pnggccrd.c | 434 +++++++++++++++++++++++++++++++++------------------ pngget.c | 90 ++++++++++- pngmem.c | 2 +- pngpread.c | 4 +- pngread.c | 41 +---- pngrio.c | 3 +- pngrtran.c | 2 +- pngrutil.c | 21 +-- pngset.c | 69 +++++++- pngtrans.c | 39 ++++- pngvcrd.c | 80 +++++----- pngwio.c | 2 +- pngwrite.c | 39 ++--- pngwtran.c | 2 +- pngwutil.c | 64 +++++--- 24 files changed, 885 insertions(+), 459 deletions(-) diff --git a/Makefile.msc b/Makefile.msc index 4bb65c044..8ae8327fc 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -12,7 +12,7 @@ # macros -------------------------------------------------------------------- CC = cl -nologo -LD = link -nologo +LD = link -nologo setargv.obj RM = del CFLAGS = -I. -DPNG_ZBUF_SIZE=0x080000 -DWIN32 -O2 LDFLAGS = diff --git a/README.txt b/README.txt index 19f5de99e..d8015aefc 100644 --- a/README.txt +++ b/README.txt @@ -40,12 +40,14 @@ case of any discrepancy, the copy in pngcrush.c shall prevail): This is the output of "pngcrush" and "pngcrush -help": - | pngcrush 1.5.6, Copyright (C) 1998-2001 Glenn Randers-Pehrson + + | pngcrush 1.5.7, Copyright (C) 1998-2001 Glenn Randers-Pehrson | This is a free, open-source program. Permission is irrevocably | granted to everyone to use this version of pngcrush without | payment of any fee. - | This program was built with libpng version 1.0.12, and is - | running with libpng version 1.0.12 - June 8, 2001 (header) + | Executable name is pngcrush + | It was built with libpng version 1.2.0, and is + | running with libpng version 1.2.0 - September 1, 2001 (header) | Copyright (C) 1998-2001 Glenn Randers-Pehrson, | Copyright (C) 1996, 1997 Andreas Dilger, | Copyright (C) 1995, Guy Eric Schalnat, Group 42 Inc., @@ -61,6 +63,7 @@ options: -bit_depth depth (bit_depth to use in output file) -brute (Use brute-force, try 114 different methods [11-124]) -c color_type of output file [0, 2, 4, or 6] + -cc (do color counting) -d directory_name (where output files will go) -double_gamma (used for fixing gamma in PhotoShop 5.0/5.02 files) -e extension (used for creating output filename) @@ -74,6 +77,8 @@ options: -loco ("loco crush" truecolor PNGs) -m method [0 through 200] -max maximum_IDAT_size [default 8192] + -no_cc (no color counting) + -nofilecheck (do not check for infile.png == outfile.png) -n (no save; does not do compression or write output PNG) -plte_len n (truncate PLTE) -q (quiet) @@ -81,6 +86,7 @@ options: -rem chunkname (or "alla" or "allb") -replace_gamma gamma (float or fixed*100000) even if gAMA is present. -res dpi + -save (keep all copy-unsafe chunks) -srgb [0, 1, 2, or 3] -text b[efore_IDAT]|a[fter_IDAT] "keyword" "text" -trns index red green blue gray @@ -95,12 +101,13 @@ options: -p (pause) - | pngcrush 1.5.6, Copyright (C) 1998-2001 Glenn Randers-Pehrson + | pngcrush 1.5.7, Copyright (C) 1998-2001 Glenn Randers-Pehrson | This is a free, open-source program. Permission is irrevocably | granted to everyone to use this version of pngcrush without | payment of any fee. - | This program was built with libpng version 1.0.12, and is - | running with libpng version 1.0.12 - June 8, 2001 (header) + | Executable name is pngcrush + | It was built with libpng version 1.2.0, and is + | running with libpng version 1.2.0 - September 1, 2001 (header) | Copyright (C) 1998-2001 Glenn Randers-Pehrson, | Copyright (C) 1996, 1997 Andreas Dilger, | Copyright (C) 1995, Guy Eric Schalnat, Group 42 Inc., @@ -145,6 +152,8 @@ options (Note: any option can be spelled out for clarity, e.g., Use 0 or 2 to delete an unwanted alpha channel. Default is to use same color type as the input file. + -cc (do color counting) + -d directory_name (where output files will go) If a directory name is given, then the output @@ -210,13 +219,22 @@ options (Note: any option can be spelled out for clarity, e.g., pngcrush method to try (0 means try all of 1-10). Can be repeated as in '-m 1 -m 4 -m 7'. - This can be useful if you run out of memory when pngcrush - tries methods 2, 3, 5, 6, 8, 9, or 10 which use - filtering and are memory intensive. Methods + This can be useful if pngcrush runs out of memory + when it tries methods 2, 3, 5, 6, 8, 9, or 10 which + use filtering and are memory intensive. Methods 1, 4, and 7 use no filtering; methods 11 and up use specified filter, compression level, and strategy. -max maximum_IDAT_size [default 8192] + + -no_cc (no color counting) + + -nofilecheck (do not check for infile.png == outfile.png) + + To avoid false hits from MSVC-compiled code. Note + that if you use this option, you are responsible for + ensuring that the input file is not the output file. + -n (no save; does not do compression or write output PNG) Useful in conjunction with -v option to get info. @@ -254,6 +272,12 @@ options (Note: any option can be spelled out for clarity, e.g., Write a pHYs chunk with the given resolution. + -save (keep all copy-unsafe chunks) + + Save otherwise unknown ancillary chunks that would + be considered copy-unsafe. This option makes + chunks 'known' to pngcrush, so they can be copied. + -srgb [0, 1, 2, or 3] Value of 'rendering intent' for sRGB chunk. @@ -312,4 +336,3 @@ options (Note: any option can be spelled out for clarity, e.g., Wait for [enter] key before continuing display. e.g., type 'pngcrush -pause -help', if the help screen scrolls out of sight. - diff --git a/png.c b/png.c index 0cc4e8ee4..8b56feed3 100644 --- a/png.c +++ b/png.c @@ -1,7 +1,7 @@ /* png.c - location for general purpose libpng functions * - * libpng version 1.0.12 - June 8, 2001 + * libpng version 1.2.0 - September 1, 2001 * Copyright (c) 1998-2001 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) @@ -13,14 +13,14 @@ #include "png.h" /* Generate a compiler error if there is an old png.h in the search path. */ -typedef version_1_0_12 Your_png_h_is_not_version_1_0_12; +typedef version_1_2_0 Your_png_h_is_not_version_1_2_0; /* Version information for C files. This had better match the version * string defined in png.h. */ #ifdef PNG_USE_GLOBAL_ARRAYS /* png_libpng_ver was changed to a function in version 1.0.5c */ -const char png_libpng_ver[18] = "1.0.12"; +const char png_libpng_ver[18] = "1.2.0"; /* png_sig was changed to a function in version 1.0.5c */ /* Place to hold the signature string for a PNG file. */ @@ -551,7 +551,7 @@ png_info_destroy(png_structp png_ptr, png_infop info_ptr) if (png_ptr->num_chunk_list) { png_free(png_ptr, png_ptr->chunk_list); - png_ptr->chunk_list=NULL; + png_ptr->chunk_list=(png_bytep)NULL; png_ptr->num_chunk_list=0; } #endif @@ -646,7 +646,7 @@ png_charp PNGAPI png_get_copyright(png_structp png_ptr) { if (png_ptr != NULL || png_ptr == NULL) /* silence compiler warning */ - return ((png_charp) "\n libpng version 1.0.12 - June 8, 2001\n\ + return ((png_charp) "\n libpng version 1.2.0 - September 1, 2001\n\ Copyright (c) 1998-2001 Glenn Randers-Pehrson\n\ Copyright (c) 1996, 1997 Andreas Dilger\n\ Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.\n"); @@ -664,8 +664,8 @@ png_get_libpng_ver(png_structp png_ptr) { /* Version of *.c files used when building libpng */ if(png_ptr != NULL) /* silence compiler warning about unused png_ptr */ - return((png_charp) "1.0.12"); - return((png_charp) "1.0.12"); + return((png_charp) "1.2.0"); + return((png_charp) "1.2.0"); } png_charp PNGAPI @@ -715,9 +715,58 @@ png_uint_32 PNGAPI png_access_version_number(void) { /* Version of *.c files used when building libpng */ - return((png_uint_32) 10012L); + return((png_uint_32) 10200L); } + +#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()) { + 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)) diff --git a/png.h b/png.h index ad41d48fc..f9d4cbd84 100644 --- a/png.h +++ b/png.h @@ -1,7 +1,7 @@ /* png.h - header file for PNG reference library * - * libpng version 1.0.12 - June 8, 2001 + * libpng version 1.2.0 - September 1, 2001 * Copyright (c) 1998-2001 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.) @@ -9,7 +9,7 @@ * 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.0.12 - June 8, 2001: Glenn + * libpng versions 0.97, January 1998, through 1.2.0 - September 1, 2001: Glenn * See also "Contributing Authors", below. * * Note about libpng version numbers: @@ -70,7 +70,12 @@ * 1.0.11beta1-3 1 10011 2.1.0.11beta1-3 * 1.0.11rc1 1 10011 2.1.0.11rc1 * 1.0.11 1 10011 2.1.0.11 - * 1.0.12beta1-2 2 10012 2.1.0.11beta1-2 + * 1.0.12beta1-2 2 10012 2.1.0.12beta1-2 + * 1.0.12rc1 2 10012 2.1.0.12rc1 + * 1.0.12 2 10012 2.1.0.12 + * 1.1.0a-f - 10100 2.1.1.0a-f (branch abandoned) + * 1.2.0beta1-2 2 10200 2.1.2.0beta1-2 + * 1.2.0beta3-4 3 10200 3.1.2.0beta3-4 * * Henceforth the source version will match the shared-library major * and minor numbers; the shared-library major version number will be @@ -100,7 +105,7 @@ * If you modify libpng you may insert additional notices immediately following * this sentence. * - * libpng versions 1.0.7, July 1, 2000, through 1.0.12, June 8, 2001, are + * libpng versions 1.0.7, July 1, 2000, through 1.2.0, September 1, 2001, are * Copyright (c) 2000, 2001 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 @@ -205,13 +210,13 @@ * Y2K compliance in libpng: * ========================= * - * June 8, 2001 + * September 1, 2001 * * Since the PNG Development group is an ad-hoc body, we can't make * an official declaration. * * This is your unofficial assurance that libpng from version 0.71 and - * upward through 1.0.12 are Y2K compliant. It is my belief that earlier + * upward through 1.2.0 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 @@ -267,15 +272,15 @@ */ /* Version information for png.h - this should match the version in png.c */ -#define PNG_LIBPNG_VER_STRING "1.0.12" +#define PNG_LIBPNG_VER_STRING "1.2.0" -#define PNG_LIBPNG_VER_SONUM 2 +#define PNG_LIBPNG_VER_SONUM 3 #define PNG_LIBPNG_VER_DLLNUM %DLLNUM% /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */ #define PNG_LIBPNG_VER_MAJOR 1 -#define PNG_LIBPNG_VER_MINOR 0 -#define PNG_LIBPNG_VER_RELEASE 12 +#define PNG_LIBPNG_VER_MINOR 2 +#define PNG_LIBPNG_VER_RELEASE 0 /* This should match the numeric part of the final component of * PNG_LIBPNG_VER_STRING, omitting any leading zero: */ @@ -294,7 +299,7 @@ * Versions 0.7 through 1.0.0 were in the range 0 to 100 here (only * version 1.0.0 was mis-numbered 100 instead of 10000). From * version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release */ -#define PNG_LIBPNG_VER 10012 /* 1.0.12 */ +#define PNG_LIBPNG_VER 10200 /* 1.2.0 */ #ifndef PNG_VERSION_INFO_ONLY @@ -1171,7 +1176,7 @@ struct png_struct_def defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \ defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) /* changed from png_byte to png_uint_32 at version 1.2.0 */ - png_byte mng_features_permitted; + png_uint_32 mng_features_permitted; #endif /* New member added in libpng-1.0.7 */ @@ -1203,13 +1208,15 @@ struct png_struct_def png_free_ptr free_fn; /* function for freeing memory */ #endif + png_bytep big_row_buf; /* buffer to save current (unfiltered) row */ + }; /* This prevents a compiler error in png_get_copyright() in png.c if png.c - and png.h are both at version 1.0.12 + and png.h are both at version 1.2.0 */ -typedef png_structp version_1_0_12; +typedef png_structp version_1_2_0; typedef png_struct FAR * FAR * png_structpp; @@ -2253,11 +2260,68 @@ extern PNG_EXPORT(png_uint_32,png_permit_mng_features) PNGARG((png_structp png_ptr, png_uint_32 mng_features_permitted)); #endif -/* png_mmx_support will be included unconditionally starting in version 1.2.0 */ -#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) || defined(PNG_USE_PNGGCCRD) +/* Added to version 1.2.0 */ +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) +#define PNG_ASM_FLAG_MMX_SUPPORT_COMPILED 0x01 /* not user-settable */ +#define PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU 0x02 /* not user-settable */ +#define PNG_ASM_FLAG_MMX_READ_COMBINE_ROW 0x04 +#define PNG_ASM_FLAG_MMX_READ_INTERLACE 0x08 +#define PNG_ASM_FLAG_MMX_READ_FILTER_SUB 0x10 +#define PNG_ASM_FLAG_MMX_READ_FILTER_UP 0x20 +#define PNG_ASM_FLAG_MMX_READ_FILTER_AVG 0x40 +#define PNG_ASM_FLAG_MMX_READ_FILTER_PAETH 0x80 +#define PNG_ASM_FLAGS_INITIALIZED 0x80000000 /* not user-settable */ + +#define PNG_MMX_READ_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 ) +#define PNG_MMX_WRITE_FLAGS ( 0 ) + +#define PNG_MMX_FLAGS ( PNG_ASM_FLAG_MMX_SUPPORT_COMPILED \ + | PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU \ + | PNG_MMX_READ_FLAGS \ + | PNG_MMX_WRITE_FLAGS ) + +#define PNG_SELECT_READ 1 +#define PNG_SELECT_WRITE 2 + + +/* pngget.c */ +extern PNG_EXPORT(png_uint_32,png_get_mmx_flagmask) + PNGARG((int flag_select, int *compilerID)); + +/* pngget.c */ +extern PNG_EXPORT(png_uint_32,png_get_asm_flagmask) + PNGARG((int flag_select)); + +/* pngget.c */ +extern PNG_EXPORT(png_uint_32,png_get_asm_flags) + PNGARG((png_structp png_ptr)); + +/* pngget.c */ +extern PNG_EXPORT(png_byte,png_get_mmx_bitdepth_threshold) + PNGARG((png_structp png_ptr)); + +/* pngget.c */ +extern PNG_EXPORT(png_uint_32,png_get_mmx_rowbytes_threshold) + PNGARG((png_structp png_ptr)); + +/* pngset.c */ +extern PNG_EXPORT(void,png_set_asm_flags) + PNGARG((png_structp png_ptr, png_uint_32 asm_flags)); + +/* pngset.c */ +extern PNG_EXPORT(void,png_set_mmx_thresholds) + PNGARG((png_structp png_ptr, png_byte mmx_bitdepth_threshold, + png_uint_32 mmx_rowbytes_threshold)); + +#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ + /* png.c, pnggccrd.c, or pngvcrd.c */ extern PNG_EXPORT(int,png_mmx_support) PNGARG((void)); -#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. */ @@ -2269,7 +2333,7 @@ extern PNG_EXPORT(void,png_set_strip_error_numbers) PNGARG((png_structp /* Maintainer: Put new public prototypes here ^, in libpng.3, and project defs */ #define PNG_HEADER_VERSION_STRING \ - " libpng version 1.0.12 - June 8, 2001 (header)\n" + " libpng version 1.2.0 - September 1, 2001 (header)\n" #ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED /* With these routines we avoid an integer divide, which will be slower on @@ -2589,7 +2653,7 @@ PNG_EXTERN void png_flush PNGARG((png_structp png_ptr)); */ PNG_EXTERN void png_save_uint_32 PNGARG((png_bytep buf, png_uint_32 i)); -#if defined(PNG_WRITE_pCAL_SUPPORTED) +#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 @@ -2707,7 +2771,7 @@ PNG_EXTERN void png_write_iTXt PNGARG((png_structp png_ptr, #if defined(PNG_WRITE_oFFs_SUPPORTED) PNG_EXTERN void png_write_oFFs PNGARG((png_structp png_ptr, - png_uint_32 x_offset, png_uint_32 y_offset, int unit_type)); + png_int_32 x_offset, png_int_32 y_offset, int unit_type)); #endif #if defined(PNG_WRITE_pCAL_SUPPORTED) @@ -3075,6 +3139,10 @@ PNG_EXTERN void png_do_write_intrapixel PNGARG((png_row_infop row_info, png_bytep row)); #endif +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) +/* png.c */ /* PRIVATE */ +PNG_EXTERN void png_init_mmx_flags PNGARG((png_structp png_ptr)); +#endif /* Maintainer: Put new private prototypes here ^ and in libpngpf.3 */ #endif /* PNG_INTERNAL */ diff --git a/pngasmrd.h b/pngasmrd.h index 2db18524d..420f5fed7 100644 --- a/pngasmrd.h +++ b/pngasmrd.h @@ -1,6 +1,6 @@ /* pngasmrd.h - assembler version of utilities to read a PNG file * - * libpng 1.0.12 - June 8, 2001 + * libpng 1.2.0 - September 1, 2001 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 2001 Glenn Randers-Pehrson * diff --git a/pngconf.h b/pngconf.h index aa3ae1db3..2fd7b7cea 100644 --- a/pngconf.h +++ b/pngconf.h @@ -1,6 +1,6 @@ /* pngconf.h - machine configurable file for libpng * - * libpng 1.0.12 - June 8, 2001 + * libpng 1.2.0 - September 1, 2001 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2001 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) @@ -49,13 +49,11 @@ /* Enabled by default in 1.2.0. You can disable this if you don't need to support PNGs that are embedded in MNG datastreams */ -/* #ifndef PNG_NO_MNG_FEATURES # ifndef PNG_MNG_FEATURES_SUPPORTED # define PNG_MNG_FEATURES_SUPPORTED # endif #endif -*/ #ifndef PNG_NO_FLOATING_POINT_SUPPORTED # ifndef PNG_FLOATING_POINT_SUPPORTED @@ -230,7 +228,7 @@ # include #endif -#ifndef PNG_SETJMP_NOT_SUPPORTED +#if !defined(PNG_SETJMP_NOT_SUPPORTED) && !defined(PNG_NO_SETJMP_SUPPORTED) # define PNG_SETJMP_SUPPORTED #endif @@ -592,12 +590,9 @@ # define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED #endif -/* Will be enabled in libpng-1.2.0 */ -/* #ifndef PNG_NO_ERROR_NUMBERS #define PNG_ERROR_NUMBERS_SUPPORTED #endif -*/ #ifndef PNG_NO_WRITE_FLUSH # define PNG_WRITE_FLUSH_SUPPORTED @@ -636,7 +631,6 @@ /* PNG_ASSEMBLER_CODE was enabled by default in version 1.2.0 even when PNG_USE_PNGVCRD or PNG_USE_PNGGCCRD is not defined */ -/* #if defined(PNG_READ_SUPPORTED) && !defined(PNG_NO_ASSEMBLER_CODE) # ifndef PNG_ASSEMBLER_CODE_SUPPORTED # define PNG_ASSEMBLER_CODE_SUPPORTED @@ -645,24 +639,16 @@ # define PNG_MMX_CODE_SUPPORTED # endif #endif -*/ -#if defined(PNG_READ_SUPPORTED) && !defined(PNG_NO_ASSEMBLER_CODE) -# if defined(PNG_USE_PNGVCRD) || defined(PNG_USE_PNGGCCRD) -# ifndef PNG_ASSEMBLER_CODE_SUPPORTED -# define PNG_ASSEMBLER_CODE_SUPPORTED -# endif -# if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE) -# define PNG_MMX_CODE_SUPPORTED -# endif -# endif -#endif -/* This will be enabled by default in libpng-1.2.0 */ -/* +/* 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 +*/ + #if !defined(PNG_NO_USER_MEM) && !defined(PNG_USER_MEM_SUPPORTED) # define PNG_USER_MEM_SUPPORTED #endif -*/ /* These are currently experimental features, define them if you want */ diff --git a/pngcrush.c b/pngcrush.c index e2e09f484..06256641b 100644 --- a/pngcrush.c +++ b/pngcrush.c @@ -25,7 +25,7 @@ * */ -#define PNGCRUSH_VERSION "1.5.6" +#define PNGCRUSH_VERSION "1.5.7" /* #define PNGCRUSH_COUNT_COLORS @@ -66,6 +66,17 @@ */ /* Change log: + * + * Version 1.5.7 (built with libpng-1.2.0) + * + * Added setargv.obj to Makefile.msc to expand wildcards, e.g., *.png + * + * Use constant string "pngcrush" instead of argv[0] when appropriate. + * + * Only check stats for infile==outfile once per input file, or not at all + * if "-nofilecheck" option is present or if a directory was created. + * + * Fixed bugs with changing bit_depth of grayscale images. * * Version 1.5.6 (built with libpng-1.0.12) * @@ -139,7 +150,7 @@ * Disabled color counting by default and made it controllable with new * -cc and -no_cc commandline arguments. * - * Added some #ifdef PNG_COUNT_COLORS around code that needs it. + * Added some #ifdef PNGCRUSH_COUNT_COLORS around code that needs it. * * Revised count_colors() attempting to avoid stack corruption that has * been observed on RedHat 6.2 @@ -381,7 +392,6 @@ * Move the Photoshop-fixing stuff into a separate program. * * add "-time" directive - * */ #define PNG_INTERNAL @@ -529,7 +539,7 @@ main() #endif /* input and output filenames */ -static PNG_CONST char *progname = "pngtest" DOT "png"; +static PNG_CONST char *progname = "pngtest" DOT "exe"; static PNG_CONST char *inname = "pngtest" DOT "png"; static PNG_CONST char *outname = "pngout" DOT "png"; static PNG_CONST char *directory_name = "pngcrush" DOT "bak"; @@ -617,7 +627,7 @@ static int brute_force_strategies[3]={1,1,1}; static int method=10; static int pauses=0; static int nosave=0; -static int nointerlace=0; +static int nofilecheck=0; static png_bytep row_buf; #ifdef PNGCRUSH_MULTIPLE_ROWS static png_bytepp row_pointers; @@ -940,7 +950,7 @@ static void setfiletype(const char *name) _kernel_swi(8 | 1<<31, &r, &r); # endif } -#else +#else /* !defined(__riscos) */ # define setfiletype(x) #endif @@ -1444,10 +1454,8 @@ main(int argc, char *argv[]) brute_force=0; try_method[method]=0; } -#if 0 - else if(!strncmp(argv[i],"-ni",3)) - nointerlace++; -#endif + else if(!strncmp(argv[i],"-nofilecheck",5)) + nofilecheck++; else if(!strncmp(argv[i],"-nosave",2)) { /* no save; I just use this for testing decode speed */ @@ -1476,7 +1484,8 @@ main(int argc, char *argv[]) verbose=0; else if(!strncmp(argv[i],"-reduce",7)) { - reduction_ok++; + reduction_ok++; + do_color_count=1; } #ifdef PNG_gAMA_SUPPORTED else if(!strncmp(argv[i],"-rep",4)) @@ -1719,8 +1728,8 @@ main(int argc, char *argv[]) /* If you have modified this source, you may insert additional notices * immediately after this sentence. */ fprintf(STDERR, - "\n | %s %s, Copyright (C) 1998-2001 Glenn Randers-Pehrson\n", - progname, PNGCRUSH_VERSION); + "\n | pngcrush %s, Copyright (C) 1998-2001 Glenn Randers-Pehrson\n", + PNGCRUSH_VERSION); fprintf(STDERR, " | This is a free, open-source program. Permission is irrevocably\n"); fprintf(STDERR, @@ -1728,7 +1737,9 @@ main(int argc, char *argv[]) fprintf(STDERR, " | payment of any fee.\n"); fprintf(STDERR, - " | This program was built with libpng version %s, and is\n", + " | Executable name is %s\n",progname); + fprintf(STDERR, + " | It was built with libpng version %s, and is\n", PNG_LIBPNG_VER_STRING); #if PNG_LIBPNG_VER > 10001 fprintf(STDERR, @@ -2003,16 +2014,15 @@ main(int argc, char *argv[]) if(verbose > 1) { fprintf(STDERR, - "\n %s method to try (0 means try all of 1-10).\n",progname); + "\n pngcrush method to try (0 means try all of 1-10).\n"); fprintf(STDERR, " Can be repeated as in '-m 1 -m 4 -m 7'.\n"); fprintf(STDERR, - " This can be useful if you run out of memory when %s\n", - progname); + " This can be useful if pngcrush runs out of memory\n"); fprintf(STDERR, - " tries methods 2, 3, 5, 6, 8, 9, or 10 which use \n"); + " when it tries methods 2, 3, 5, 6, 8, 9, or 10 which\n"); fprintf(STDERR, - " filtering and are memory intensive. Methods\n"); + " use filtering and are memory intensive. Methods\n"); fprintf(STDERR, " 1, 4, and 7 use no filtering; methods 11 and up use \n"); fprintf(STDERR, @@ -2022,18 +2032,25 @@ main(int argc, char *argv[]) fprintf(STDERR, " -max maximum_IDAT_size [default %d]\n",PNG_ZBUF_SIZE); -#if 0 - fprintf(STDERR, - " -ni (no interlace)\n"); if(verbose > 1) fprintf(STDERR,"\n"); -#endif #ifdef PNGCRUSH_COUNT_COLORS fprintf(STDERR, " -no_cc (no color counting)\n"); if(verbose > 1) fprintf(STDERR,"\n"); #endif + fprintf(STDERR, + " -nofilecheck (do not check for infile.png == outfile.png)\n"); + if(verbose > 1) + { + fprintf(STDERR, + "\n To avoid false hits from MSVC-compiled code. Note\n"); + fprintf(STDERR, + " that if you use this option, you are responsible for\n"); + fprintf(STDERR, + " ensuring that the input file is not the output file.\n\n"); + } fprintf(STDERR, " -n (no save; does not do compression or write output PNG)\n"); if(verbose > 1) @@ -2106,20 +2123,17 @@ main(int argc, char *argv[]) fprintf(STDERR, "\n Write a pHYs chunk with the given resolution.\n\n"); } -#if 0 /* TO DO */ fprintf(STDERR, " -save (keep all copy-unsafe chunks)\n"); if(verbose > 1) { fprintf(STDERR, - "\n Save otherwise unknown ancillary chunks that\n"); + "\n Save otherwise unknown ancillary chunks that would\n"); fprintf(STDERR, - " would be considered copy-unsafe. This option makes\n"); + " be considered copy-unsafe. This option makes\n"); fprintf(STDERR, - " all chunks 'known' to %s, so they can be copied.\n\n", - progname); + " chunks 'known' to pngcrush, so they can be copied.\n\n"); } -#endif png_crush_pause(); fprintf(STDERR, @@ -2279,15 +2293,12 @@ main(int argc, char *argv[]) for (ia=0; ia<256; ia++) trns_array[ia]=255; - P2 (" gthc=%d\n",global_things_have_changed); - for(;;) /* loop on input files */ { first_trial = 1; things_have_changed=global_things_have_changed; - P2 (" thc=%d\n",things_have_changed); if(png_row_filters != NULL) { @@ -2322,6 +2333,7 @@ main(int argc, char *argv[]) fprintf(STDERR,"could not create directory %s\n",directory_name); exit(1); } + nofilecheck=1; } out_string[0] = '\0'; str_return = strcat(out_string,directory_name); @@ -2467,6 +2479,11 @@ main(int argc, char *argv[]) } #if 0 /* TO DO */ + if (output_color_type == 0) + /* see if bit depth can be reduced */ + { + } + if (input_color_type == 2) /* check for 256 or fewer colors */ { @@ -2520,9 +2537,6 @@ main(int argc, char *argv[]) if(idat_length[best] == idat_length[0] && things_have_changed == 0 && best != final_method && nosave == 0) { -#ifndef __riscos - struct stat stat_in, stat_out; -#endif /* just copy input to output */ P2("prepare to copy input to output\n"); @@ -2545,29 +2559,14 @@ main(int argc, char *argv[]) number_of_open_files++; P2("copying input to output... tc=%d ...",things_have_changed); -#ifdef __riscos - /* (brokenly) assume that they're different */ -#else - if ((stat(inname, &stat_in) == 0) || - (stat(outname, &stat_out) != 0) || -#ifdef _MSC_VER /* maybe others? */ - (stat_in.st_size != stat_out.st_size) || -#else - (stat_in.st_ino != stat_out.st_ino) || -#endif - (stat_in.st_dev != stat_out.st_dev)) -#endif + for(;;) { - for(;;) - { - png_size_t num_in; + png_size_t num_in; - num_in = fread(buffer, 1, 1, fpin); - if (!num_in) - break; - fwrite(buffer, 1, 1, fpout); - - } + num_in = fread(buffer, 1, 1, fpin); + if (!num_in) + break; + fwrite(buffer, 1, 1, fpout); } P2("copy complete.\n"); png_crush_pause(); @@ -2629,7 +2628,7 @@ main(int argc, char *argv[]) update or output */ struct stat stat_in, stat_out; - if ((stat(inname, &stat_in) == 0) && + if (first_trial && !nofilecheck && (stat(inname, &stat_in) == 0) && (stat(outname, &stat_out) == 0) && #if defined(_MSC_VER) || defined(__MINGW32__) /* maybe others? */ /* MSVC++6.0 will erroneously return 0 for both files, so we @@ -2643,7 +2642,7 @@ main(int argc, char *argv[]) #endif (stat_in.st_dev == stat_out.st_dev)) { - fprintf(STDERR, "\n Cannot overwrite input file %s\n", inname); + fprintf(STDERR, "\n Cannot overwrite input file %s\n", outname); P1(" st_ino=%d, st_size=%d\n\n", (int)stat_in.st_ino, (int)stat_in.st_size); FCLOSE(fpin); @@ -2941,24 +2940,26 @@ main(int argc, char *argv[]) &color_type, &interlace_method, &compression_method, &filter_method)) { int need_expand = 0; - int output_interlace_method=interlace_method; input_color_type=color_type; input_bit_depth=bit_depth; - if(nointerlace) - output_interlace_method=0; + + if(output_color_type > 7) + { + output_color_type=input_color_type; + } + if(verbose > 1 && first_trial) { fprintf(STDERR, " IHDR chunk data:\n"); fprintf(STDERR, " Width=%ld, height=%ld\n", width, height); fprintf(STDERR, " Bit depth =%d\n", bit_depth); fprintf(STDERR, " Color type=%d\n", color_type); + if (output_color_type != color_type) + fprintf(STDERR, " Output color type=%d\n", + output_color_type); fprintf(STDERR, " Interlace =%d\n", interlace_method); } - if(output_color_type > 7) - { - output_color_type=input_color_type; - } #ifndef PNG_WRITE_PACK_SUPPORTED if(output_bit_depth == 0) @@ -2968,8 +2969,9 @@ main(int argc, char *argv[]) { output_bit_depth=input_bit_depth; } - if(output_bit_depth != input_bit_depth) - need_expand = 1; + if((output_color_type != 3 || output_bit_depth > 8) && + output_bit_depth >= 8 && output_bit_depth != input_bit_depth) + need_expand = 1; #if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED) if((color_type == 2 || color_type == 6 || color_type == 3) && @@ -3052,6 +3054,18 @@ main(int argc, char *argv[]) png_set_expand(read_ptr); #endif +#ifdef PNG_READ_PACK_SUPPORTED + if(input_bit_depth < 8) + { + png_set_packing(read_ptr); + } + if(output_color_type == 0 && output_bit_depth < 8) + { + png_color_8 true_bits; + true_bits.gray = (png_byte)(output_bit_depth); + png_set_shift(read_ptr, &true_bits); + } +#endif if(verbose > 1) fprintf(STDERR, " Setting IHDR\n"); @@ -3074,10 +3088,11 @@ main(int argc, char *argv[]) #endif png_set_IHDR(write_ptr, write_info_ptr, width, height, - output_bit_depth, output_color_type, output_interlace_method, + output_bit_depth, output_color_type, interlace_method, compression_method, filter_method); if(output_color_type != input_color_type) things_have_changed=1; + } } #if defined(PNG_READ_bKGD_SUPPORTED) && defined(PNG_WRITE_bKGD_SUPPORTED) @@ -3780,7 +3795,7 @@ main(int argc, char *argv[]) png_crush_pause(); png_debug(0, "\nWriting info struct\n"); -#if 0 +#if 0 /* doesn't work; compression level has to be the same as in IDAT */ /* if zTXt other compressed chunk */ png_set_compression_level(write_ptr, 9); png_set_compression_window_bits(write_ptr, 15); @@ -3848,19 +3863,19 @@ main(int argc, char *argv[]) png_write_info(write_ptr, write_info_ptr); png_debug(0, "\nWrote info struct\n"); P2("wrote info structure.\n"); - -#if (PNG_LIBPNG_VER > 90) #ifdef PNG_WRITE_PACK_SUPPORTED - if(output_bit_depth < input_bit_depth) + if(output_bit_depth < 8) { - png_color_8 true_bits; - true_bits.gray = (png_byte)(8 - (input_bit_depth - output_bit_depth)); - png_set_shift(read_ptr, &true_bits); + if(output_color_type == 0) + { + png_color_8 true_bits; + true_bits.gray = (png_byte)(output_bit_depth); + png_set_shift(write_ptr, &true_bits); + } + png_set_packing(write_ptr); } - if(output_bit_depth != input_bit_depth && output_bit_depth < 8) - png_set_packing(write_ptr); #endif -#endif /* PNG_LIBPNG_VER > 90 */ + } /* no save */ #define LARGE_PNGCRUSH @@ -3886,10 +3901,7 @@ main(int argc, char *argv[]) row_buf = png_malloc(read_ptr, rowbytes+16); #endif else - { - fprintf(STDERR, "rowbytes= %d\n",rowbytes); row_buf = NULL; - } } #else { @@ -4153,7 +4165,7 @@ main(int argc, char *argv[]) if(nosave == 0) { -#if 0 +#if 0 /* doesn't work; compression level has to be the same as in IDAT */ /* if zTXt other compressed chunk */ png_set_compression_level(write_ptr, 9); png_set_compression_window_bits(write_ptr, 15); @@ -4291,17 +4303,17 @@ main(int argc, char *argv[]) total_input_length += input_length + output_length; if(input_length == output_length) fprintf(STDERR, - " Best %s method = %d for %s (no change)\n\n", - progname, best, outname); + " Best pngcrush method = %d for %s (no change)\n\n", + best, outname); else if(input_length > output_length) fprintf(STDERR, - " Best %s method = %d for %s (%4.2f%% reduction)\n\n", - progname, best, outname, + " Best pngcrush method = %d for %s (%4.2f%% reduction)\n\n", + best, outname, (100.0 - (100.0*output_length)/input_length)); else fprintf(STDERR, - " Best %s method = %d for %s (%4.2f%% increase)\n\n", - progname, best, outname, + " Best pngcrush method = %d for %s (%4.2f%% increase)\n\n", + best, outname, -(100.0 - (100.0*output_length)/input_length)); if(verbose > 2) fprintf(STDERR, " Number of open files=%d\n",number_of_open_files); @@ -4566,7 +4578,7 @@ count_colors(FILE *fpin) png_debug(0, "Allocating read_info structure\n"); read_info_ptr = png_create_info_struct(read_ptr); if (read_info_ptr == NULL) - png_destroy_read_struct(&read_ptr, (png_infop)NULL, (png_infop)NULL); + png_destroy_read_struct(&read_ptr, (png_infopp)NULL, (png_infopp)NULL); } else read_info_ptr = NULL; @@ -4939,7 +4951,7 @@ count_colors(FILE *fpin) png_free (read_ptr, row_buf); row_buf = (png_bytep)NULL; png_debug(0, "Destroying data structs\n"); - png_destroy_read_struct(&read_ptr, &read_info_ptr, (png_infop)NULL); + png_destroy_read_struct(&read_ptr, &read_info_ptr, (png_infopp)NULL); } else result=2; @@ -4949,7 +4961,7 @@ count_colors(FILE *fpin) fprintf(STDERR, "\nWhile checking alphas in %s ", inname); fprintf(STDERR,"pngcrush caught libpng error:\n %s\n\n",msg); png_free (read_ptr, row_buf); row_buf = (png_bytep)NULL; - png_destroy_read_struct(&read_ptr, &read_info_ptr, (png_infop)NULL); + png_destroy_read_struct(&read_ptr, &read_info_ptr, (png_infopp)NULL); png_debug(0, "Destroyed data structs\n"); result=2; } diff --git a/pngcrush.h b/pngcrush.h index a630f30bb..1c9f6af67 100644 --- a/pngcrush.h +++ b/pngcrush.h @@ -71,6 +71,11 @@ #define PNG_READ_STRIP_ALPHA_SUPPORTED #define PNG_READ_EXPAND_SUPPORTED #define PNG_READ_FILLER_SUPPORTED +#define PNG_READ_PACK_SUPPORTED +#define PNG_READ_SHIFT_SUPPORTED + +#define PNG_WRITE_PACK_SUPPORTED +#define PNG_WRITE_SHIFT_SUPPORTED #if (PNGCRUSH_LIBPNG_VER > 10002) /* versions 0.96 through 1.0.2 have a stub png_rgb_to_gray() with the diff --git a/pngerror.c b/pngerror.c index c2285ff6d..cf04c9157 100644 --- a/pngerror.c +++ b/pngerror.c @@ -1,7 +1,7 @@ /* pngerror.c - stub functions for i/o and memory allocation * - * libpng 1.0.12 - June 8, 2001 + * libpng 1.2.0 - September 1, 2001 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2001 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) @@ -287,4 +287,3 @@ png_set_strip_error_numbers(png_structp png_ptr, png_uint_32 strip_mode) } } #endif - diff --git a/pnggccrd.c b/pnggccrd.c index 62ea6905b..ce519c51e 100644 --- a/pnggccrd.c +++ b/pnggccrd.c @@ -6,7 +6,7 @@ * 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.0.12 - June 8, 2001 + * libpng version 1.2.0 - September 1, 2001 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2001 Glenn Randers-Pehrson * Copyright (c) 1998, Intel Corporation @@ -203,9 +203,14 @@ * - "_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 + * 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 @@ -226,15 +231,9 @@ * 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) - * - add support for runtime enable/disable/query of various MMX routines + * x add support for runtime enable/disable/query of various MMX routines */ -/* -#ifndef PNG_DEBUG -# define PNG_DEBUG 0 -#endif -*/ - #define PNG_INTERNAL #include "png.h" @@ -253,7 +252,6 @@ static const int FARDATA png_pass_width[7] = {8, 4, 4, 2, 2, 1, 1}; * so define them without: */ #if defined(__DJGPP__) || defined(WIN32) || defined(__CYGWIN__) # define _mmx_supported mmx_supported -# define _unmask unmask # define _const4 const4 # define _const6 const6 # define _mask8_0 mask8_0 @@ -272,9 +270,6 @@ static const int FARDATA png_pass_width[7] = {8, 4, 4, 2, 2, 1, 1}; # define _mask48_2 mask48_2 # define _mask48_1 mask48_1 # define _mask48_0 mask48_0 -# define _FullLength FullLength -# define _MMXLength MMXLength -# define _dif dif # define _LBCarryMask LBCarryMask # define _HBClearMask HBClearMask # define _ActiveMask ActiveMask @@ -282,10 +277,16 @@ static const int FARDATA png_pass_width[7] = {8, 4, 4, 2, 2, 1, 1}; # 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. @@ -297,7 +298,9 @@ static const int FARDATA png_pass_width[7] = {8, 4, 4, 2, 2, 1, 1}; * "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; @@ -326,24 +329,29 @@ 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 -static void /* PRIVATE */ +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; - _MMXLength = _MMXLength; _mask8_0 = _mask8_0; _mask16_1 = _mask16_1; _mask16_0 = _mask16_0; @@ -363,6 +371,7 @@ png_squelch_warnings(void) } #endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ + static int _mmx_supported = 2; /*===========================================================================*/ @@ -398,9 +407,13 @@ 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) { + /* this should have happened in png_init_mmx_flags() already */ + png_warning(png_ptr, "asm_flags may not have been initialized"); png_mmx_support(); } +#endif if (mask == 0xff) { @@ -583,8 +596,9 @@ png_combine_row(png_structp png_ptr, png_bytep row, int mask) png_bytep srcptr; png_bytep dstptr; -#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) - if ( _mmx_supported ) +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) + /* && _mmx_supported */ ) { png_uint_32 len; int diff; @@ -716,8 +730,9 @@ png_combine_row(png_structp png_ptr, png_bytep row, int mask) png_bytep srcptr; png_bytep dstptr; -#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) - if ( _mmx_supported ) +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) + /* && _mmx_supported */ ) { png_uint_32 len; int diff; @@ -864,8 +879,9 @@ png_combine_row(png_structp png_ptr, png_bytep row, int mask) png_bytep srcptr; png_bytep dstptr; -#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) - if ( _mmx_supported ) +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) + /* && _mmx_supported */ ) { png_uint_32 len; int diff; @@ -1027,8 +1043,9 @@ png_combine_row(png_structp png_ptr, png_bytep row, int mask) png_bytep srcptr; png_bytep dstptr; -#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) - if ( _mmx_supported ) +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) + /* && _mmx_supported */ ) { png_uint_32 len; int diff; @@ -1197,8 +1214,9 @@ png_combine_row(png_structp png_ptr, png_bytep row, int mask) png_bytep srcptr; png_bytep dstptr; -#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) - if ( _mmx_supported ) +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) + /* && _mmx_supported */ ) { png_uint_32 len; int diff; @@ -1422,10 +1440,7 @@ png_combine_row(png_structp png_ptr, png_bytep row, int mask) default: /* png_ptr->row_info.pixel_depth != 1,2,4,8,16,24,32,48,64 */ { /* this should never happen */ - fprintf(stderr, - "libpng internal error: png_ptr->row_info.pixel_depth = %d\n", - png_ptr->row_info.pixel_depth); - fflush(stderr); + png_warning(png_ptr, "Invalid row_info.pixel_depth in pnggccrd"); break; } } /* end switch (png_ptr->row_info.pixel_depth) */ @@ -1464,9 +1479,13 @@ png_do_read_interlace(png_structp png_ptr) png_debug(1, "in png_do_read_interlace (pnggccrd.c)\n"); +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) if (_mmx_supported == 2) { + /* this should have happened in png_init_mmx_flags() already */ + png_warning(png_ptr, "asm_flags may not have been initialized"); png_mmx_support(); } +#endif if (row != NULL && row_info != NULL) { @@ -1672,7 +1691,8 @@ png_do_read_interlace(png_structp png_ptr) /* New code by Nirav Chhatrapati - Intel Corporation */ #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) - if ( _mmx_supported ) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_INTERLACE) + /* && _mmx_supported */ ) { //-------------------------------------------------------------- if (pixel_bytes == 3) @@ -2617,12 +2637,12 @@ png_do_read_interlace(png_structp png_ptr) 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); - } + 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; @@ -2693,7 +2713,7 @@ png_do_read_interlace(png_structp png_ptr) - +#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 @@ -2706,8 +2726,7 @@ union uAll { _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 // @@ -2830,53 +2849,76 @@ png_read_filter_row_mmx_avg(png_row_infop row_info, png_bytep row, "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 + "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 + "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 + "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 + "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 + "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 + "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 + "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 + "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 + "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 + "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 + "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" @@ -2914,7 +2956,8 @@ png_read_filter_row_mmx_avg(png_row_infop row_info, png_bytep row, "movq _HBClearMask, %%mm4 \n\t" // re-init address pointers and offset - "movl _dif, %%ecx \n\t" // ecx: x = offset to alignment boundary + "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" @@ -2923,7 +2966,8 @@ png_read_filter_row_mmx_avg(png_row_infop row_info, png_bytep row, // 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 + "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 @@ -2936,30 +2980,44 @@ png_read_filter_row_mmx_avg(png_row_infop row_info, png_bytep row, "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 + "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 + "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 + "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 + "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 + "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 @@ -2993,7 +3051,8 @@ png_read_filter_row_mmx_avg(png_row_infop row_info, png_bytep row, // load _ActiveMask "movq _ActiveMask, %%mm7 \n\t" // re-init address pointers and offset - "movl _dif, %%ecx \n\t" // ecx: x = offset to alignment boundary + "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" @@ -3010,59 +3069,91 @@ png_read_filter_row_mmx_avg(png_row_infop row_info, png_bytep row, "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 + "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 + "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) + "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 + "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 + "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) + "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 + "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 + "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) + "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 + "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 + "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) + "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 + "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 @@ -3093,7 +3184,8 @@ png_read_filter_row_mmx_avg(png_row_infop row_info, png_bytep row, #ifdef __PIC__ "pushl %%ebx \n\t" // save Global Offset Table index #endif - "movl _dif, %%ebx \n\t" // ebx: x = offset to alignment boundary + "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" @@ -3112,7 +3204,8 @@ png_read_filter_row_mmx_avg(png_row_infop row_info, png_bytep row, "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 + "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 @@ -3191,15 +3284,18 @@ png_read_filter_row_mmx_avg(png_row_infop row_info, png_bytep row, default: // bpp greater than 8 (!= 1,2,3,4,[5],6,[7],8) { +#ifdef PNG_DEBUG // GRR: PRINT ERROR HERE: SHOULD NEVER BE REACHED - fprintf(stderr, - "libpng: internal logic error (png_read_filter_row_mmx_avg())\n"); + 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 _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" @@ -3212,15 +3308,20 @@ png_read_filter_row_mmx_avg(png_row_infop row_info, png_bytep row, "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 + "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 + "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 + "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" @@ -3289,10 +3390,11 @@ png_read_filter_row_mmx_avg(png_row_infop row_info, png_bytep row, ); } /* 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 // @@ -3338,9 +3440,11 @@ png_read_filter_row_mmx_paeth(png_row_infop row_info, png_bytep row, "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 + "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 + "subl %%edi, _dif \n\t" // subtract from start ==> value ebx + // at alignment "jz paeth_go \n\t" // fix alignment @@ -3458,12 +3562,14 @@ png_read_filter_row_mmx_paeth(png_row_infop row_info, png_bytep row, // 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 + "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 + "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 @@ -3518,7 +3624,8 @@ png_read_filter_row_mmx_paeth(png_row_infop row_info, png_bytep row, "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) + "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 @@ -3575,7 +3682,8 @@ png_read_filter_row_mmx_paeth(png_row_infop row_info, png_bytep row, "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 + "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) @@ -3635,7 +3743,8 @@ png_read_filter_row_mmx_paeth(png_row_infop row_info, png_bytep row, // 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) + "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 @@ -4335,10 +4444,12 @@ png_read_filter_row_mmx_paeth(png_row_infop row_info, png_bytep row, ); } /* 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 // @@ -4757,6 +4868,7 @@ png_read_filter_row_mmx_sub(png_row_infop row_info, png_bytep row) ); } // end of png_read_filter_row_mmx_sub() +#endif @@ -4912,7 +5024,6 @@ png_read_filter_row_mmx_up(png_row_infop row_info, png_bytep row, /* */ /*===========================================================================*/ -#if defined(PNG_HAVE_ASSEMBLER_READ_FILTER_ROW) /* Optimized png_read_filter_row routines */ @@ -4932,6 +5043,8 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep #define UseMMX_paeth 1 // GRR: converted 20000828 if (_mmx_supported == 2) { + /* this should have happened in png_init_mmx_flags() already */ + png_warning(png_ptr, "asm_flags may not have been initialized"); png_mmx_support(); } #endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ @@ -4942,13 +5055,29 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep { case 0: sprintf(filnm, "none"); break; - case 1: sprintf(filnm, "sub-%s", "MMX"); + case 1: sprintf(filnm, "sub-%s", +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) + (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_SUB)? "MMX" : +#endif +"x86"); break; - case 2: sprintf(filnm, "up-%s", "MMX"); + case 2: sprintf(filnm, "up-%s", +#ifdef PNG_ASSEMBLER_CODE_SUPPORTED + (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_UP)? "MMX" : +#endif + "x86"); break; - case 3: sprintf(filnm, "avg-%s", "MMX"); + case 3: sprintf(filnm, "avg-%s", +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) + (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_AVG)? "MMX" : +#endif + "x86"); break; - case 4: sprintf(filnm, "Paeth-%s", "MMX"); + case 4: sprintf(filnm, "Paeth-%s", +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) + (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_PAETH)? "MMX": +#endif +"x86"); break; default: sprintf(filnm, "unknw"); break; @@ -4966,10 +5095,10 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep break; case PNG_FILTER_VALUE_SUB: -#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) - if ( _mmx_supported && - (row_info->pixel_depth >= PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT) && - (row_info->rowbytes >= PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT)) +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) + 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)) { png_read_filter_row_mmx_sub(row_info, row); } @@ -4992,9 +5121,9 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep case PNG_FILTER_VALUE_UP: #if defined(PNG_ASSEMBLER_CODE_SUPPORTED) - if ( _mmx_supported && - (row_info->pixel_depth >= PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT) && - (row_info->rowbytes >= PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT)) + 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)) { png_read_filter_row_mmx_up(row_info, row, prev_row); } @@ -5015,10 +5144,10 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep break; case PNG_FILTER_VALUE_AVG: -#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) - if ( _mmx_supported && - (row_info->pixel_depth >= PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT) && - (row_info->rowbytes >= PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT)) +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) + 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)) { png_read_filter_row_mmx_avg(row_info, row, prev_row); } @@ -5049,10 +5178,10 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep break; case PNG_FILTER_VALUE_PAETH: -#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) - if ( _mmx_supported && - (row_info->pixel_depth >= PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT) && - (row_info->rowbytes >= PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT)) +#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK) + 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)) { png_read_filter_row_mmx_paeth(row_info, row, prev_row); } @@ -5205,4 +5334,5 @@ png_mmx_support(void) return _mmx_supported; } + #endif /* PNG_USE_PNGGCCRD */ diff --git a/pngget.c b/pngget.c index 208918f0c..d95d246fa 100644 --- a/pngget.c +++ b/pngget.c @@ -1,7 +1,7 @@ /* pngget.c - retrieval of values from info struct * - * libpng 1.0.12 - June 8, 2001 + * libpng 1.2.0 - September 1, 2001 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2001 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) @@ -827,3 +827,91 @@ png_get_compression_buffer_size(png_structp png_ptr) } +#ifdef PNG_ASSEMBLER_CODE_SUPPORTED +/* 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); +} + +/* 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 */ +} +#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 */ +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 */ +} + +/* 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); +} + +/* 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); +} +#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */ diff --git a/pngmem.c b/pngmem.c index dd74715eb..4cf4db623 100644 --- a/pngmem.c +++ b/pngmem.c @@ -1,7 +1,7 @@ /* pngmem.c - stub functions for memory allocation * - * libpng 1.0.12 - June 8, 2001 + * libpng 1.2.0 - September 1, 2001 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2001 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) diff --git a/pngpread.c b/pngpread.c index 9b4b77a93..4f7baf66c 100644 --- a/pngpread.c +++ b/pngpread.c @@ -1,7 +1,7 @@ /* pngpread.c - read a png file in push mode * - * libpng 1.0.12 - June 8, 2001 + * libpng 1.2.0 - September 1, 2001 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2001 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) @@ -1499,6 +1499,4 @@ png_get_progressive_ptr(png_structp png_ptr) { return png_ptr->io_ptr; } - #endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ - diff --git a/pngread.c b/pngread.c index ca6969982..cec672a9c 100644 --- a/pngread.c +++ b/pngread.c @@ -1,7 +1,7 @@ /* pngread.c - read a PNG file * - * libpng 1.0.12 - June 8, 2001 + * libpng 1.2.0 - September 1, 2001 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2001 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) @@ -54,6 +54,10 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, return (png_structp)NULL; } +#ifdef PNG_ASSEMBLER_CODE_SUPPORTED + png_init_mmx_flags(png_ptr); /* 1.2.0 addition */ +#endif + #ifdef PNG_SETJMP_SUPPORTED #ifdef USE_FAR_KEYWORD if (setjmp(jmpbuf)) @@ -113,35 +117,6 @@ png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, png_error(png_ptr, "Incompatible libpng version in application and library"); } - - /* Libpng 1.0.6 was not binary compatible, due to insertion of the - info_ptr->free_me member. Libpng-1.0.1 and earlier were not - compatible due to insertion of the user transform function. Note - to maintainer: this test can be removed from version 1.2.0 and - beyond because the previous test would have already rejected it. */ - - if (user_png_ver[0] == '1' && user_png_ver[2] == '0' && - (user_png_ver[4] < '2' || user_png_ver[4] == '6') && - user_png_ver[5] == '\0') - { -#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) - char msg[80]; - if (user_png_ver) - { - sprintf(msg, "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_libpng_ver); - png_warning(png_ptr, msg); -#endif -#ifdef PNG_ERROR_NUMBERS_SUPPORTED - png_ptr->flags=0; -#endif - png_error(png_ptr, - "Application must be recompiled; versions <= 1.0.6 were incompatible"); - } } /* initialize zbuf - compression buffer */ @@ -794,7 +769,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row) * not called png_set_interlace_handling(), the display_row buffer will * be ignored, so pass NULL to it. * - * [*] png_handle_alpha() does not exist yet, as of libpng version 1.0.12 + * [*] png_handle_alpha() does not exist yet, as of libpng version 1.2.0 */ void PNGAPI @@ -843,7 +818,7 @@ png_read_rows(png_structp png_ptr, png_bytepp row, * only call this function once. If you desire to have an image for * each pass of a interlaced image, use png_read_rows() instead. * - * [*] png_handle_alpha() does not exist yet, as of libpng version 1.0.12 + * [*] png_handle_alpha() does not exist yet, as of libpng version 1.2.0 */ void PNGAPI png_read_image(png_structp png_ptr, png_bytepp image) @@ -1158,7 +1133,7 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr png_info_destroy(png_ptr, end_info_ptr); png_free(png_ptr, png_ptr->zbuf); - png_free(png_ptr, png_ptr->row_buf); + png_free(png_ptr, png_ptr->big_row_buf); png_free(png_ptr, png_ptr->prev_row); #if defined(PNG_READ_DITHER_SUPPORTED) png_free(png_ptr, png_ptr->palette_lookup); diff --git a/pngrio.c b/pngrio.c index 707a139d4..97fcdaa65 100644 --- a/pngrio.c +++ b/pngrio.c @@ -1,7 +1,7 @@ /* pngrio.c - functions for data input * - * libpng 1.0.12 - June 8, 2001 + * libpng 1.2.0 - September 1, 2001 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2001 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) @@ -159,4 +159,3 @@ png_set_read_fn(png_structp png_ptr, png_voidp io_ptr, png_ptr->output_flush_fn = NULL; #endif } - diff --git a/pngrtran.c b/pngrtran.c index ef070c88e..e045c94cb 100644 --- a/pngrtran.c +++ b/pngrtran.c @@ -1,7 +1,7 @@ /* pngrtran.c - transforms the data in a row for PNG readers * - * libpng 1.0.12 - June 8, 2001 + * libpng 1.2.0 - September 1, 2001 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2001 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) diff --git a/pngrutil.c b/pngrutil.c index ec970ce41..1977783fb 100644 --- a/pngrutil.c +++ b/pngrutil.c @@ -1,7 +1,7 @@ /* pngrutil.c - utilities to read a PNG file * - * libpng 1.0.12 - June 8, 2001 + * libpng 1.2.0 - September 1, 2001 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2001 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) @@ -794,12 +794,12 @@ png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { if (abs(int_x_white - 31270L) > 1000 || abs(int_y_white - 32900L) > 1000 || - abs( int_x_red - 64000L) > 1000 || - abs( int_y_red - 33000L) > 1000 || + abs(int_x_red - 64000L) > 1000 || + abs(int_y_red - 33000L) > 1000 || abs(int_x_green - 30000L) > 1000 || abs(int_y_green - 60000L) > 1000 || - abs( int_x_blue - 15000L) > 1000 || - abs( int_y_blue - 6000L) > 1000) + abs(int_x_blue - 15000L) > 1000 || + abs(int_y_blue - 6000L) > 1000) { png_warning(png_ptr, @@ -928,12 +928,12 @@ png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) if (info_ptr->valid & PNG_INFO_cHRM) if (abs(info_ptr->int_x_white - 31270L) > 1000 || abs(info_ptr->int_y_white - 32900L) > 1000 || - abs( info_ptr->int_x_red - 64000L) > 1000 || - abs( info_ptr->int_y_red - 33000L) > 1000 || + abs(info_ptr->int_x_red - 64000L) > 1000 || + abs(info_ptr->int_y_red - 33000L) > 1000 || abs(info_ptr->int_x_green - 30000L) > 1000 || abs(info_ptr->int_y_green - 60000L) > 1000 || - abs( info_ptr->int_x_blue - 15000L) > 1000 || - abs( info_ptr->int_y_blue - 6000L) > 1000) + abs(info_ptr->int_x_blue - 15000L) > 1000 || + abs(info_ptr->int_y_blue - 6000L) > 1000) { png_warning(png_ptr, "Ignoring incorrect cHRM value when sRGB is also present"); @@ -2975,7 +2975,8 @@ defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) if (row_bytes > (png_uint_32)65536L) png_error(png_ptr, "This image requires a row greater than 64KB"); #endif - png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, row_bytes); + 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 diff --git a/pngset.c b/pngset.c index ddc4d0cb7..8845d38a4 100644 --- a/pngset.c +++ b/pngset.c @@ -1,7 +1,7 @@ /* pngset.c - storage of image information into info struct * - * libpng 1.0.12 - June 8, 2001 + * libpng 1.2.0 - September 1, 2001 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2001 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) @@ -741,8 +741,8 @@ png_set_tRNS(png_structp png_ptr, png_infop info_ptr, png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0); #endif png_ptr->trans = info_ptr->trans = (png_bytep)png_malloc(png_ptr, - num_trans); - png_memcpy(info_ptr->trans, trans, num_trans); + (png_uint_32)num_trans); + png_memcpy(info_ptr->trans, trans, (png_size_t)num_trans); #ifdef PNG_FREE_ME_SUPPORTED info_ptr->free_me |= PNG_FREE_TRNS; #else @@ -905,14 +905,17 @@ png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_bytep if (chunk_list == NULL) return; old_num_chunks=png_ptr->num_chunk_list; - new_list=(png_bytep)png_malloc(png_ptr,5*(num_chunks+old_num_chunks)); + 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, 5*old_num_chunks); + 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, 5*num_chunks); + 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; @@ -970,3 +973,57 @@ png_set_invalid(png_structp png_ptr, png_infop info_ptr, int mask) } +#ifdef PNG_ASSEMBLER_CODE_SUPPORTED +/* this 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 */ +} +#endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */ + +#ifdef PNG_ASSEMBLER_CODE_SUPPORTED +/* 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; +} +#endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */ diff --git a/pngtrans.c b/pngtrans.c index 3e757c171..6398dcf34 100644 --- a/pngtrans.c +++ b/pngtrans.c @@ -1,7 +1,7 @@ /* pngtrans.c - transforms the data in a row (used by both readers and writers) * - * libpng 1.0.12 - June 8, 2001 + * libpng 1.2.0 - September 1, 2001 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2001 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) @@ -153,11 +153,14 @@ void /* PRIVATE */ png_do_invert(png_row_infop row_info, png_bytep row) { png_debug(1, "in png_do_invert\n"); - if (row_info->bit_depth == 1 && + /* This test removed from libpng version 1.0.13 and 1.2.0: + * if (row_info->bit_depth == 1 && + */ #if defined(PNG_USELESS_TESTS_SUPPORTED) - row != NULL && row_info != NULL && + if (row == NULL || row_info == NULL) + return; #endif - row_info->color_type == PNG_COLOR_TYPE_GRAY) + if (row_info->color_type == PNG_COLOR_TYPE_GRAY) { png_bytep rp = row; png_uint_32 i; @@ -169,6 +172,33 @@ png_do_invert(png_row_infop row_info, png_bytep row) rp++; } } + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && + row_info->bit_depth == 8) + { + png_bytep rp = row; + png_uint_32 i; + png_uint_32 istop = row_info->rowbytes; + + for (i = 0; i < istop; i+=2) + { + *rp = (png_byte)(~(*rp)); + rp+=2; + } + } + else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA && + row_info->bit_depth == 16) + { + png_bytep rp = row; + png_uint_32 i; + png_uint_32 istop = row_info->rowbytes; + + for (i = 0; i < istop; i+=4) + { + *rp = (png_byte)(~(*rp)); + *(rp+1) = (png_byte)(~(*(rp+1))); + rp+=4; + } + } } #endif @@ -608,4 +638,3 @@ png_get_user_transform_ptr(png_structp png_ptr) return (NULL); #endif } - diff --git a/pngvcrd.c b/pngvcrd.c index f464f34cb..d92c5464d 100644 --- a/pngvcrd.c +++ b/pngvcrd.c @@ -2,14 +2,14 @@ * * For Intel x86 CPU and Microsoft Visual C++ compiler * - * libpng 1.0.12 - June 8, 2001 + * libpng 1.2.0 - September 1, 2001 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2001 Glenn Randers-Pehrson * Copyright (c) 1998, Intel Corporation * * Contributed by Nirav Chhatrapati, Intel Corporation, 1998 * Interface to libpng contributed by Gilles Vollant, 1999 - * Debugging and cleanup by Greg Roelofs, 2000, 2001 + * * * 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 @@ -19,6 +19,8 @@ * * [png_read_filter_row_mmx_avg() bpp == 2 bugfix, GRR 20000916] * + * [runtime MMX configuration, GRR 20010102] + * */ #define PNG_INTERNAL @@ -110,6 +112,8 @@ png_combine_row(png_structp png_ptr, png_bytep row, int mask) png_debug(1,"in png_combine_row_asm\n"); if (mmx_supported == 2) { + /* this should have happened in png_init_mmx_flags() already */ + png_warning(png_ptr, "asm_flags may not have been initialized"); png_mmx_support(); } @@ -300,7 +304,8 @@ png_combine_row(png_structp png_ptr, png_bytep row, int mask) __int64 mask0=0x0102040810204080; - if ( mmx_supported ) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) + /* && mmx_supported */ ) { srcptr = png_ptr->row_buf + 1; dstptr = row; @@ -382,8 +387,6 @@ end8: incr1 = (disp)*pixel_bytes; for (i = initial_val; i < final_val; i += incr1) { - if (pixel_bytes > (png_size_t)(final_val-i)) - pixel_bytes = (png_size_t)(final_val-i); png_memcpy(dstptr, srcptr, pixel_bytes); srcptr += incr1; dstptr += incr1; @@ -402,7 +405,8 @@ end8: __int64 mask1=0x0101020204040808, mask0=0x1010202040408080; - if ( mmx_supported ) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) + /* && mmx_supported */ ) { srcptr = png_ptr->row_buf + 1; dstptr = row; @@ -495,8 +499,6 @@ end16: incr1 = (disp)*pixel_bytes; for (i = initial_val; i < final_val; i += incr1) { - if (pixel_bytes > (png_size_t)(final_val-i)) - pixel_bytes = (png_size_t)(final_val-i); png_memcpy(dstptr, srcptr, pixel_bytes); srcptr += incr1; dstptr += incr1; @@ -524,7 +526,8 @@ end16: len = (png_ptr->width)&~7; diff = (png_ptr->width)&7; - if ( mmx_supported ) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) + /* && mmx_supported */ ) { _asm { @@ -627,8 +630,6 @@ end24: incr1 = (disp)*pixel_bytes; for (i = initial_val; i < final_val; i += incr1) { - if (pixel_bytes > (png_size_t)(final_val-i)) - pixel_bytes = (png_size_t)(final_val-i); png_memcpy(dstptr, srcptr, pixel_bytes); srcptr += incr1; dstptr += incr1; @@ -657,7 +658,8 @@ end24: len = (png_ptr->width)&~7; diff = (png_ptr->width)&7; - if ( mmx_supported ) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) + /* && mmx_supported */ ) { _asm { @@ -768,8 +770,6 @@ end32: incr1 = (disp)*pixel_bytes; for (i = initial_val; i < final_val; i += incr1) { - if (pixel_bytes > (png_size_t)(final_val-i)) - pixel_bytes = (png_size_t)(final_val-i); png_memcpy(dstptr, srcptr, pixel_bytes); srcptr += incr1; dstptr += incr1; @@ -793,7 +793,8 @@ end32: mask1=0x2020202040404040, mask0=0x4040808080808080; - if ( mmx_supported ) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW) + /* && mmx_supported */ ) { srcptr = png_ptr->row_buf + 1; dstptr = row; @@ -927,8 +928,6 @@ end48: incr1 = (disp)*pixel_bytes; for (i = initial_val; i < final_val; i += incr1) { - if (pixel_bytes > (png_size_t)(final_val-i)) - pixel_bytes = (png_size_t)(final_val-i); png_memcpy(dstptr, srcptr, pixel_bytes); srcptr += incr1; dstptr += incr1; @@ -957,8 +956,6 @@ end48: incr1 = (disp)*pixel_bytes; for (i = initial_val; i < final_val; i += incr1) { - if (pixel_bytes > (png_size_t)(final_val-i)) - pixel_bytes = (png_size_t)(final_val-i); png_memcpy(dp, sptr, pixel_bytes); sptr += incr1; dp += incr1; @@ -987,6 +984,8 @@ png_do_read_interlace(png_structp png_ptr) png_debug(1,"in png_do_read_interlace\n"); if (mmx_supported == 2) { + /* this should have happened in png_init_mmx_flags() already */ + png_warning(png_ptr, "asm_flags may not have been initialized"); png_mmx_support(); } @@ -1187,7 +1186,8 @@ png_do_read_interlace(png_structp png_ptr) // NOTE: there is NO MMX code for 48-bit and 64-bit images // use MMX routine if machine supports it - if ( mmx_supported ) + if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_INTERLACE) + /* && mmx_supported */ ) { if (pixel_bytes == 3) { @@ -1777,7 +1777,7 @@ loop4_pass4: } /* end of mmx_supported */ else /* MMX not supported: use modified C code - takes advantage - * of inlining of png_memcpy for a constant */ + * of inlining of memcpy for a constant */ { if (pixel_bytes == 1) { @@ -3649,6 +3649,8 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep #endif if (mmx_supported == 2) { + /* this should have happened in png_init_mmx_flags() already */ + png_warning(png_ptr, "asm_flags may not have been initialized"); png_mmx_support(); } @@ -3658,13 +3660,17 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep { case 0: sprintf(filnm, "none"); break; - case 1: sprintf(filnm, "sub-%s", "MMX"); + 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", "MMX"); + 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", "MMX"); + 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", "MMX"); + case 4: sprintf(filnm, "Paeth-%s", + (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_PAETH)? "MMX":"x86"); break; default: sprintf(filnm, "unknw"); break; @@ -3682,9 +3688,9 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep case PNG_FILTER_VALUE_SUB: { - if ( - (row_info->pixel_depth >= PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT) && - (row_info->rowbytes >= PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT)) + 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)) { png_read_filter_row_mmx_sub(row_info, row); } @@ -3707,9 +3713,9 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep case PNG_FILTER_VALUE_UP: { - if ( - (row_info->pixel_depth >= PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT) && - (row_info->rowbytes >= PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT)) + 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)) { png_read_filter_row_mmx_up(row_info, row, prev_row); } @@ -3731,9 +3737,9 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep case PNG_FILTER_VALUE_AVG: { - if ( - (row_info->pixel_depth >= PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT) && - (row_info->rowbytes >= PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT)) + 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)) { png_read_filter_row_mmx_avg(row_info, row, prev_row); } @@ -3765,9 +3771,9 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep case PNG_FILTER_VALUE_PAETH: { - if ( - (row_info->pixel_depth >= PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT) && - (row_info->rowbytes >= PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT)) + 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)) { png_read_filter_row_mmx_paeth(row_info, row, prev_row); } diff --git a/pngwio.c b/pngwio.c index 23f881e98..efc39e690 100644 --- a/pngwio.c +++ b/pngwio.c @@ -1,7 +1,7 @@ /* pngwio.c - functions for data output * - * libpng 1.0.12 - June 8, 2001 + * libpng 1.2.0 - September 1, 2001 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2001 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) diff --git a/pngwrite.c b/pngwrite.c index 63208b629..afec136cb 100644 --- a/pngwrite.c +++ b/pngwrite.c @@ -1,7 +1,7 @@ /* pngwrite.c - general routines to write a PNG file * - * libpng 1.0.12 - June 8, 2001 + * libpng 1.2.0 - September 1, 2001 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2001 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) @@ -452,6 +452,10 @@ png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, return ((png_structp)NULL); } +#ifdef PNG_ASSEMBLER_CODE_SUPPORTED + png_init_mmx_flags(png_ptr); /* 1.2.0 addition */ +#endif + #ifdef PNG_SETJMP_SUPPORTED #ifdef USE_FAR_KEYWORD if (setjmp(jmpbuf)) @@ -510,35 +514,6 @@ png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr, png_error(png_ptr, "Incompatible libpng version in application and library"); } - - /* Libpng 1.0.6 was not binary compatible, due to insertion of the - info_ptr->free_me member. Libpng-1.0.1 and earlier were not - compatible due to insertion of the user transform function. Note - to maintainer: this test can be removed from version 1.2.0 and - beyond because the previous test would have already rejected it. */ - - if (user_png_ver[0] == '1' && user_png_ver[2] == '0' && - (user_png_ver[4] < '2' || user_png_ver[4] == '6') && - user_png_ver[5] == '\0') - { -#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) - char msg[80]; - if (user_png_ver) - { - sprintf(msg, "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_libpng_ver); - png_warning(png_ptr, msg); -#endif -#ifdef PNG_ERROR_NUMBERS_SUPPORTED - png_ptr->flags=0; -#endif - png_error(png_ptr, - "Application must be recompiled; versions <= 1.0.6 were incompatible"); - } } /* initialize zbuf - compression buffer */ @@ -650,6 +625,10 @@ png_write_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver, /* reset all variables to 0 */ png_memset(png_ptr, 0, sizeof (png_struct)); +#ifdef PNG_ASSEMBLER_CODE_SUPPORTED + png_init_mmx_flags(png_ptr); /* 1.2.0 addition */ +#endif + #ifdef PNG_SETJMP_SUPPORTED /* restore jump buffer */ png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf)); diff --git a/pngwtran.c b/pngwtran.c index 3cc60672a..7a38b9c41 100644 --- a/pngwtran.c +++ b/pngwtran.c @@ -1,7 +1,7 @@ /* pngwtran.c - transforms the data in a row for PNG writers * - * libpng 1.0.12 - June 8, 2001 + * libpng 1.2.0 - September 1, 2001 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2001 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) diff --git a/pngwutil.c b/pngwutil.c index a1db9c291..5613a1f17 100644 --- a/pngwutil.c +++ b/pngwutil.c @@ -1,7 +1,7 @@ /* pngwutil.c - utilities to write a PNG file * - * libpng 1.0.12 - June 8, 2001 + * libpng 1.2.0 - September 1, 2001 * For conditions of distribution and use, see copyright notice in png.h * Copyright (c) 1998-2001 Glenn Randers-Pehrson * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) @@ -25,7 +25,7 @@ png_save_uint_32(png_bytep buf, png_uint_32 i) buf[3] = (png_byte)(i & 0xff); } -#if defined(PNG_WRITE_pCAL_SUPPORTED) +#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. @@ -332,7 +332,8 @@ png_write_compressed_data_out(png_structp png_ptr, compression_state *comp) /* handle the no-compression case */ if (comp->input) { - png_write_chunk_data(png_ptr, (png_bytep)comp->input, comp->input_len); + png_write_chunk_data(png_ptr, (png_bytep)comp->input, + (png_size_t)comp->input_len); return; } @@ -537,8 +538,7 @@ png_write_PLTE(png_structp png_ptr, png_colorp palette, png_uint_32 num_pal) png_debug(1, "in png_write_PLTE\n"); if (( -#if defined(PNG_MNG_FEATURES_SUPPORTED) || \ - defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) +#if defined(PNG_MNG_FEATURES_SUPPORTED) !(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) && #endif num_pal == 0) || num_pal > 256) @@ -642,7 +642,7 @@ png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma) png_debug(1, "in png_write_gAMA\n"); /* file_gamma is saved in 1/100,000ths */ - png_save_uint_32(buf, file_gamma); + png_save_uint_32(buf, (png_uint_32)file_gamma); png_write_chunk(png_ptr, (png_bytep)png_gAMA, buf, (png_size_t)4); } #endif @@ -764,7 +764,7 @@ png_write_sPLT(png_structp png_ptr, png_sPLT_tp spalette) png_save_uint_16(entrybuf + 6, ep->alpha); png_save_uint_16(entrybuf + 8, ep->frequency); } - png_write_chunk_data(png_ptr, entrybuf, entry_size); + png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size); } #else ep=spalette->entries; @@ -939,32 +939,32 @@ png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x, #endif return; } - png_save_uint_32(buf, white_x); - png_save_uint_32(buf + 4, white_y); + 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, red_x); - png_save_uint_32(buf + 12, red_y); + png_save_uint_32(buf + 8, (png_uint_32)red_x); + png_save_uint_32(buf + 12, (png_uint_32)red_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, green_x); - png_save_uint_32(buf + 20, green_y); + png_save_uint_32(buf + 16, (png_uint_32)green_x); + png_save_uint_32(buf + 20, (png_uint_32)green_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, blue_x); - png_save_uint_32(buf + 28, blue_y); + 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); } @@ -996,6 +996,12 @@ png_write_tRNS(png_structp png_ptr, png_bytep trans, png_color_16p tran, else if (color_type == PNG_COLOR_TYPE_GRAY) { /* one 16 bit value */ + if(tran->gray >= (1 << png_ptr->bit_depth)) + { + png_warning(png_ptr, + "Ignoring attempt to write tRNS chunk out-of-range for bit_depth"); + return; + } png_save_uint_16(buf, tran->gray); png_write_chunk(png_ptr, (png_bytep)png_tRNS, buf, (png_size_t)2); } @@ -1005,6 +1011,12 @@ png_write_tRNS(png_structp png_ptr, png_bytep trans, png_color_16p tran, png_save_uint_16(buf, tran->red); png_save_uint_16(buf + 2, tran->green); png_save_uint_16(buf + 4, tran->blue); + 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 @@ -1028,8 +1040,7 @@ png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type) if (color_type == PNG_COLOR_TYPE_PALETTE) { if ( -#if defined(PNG_MNG_FEATURES_SUPPORTED) || \ - defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED) +#if defined(PNG_MNG_FEATURES_SUPPORTED) (png_ptr->num_palette || (!(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE))) && #endif @@ -1046,10 +1057,22 @@ 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; + } png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)6); } else { + if(back->gray >= (1 << png_ptr->bit_depth)) + { + png_warning(png_ptr, + "Ignoring attempt to write bKGD chunk out-of-range for bit_depth"); + return; + } png_save_uint_16(buf, back->gray); png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)2); } @@ -1385,8 +1408,7 @@ png_write_iTXt(png_structp png_ptr, int compression, png_charp key, #if defined(PNG_WRITE_oFFs_SUPPORTED) /* write the oFFs chunk */ void /* PRIVATE */ -png_write_oFFs(png_structp png_ptr, png_uint_32 x_offset, - png_uint_32 y_offset, +png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset, int unit_type) { #ifdef PNG_USE_LOCAL_ARRAYS @@ -1398,8 +1420,8 @@ png_write_oFFs(png_structp png_ptr, png_uint_32 x_offset, if (unit_type >= PNG_OFFSET_LAST) png_warning(png_ptr, "Unrecognized unit type for oFFs chunk"); - png_save_uint_32(buf, x_offset); - png_save_uint_32(buf + 4, y_offset); + png_save_int_32(buf, x_offset); + png_save_int_32(buf + 4, y_offset); buf[8] = (png_byte)unit_type; png_write_chunk(png_ptr, (png_bytep)png_oFFs, buf, (png_size_t)9);