pax_global_header00006660000000000000000000000064145660652540014527gustar00rootroot0000000000000052 comment=ed217e3e601d8e462f7fd1e04bed43ac42212429 libpng-1.6.43/000077500000000000000000000000001456606525400130755ustar00rootroot00000000000000libpng-1.6.43/.appveyor.yml000066400000000000000000000061571456606525400155540ustar00rootroot00000000000000version: 1.6.x-{build} branches: except: - /libpng[0-1][0-7]/ - /v[0-1][.][0-7][.][0-9]+/ image: - Visual Studio 2022 shallow_clone: true environment: matrix: - TOOLCHAIN: vstudio AUTOMATION: cmake ARCH: x86 - TOOLCHAIN: vstudio AUTOMATION: cmake ARCH: x64 - TOOLCHAIN: vstudio AUTOMATION: cmake ARCH: arm64 - TOOLCHAIN: llvm AUTOMATION: cmake ARCH: x64 - TOOLCHAIN: msys2 AUTOMATION: cmake ARCH: i686 - TOOLCHAIN: msys2 AUTOMATION: cmake ARCH: x86_64 - TOOLCHAIN: msys2 AUTOMATION: configure ARCH: i686 - TOOLCHAIN: msys2 AUTOMATION: configure ARCH: x86_64 - TOOLCHAIN: msys2 AUTOMATION: makefiles ARCH: i686 - TOOLCHAIN: msys2 AUTOMATION: makefiles ARCH: x86_64 install: - 'if "%TOOLCHAIN%"=="vstudio" C:\tools\vcpkg\vcpkg.exe install zlib:%ARCH%-windows' - 'if "%TOOLCHAIN%"=="vstudio" C:\tools\vcpkg\vcpkg.exe integrate install' - 'if "%TOOLCHAIN%"=="llvm" C:\tools\vcpkg\vcpkg.exe install zlib:%ARCH%-windows' - 'if "%TOOLCHAIN%"=="llvm" C:\tools\vcpkg\vcpkg.exe integrate install' before_build: - 'if "%TOOLCHAIN%"=="vstudio" set CI_CMAKE_GENERATOR=Visual Studio 17 2022' - 'if "%TOOLCHAIN%"=="vstudio" set CI_CMAKE_TOOLCHAIN_FILE=C:\tools\vcpkg\scripts\buildsystems\vcpkg.cmake' - 'if "%TOOLCHAIN%"=="vstudio" if "%ARCH%"=="x86" set CI_CMAKE_GENERATOR_PLATFORM=Win32' - 'if "%TOOLCHAIN%"=="vstudio" if "%ARCH%"=="x64" set CI_CMAKE_GENERATOR_PLATFORM=x64' - 'if "%TOOLCHAIN%"=="vstudio" if "%ARCH%"=="arm64" set CI_CMAKE_GENERATOR_PLATFORM=ARM64' - 'if "%TOOLCHAIN%"=="vstudio" if "%ARCH%"=="arm64" set CI_CMAKE_VARS=-DPNG_TESTS=0' - 'if "%TOOLCHAIN%"=="llvm" set CI_CMAKE_GENERATOR=Ninja' - 'if "%TOOLCHAIN%"=="llvm" set CI_CMAKE_TOOLCHAIN_FILE=C:\tools\vcpkg\scripts\buildsystems\vcpkg.cmake' - 'if "%TOOLCHAIN%"=="llvm" set CI_CC=clang.exe' - 'if "%TOOLCHAIN%"=="msys2" if "%AUTOMATION%"=="cmake" set CI_CMAKE_GENERATOR=Unix Makefiles' - 'if "%TOOLCHAIN%"=="msys2" if "%ARCH%"=="i686" set PATH=C:\msys64\mingw32\bin;%PATH%' - 'if "%TOOLCHAIN%"=="msys2" if "%ARCH%"=="x86_64" set PATH=C:\msys64\mingw64\bin;%PATH%' - 'if "%TOOLCHAIN%"=="msys2" set CI_CC=%ARCH%-w64-mingw32-gcc.exe' - 'set CI_CMAKE_BUILD_FLAGS=-j2' - 'set CI_CTEST_FLAGS=-j2' - 'set CI_MAKE_FLAGS=-j2' - 'set CI_MAKEFILES=scripts/makefile.gcc scripts/makefile.msys scripts/makefile.std' build_script: - 'if "%TOOLCHAIN%"=="vstudio" C:\msys64\usr\bin\bash.exe -l "%APPVEYOR_BUILD_FOLDER%\ci\ci_verify_cmake.sh"' - 'if "%TOOLCHAIN%"=="llvm" C:\msys64\usr\bin\bash.exe -l "%APPVEYOR_BUILD_FOLDER%\ci\ci_verify_cmake.sh"' - 'if "%TOOLCHAIN%"=="msys2" if "%AUTOMATION%"=="cmake" C:\msys64\usr\bin\bash.exe -l "%APPVEYOR_BUILD_FOLDER%\ci\ci_verify_cmake.sh"' - 'if "%TOOLCHAIN%"=="msys2" if "%AUTOMATION%"=="configure" C:\msys64\usr\bin\bash.exe -l "%APPVEYOR_BUILD_FOLDER%\ci\ci_verify_configure.sh"' - 'if "%TOOLCHAIN%"=="msys2" if "%AUTOMATION%"=="makefiles" C:\msys64\usr\bin\bash.exe -l "%APPVEYOR_BUILD_FOLDER%\ci\ci_verify_makefiles.sh"' cache: - C:\tools\vcpkg\installed libpng-1.6.43/.editorconfig000066400000000000000000000012641456606525400155550ustar00rootroot00000000000000# https://editorconfig.org root = true [*] charset = utf-8 insert_final_newline = true trim_trailing_whitespace = true [*.txt] indent_style = space [*.[chS]] indent_style = space max_doc_length = 80 max_line_length = 80 [*.dfa] indent_style = space max_doc_length = 80 max_line_length = 80 [*.{awk,cmake}] indent_style = space max_doc_length = 80 max_line_length = 100 [*.{in,sh}] indent_style = space max_doc_length = 100 max_line_length = 100 [{Makefile.in,ltmain.sh}] indent_style = unset insert_final_newline = unset max_doc_length = unset max_line_length = unset trim_trailing_whitespace = unset [COMMIT_EDITMSG] indent_style = space max_doc_length = unset max_line_length = 72 libpng-1.6.43/.github/000077500000000000000000000000001456606525400144355ustar00rootroot00000000000000libpng-1.6.43/.github/workflows/000077500000000000000000000000001456606525400164725ustar00rootroot00000000000000libpng-1.6.43/.github/workflows/lint.yml000066400000000000000000000011411456606525400201600ustar00rootroot00000000000000name: Linting libpng on: push: branches: - libpng16 pull_request: branches: - libpng16 jobs: lint: runs-on: ubuntu-latest timeout-minutes: 5 steps: - name: Set up the cache uses: actions/cache@v4 with: path: ~/.cache/pip key: ${{ runner.os }}-pip-${{ hashFiles('**/pip.txt') }} restore-keys: ${{ runner.os }}-pip- - name: Install yamllint run: pip install yamllint - name: Check out the code uses: actions/checkout@v4 - name: Run the linting script run: bash ./ci/ci_lint.sh libpng-1.6.43/.gitignore000066400000000000000000000014321456606525400150650ustar00rootroot00000000000000# Prerequisites *.d # Precompiled headers *.gch *.pch # Object files *.slo *.lo *.o *.obj # Linker output files *.exp *.ilk *.map # Compiled dynamic libraries *.dll *.dylib *.so *.so.* # Compiled static libraries *.a *.la *.lai *.lib # Compiled executables *.app/ *.exe # Debug files *.dSYM/ *.idb *.pdb *.su # Libpng configuration and build artifacts *.out .deps/ .dirstamp /Makefile /autom4te.cache/ /config.guess~ /config.h.in~ /config.log /config.status /config.sub~ /configure~ /install-sh~ /libpng-config /libpng.pc /libpng.vers /libpng16-config /libpng16.pc /libtool /stamp-h1 pnglibconf.[ch] pnglibconf.dfn pnglibconf.pre pngprefix.h # Libpng test artifacts png-fix-itxt pngcp pngfix pngimage pngstest pngtest pngunknown pngvalid timepng pngout.png # Libpng CI artifacts out/ libpng-1.6.43/.travis.yml000066400000000000000000000017041456606525400152100ustar00rootroot00000000000000branches: except: - /libpng[0-1][0-7]/ - /v[0-1][.][0-7][.][0-9]+/ language: c os: - freebsd - linux - osx env: - AUTOMATION=cmake CI_CMAKE_VARS="-DPNG_HARDWARE_OPTIMIZATIONS=ON" - AUTOMATION=cmake CI_CMAKE_VARS="-DPNG_HARDWARE_OPTIMIZATIONS=OFF" - AUTOMATION=configure CI_CONFIGURE_FLAGS="--enable-hardware-optimizations" - AUTOMATION=configure CI_CONFIGURE_FLAGS="--disable-hardware-optimizations" - AUTOMATION=makefiles matrix: include: - os: osx env: AUTOMATION=cmake CI_CMAKE_GENERATOR=Xcode before_script: - 'if test "$TRAVIS_OS_NAME" = "linux"; then export CI_CC="gcc"; else export CI_CC="clang"; fi' - 'if test "$TRAVIS_OS_NAME" != "osx"; then export CI_SANITIZERS="address,undefined"; fi' - 'export CI_MAKEFILES="scripts/makefile.$CI_CC scripts/makefile.std"' - 'export CI_MAKE_FLAGS=-j2' - 'export CI_CMAKE_BUILD_FLAGS=-j2' - 'export CI_CTEST_FLAGS=-j2' script: - './ci/ci_verify_$AUTOMATION.sh' libpng-1.6.43/.yamllint.yml000066400000000000000000000002011456606525400155200ustar00rootroot00000000000000extends: default rules: document-start: disable document-end: disable line-length: disable truthy: check-keys: false libpng-1.6.43/ANNOUNCE000066400000000000000000000043511456606525400142310ustar00rootroot00000000000000libpng 1.6.43 - February 23, 2024 ================================= This is a public release of libpng, intended for use in production code. Files available for download ---------------------------- Source files with LF line endings (for Unix/Linux): * libpng-1.6.43.tar.xz (LZMA-compressed, recommended) * libpng-1.6.43.tar.gz (deflate-compressed) Source files with CRLF line endings (for Windows): * lpng1643.7z (LZMA-compressed, recommended) * lpng1643.zip (deflate-compressed) Other information: * README.md * LICENSE.md * AUTHORS.md * TRADEMARK.md Changes from version 1.6.42 to version 1.6.43 --------------------------------------------- * Fixed the row width check in png_check_IHDR(). This corrected a bug that was specific to the 16-bit platforms, and removed a spurious compiler warning from the 64-bit builds. (Reported by Jacek Caban; fixed by John Bowler) * Added eXIf chunk support to the push-mode reader in pngpread.c. (Contributed by Chris Blume) * Added contrib/pngexif for the benefit of the users who would like to inspect the content of eXIf chunks. * Added contrib/conftest/basic.dfa, a basic build-time configuration. (Contributed by John Bowler) * Fixed a preprocessor condition in pngread.c that broke build-time configurations like contrib/conftest/pngcp.dfa. (Contributed by John Bowler) * Added CMake build support for LoongArch LSX. (Contributed by GuXiWei) * Fixed a CMake build error that occurred under a peculiar state of the dependency tree. This was a regression introduced in libpng-1.6.41. (Contributed by Dan Rosser) * Marked the installed libpng headers as system headers in CMake. (Contributed by Benjamin Buch) * Updated the build support for RISCOS. (Contributed by Cameron Cawley) * Updated the makefiles to allow cross-platform builds to initialize conventional make variables like AR and ARFLAGS. * Added various improvements to the CI scripts in areas like version consistency verification and text linting. * Added version consistency verification to pngtest.c also. Send comments/corrections/commendations to png-mng-implement at lists.sf.net. Subscription is required; visit https://lists.sourceforge.net/lists/listinfo/png-mng-implement to subscribe. libpng-1.6.43/AUTHORS000066400000000000000000000026521456606525400141520ustar00rootroot00000000000000PNG REFERENCE LIBRARY AUTHORS ============================= This is the list of PNG Reference Library ("libpng") Contributing Authors, for copyright and licensing purposes. * Adam Richter * Andreas Dilger * Chris Blume * Cosmin Truta * Dave Martindale * Eric S. Raymond * Gilles Vollant * Glenn Randers-Pehrson * Greg Roelofs * Guy Eric Schalnat * James Yu * John Bowler * Kevin Bracey * Magnus Holmgren * Mandar Sahastrabuddhe * Mans Rullgard * Matt Sarett * Mike Klein * Pascal Massimino * Paul Schmidt * Philippe Antoine * Qiang Zhou * Sam Bushell * Samuel Williams * Simon-Pierre Cadieux * Tim Wegner * Tom Lane * Tom Tanner * Vadim Barkov * Willem van Schaik * Zhijie Liang * Apple Inc. - Zixu Wang (王子旭) * Arm Holdings - Richard Townsend * Google Inc. - Dan Field - Leon Scroggins III - Matt Sarett - Mike Klein - Sami Boukortt - Wan-Teh Chang * Loongson Technology Corporation Ltd. - GuXiWei (顾希伟) - JinBo (金波) - ZhangLixia (张利霞) The build projects, the build scripts, the test scripts, and other files in the "projects", "scripts" and "tests" directories, have other copyright owners, but are released under the libpng license. Some files in the "ci" and "contrib" directories, as well as some of the tools-generated files that are distributed with libpng, have other copyright owners, and are released under other open source licenses. libpng-1.6.43/CHANGES000066400000000000000000011334441456606525400141020ustar00rootroot00000000000000CHANGES - changes for libpng version 0.1 [March 29, 1995] initial work-in-progress release version 0.2 [April 1, 1995] added reader into png.h fixed small problems in stub file version 0.3 [April 8, 1995] added pull reader split up pngwrite.c to several files added pnglib.txt added example.c cleaned up writer, adding a few new transformations fixed some bugs in writer interfaced with zlib 0.5 added K&R support added check for 64 KB blocks for 16 bit machines version 0.4 [April 26, 1995] cleaned up code and commented code simplified time handling into png_time created png_color_16 and png_color_8 to handle color needs cleaned up color type defines fixed various bugs made various names more consistent interfaced with zlib 0.71 cleaned up zTXt reader and writer (using zlib's Reset functions) split transformations into pngrtran.c and pngwtran.c version 0.5 [April 30, 1995] interfaced with zlib 0.8 fixed many reading and writing bugs saved using 3 spaces instead of tabs version 0.6 [May 1, 1995] first beta release added png_large_malloc() and png_large_free() added png_size_t cleaned up some compiler warnings added png_start_read_image() version 0.7 [June 24, 1995] cleaned up lots of bugs finished dithering and other stuff added test program changed name from pnglib to libpng version 0.71 [June 26, 1995] changed pngtest.png for zlib 0.93 fixed error in libpng.txt and example.c version 0.8 [August 20, 1995] cleaned up some bugs added png_set_filler() split up pngstub.c into pngmem.c, pngio.c, and pngerror.c added #define's to remove unwanted code moved png_info_init() to png.c added old_size into png_realloc() added functions to manually set filtering and compression info changed compression parameters based on image type optimized filter selection code added version info changed external functions passing floats to doubles (k&r problems?) put all the configurable stuff in pngconf.h enabled png_set_shift to work with paletted images on read added png_read_update_info() - updates info structure with transformations Version 0.81 [August, 1995] incorporated Tim Wegner's medium model code (thanks, Tim) Version 0.82 [September, 1995] [unspecified changes] Version 0.85 [December, 1995] added more medium model code (almost everything's a far) added i/o, error, and memory callback functions fixed some bugs (16-bit, 4-bit interlaced, etc.) added first run progressive reader (barely tested) Version 0.86 [January, 1996] fixed bugs improved documentation Version 0.87 [January, 1996] fixed medium model bugs fixed other bugs introduced in 0.85 and 0.86 added some minor documentation Version 0.88 [January, 1996] fixed progressive bugs replaced tabs with spaces cleaned up documentation added callbacks for read/write and warning/error functions Version 0.89 [June 5, 1996] Added new initialization API to make libpng work better with shared libs we now have png_create_read_struct(), png_create_write_struct(), png_create_info_struct(), png_destroy_read_struct(), and png_destroy_write_struct() instead of the separate calls to malloc and png_read_init(), png_info_init(), and png_write_init() Changed warning/error callback functions to fix bug - this means you should use the new initialization API if you were using the old png_set_message_fn() calls, and that the old API no longer exists so that people are aware that they need to change their code Changed filter selection API to allow selection of multiple filters since it didn't work in previous versions of libpng anyways Optimized filter selection code Fixed png_set_background() to allow using an arbitrary RGB color for paletted images Fixed gamma and background correction for paletted images, so png_correct_palette is not needed unless you are correcting an external palette (you will need to #define PNG_CORRECT_PALETTE_SUPPORTED in pngconf.h) - if nobody uses this, it may disappear in the future. Fixed bug with Borland 64K memory allocation (Alexander Lehmann) Fixed bug in interlace handling (Smarasderagd, I think) Added more error checking for writing and image to reduce invalid files Separated read and write functions so that they won't both be linked into a binary when only reading or writing functionality is used New pngtest image also has interlacing and zTXt Updated documentation to reflect new API Version 0.89c [June 17, 1996] Bug fixes. Version 0.90 [January, 1997] Made CRC errors/warnings on critical and ancillary chunks configurable libpng will use the zlib CRC routines by (compile-time) default Changed DOS small/medium model memory support - needs zlib 1.04 (Tim Wegner) Added external C++ wrapper statements to png.h (Gilles Dauphin) Allow PNG file to be read when some or all of file signature has already been read from the beginning of the stream. ****This affects the size of info_struct and invalidates all programs that use a shared libpng**** Fixed png_filler() declarations Fixed? background color conversions Fixed order of error function pointers to match documentation Current chunk name is now available in png_struct to reduce the number of nearly identical error messages (will simplify multi-lingual support when available) Try to get ready for unknown-chunk callback functions: - previously read critical chunks are flagged, so the chunk handling routines can determine if the chunk is in the right place - all chunk handling routines have the same prototypes, so we will be able to handle all chunks via a callback mechanism Try to fix Linux "setjmp" buffer size problems Removed png_large_malloc, png_large_free, and png_realloc functions. Version 0.95 [March, 1997] Fixed bug in pngwutil.c allocating "up_row" twice and "avg_row" never Fixed bug in PNG file signature compares when start != 0 Changed parameter type of png_set_filler(...filler...) from png_byte to png_uint_32 Added test for MACOS to ensure that both math.h and fp.h are not #included Added macros for libpng to be compiled as a Windows DLL (Andreas Kupries) Added "packswap" transformation, which changes the endianness of packed-pixel bytes (Kevin Bracey) Added "strip_alpha" transformation, which removes the alpha channel of input images without using it (not necessarily a good idea) Added "swap_alpha" transformation, which puts the alpha channel in front of the color bytes instead of after Removed all implicit variable tests which assume NULL == 0 (I think) Changed several variables to "png_size_t" to show 16/32-bit limitations Added new pCAL chunk read/write support Added experimental filter selection weighting (Greg Roelofs) Removed old png_set_rgbx() and png_set_xrgb() functions that have been obsolete for about 2 years now (use png_set_filler() instead) Added macros to read 16- and 32-bit ints directly from buffer, to be used only on those systems that support it (namely PowerPC and 680x0) With some testing, this may become the default for MACOS/PPC systems. Only calculate CRC on data if we are going to use it Added macros for zTXt compression type PNG_zTXt_COMPRESSION_??? Added macros for simple libpng debugging output selectable at compile time Removed PNG_READ_END_MODE in progressive reader (Smarasderagd) More description of info_struct in libpng.txt and png.h More instructions in example.c More chunk types tested in pngtest.c Renamed pngrcb.c to pngset.c, and all png_read_ functions to be png_set_. We now have corresponding png_get_ functions in pngget.c to get information in info_ptr. This isolates the application from the internal organization of png_info_struct (good for shared library implementations). Version 0.96 [May, 1997] Fixed serious bug with < 8bpp images introduced in 0.95 Fixed 256-color transparency bug (Greg Roelofs) Fixed up documentation (Greg Roelofs, Laszlo Nyul) Fixed "error" in pngconf.h for Linux setjmp() behavior Fixed DOS medium model support (Tim Wegner) Fixed png_check_keyword() for case with error in static string text Added read of CRC after IEND chunk for embedded PNGs (Laszlo Nyul) Added typecasts to quiet compiler errors Added more debugging info Version 0.97 [January, 1998] Removed PNG_USE_OWN_CRC capability Relocated png_set_crc_action from pngrutil.c to pngrtran.c Fixed typecasts of "new_key", etc. (Andreas Dilger) Added RFC 1152 [sic] date support Fixed bug in gamma handling of 4-bit grayscale Added 2-bit grayscale gamma handling (Glenn R-P) Added more typecasts. 65536L becomes (png_uint_32)65536L, etc. (Glenn R-P) Minor corrections in libpng.txt Added simple sRGB support (Glenn R-P) Easier conditional compiling, e.g., define PNG_READ/WRITE_NOT_FULLY_SUPPORTED; all configurable options can be selected from command line instead of having to edit pngconf.h (Glenn R-P) Fixed memory leak in pngwrite.c (free info_ptr->text) (Glenn R-P) Added more conditions for png_do_background, to avoid changing black pixels to background when a background is supplied and no pixels are transparent Repaired PNG_NO_STDIO behavior Tested NODIV support and made it default behavior (Greg Roelofs) Added "-m" option and PNGTEST_DEBUG_MEMORY to pngtest (John Bowler) Regularized version numbering scheme and bumped shared-library major version number to 2 to avoid problems with libpng 0.89 apps (Greg Roelofs) Version 0.98 [January, 1998] Cleaned up some typos in libpng.txt and in code documentation Fixed memory leaks in pCAL chunk processing (Glenn R-P and John Bowler) Cosmetic change "display_gamma" to "screen_gamma" in pngrtran.c Changed recommendation about file_gamma for PC images to .51 from .45, in example.c and libpng.txt, added comments to distinguish between screen_gamma, viewing_gamma, and display_gamma. Changed all references to RFC1152 to read RFC1123 and changed the PNG_TIME_RFC1152_SUPPORTED macro to PNG_TIME_RFC1123_SUPPORTED Added png_invert_alpha capability (Glenn R-P -- suggestion by Jon Vincent) Changed srgb_intent from png_byte to int to avoid compiler bugs Version 0.99 [January 30, 1998] Free info_ptr->text instead of end_info_ptr->text in pngread.c (John Bowler) Fixed a longstanding "packswap" bug in pngtrans.c Fixed some inconsistencies in pngconf.h that prevented compiling with PNG_READ_GAMMA_SUPPORTED and PNG_READ_hIST_SUPPORTED undefined Fixed some typos and made other minor rearrangement of libpng.txt (Andreas) Changed recommendation about file_gamma for PC images to .50 from .51 in example.c and libpng.txt, and changed file_gamma for sRGB images to .45 Added a number of functions to access information from the png structure png_get_image_height(), etc. (Glenn R-P, suggestion by Brad Pettit) Added TARGET_MACOS similar to zlib-1.0.8 Define PNG_ALWAYS_EXTERN when __MWERKS__ && WIN32 are defined Added type casting to all png_malloc() function calls Version 0.99a [January 31, 1998] Added type casts and parentheses to all returns that return a value.(Tim W.) Version 0.99b [February 4, 1998] Added type cast png_uint_32 on malloc function calls where needed. Changed type of num_hist from png_uint_32 to int (same as num_palette). Added checks for rowbytes overflow, in case png_size_t is less than 32 bits. Renamed makefile.elf to makefile.lnx. Version 0.99c [February 7, 1998] More type casting. Removed erroneous overflow test in pngmem.c. Added png_buffered_memcpy() and png_buffered_memset(), apply them to rowbytes. Added UNIX manual pages libpng.3 (incorporating libpng.txt) and png.5. Version 0.99d [February 11, 1998] Renamed "far_to_near()" "png_far_to_near()" Revised libpng.3 Version 99c "buffered" operations didn't work as intended. Replaced them with png_memcpy_check() and png_memset_check(). Added many "if (png_ptr == NULL) return" to quell compiler warnings about unused png_ptr, mostly in pngget.c and pngset.c. Check for overlength tRNS chunk present when indexed-color PLTE is read. Cleaned up spelling errors in libpng.3/libpng.txt Corrected a problem with png_get_tRNS() which returned undefined trans array Version 0.99e [February 28, 1998] Corrected png_get_tRNS() again. Add parentheses for easier reading of pngget.c, fixed "||" should be "&&". Touched up example.c to make more of it compileable, although the entire file still can't be compiled (Willem van Schaik) Fixed a bug in png_do_shift() (Bryan Tsai) Added a space in png.h prototype for png_write_chunk_start() Replaced pngtest.png with one created with zlib 1.1.1 Changed pngtest to report PASS even when file size is different (Jean-loup G.) Corrected some logic errors in png_do_invert_alpha() (Chris Patterson) Version 0.99f [March 5, 1998] Corrected a bug in pngpread() introduced in version 99c (Kevin Bracey) Moved makefiles into a "scripts" directory, and added INSTALL instruction file Added makefile.os2 and pngos2.def (A. Zabolotny) and makefile.s2x (W. Sebok) Added pointers to "note on libpng versions" in makefile.lnx and README Added row callback feature when reading and writing nonprogressive rows and added a test of this feature in pngtest.c Added user transform callbacks, with test of the feature in pngtest.c Version 0.99g [March 6, 1998, morning] Minor changes to pngtest.c to suppress compiler warnings. Removed "beta" language from documentation. Version 0.99h [March 6, 1998, evening] Minor changes to previous minor changes to pngtest.c Changed PNG_READ_NOT_FULLY_SUPPORTED to PNG_READ_TRANSFORMS_NOT_SUPPORTED and added PNG_PROGRESSIVE_READ_NOT_SUPPORTED macro Added user transform capability Version 1.00 [March 7, 1998] Changed several typedefs in pngrutil.c Added makefile.wat (Pawel Mrochen), updated makefile.tc3 (Willem van Schaik) Replaced "while(1)" with "for(;;)" Added PNGARG() to prototypes in pngtest.c and removed some prototypes Updated some of the makefiles (Tom Lane) Changed some typedefs (s_start, etc.) in pngrutil.c Fixed dimensions of "short_months" array in pngwrite.c Replaced ansi2knr.c with the one from jpeg-v6 Version 1.0.0 [March 8, 1998] Changed name from 1.00 to 1.0.0 (Adam Costello) Added smakefile.ppc (with SCOPTIONS.ppc) for Amiga PPC (Andreas Kleinert) Version 1.0.0a [March 9, 1998] Fixed three bugs in pngrtran.c to make gamma+background handling consistent (Greg Roelofs) Changed format of the PNG_LIBPNG_VER integer to xyyzz instead of xyz for major, minor, and bugfix releases. This is 10001. (Adam Costello, Tom Lane) Make months range from 1-12 in png_convert_to_rfc1123 Version 1.0.0b [March 13, 1998] Quieted compiler complaints about two empty "for" loops in pngrutil.c Minor changes to makefile.s2x Removed #ifdef/#endif around a png_free() in pngread.c Version 1.0.1 [March 14, 1998] Changed makefile.s2x to reduce security risk of using a relative pathname Fixed some typos in the documentation (Greg). Fixed a problem with value of "channels" returned by png_read_update_info() Version 1.0.1a [April 21, 1998] Optimized Paeth calculations by replacing abs() function calls with intrinsics plus other loop optimizations. Improves avg decoding speed by about 20%. Commented out i386istic "align" compiler flags in makefile.lnx. Reduced the default warning level in some makefiles, to make them consistent. Removed references to IJG and JPEG in the ansi2knr.c copyright statement. Fixed a bug in png_do_strip_filler with XXRRGGBB => RRGGBB transformation. Added grayscale and 16-bit capability to png_do_read_filler(). Fixed a bug in pngset.c, introduced in version 0.99c, that sets rowbytes too large when writing an image with bit_depth < 8 (Bob Dellaca). Corrected some bugs in the experimental weighted filtering heuristics. Moved a misplaced pngrutil code block that truncates tRNS if it has more than num_palette entries -- test was done before num_palette was defined. Fixed a png_convert_to_rfc1123() bug that converts day 31 to 0 (Steve Eddins). Changed compiler flags in makefile.wat for better optimization (Pawel Mrochen). Version 1.0.1b [May 2, 1998] Relocated png_do_gray_to_rgb() within png_do_read_transformations() (Greg). Relocated the png_composite macros from pngrtran.c to png.h (Greg). Added makefile.sco (contributed by Mike Hopkirk). Fixed two bugs (missing definitions of "istop") introduced in libpng-1.0.1a. Fixed a bug in pngrtran.c that would set channels=5 under some circumstances. More work on the Paeth-filtering, achieving imperceptible speedup (A Kleinert). More work on loop optimization which may help when compiled with C++ compilers. Added warnings when people try to use transforms they've defined out. Collapsed 4 "i" and "c" loops into single "i" loops in pngrtran and pngwtran. Revised paragraph about png_set_expand() in libpng.txt and libpng.3 (Greg) Version 1.0.1c [May 11, 1998] Fixed a bug in pngrtran.c (introduced in libpng-1.0.1a) where the masks for filler bytes should have been 0xff instead of 0xf. Added max_pixel_depth=32 in pngrutil.c when using FILLER with palette images. Moved PNG_WRITE_WEIGHTED_FILTER_SUPPORTED and PNG_WRITE_FLUSH_SUPPORTED out of the PNG_WRITE_TRANSFORMS_NOT_SUPPORTED block of pngconf.h Added "PNG_NO_WRITE_TRANSFORMS" etc., as alternatives for *_NOT_SUPPORTED, for consistency, in pngconf.h Added individual "ifndef PNG_NO_[CAPABILITY]" in pngconf.h to make it easier to remove unwanted capabilities via the compile line Made some corrections to grammar (which, it's) in documentation (Greg). Corrected example.c, use of row_pointers in png_write_image(). Version 1.0.1d [May 24, 1998] Corrected several statements that used side effects illegally in pngrutil.c and pngtrans.c, that were introduced in version 1.0.1b Revised png_read_rows() to avoid repeated if-testing for NULL (A Kleinert) More corrections to example.c, use of row_pointers in png_write_image() and png_read_rows(). Added pngdll.mak and pngdef.pas to scripts directory, contributed by Bob Dellaca, to make a png32bd.dll with Borland C++ 4.5 Fixed error in example.c with png_set_text: num_text is 3, not 2 (Guido V.) Changed several loops from count-down to count-up, for consistency. Version 1.0.1e [June 6, 1998] Revised libpng.txt and libpng.3 description of png_set_read|write_fn(), and added warnings when people try to set png_read_fn and png_write_fn in the same structure. Added a test such that png_do_gamma will be done when num_trans==0 for truecolor images that have defined a background. This corrects an error that was introduced in libpng-0.90 that can cause gamma processing to be skipped. Added tests in png.h to include "trans" and "trans_values" in structures when PNG_READ_BACKGROUND_SUPPORTED or PNG_READ_EXPAND_SUPPORTED is defined. Add png_free(png_ptr->time_buffer) in png_destroy_read_struct() Moved png_convert_to_rfc_1123() from pngwrite.c to png.c Added capability for user-provided malloc_fn() and free_fn() functions, and revised pngtest.c to demonstrate their use, replacing the PNGTEST_DEBUG_MEM feature. Added makefile.w32, for Microsoft C++ 4.0 and later (Tim Wegner). Version 1.0.2 [June 14, 1998] Fixed two bugs in makefile.bor . Version 1.0.2a [December 30, 1998] Replaced and extended code that was removed from png_set_filler() in 1.0.1a. Fixed a bug in png_do_filler() that made it fail to write filler bytes in the left-most pixel of each row (Kevin Bracey). Changed "static pngcharp tIME_string" to "static char tIME_string[30]" in pngtest.c (Duncan Simpson). Fixed a bug in pngtest.c that caused pngtest to try to write a tIME chunk even when no tIME chunk was present in the source file. Fixed a problem in pngrutil.c: gray_to_rgb didn't always work with 16-bit. Fixed a problem in png_read_push_finish_row(), which would not skip some passes that it should skip, for images that are less than 3 pixels high. Interchanged the order of calls to png_do_swap() and png_do_shift() in pngwtran.c (John Cromer). Added #ifdef PNG_DEBUG/#endif surrounding use of PNG_DEBUG in png.h . Changed "bad adaptive filter type" from error to warning in pngrutil.c . Fixed a documentation error about default filtering with 8-bit indexed-color. Separated the PNG_NO_STDIO macro into PNG_NO_STDIO and PNG_NO_CONSOLE_IO (L. Peter Deutsch). Added png_set_rgb_to_gray() and png_get_rgb_to_gray_status() functions. Added png_get_copyright() and png_get_header_version() functions. Revised comments on png_set_progressive_read_fn() in libpng.txt and example.c Added information about debugging in libpng.txt and libpng.3 . Changed "ln -sf" to "ln -s -f" in makefile.s2x, makefile.lnx, and makefile.sco. Removed lines after Dynamic Dependencies" in makefile.aco . Revised makefile.dec to make a shared library (Jeremie Petit). Removed trailing blanks from all files. Version 1.0.2a [January 6, 1999] Removed misplaced #endif and #ifdef PNG_NO_EXTERN near the end of png.h Added "if" tests to silence complaints about unused png_ptr in png.h and png.c Changed "check_if_png" function in example.c to return true (nonzero) if PNG. Changed libpng.txt to demonstrate png_sig_cmp() instead of png_check_sig() which is obsolete. Version 1.0.3 [January 14, 1999] Added makefile.hux, for Hewlett Packard HPUX 10.20 and 11.00 (Jim Rice) Added a statement of Y2K compliance in png.h, libpng.3, and Y2KINFO. Version 1.0.3a [August 12, 1999] Added check for PNG_READ_INTERLACE_SUPPORTED in pngread.c; issue a warning if an attempt is made to read an interlaced image when it's not supported. Added check if png_ptr->trans is defined before freeing it in pngread.c Modified the Y2K statement to include versions back to version 0.71 Fixed a bug in the check for valid IHDR bit_depth/color_types in pngrutil.c Modified makefile.wat (added -zp8 flag, ".symbolic", changed some comments) Replaced leading blanks with tab characters in makefile.hux Changed "dworkin.wustl.edu" to "ccrc.wustl.edu" in various documents. Changed (float)red and (float)green to (double)red, (double)green in png_set_rgb_to_gray() to avoid "promotion" problems in AIX. Fixed a bug in pngconf.h that omitted when PNG_DEBUG==0 (K Bracey). Reformatted libpng.3 and libpngpf.3 with proper fonts (script by J. vanZandt). Updated documentation to refer to the PNG-1.2 specification. Removed ansi2knr.c and left pointers to the latest source for ansi2knr.c in makefile.knr, INSTALL, and README (L. Peter Deutsch) Fixed bugs in calculation of the length of rowbytes when adding alpha channels to 16-bit images, in pngrtran.c (Chris Nokleberg) Added function png_set_user_transform_info() to store user_transform_ptr, user_depth, and user_channels into the png_struct, and a function png_get_user_transform_ptr() to retrieve the pointer (Chris Nokleberg) Added function png_set_empty_plte_permitted() to make libpng useable in MNG applications. Corrected the typedef for png_free_ptr in png.h (Jesse Jones). Correct gamma with srgb is 45455 instead of 45000 in pngrutil.c, to be consistent with PNG-1.2, and allow variance of 500 before complaining. Added assembler code contributed by Intel in file pngvcrd.c and modified makefile.w32 to use it (Nirav Chhatrapati, INTEL Corporation, Gilles Vollant) Changed "ln -s -f" to "ln -f -s" in the makefiles to make Solaris happy. Added some aliases for png_set_expand() in pngrtran.c, namely png_set_expand_PLTE(), png_set_expand_depth(), and png_set_expand_tRNS() (Greg Roelofs, in "PNG: The Definitive Guide"). Added makefile.beo for BEOS on X86, contributed by Sander Stok. Version 1.0.3b [August 26, 1999] Replaced 2147483647L several places with PNG_MAX_UINT macro, defined in png.h Changed leading blanks to tabs in all makefiles. Define PNG_USE_PNGVCRD in makefile.w32, to get MMX assembler code. Made alternate versions of png_set_expand() in pngrtran.c, namely png_set_gray_1_2_4_to_8, png_set_palette_to_rgb, and png_set_tRNS_to_alpha (Greg Roelofs, in "PNG: The Definitive Guide"). Deleted the 1.0.3a aliases. Relocated start of 'extern "C"' block in png.h so it doesn't include pngconf.h Revised calculation of num_blocks in pngmem.c to avoid a potentially negative shift distance, whose results are undefined in the C language. Added a check in pngset.c to prevent writing multiple tIME chunks. Added a check in pngwrite.c to detect invalid small window_bits sizes. Version 1.0.3d [September 4, 1999] Fixed type casting of igamma in pngrutil.c Added new png_expand functions to scripts/pngdef.pas and pngos2.def Added a demo read_user_transform_fn that examines the row filters in pngtest.c Version 1.0.4 [September 24, 1999, not distributed publicly] Define PNG_ALWAYS_EXTERN in pngconf.h if __STDC__ is defined Delete #define PNG_INTERNAL and include "png.h" from pngasmrd.h Made several minor corrections to pngtest.c Renamed the makefiles with longer but more user friendly extensions. Copied the PNG copyright and license to a separate LICENSE file. Revised documentation, png.h, and example.c to remove reference to "viewing_gamma" which no longer appears in the PNG specification. Revised pngvcrd.c to use MMX code for interlacing only on the final pass. Updated pngvcrd.c to use the faster C filter algorithms from libpng-1.0.1a Split makefile.win32vc into two versions, makefile.vcawin32 (uses MMX assembler code) and makefile.vcwin32 (doesn't). Added a CPU timing report to pngtest.c (enabled by defining PNGTEST_TIMING) Added a copy of pngnow.png to the distribution. Version 1.0.4a [September 25, 1999] Increase max_pixel_depth in pngrutil.c if a user transform needs it. Changed several division operations to right-shifts in pngvcrd.c Version 1.0.4b [September 30, 1999] Added parentheses in line 3732 of pngvcrd.c Added a comment in makefile.linux warning about buggy -O3 in pgcc 2.95.1 Version 1.0.4c [October 1, 1999] Added a "png_check_version" function in png.c and pngtest.c that will generate a helpful compiler error if an old png.h is found in the search path. Changed type of png_user_transform_depth|channels from int to png_byte. Added "Libpng is OSI Certified Open Source Software" statement to png.h Version 1.0.4d [October 6, 1999] Changed 0.45 to 0.45455 in png_set_sRGB() Removed unused PLTE entries from pngnow.png Re-enabled some parts of pngvcrd.c (png_combine_row) that work properly. Version 1.0.4e [October 10, 1999] Fixed sign error in pngvcrd.c (Greg Roelofs) Replaced some instances of memcpy with simple assignments in pngvcrd (GR-P) Version 1.0.4f [October 15, 1999] Surrounded example.c code with #if 0 .. #endif to prevent people from inadvertently trying to compile it. Changed png_get_header_version() from a function to a macro in png.h Added type casting mostly in pngrtran.c and pngwtran.c Removed some pointless "ptr = NULL" in pngmem.c Added a "contrib" directory containing the source code from Greg's book. Version 1.0.5 [October 15, 1999] Minor editing of the INSTALL and README files. Version 1.0.5a [October 23, 1999] Added contrib/pngsuite and contrib/pngminus (Willem van Schaik) Fixed a typo in the png_set_sRGB() function call in example.c (Jan Nijtmans) Further optimization and bugfix of pngvcrd.c Revised pngset.c so that it does not allocate or free memory in the user's text_ptr structure. Instead, it makes its own copy. Created separate write_end_info_struct in pngtest.c for a more severe test. Added code in pngwrite.c to free info_ptr->text[i].key to stop a memory leak. Version 1.0.5b [November 23, 1999] Moved PNG_FLAG_HAVE_CHUNK_HEADER, PNG_FLAG_BACKGROUND_IS_GRAY and PNG_FLAG_WROTE_tIME from flags to mode. Added png_write_info_before_PLTE() function. Fixed some typecasting in contrib/gregbook/*.c Updated scripts/makevms.com and added makevms.com to contrib/gregbook and contrib/pngminus (Martin Zinser) Version 1.0.5c [November 26, 1999] Moved png_get_header_version from png.h to png.c, to accommodate ansi2knr. Removed all global arrays (according to PNG_NO_GLOBAL_ARRAYS macro), to accommodate making DLL's: Moved usr_png_ver from global variable to function png_get_header_ver() in png.c. Moved png_sig to png_sig_bytes in png.c and eliminated use of png_sig in pngwutil.c. Moved the various png_CHNK arrays into pngtypes.h. Eliminated use of global png_pass arrays. Declared the png_CHNK and png_pass arrays to be "const". Made the global arrays available to applications (although none are used in libpng itself) when PNG_NO_GLOBAL_ARRAYS is not defined or when PNG_GLOBAL_ARRAYS is defined. Removed some extraneous "-I" from contrib/pngminus/makefile.std Changed the PNG_sRGB_INTENT macros in png.h to be consistent with PNG-1.2. Change PNG_SRGB_INTENT to PNG_sRGB_INTENT in libpng.txt and libpng.3 Version 1.0.5d [November 29, 1999] Add type cast (png_const_charp) two places in png.c Eliminated pngtypes.h; use macros instead to declare PNG_CHNK arrays. Renamed "PNG_GLOBAL_ARRAYS" to "PNG_USE_GLOBAL_ARRAYS" and made available to applications a macro "PNG_USE_LOCAL_ARRAYS". comment out (with #ifdef) all the new declarations when PNG_USE_GLOBAL_ARRAYS is defined. Added PNG_EXPORT_VAR macro to accommodate making DLL's. Version 1.0.5e [November 30, 1999] Added iCCP, iTXt, and sPLT support; added "lang" member to the png_text structure; refactored the inflate/deflate support to make adding new chunks with trailing compressed parts easier in the future, and added new functions png_free_iCCP, png_free_pCAL, png_free_sPLT, png_free_text, png_get_iCCP, png_get_spalettes, png_set_iCCP, png_set_spalettes (Eric S. Raymond). NOTE: Applications that write text chunks MUST define png_text->lang before calling png_set_text(). It must be set to NULL if you want to write tEXt or zTXt chunks. If you want your application to be able to run with older versions of libpng, use #ifdef PNG_iTXt_SUPPORTED png_text[i].lang = NULL; #endif Changed png_get_oFFs() and png_set_oFFs() to use signed rather than unsigned offsets (Eric S. Raymond). Combined PNG_READ_cHNK_SUPPORTED and PNG_WRITE_cHNK_SUPPORTED macros into PNG_cHNK_SUPPORTED and combined the three types of PNG_text_SUPPORTED macros, leaving the separate macros also available. Removed comments on #endifs at the end of many short, non-nested #if-blocks. Version 1.0.5f [December 6, 1999] Changed makefile.solaris to issue a warning about potential problems when the ucb "ld" is in the path ahead of the ccs "ld". Removed "- [date]" from the "synopsis" line in libpng.3 and libpngpf.3. Added sCAL chunk support (Eric S. Raymond). Version 1.0.5g [December 7, 1999] Fixed "png_free_spallettes" typo in png.h Added code to handle new chunks in pngpread.c Moved PNG_CHNK string macro definitions outside of PNG_NO_EXTERN block Added "translated_key" to png_text structure and png_write_iTXt(). Added code in pngwrite.c to work around a newly discovered zlib bug. Version 1.0.5h [December 10, 1999] NOTE: regarding the note for version 1.0.5e, the following must also be included in your code: png_text[i].translated_key = NULL; Unknown chunk handling is now supported. Option to eliminate all floating point support was added. Some new fixed-point functions such as png_set_gAMA_fixed() were added. Expanded tabs and removed trailing blanks in source files. Version 1.0.5i [December 13, 1999] Added some type casts to silence compiler warnings. Renamed "png_free_spalette" to "png_free_spalettes" for consistency. Removed leading blanks from a #define in pngvcrd.c Added some parameters to the new png_set_keep_unknown_chunks() function. Added a test for up->location != 0 in the first instance of writing unknown chunks in pngwrite.c Changed "num" to "i" in png_free_spalettes() and png_free_unknowns() to prevent recursion. Added png_free_hIST() function. Various patches to fix bugs in the sCAL and integer cHRM processing, and to add some convenience macros for use with sCAL. Version 1.0.5j [December 21, 1999] Changed "unit" parameter of png_write_sCAL from png_byte to int, to work around buggy compilers. Added new type "png_fixed_point" for integers that hold float*100000 values Restored backward compatibility of tEXt/zTXt chunk processing: Restored the first four members of png_text to the same order as v.1.0.5d. Added members "lang_key" and "itxt_length" to png_text struct. Set text_length=0 when "text" contains iTXt data. Use the "compression" member to distinguish among tEXt/zTXt/iTXt types. Added PNG_ITXT_COMPRESSION_NONE (1) and PNG_ITXT_COMPRESSION_zTXt(2) macros. The "Note" above, about backward incompatibility of libpng-1.0.5e, no longer applies. Fixed png_read|write_iTXt() to read|write parameters in the right order, and to write the iTXt chunk after IDAT if it appears in the end_ptr. Added pnggccrd.c, version of pngvcrd.c Intel assembler for gcc (Greg Roelofs) Reversed the order of trying to write floating-point and fixed-point gAMA. Version 1.0.5k [December 27, 1999] Added many parentheses, e.g., "if (a && b & c)" becomes "if (a && (b & c))" Added png_handle_as_unknown() function (Glenn) Added png_free_chunk_list() function and chunk_list and num_chunk_list members of png_ptr. Eliminated erroneous warnings about multiple sPLT chunks and sPLT-after-PLTE. Fixed a libpng-1.0.5h bug in pngrutil.c that was issuing erroneous warnings about ignoring incorrect gAMA with sRGB (gAMA was in fact not ignored) Added png_free_tRNS(); png_set_tRNS() now malloc's its own trans array (ESR). Define png_get_int_32 when oFFs chunk is supported as well as when pCAL is. Changed type of proflen from png_int_32 to png_uint_32 in png_get_iCCP(). Version 1.0.5l [January 1, 2000] Added functions png_set_read_user_chunk_fn() and png_get_user_chunk_ptr() for setting a callback function to handle unknown chunks and for retrieving the associated user pointer (Glenn). Version 1.0.5m [January 7, 2000] Added high-level functions png_read_png(), png_write_png(), png_free_pixels(). Version 1.0.5n [January 9, 2000] Added png_free_PLTE() function, and modified png_set_PLTE() to malloc its own memory for info_ptr->palette. This makes it safe for the calling application to free its copy of the palette any time after it calls png_set_PLTE(). Version 1.0.5o [January 20, 2000] Cosmetic changes only (removed some trailing blanks and TABs) Version 1.0.5p [January 31, 2000] Renamed pngdll.mak to makefile.bd32 Cosmetic changes in pngtest.c Version 1.0.5q [February 5, 2000] Relocated the makefile.solaris warning about PATH problems. Fixed pngvcrd.c bug by pushing/popping registers in mmxsupport (Bruce Oberg) Revised makefile.gcmmx Added PNG_SETJMP_SUPPORTED, PNG_SETJMP_NOT_SUPPORTED, and PNG_ABORT() macros Version 1.0.5r [February 7, 2000] Removed superfluous prototype for png_get_itxt from png.h Fixed a bug in pngrtran.c that improperly expanded the background color. Return *num_text=0 from png_get_text() when appropriate, and fix documentation of png_get_text() in libpng.txt/libpng.3. Version 1.0.5s [February 18, 2000] Added "png_jmp_env()" macro to pngconf.h, to help people migrate to the new error handler that's planned for the next libpng release, and changed example.c, pngtest.c, and contrib programs to use this macro. Revised some of the DLL-export macros in pngconf.h (Greg Roelofs) Fixed a bug in png_read_png() that caused it to fail to expand some images that it should have expanded. Fixed some mistakes in the unused and undocumented INCH_CONVERSIONS functions in pngget.c Changed the allocation of palette, history, and trans arrays back to the version 1.0.5 method (linking instead of copying) which restores backward compatibility with version 1.0.5. Added some remarks about that in example.c. Added "free_me" member to info_ptr and png_ptr and added png_free_data() function. Updated makefile.linux and makefile.gccmmx to make directories conditionally. Made cosmetic changes to pngasmrd.h Added png_set_rows() and png_get_rows(), for use with png_read|write_png(). Modified png_read_png() to allocate info_ptr->row_pointers only if it hasn't already been allocated. Version 1.0.5t [March 4, 2000] Changed png_jmp_env() migration aiding macro to png_jmpbuf(). Fixed "interlace" typo (should be "interlaced") in contrib/gregbook/read2-x.c Fixed bug with use of PNG_BEFORE_IHDR bit in png_ptr->mode, introduced when PNG_FLAG_HAVE_CHUNK_HEADER was moved into png_ptr->mode in version 1.0.5b Files in contrib/gregbook were revised to use png_jmpbuf() and to select a 24-bit visual if one is available, and to allow abbreviated options. Files in contrib/pngminus were revised to use the png_jmpbuf() macro. Removed spaces in makefile.linux and makefile.gcmmx, introduced in 1.0.5s Version 1.0.5u [March 5, 2000] Simplified the code that detects old png.h in png.c and pngtest.c Renamed png_spalette (_p, _pp) to png_sPLT_t (_tp, _tpp) Increased precision of rgb_to_gray calculations from 8 to 15 bits and added png_set_rgb_to_gray_fixed() function. Added makefile.bc32 (32-bit Borland C++, C mode) Version 1.0.5v [March 11, 2000] Added some parentheses to the png_jmpbuf macro definition. Updated references to the zlib home page, which has moved to freesoftware.com. Corrected bugs in documentation regarding png_read_row() and png_write_row(). Updated documentation of png_rgb_to_gray calculations in libpng.3/libpng.txt. Renamed makefile.borland,turboc3 back to makefile.bor,tc3 as in version 1.0.3, revised borland makefiles; added makefile.ibmvac3 and makefile.gcc (Cosmin) Version 1.0.6 [March 20, 2000] Minor revisions of makefile.bor, libpng.txt, and gregbook/rpng2-win.c Added makefile.sggcc (SGI IRIX with gcc) Version 1.0.6d [April 7, 2000] Changed sprintf() to strcpy() in png_write_sCAL_s() to work without STDIO Added data_length parameter to png_decompress_chunk() function Revised documentation to remove reference to abandoned png_free_chnk functions Fixed an error in png_rgb_to_gray_fixed() Revised example.c, usage of png_destroy_write_struct(). Renamed makefile.ibmvac3 to makefile.ibmc, added libpng.icc IBM project file Added a check for info_ptr->free_me&PNG_FREE_TEXT when freeing text in png.c Simplify png_sig_bytes() function to remove use of non-ISO-C strdup(). Version 1.0.6e [April 9, 2000] Added png_data_freer() function. In the code that checks for over-length tRNS chunks, added check of info_ptr->num_trans as well as png_ptr->num_trans (Matthias Benckmann) Minor revisions of libpng.txt/libpng.3. Check for existing data and free it if the free_me flag is set, in png_set_*() and png_handle_*(). Only define PNG_WEIGHTED_FILTERS_SUPPORTED when PNG_FLOATING_POINT_SUPPORTED is defined. Changed several instances of PNG_NO_CONSOLE_ID to PNG_NO_STDIO in pngrutil.c and mentioned the purposes of the two macros in libpng.txt/libpng.3. Version 1.0.6f [April 14, 2000] Revised png_set_iCCP() and png_set_rows() to avoid prematurely freeing data. Add checks in png_set_text() for NULL members of the input text structure. Revised libpng.txt/libpng.3. Removed superfluous prototype for png_set_iTXt from png.h Removed "else" from pngread.c, after png_error(), and changed "0" to "length". Changed several png_errors about malformed ancillary chunks to png_warnings. Version 1.0.6g [April 24, 2000] Added png_pass-* arrays to pnggccrd.c when PNG_USE_LOCAL_ARRAYS is defined. Relocated paragraph about png_set_background() in libpng.3/libpng.txt and other revisions (Matthias Benckmann) Relocated info_ptr->free_me, png_ptr->free_me, and other info_ptr and png_ptr members to restore binary compatibility with libpng-1.0.5 (breaks compatibility with libpng-1.0.6). Version 1.0.6h [April 24, 2000] Changed shared library so-number pattern from 2.x.y.z to xy.z (this builds libpng.so.10 & libpng.so.10.6h instead of libpng.so.2 & libpng.so.2.1.0.6h) This is a temporary change for test purposes. Version 1.0.6i [May 2, 2000] Rearranged some members at the end of png_info and png_struct, to put unknown_chunks_num and free_me within the original size of the png_structs and free_me, png_read_user_fn, and png_free_fn within the original png_info, because some old applications allocate the structs directly instead of using png_create_*(). Added documentation of user memory functions in libpng.txt/libpng.3 Modified png_read_png so that it will use user_allocated row_pointers if present, unless free_me directs that it be freed, and added description of the use of png_set_rows() and png_get_rows() in libpng.txt/libpng.3. Added PNG_LEGACY_SUPPORTED macro, and #ifdef out all new (since version 1.00) members of png_struct and png_info, to regain binary compatibility when you define this macro. Capabilities lost in this event are user transforms (new in version 1.0.0),the user transform pointer (new in version 1.0.2), rgb_to_gray (new in 1.0.5), iCCP, sCAL, sPLT, the high-level interface, and unknown chunks support (all new in 1.0.6). This was necessary because of old applications that allocate the structs directly as authors were instructed to do in libpng-0.88 and earlier, instead of using png_create_*(). Added modes PNG_CREATED_READ_STRUCT and PNG_CREATED_WRITE_STRUCT which can be used to detect codes that directly allocate the structs, and code to check these modes in png_read_init() and png_write_init() and generate a libpng error if the modes aren't set and PNG_LEGACY_SUPPORTED was not defined. Added makefile.intel and updated makefile.watcom (Pawel Mrochen) Version 1.0.6j [May 3, 2000] Overloaded png_read_init() and png_write_init() with macros that convert calls to png_read_init_2() or png_write_init_2() that check the version and structure sizes. Version 1.0.7beta11 [May 7, 2000] Removed the new PNG_CREATED_READ_STRUCT and PNG_CREATED_WRITE_STRUCT modes which are no longer used. Eliminated the three new members of png_text when PNG_LEGACY_SUPPORTED is defined or when neither PNG_READ_iTXt_SUPPORTED nor PNG_WRITE_iTXt_SUPPORTED is defined. Made PNG_NO_READ|WRITE_iTXt the default setting, to avoid memory overrun when old applications fill the info_ptr->text structure directly. Added PNGAPI macro, and added it to the definitions of all exported functions. Relocated version macro definitions ahead of the includes of zlib.h and pngconf.h in png.h. Version 1.0.7beta12 [May 12, 2000] Revised pngset.c to avoid a problem with expanding the png_debug macro. Deleted some extraneous defines from pngconf.h Made PNG_NO_CONSOLE_IO the default condition when PNG_BUILD_DLL is defined. Use MSC _RPTn debugging instead of fprintf if _MSC_VER is defined. Added png_access_version_number() function. Check for mask&PNG_FREE_CHNK (for TEXT, SCAL, PCAL) in png_free_data(). Expanded libpng.3/libpng.txt information about png_data_freer(). Version 1.0.7beta14 [May 17, 2000] (beta13 was not published) Changed pnggccrd.c and pngvcrd.c to handle bad adaptive filter types as warnings instead of errors, as pngrutil.c does. Set the PNG_INFO_IDAT valid flag in png_set_rows() so png_write_png() will actually write IDATs. Made the default PNG_USE_LOCAL_ARRAYS depend on PNG_DLL instead of WIN32. Make png_free_data() ignore its final parameter except when freeing data that can have multiple instances (text, sPLT, unknowns). Fixed a new bug in png_set_rows(). Removed info_ptr->valid tests from png_free_data(), as in version 1.0.5. Added png_set_invalid() function. Fixed incorrect illustrations of png_destroy_write_struct() in example.c. Version 1.0.7beta15 [May 30, 2000] Revised the deliberately erroneous Linux setjmp code in pngconf.h to produce fewer error messages. Rearranged checks for Z_OK to check the most likely path first in pngpread.c and pngwutil.c. Added checks in pngtest.c for png_create_*() returning NULL, and mentioned in libpng.txt/libpng.3 the need for applications to check this. Changed names of png_default_*() functions in pngtest to pngtest_*(). Changed return type of png_get_x|y_offset_*() from png_uint_32 to png_int_32. Fixed some bugs in the unused PNG_INCH_CONVERSIONS functions in pngget.c Set each pointer to NULL after freeing it in png_free_data(). Worked around a problem in pngconf.h; AIX's strings.h defines an "index" macro that conflicts with libpng's png_color_16.index. (Dimitri Papadapoulos) Added "msvc" directory with MSVC++ project files (Simon-Pierre Cadieux). Version 1.0.7beta16 [June 4, 2000] Revised the workaround of AIX string.h "index" bug. Added a check for overlength PLTE chunk in pngrutil.c. Added PNG_NO_POINTER_INDEXING macro to use array-indexing instead of pointer indexing in pngrutil.c and pngwutil.c to accommodate a buggy compiler. Added a warning in png_decompress_chunk() when it runs out of data, e.g. when it tries to read an erroneous PhotoShop iCCP chunk. Added PNG_USE_DLL macro. Revised the copyright/disclaimer/license notice. Added contrib/msvctest directory Version 1.0.7rc1 [June 9, 2000] Corrected the definition of PNG_TRANSFORM_INVERT_ALPHA (0x0400 not 0x0200) Added contrib/visupng directory (Willem van Schaik) Version 1.0.7beta18 [June 23, 2000] Revised PNGAPI definition, and pngvcrd.c to work with __GCC__ and do not redefine PNGAPI if it is passed in via a compiler directive. Revised visupng/PngFile.c to remove returns from within the Try block. Removed leading underscores from "_PNG_H" and "_PNG_SAVE_BSD_SOURCE" macros. Updated contrib/visupng/cexcept.h to version 1.0.0. Fixed bugs in pngwrite.c and pngwutil.c that prevented writing iCCP chunks. Version 1.0.7rc2 [June 28, 2000] Updated license to include disclaimers required by UCITA. Fixed "DJBPP" typo in pnggccrd.c introduced in beta18. Version 1.0.7 [July 1, 2000] Revised the definition of "trans_values" in libpng.3/libpng.txt Version 1.0.8beta1 [July 8, 2000] Added png_free(png_ptr, key) two places in pngpread.c to stop memory leaks. Changed PNG_NO_STDIO to PNG_NO_CONSOLE_IO, several places in pngrutil.c and pngwutil.c. Changed PNG_EXPORT_VAR to use PNG_IMPEXP, in pngconf.h. Removed unused "#include " from png.c Added WindowsCE support. Revised pnggccrd.c to work with gcc-2.95.2 and in the Cygwin environment. Version 1.0.8beta2 [July 10, 2000] Added project files to the wince directory and made further revisions of pngtest.c, pngrio.c, and pngwio.c in support of WindowsCE. Version 1.0.8beta3 [July 11, 2000] Only set the PNG_FLAG_FREE_TRNS or PNG_FREE_TRNS flag in png_handle_tRNS() for indexed-color input files to avoid potential double-freeing trans array under some unusual conditions; problem was introduced in version 1.0.6f. Further revisions to pngtest.c and files in the wince subdirectory. Version 1.0.8beta4 [July 14, 2000] Added the files pngbar.png and pngbar.jpg to the distribution. Added makefile.cygwin, and cygwin support in pngconf.h Added PNG_NO_ZALLOC_ZERO macro (makes png_zalloc skip zeroing memory) Version 1.0.8rc1 [July 16, 2000] Revised png_debug() macros and statements to eliminate compiler warnings. Version 1.0.8 [July 24, 2000] Added png_flush() in pngwrite.c, after png_write_IEND(). Updated makefile.hpux to build a shared library. Version 1.0.9beta1 [November 10, 2000] Fixed typo in scripts/makefile.hpux Updated makevms.com in scripts and contrib/* and contrib/* (Martin Zinser) Fixed sequence-point bug in contrib/pngminus/png2pnm (Martin Zinser) Changed "cdrom.com" in documentation to "libpng.org" Revised pnggccrd.c to get it all working, and updated makefile.gcmmx (Greg). Changed type of "params" from voidp to png_voidp in png_read|write_png(). Make sure PNGAPI and PNG_IMPEXP are defined in pngconf.h. Revised the 3 instances of WRITEFILE in pngtest.c. Relocated "msvc" and "wince" project subdirectories into "dll" subdirectory. Updated png.rc in dll/msvc project Revised makefile.dec to define and use LIBPATH and INCPATH Increased size of global png_libpng_ver[] array from 12 to 18 chars. Made global png_libpng_ver[], png_sig[] and png_pass_*[] arrays const. Removed duplicate png_crc_finish() from png_handle_bKGD() function. Added a warning when application calls png_read_update_info() multiple times. Revised makefile.cygwin Fixed bugs in iCCP support in pngrutil.c and pngwutil.c. Replaced png_set_empty_plte_permitted() with png_permit_mng_features(). Version 1.0.9beta2 [November 19, 2000] Renamed the "dll" subdirectory "projects". Added borland project files to "projects" subdirectory. Set VS_FF_PRERELEASE and VS_FF_PATCHED flags in msvc/png.rc when appropriate. Add error message in png_set_compression_buffer_size() when malloc fails. Version 1.0.9beta3 [November 23, 2000] Revised PNG_LIBPNG_BUILD_TYPE macro in png.h, used in the msvc project. Removed the png_flush() in pngwrite.c that crashes some applications that don't set png_output_flush_fn. Added makefile.macosx and makefile.aix to scripts directory. Version 1.0.9beta4 [December 1, 2000] Change png_chunk_warning to png_warning in png_check_keyword(). Increased the first part of msg buffer from 16 to 18 in png_chunk_error(). Version 1.0.9beta5 [December 15, 2000] Added support for filter method 64 (for PNG datastreams embedded in MNG). Version 1.0.9beta6 [December 18, 2000] Revised png_set_filter() to accept filter method 64 when appropriate. Added new PNG_HAVE_PNG_SIGNATURE bit to png_ptr->mode and use it to help prevent applications from using MNG features in PNG datastreams. Added png_permit_mng_features() function. Revised libpng.3/libpng.txt. Changed "filter type" to "filter method". Version 1.0.9rc1 [December 23, 2000] Revised test for PNG_HAVE_PNG_SIGNATURE in pngrutil.c Fixed error handling of unknown compression type in png_decompress_chunk(). In pngconf.h, define __cdecl when _MSC_VER is defined. Version 1.0.9beta7 [December 28, 2000] Changed PNG_TEXT_COMPRESSION_zTXt to PNG_COMPRESSION_TYPE_BASE several places. Revised memory management in png_set_hIST and png_handle_hIST in a backward compatible manner. PLTE and tRNS were revised similarly. Revised the iCCP chunk reader to ignore trailing garbage. Version 1.0.9beta8 [January 12, 2001] Moved pngasmrd.h into pngconf.h. Improved handling of out-of-spec garbage iCCP chunks generated by PhotoShop. Version 1.0.9beta9 [January 15, 2001] Added png_set_invalid, png_permit_mng_features, and png_mmx_supported to wince and msvc project module definition files. Minor revision of makefile.cygwin. Fixed bug with progressive reading of narrow interlaced images in pngpread.c Version 1.0.9beta10 [January 16, 2001] Do not typedef png_FILE_p in pngconf.h when PNG_NO_STDIO is defined. Fixed "png_mmx_supported" typo in project definition files. Version 1.0.9beta11 [January 19, 2001] Updated makefile.sgi to make shared library. Removed png_mmx_support() function and disabled PNG_MNG_FEATURES_SUPPORTED by default, for the benefit of DLL forward compatibility. These will be re-enabled in version 1.2.0. Version 1.0.9rc2 [January 22, 2001] Revised cygwin support. Version 1.0.9 [January 31, 2001] Added check of cygwin's ALL_STATIC in pngconf.h Added "-nommx" parameter to contrib/gregbook/rpng2-win and rpng2-x demos. Version 1.0.10beta1 [March 14, 2001] Revised makefile.dec, makefile.sgi, and makefile.sggcc; added makefile.hpgcc. Reformatted libpng.3 to eliminate bad line breaks. Added checks for _mmx_supported in the read_filter_row function of pnggccrd.c Added prototype for png_mmx_support() near the top of pnggccrd.c Moved some error checking from png_handle_IHDR to png_set_IHDR. Added PNG_NO_READ_SUPPORTED and PNG_NO_WRITE_SUPPORTED macros. Revised png_mmx_support() function in pnggccrd.c Restored version 1.0.8 PNG_WRITE_EMPTY_PLTE_SUPPORTED behavior in pngwutil.c Fixed memory leak in contrib/visupng/PngFile.c Fixed bugs in png_combine_row() in pnggccrd.c and pngvcrd.c (C version) Added warnings when retrieving or setting gamma=0. Increased the first part of msg buffer from 16 to 18 in png_chunk_warning(). Version 1.0.10rc1 [March 23, 2001] Changed all instances of memcpy, strcpy, and strlen to png_memcpy, png_strcpy, and png_strlen. Revised png_mmx_supported() function in pnggccrd.c to return proper value. Fixed bug in progressive reading (pngpread.c) with small images (height < 8). Version 1.0.10 [March 30, 2001] Deleted extraneous space (introduced in 1.0.9) from line 42 of makefile.cygwin Added beos project files (Chris Herborth) Version 1.0.11beta1 [April 3, 2001] Added type casts on several png_malloc() calls (Dimitri Papadapoulos). Removed a no-longer needed AIX work-around from pngconf.h Changed several "//" single-line comments to C-style in pnggccrd.c Version 1.0.11beta2 [April 11, 2001] Removed PNGAPI from several functions whose prototypes did not have PNGAPI. Updated scripts/pngos2.def Version 1.0.11beta3 [April 14, 2001] Added checking the results of many instances of png_malloc() for NULL Version 1.0.11beta4 [April 20, 2001] Undid the changes from version 1.0.11beta3. Added a check for NULL return from user's malloc_fn(). Removed some useless type casts of the NULL pointer. Added makefile.netbsd Version 1.0.11 [April 27, 2001] Revised makefile.netbsd Version 1.0.12beta1 [May 14, 2001] Test for Windows platform in pngconf.h when including malloc.h (Emmanuel Blot) Updated makefile.cygwin and handling of Cygwin's ALL_STATIC in pngconf.h Added some never-to-be-executed code in pnggccrd.c to quiet compiler warnings. Eliminated the png_error about apps using png_read|write_init(). Instead, libpng will reallocate the png_struct and info_struct if they are too small. This retains future binary compatibility for old applications written for libpng-0.88 and earlier. Version 1.2.0beta1 [May 6, 2001] Bumped DLLNUM to 2. Re-enabled PNG_MNG_FEATURES_SUPPORTED and enabled PNG_ASSEMBLER_CODE_SUPPORTED by default. Added runtime selection of MMX features. Added png_set_strip_error_numbers function and related macros. Version 1.2.0beta2 [May 7, 2001] Finished merging 1.2.0beta1 with version 1.0.11 Added a check for attempts to read or write PLTE in grayscale PNG datastreams. Version 1.2.0beta3 [May 17, 2001] Enabled user memory function by default. Modified png_create_struct so it passes user mem_ptr to user memory allocator. Increased png_mng_features flag from png_byte to png_uint_32. Bumped shared-library (so-number) and dll-number to 3. Version 1.2.0beta4 [June 23, 2001] Check for missing profile length field in iCCP chunk and free chunk_data in case of truncated iCCP chunk. Bumped shared-library number to 3 in makefile.sgi and makefile.sggcc Bumped dll-number from 2 to 3 in makefile.cygwin Revised contrib/gregbook/rpng*-x.c to avoid a memory leak and to exit cleanly if user attempts to run it on an 8-bit display. Updated contrib/gregbook Use png_malloc instead of png_zalloc to allocate palette in pngset.c Updated makefile.ibmc Added some typecasts to eliminate gcc 3.0 warnings. Changed prototypes of png_write_oFFS width and height from png_uint_32 to png_int_32. Updated example.c Revised prototypes for png_debug_malloc and png_debug_free in pngtest.c Version 1.2.0beta5 [August 8, 2001] Revised contrib/gregbook Revised makefile.gcmmx Revised pnggccrd.c to conditionally compile some thread-unsafe code only when PNG_THREAD_UNSAFE_OK is defined. Added tests to prevent pngwutil.c from writing a bKGD or tRNS chunk with value exceeding 2^bit_depth-1 Revised makefile.sgi and makefile.sggcc Replaced calls to fprintf(stderr,...) with png_warning() in pnggccrd.c Removed restriction that do_invert_mono only operate on 1-bit opaque files Version 1.2.0 [September 1, 2001] Changed a png_warning() to png_debug() in pnggccrd.c Fixed contrib/gregbook/rpng-x.c, rpng2-x.c to avoid crash with XFreeGC(). Version 1.2.1beta1 [October 19, 2001] Revised makefile.std in contrib/pngminus Include background_1 in png_struct regardless of gamma support. Revised makefile.netbsd and makefile.macosx, added makefile.darwin. Revised example.c to provide more details about using row_callback(). Version 1.2.1beta2 [October 25, 2001] Added type cast to each NULL appearing in a function call, except for WINCE functions. Added makefile.so9. Version 1.2.1beta3 [October 27, 2001] Removed type casts from all NULLs. Simplified png_create_struct_2(). Version 1.2.1beta4 [November 7, 2001] Revised png_create_info_struct() and png_creat_struct_2(). Added error message if png_write_info() was omitted. Type cast NULLs appearing in function calls when _NO_PROTO or PNG_TYPECAST_NULL is defined. Version 1.2.1rc1 [November 24, 2001] Type cast NULLs appearing in function calls except when PNG_NO_TYPECAST_NULL is defined. Changed typecast of "size" argument to png_size_t in pngmem.c calls to the user malloc_fn, to agree with the prototype in png.h Added a pop/push operation to pnggccrd.c, to preserve Eflag (Maxim Sobolev) Updated makefile.sgi to recognize LIBPATH and INCPATH. Updated various makefiles so "make clean" does not remove previous major version of the shared library. Version 1.2.1rc2 [December 4, 2001] Always allocate 256-entry internal palette, hist, and trans arrays, to avoid out-of-bounds memory reference caused by invalid PNG datastreams. Added a check for prefix_length > data_length in iCCP chunk handler. Version 1.2.1 [December 7, 2001] None. Version 1.2.2beta1 [February 22, 2002] Fixed a bug with reading the length of iCCP profiles (Larry Reeves). Revised makefile.linux, makefile.gcmmx, and makefile.sgi to generate libpng.a, libpng12.so (not libpng.so.3), and libpng12/png.h Revised makefile.darwin to remove "-undefined suppress" option. Added checks for gamma and chromaticity values over 21474.83, which exceed the limit for PNG unsigned 32-bit integers when encoded. Revised calls to png_create_read_struct() and png_create_write_struct() for simpler debugging. Revised png_zalloc() so zlib handles errors (uses PNG_FLAG_MALLOC_NULL_MEM_OK) Version 1.2.2beta2 [February 23, 2002] Check chunk_length and idat_size for invalid (over PNG_MAX_UINT) lengths. Check for invalid image dimensions in png_get_IHDR. Added missing "fi;" in the install target of the SGI makefiles. Added install-static to all makefiles that make shared libraries. Always do gamma compensation when image is partially transparent. Version 1.2.2beta3 [March 7, 2002] Compute background.gray and background_1.gray even when color_type is RGB in case image gets reduced to gray later. Modified shared-library makefiles to install pkgconfig/libpngNN.pc. Export (with PNGAPI) png_zalloc, png_zfree, and png_handle_as_unknown Removed unused png_write_destroy_info prototype from png.h Eliminated incorrect use of width_mmx from pnggccrd.c in pixel_bytes == 8 case Added install-shared target to all makefiles that make shared libraries. Stopped a double free of palette, hist, and trans when not using free_me. Added makefile.32sunu for Sun Ultra 32 and makefile.64sunu for Sun Ultra 64. Version 1.2.2beta4 [March 8, 2002] Compute background.gray and background_1.gray even when color_type is RGB in case image gets reduced to gray later (Jason Summers). Relocated a misplaced /bin/rm in the "install-shared" makefile targets Added PNG_1_0_X macro which can be used to build a 1.0.x-compatible library. Version 1.2.2beta5 [March 26, 2002] Added missing PNGAPI to several function definitions. Check for invalid bit_depth or color_type in png_get_IHDR(), and check for missing PLTE or IHDR in png_push_read_chunk() (Matthias Clasen). Revised iTXt support to accept NULL for lang and lang_key. Compute gamma for color components of background even when color_type is gray. Changed "()" to "{}" in scripts/libpng.pc.in. Revised makefiles to put png.h and pngconf.h only in $prefix/include/libpngNN Revised makefiles to make symlink to libpng.so.NN in addition to libpngNN.so Version 1.2.2beta6 [March 31, 2002] Version 1.0.13beta1 [March 31, 2002] Prevent png_zalloc() from trying to memset memory that it failed to acquire. Add typecasts of PNG_MAX_UINT in pngset_cHRM_fixed() (Matt Holgate). Ensure that the right function (user or default) is used to free the png_struct after an error in png_create_read_struct_2(). Version 1.2.2rc1 [April 7, 2002] Version 1.0.13rc1 [April 7, 2002] Save the ebx register in pnggccrd.c (Sami Farin) Add "mem_ptr = png_ptr->mem_ptr" in png_destroy_write_struct() (Paul Gardner). Updated makefiles to put headers in include/libpng and remove old include/*.h. Version 1.2.2 [April 15, 2002] Version 1.0.13 [April 15, 2002] Revised description of png_set_filter() in libpng.3/libpng.txt. Revised makefile.netbsd and added makefile.neNNbsd and makefile.freebsd Version 1.0.13patch01 [April 17, 2002] Version 1.2.2patch01 [April 17, 2002] Changed ${PNGMAJ}.${PNGVER} bug to ${PNGVER} in makefile.sgi and makefile.sggcc Fixed VER -> PNGVER typo in makefile.macosx and added install-static to install Added install: target to makefile.32sunu and makefile.64sunu Version 1.0.13patch03 [April 18, 2002] Version 1.2.2patch03 [April 18, 2002] Revised 15 makefiles to link libpng.a to libpngNN.a and the include libpng subdirectory to libpngNN subdirectory without the full pathname. Moved generation of libpng.pc from "install" to "all" in 15 makefiles. Version 1.2.3rc1 [April 28, 2002] Added install-man target to 15 makefiles (Dimitri Papadopolous-Orfanos). Added $(DESTDIR) feature to 24 makefiles (Tim Mooney) Fixed bug with $prefix, should be $(prefix) in makefile.hpux. Updated cygwin-specific portion of pngconf.h and revised makefile.cygwin Added a link from libpngNN.pc to libpng.pc in 15 makefiles. Added links from include/libpngNN/*.h to include/*.h in 24 makefiles. Revised makefile.darwin to make relative links without full pathname. Added setjmp() at the end of png_create_*_struct_2() in case user forgets to put one in their application. Restored png_zalloc() and png_zfree() prototypes to version 1.2.1 and removed them from module definition files. Version 1.2.3rc2 [May 1, 2002] Fixed bug in reporting number of channels in pngget.c and pngset.c, that was introduced in version 1.2.2beta5. Exported png_zalloc(), png_zfree(), png_default_read(), png_default_write(), png_default_flush(), and png_push_fill_buffer() and included them in module definition files. Added "libpng.pc" dependency to the "install-shared" target in 15 makefiles. Version 1.2.3rc3 [May 1, 2002] Revised prototype for png_default_flush() Remove old libpng.pc and libpngNN.pc before installing new ones. Version 1.2.3rc4 [May 2, 2002] Typos in *.def files (png_default_read|write -> png_default_read|write_data) In makefiles, changed rm libpng.NN.pc to rm libpngNN.pc Added libpng-config and libpngNN-config and modified makefiles to install them. Changed $(MANPATH) to $(DESTDIR)$(MANPATH) in makefiles Added "Win32 DLL VB" configuration to projects/msvc/libpng.dsp Version 1.2.3rc5 [May 11, 2002] Changed "error" and "message" in prototypes to "error_message" and "warning_message" to avoid namespace conflict. Revised 15 makefiles to build libpng-config from libpng-config-*.in Once more restored png_zalloc and png_zfree to regular nonexported form. Restored png_default_read|write_data, png_default_flush, png_read_fill_buffer to nonexported form, but with PNGAPI, and removed them from module def files. Version 1.2.3rc6 [May 14, 2002] Removed "PNGAPI" from png_zalloc() and png_zfree() in png.c Changed "Gz" to "Gd" in projects/msvc/libpng.dsp and zlib.dsp. Removed leftover libpng-config "sed" script from four makefiles. Revised libpng-config creating script in 16 makefiles. Version 1.2.3 [May 22, 2002] Revised libpng-config target in makefile.cygwin. Removed description of png_set_mem_fn() from documentation. Revised makefile.freebsd. Minor cosmetic changes to 15 makefiles, e.g., $(DI) = $(DESTDIR)/$(INCDIR). Revised projects/msvc/README.txt Changed -lpng to -lpngNN in LDFLAGS in several makefiles. Version 1.2.4beta1 [May 24, 2002] Added libpng.pc and libpng-config to "all:" target in 16 makefiles. Fixed bug in 16 makefiles: $(DESTDIR)/$(LIBPATH) to $(DESTDIR)$(LIBPATH) Added missing "\" before closing double quote in makefile.gcmmx. Plugged various memory leaks; added png_malloc_warn() and png_set_text_2() functions. Version 1.2.4beta2 [June 25, 2002] Plugged memory leak of png_ptr->current_text (Matt Holgate). Check for buffer overflow before reading CRC in pngpread.c (Warwick Allison) Added -soname to the loader flags in makefile.dec, makefile.sgi, and makefile.sggcc. Added "test-installed" target to makefile.linux, makefile.gcmmx, makefile.sgi, and makefile.sggcc. Version 1.2.4beta3 [June 28, 2002] Plugged memory leak of row_buf in pngtest.c when there is a png_error(). Detect buffer overflow in pngpread.c when IDAT is corrupted with extra data. Added "test-installed" target to makefile.32sunu, makefile.64sunu, makefile.beos, makefile.darwin, makefile.dec, makefile.macosx, makefile.solaris, makefile.hpux, makefile.hpgcc, and makefile.so9. Version 1.2.4rc1 and 1.0.14rc1 [July 2, 2002] Added "test-installed" target to makefile.cygwin and makefile.sco. Revised pnggccrd.c to be able to back out version 1.0.x via PNG_1_0_X macro. Version 1.2.4 and 1.0.14 [July 8, 2002] Changed png_warning() to png_error() when width is too large to process. Version 1.2.4patch01 [July 20, 2002] Revised makefile.cygwin to use DLL number 12 instead of 13. Version 1.2.5beta1 [August 6, 2002] Added code to contrib/gregbook/readpng2.c to ignore unused chunks. Replaced toucan.png in contrib/gregbook (it has been corrupt since 1.0.11) Removed some stray *.o files from contrib/gregbook. Changed png_error() to png_warning() about "Too much data" in pngpread.c and about "Extra compressed data" in pngrutil.c. Prevent png_ptr->pass from exceeding 7 in png_push_finish_row(). Updated makefile.hpgcc Updated png.c and pnggccrd.c handling of return from png_mmx_support() Version 1.2.5beta2 [August 15, 2002] Only issue png_warning() about "Too much data" in pngpread.c when avail_in is nonzero. Updated makefiles to install a separate libpng.so.3 with its own rpath. Version 1.2.5rc1 and 1.0.15rc1 [August 24, 2002] Revised makefiles to not remove previous minor versions of shared libraries. Version 1.2.5rc2 and 1.0.15rc2 [September 16, 2002] Revised 13 makefiles to remove "-lz" and "-L$(ZLIBLIB)", etc., from shared library loader directive. Added missing "$OBJSDLL" line to makefile.gcmmx. Added missing "; fi" to makefile.32sunu. Version 1.2.5rc3 and 1.0.15rc3 [September 18, 2002] Revised libpng-config script. Version 1.2.5 and 1.0.15 [October 3, 2002] Revised makefile.macosx, makefile.darwin, makefile.hpgcc, and makefile.hpux, and makefile.aix. Relocated two misplaced PNGAPI lines in pngtest.c Version 1.2.6beta1 [October 22, 2002] Commented out warning about uninitialized mmx_support in pnggccrd.c. Changed "IBMCPP__" flag to "__IBMCPP__" in pngconf.h. Relocated two more misplaced PNGAPI lines in pngtest.c Fixed memory overrun bug in png_do_read_filler() with 16-bit datastreams, introduced in version 1.0.2. Revised makefile.macosx, makefile.dec, makefile.aix, and makefile.32sunu. Version 1.2.6beta2 [November 1, 2002] Added libpng-config "--ldopts" output. Added "AR=ar" and "ARFLAGS=rc" and changed "ar rc" to "$(AR) $(ARFLAGS)" in makefiles. Version 1.2.6beta3 [July 18, 2004] Reverted makefile changes from version 1.2.6beta2 and some of the changes from version 1.2.6beta1; these will be postponed until version 1.2.7. Version 1.2.6 is going to be a simple bugfix release. Changed the one instance of "ln -sf" to "ln -f -s" in each Sun makefile. Fixed potential overrun in pngerror.c by using strncpy instead of memcpy. Added "#!/bin/sh" at the top of configure, for recognition of the 'x' flag under Cygwin (Cosmin). Optimized vacuous tests that silence compiler warnings, in png.c (Cosmin). Added support for PNG_USER_CONFIG, in pngconf.h (Cosmin). Fixed the special memory handler for Borland C under DOS, in pngmem.c (Cosmin). Removed some spurious assignments in pngrutil.c (Cosmin). Replaced 65536 with 65536L, and 0xffff with 0xffffL, to silence warnings on 16-bit platforms (Cosmin). Enclosed shift op expressions in parentheses, to silence warnings (Cosmin). Used proper type png_fixed_point, to avoid problems on 16-bit platforms, in png_handle_sRGB() (Cosmin). Added compression_type to png_struct, and optimized the window size inside the deflate stream (Cosmin). Fixed definition of isnonalpha(), in pngerror.c and pngrutil.c (Cosmin). Fixed handling of unknown chunks that come after IDAT (Cosmin). Allowed png_error() and png_warning() to work even if png_ptr == NULL (Cosmin). Replaced row_info->rowbytes with row_bytes in png_write_find_filter() (Cosmin). Fixed definition of PNG_LIBPNG_VER_DLLNUM (Simon-Pierre). Used PNG_LIBPNG_VER and PNG_LIBPNG_VER_STRING instead of the hardcoded values in png.c (Simon-Pierre, Cosmin). Initialized png_libpng_ver[] with PNG_LIBPNG_VER_STRING (Simon-Pierre). Replaced PNG_LIBPNG_VER_MAJOR with PNG_LIBPNG_VER_DLLNUM in png.rc (Simon-Pierre). Moved the definition of PNG_HEADER_VERSION_STRING near the definitions of the other PNG_LIBPNG_VER_... symbols in png.h (Cosmin). Relocated #ifndef PNGAPI guards in pngconf.h (Simon-Pierre, Cosmin). Updated scripts/makefile.vc(a)win32 (Cosmin). Updated the MSVC project (Simon-Pierre, Cosmin). Updated the Borland C++ Builder project (Cosmin). Avoided access to asm_flags in pngvcrd.c, if PNG_1_0_X is defined (Cosmin). Commented out warning about uninitialized mmx_support in pngvcrd.c (Cosmin). Removed scripts/makefile.bd32 and scripts/pngdef.pas (Cosmin). Added extra guard around inclusion of Turbo C memory headers, in pngconf.h (Cosmin). Renamed projects/msvc/ to projects/visualc6/, and projects/borland/ to projects/cbuilder5/ (Cosmin). Moved projects/visualc6/png32ms.def to scripts/pngw32.def, and projects/visualc6/png.rc to scripts/pngw32.rc (Cosmin). Added projects/visualc6/pngtest.dsp; removed contrib/msvctest/ (Cosmin). Changed line endings to DOS style in cbuilder5 and visualc6 files, even in the tar.* distributions (Cosmin). Updated contrib/visupng/VisualPng.dsp (Cosmin). Updated contrib/visupng/cexcept.h to version 2.0.0 (Cosmin). Added a separate distribution with "configure" and supporting files (Junichi). Version 1.2.6beta4 [July 28, 2004] Added user ability to change png_size_t via a PNG_SIZE_T macro. Added png_sizeof() and png_convert_size() functions. Added PNG_SIZE_MAX (maximum value of a png_size_t variable. Added check in png_malloc_default() for (size_t)size != (png_uint_32)size which would indicate an overflow. Changed sPLT failure action from png_error to png_warning and abandon chunk. Changed sCAL and iCCP failures from png_error to png_warning and abandon. Added png_get_uint_31(png_ptr, buf) function. Added PNG_UINT_32_MAX macro. Renamed PNG_MAX_UINT to PNG_UINT_31_MAX. Made png_zalloc() issue a png_warning and return NULL on potential overflow. Turn on PNG_NO_ZALLOC_ZERO by default in version 1.2.x Revised "clobber list" in pnggccrd.c so it will compile under gcc-3.4. Revised Borland portion of png_malloc() to return NULL or issue png_error() according to setting of PNG_FLAG_MALLOC_NULL_MEM_OK. Added PNG_NO_SEQUENTIAL_READ_SUPPORTED macro to conditionally remove sequential read support. Added some "#if PNG_WRITE_SUPPORTED" blocks. Added #ifdef to remove some redundancy in png_malloc_default(). Use png_malloc instead of png_zalloc to allocate the palette. Version 1.0.16rc1 and 1.2.6rc1 [August 4, 2004] Fixed buffer overflow vulnerability (CVE-2004-0597) in png_handle_tRNS(). Fixed NULL dereference vulnerability (CVE-2004-0598) in png_handle_iCCP(). Fixed integer overflow vulnerability (CVE-2004-0599) in png_read_png(). Fixed some harmless bugs in png_handle_sBIT, etc, that would cause duplicate chunk types to go undetected. Fixed some timestamps in the -config version Rearranged order of processing of color types in png_handle_tRNS(). Added ROWBYTES macro to calculate rowbytes without integer overflow. Updated makefile.darwin and removed makefile.macosx from scripts directory. Imposed default one million column, one-million row limits on the image dimensions, and added png_set_user_limits() function to override them. Revised use of PNG_SET_USER_LIMITS_SUPPORTED macro. Fixed wrong cast of returns from png_get_user_width|height_max(). Changed some "keep the compiler happy" from empty statements to returns, Revised libpng.txt to remove 1.2.x stuff from the 1.0.x distribution Version 1.0.16rc2 and 1.2.6rc2 [August 7, 2004] Revised makefile.darwin and makefile.solaris. Removed makefile.macosx. Revised pngtest's png_debug_malloc() to use png_malloc() instead of png_malloc_default() which is not supposed to be exported. Fixed off-by-one error in one of the conversions to PNG_ROWBYTES() in pngpread.c. Bug was introduced in 1.2.6rc1. Fixed bug in RGB to RGBX transformation introduced in 1.2.6rc1. Fixed old bug in RGB to Gray transformation. Fixed problem with 64-bit compilers by casting arguments to abs() to png_int_32. Changed "ln -sf" to "ln -f -s" in three makefiles (solaris, sco, so9). Changed "HANDLE_CHUNK_*" to "PNG_HANDLE_CHUNK_*" (Cosmin) Added "-@/bin/rm -f $(DL)/$(LIBNAME).so.$(PNGMAJ)" to 15 *NIX makefiles. Added code to update the row_info->colortype in png_do_read_filler() (MSB). Version 1.0.16rc3 and 1.2.6rc3 [August 9, 2004] Eliminated use of "abs()" in testing cHRM and gAMA values, to avoid trouble with some 64-bit compilers. Created PNG_OUT_OF_RANGE() macro. Revised documentation of png_set_keep_unknown_chunks(). Check handle_as_unknown status in pngpread.c, as in pngread.c previously. Moved "PNG_HANDLE_CHUNK_*" macros out of PNG_INTERNAL section of png.h Added "rim" definitions for CONST4 and CONST6 in pnggccrd.c Version 1.0.16rc4 and 1.2.6rc4 [August 10, 2004] Fixed mistake in pngtest.c introduced in 1.2.6rc2 (declaration of "pinfo" was out of place). Version 1.0.16rc5 and 1.2.6rc5 [August 10, 2004] Moved "PNG_HANDLE_CHUNK_*" macros out of PNG_ASSEMBLER_CODE_SUPPORTED section of png.h where they were inadvertently placed in version rc3. Version 1.2.6 and 1.0.16 [August 15, 2004] Revised pngtest so memory allocation testing is only done when PNG_DEBUG==1. Version 1.2.7beta1 [August 26, 2004] Removed unused pngasmrd.h file. Removed references to uu.net for archived files. Added references to PNG Spec (second edition) and the PNG ISO/IEC Standard. Added "test-dd" target in 15 makefiles, to run pngtest in DESTDIR. Fixed bug with "optimized window size" in the IDAT datastream, that causes libpng to write PNG files with incorrect zlib header bytes. Version 1.2.7beta2 [August 28, 2004] Fixed bug with sCAL chunk and big-endian machines (David Munro). Undid new code added in 1.2.6rc2 to update the color_type in png_set_filler(). Added png_set_add_alpha() that updates color type. Version 1.0.17rc1 and 1.2.7rc1 [September 4, 2004] Revised png_set_strip_filler() to not remove alpha if color_type has alpha. Version 1.2.7 and 1.0.17 [September 12, 2004] Added makefile.hp64 Changed projects/msvc/png32ms.def to scripts/png32ms.def in makefile.cygwin Version 1.2.8beta1 [November 1, 2004] Fixed bug in png_text_compress() that would fail to complete a large block. Fixed bug, introduced in libpng-1.2.7, that overruns a buffer during strip alpha operation in png_do_strip_filler(). Added PNG_1_2_X definition in pngconf.h Use #ifdef to comment out png_info_init in png.c and png_read_init in pngread.c (as of 1.3.0) Version 1.2.8beta2 [November 2, 2004] Reduce color_type to a nonalpha type after strip alpha operation in png_do_strip_filler(). Version 1.2.8beta3 [November 3, 2004] Revised definitions of PNG_MAX_UINT_32, PNG_MAX_SIZE, and PNG_MAXSUM Version 1.2.8beta4 [November 12, 2004] Fixed (again) definition of PNG_LIBPNG_VER_DLLNUM in png.h (Cosmin). Added PNG_LIBPNG_BUILD_PRIVATE in png.h (Cosmin). Set png_ptr->zstream.data_type to Z_BINARY, to avoid unnecessary detection of data type in deflate (Cosmin). Deprecated but continue to support SPECIALBUILD and PRIVATEBUILD in favor of PNG_LIBPNG_BUILD_SPECIAL_STRING and PNG_LIBPNG_BUILD_PRIVATE_STRING. Version 1.2.8beta5 [November 20, 2004] Use png_ptr->flags instead of png_ptr->transformations to pass PNG_STRIP_ALPHA info to png_do_strip_filler(), to preserve ABI compatibility. Revised handling of SPECIALBUILD, PRIVATEBUILD, PNG_LIBPNG_BUILD_SPECIAL_STRING and PNG_LIBPNG_BUILD_PRIVATE_STRING. Version 1.2.8rc1 [November 24, 2004] Moved handling of BUILD macros from pngconf.h to png.h Added definition of PNG_LIBPNG_BASE_TYPE in png.h, inadvertently omitted from beta5. Revised scripts/pngw32.rc Despammed mailing addresses by masking "@" with "at". Inadvertently installed a supposedly faster test version of pngrutil.c Version 1.2.8rc2 [November 26, 2004] Added two missing "\" in png.h Change tests in pngread.c and pngpread.c to if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA)) png_do_read_transformations(png_ptr); Version 1.2.8rc3 [November 28, 2004] Reverted pngrutil.c to version libpng-1.2.8beta5. Added scripts/makefile.elf with supporting code in pngconf.h for symbol versioning (John Bowler). Version 1.2.8rc4 [November 29, 2004] Added projects/visualc7 (Simon-pierre). Version 1.2.8rc5 [November 29, 2004] Fixed new typo in scripts/pngw32.rc Version 1.2.8 [December 3, 2004] Removed projects/visualc7, added projects/visualc71. Version 1.2.9beta1 [February 21, 2006] Initialized some structure members in pngwutil.c to avoid gcc-4.0.0 complaints Revised man page and libpng.txt to make it clear that one should not call png_read_end or png_write_end after png_read_png or png_write_png. Updated references to png-mng-implement mailing list. Fixed an incorrect typecast in pngrutil.c Added PNG_NO_READ_SUPPORTED conditional for making a write-only library. Added PNG_NO_WRITE_INTERLACING_SUPPORTED conditional. Optimized alpha-inversion loops in pngwtran.c Moved test for nonzero gamma outside of png_build_gamma_table() in pngrtran.c Make sure num_trans is <= 256 before copying data in png_set_tRNS(). Make sure num_palette is <= 256 before copying data in png_set_PLTE(). Interchanged order of write_swap_alpha and write_invert_alpha transforms. Added parentheses in the definition of PNG_LIBPNG_BUILD_TYPE (Cosmin). Optimized zlib window flag (CINFO) in contrib/pngsuite/*.png (Cosmin). Updated scripts/makefile.bc32 for Borland C++ 5.6 (Cosmin). Exported png_get_uint_32, png_save_uint_32, png_get_uint_16, png_save_uint_16, png_get_int_32, png_save_int_32, png_get_uint_31 (Cosmin). Added type cast (png_byte) in png_write_sCAL() (Cosmin). Fixed scripts/makefile.cygwin (Christian Biesinger, Cosmin). Default iTXt support was inadvertently enabled. Version 1.2.9beta2 [February 21, 2006] Check for png_rgb_to_gray and png_gray_to_rgb read transformations before checking for png_read_dither in pngrtran.c Revised checking of chromaticity limits to accommodate extended RGB colorspace (John Denker). Changed line endings in some of the project files to CRLF, even in the "Unix" tar distributions (Cosmin). Made png_get_int_32 and png_save_int_32 always available (Cosmin). Updated scripts/pngos2.def, scripts/pngw32.def and projects/wince/png32ce.def with the newly exported functions. Eliminated distributions without the "configure" script. Updated INSTALL instructions. Version 1.2.9beta3 [February 24, 2006] Fixed CRCRLF line endings in contrib/visupng/VisualPng.dsp Made libpng.pc respect EXEC_PREFIX (D. P. Kreil, J. Bowler) Removed reference to pngasmrd.h from Makefile.am Renamed CHANGES to ChangeLog. Renamed LICENSE to COPYING. Renamed ANNOUNCE to NEWS. Created AUTHORS file. Version 1.2.9beta4 [March 3, 2006] Changed definition of PKGCONFIG from $prefix/lib to $libdir in configure.ac Reverted to filenames LICENSE and ANNOUNCE; removed AUTHORS and COPYING. Removed newline from the end of some error and warning messages. Removed test for sqrt() from configure.ac and configure. Made swap tables in pngtrans.c PNG_CONST (Carlo Bramix). Disabled default iTXt support that was inadvertently enabled in libpng-1.2.9beta1. Added "OS2" to list of systems that don't need underscores, in pnggccrd.c Removed libpng version and date from *.c files. Version 1.2.9beta5 [March 4, 2006] Removed trailing blanks from source files. Put version and date of latest change in each source file, and changed copyright year accordingly. More cleanup of configure.ac, Makefile.am, and associated scripts. Restored scripts/makefile.elf which was inadvertently deleted. Version 1.2.9beta6 [March 6, 2006] Fixed typo (RELEASE) in configuration files. Version 1.2.9beta7 [March 7, 2006] Removed libpng.vers and libpng.sym from libpng12_la_SOURCES in Makefile.am Fixed inconsistent #ifdef's around png_sig_bytes() and png_set_sCAL_s() in png.h. Updated makefile.elf as suggested by debian. Made cosmetic changes to some makefiles, adding LN_SF and other macros. Made some makefiles accept "exec_prefix". Version 1.2.9beta8 [March 9, 2006] Fixed some "#if defined (..." which should be "#if defined(..." Bug introduced in libpng-1.2.8. Fixed inconsistency in definition of png_default_read_data() Restored blank that was lost from makefile.sggcc "clean" target in beta7. Revised calculation of "current" and "major" for irix in ltmain.sh Changed "mkdir" to "MKDIR_P" in some makefiles. Separated PNG_EXPAND and PNG_EXPAND_tRNS. Added png_set_expand_gray_1_2_4_to_8() and deprecated png_set_gray_1_2_4_to_8() which also expands tRNS to alpha. Version 1.2.9beta9 [March 10, 2006] Include "config.h" in pngconf.h when available. Added some checks for NULL png_ptr or NULL info_ptr (timeless) Version 1.2.9beta10 [March 20, 2006] Removed extra CR from contrib/visualpng/VisualPng.dsw (Cosmin) Made pnggccrd.c PIC-compliant (Christian Aichinger). Added makefile.mingw (Wolfgang Glas). Revised pngconf.h MMX checking. Version 1.2.9beta11 [March 22, 2006] Fixed out-of-order declaration in pngwrite.c that was introduced in beta9 Simplified some makefiles by using LIBSO, LIBSOMAJ, and LIBSOVER macros. Version 1.2.9rc1 [March 31, 2006] Defined PNG_USER_PRIVATEBUILD when including "pngusr.h" (Cosmin). Removed nonsensical assertion check from pngtest.c (Cosmin). Version 1.2.9 [April 14, 2006] Revised makefile.beos and added "none" selector in ltmain.sh Version 1.2.10beta1 [April 15, 2006] Renamed "config.h" to "png_conf.h" and revised Makefile.am to add -DPNG_BUILDING_LIBPNG to compile directive, and modified pngconf.h to include png_conf.h only when PNG_BUILDING_LIBPNG is defined. Version 1.2.10beta2 [April 15, 2006] Manually updated Makefile.in and configure. Changed png_conf.h.in back to config.h. Version 1.2.10beta3 [April 15, 2006] Change png_conf.h back to config.h in pngconf.h. Version 1.2.10beta4 [April 16, 2006] Change PNG_BUILDING_LIBPNG to PNG_CONFIGURE_LIBPNG in config/Makefile*. Version 1.2.10beta5 [April 16, 2006] Added a configure check for compiling assembler code in pnggccrd.c Version 1.2.10beta6 [April 17, 2006] Revised the configure check for pnggccrd.c Moved -DPNG_CONFIGURE_LIBPNG into @LIBPNG_DEFINES@ Added @LIBPNG_DEFINES@ to arguments when building libpng.sym Version 1.2.10beta7 [April 18, 2006] Change "exec_prefix=$prefix" to "exec_prefix=$(prefix)" in makefiles. Version 1.2.10rc1 [April 19, 2006] Ensure pngconf.h doesn't define both PNG_USE_PNGGCCRD and PNG_USE_PNGVCRD Fixed "LN_FS" typo in makefile.sco and makefile.solaris. Version 1.2.10rc2 [April 20, 2006] Added a backslash between -DPNG_CONFIGURE_LIBPNG and -DPNG_NO_ASSEMBLER_CODE in configure.ac and configure Made the configure warning about versioned symbols less arrogant. Version 1.2.10rc3 [April 21, 2006] Added a note in libpng.txt that png_set_sig_bytes(8) can be used when writing an embedded PNG without the 8-byte signature. Revised makefiles and configure to avoid making links to libpng.so.* Version 1.2.10 [April 23, 2006] Reverted configure to "rc2" state. Version 1.2.11beta1 [May 31, 2006] scripts/libpng.pc.in contained "configure" style version info and would not work with makefiles. The shared-library makefiles were linking to libpng.so.0 instead of libpng.so.3 compatibility as the library. Version 1.2.11beta2 [June 2, 2006] Increased sprintf buffer from 50 to 52 chars in pngrutil.c to avoid buffer overflow. Fixed bug in example.c (png_set_palette_rgb -> png_set_palette_to_rgb) Version 1.2.11beta3 [June 5, 2006] Prepended "#! /bin/sh" to ltmail.sh and contrib/pngminus/*.sh (Cosmin). Removed the accidental leftover Makefile.in~ (Cosmin). Avoided potential buffer overflow and optimized buffer in png_write_sCAL(), png_write_sCAL_s() (Cosmin). Removed the include directories and libraries from CFLAGS and LDFLAGS in scripts/makefile.gcc (Nelson A. de Oliveira, Cosmin). Version 1.2.11beta4 [June 6, 2006] Allow zero-length IDAT chunks after the entire zlib datastream, but not after another intervening chunk type. Version 1.0.19rc1, 1.2.11rc1 [June 13, 2006] Deleted extraneous square brackets from [config.h] in configure.ac Version 1.0.19rc2, 1.2.11rc2 [June 14, 2006] Added prototypes for PNG_INCH_CONVERSIONS functions to png.h Revised INSTALL and autogen.sh Fixed typo in several makefiles (-W1 should be -Wl) Added typedef for png_int_32 and png_uint_32 on 64-bit systems. Version 1.0.19rc3, 1.2.11rc3 [June 15, 2006] Removed the new typedefs for 64-bit systems (delay until version 1.4.0) Added one zero element to png_gamma_shift[] array in pngrtran.c to avoid reading out of bounds. Version 1.0.19rc4, 1.2.11rc4 [June 15, 2006] Really removed the new typedefs for 64-bit systems. Version 1.0.19rc5, 1.2.11rc5 [June 22, 2006] Removed png_sig_bytes entry from scripts/pngw32.def Version 1.0.19, 1.2.11 [June 26, 2006] None. Version 1.0.20, 1.2.12 [June 27, 2006] Really increased sprintf buffer from 50 to 52 chars in pngrutil.c to avoid buffer overflow. Version 1.2.13beta1 [October 2, 2006] Removed AC_FUNC_MALLOC from configure.ac Work around Intel-Mac compiler bug by setting PNG_NO_MMX_CODE in pngconf.h Change "logical" to "bitwise" throughout documentation. Detect and fix attempt to write wrong iCCP profile length (CVE-2006-7244) Version 1.0.21, 1.2.13 [November 14, 2006] Fix potential buffer overflow in sPLT chunk handler. Fix Makefile.am to not try to link to noexistent files. Check all exported functions for NULL png_ptr. Version 1.2.14beta1 [November 17, 2006] Relocated three misplaced tests for NULL png_ptr. Built Makefile.in with automake-1.9.6 instead of 1.9.2. Build configure with autoconf-2.60 instead of 2.59 Version 1.2.14beta2 [November 17, 2006] Added some typecasts in png_zalloc(). Version 1.2.14rc1 [November 20, 2006] Changed "strtod" to "png_strtod" in pngrutil.c Version 1.0.22, 1.2.14 [November 27, 2006] Added missing "$(srcdir)" in Makefile.am and Makefile.in Version 1.2.15beta1 [December 3, 2006] Generated configure with autoconf-2.61 instead of 2.60 Revised configure.ac to update libpng.pc and libpng-config. Version 1.2.15beta2 [December 3, 2006] Always export MMX asm functions, just stubs if not building pnggccrd.c Version 1.2.15beta3 [December 4, 2006] Add "png_bytep" typecast to profile while calculating length in pngwutil.c Version 1.2.15beta4 [December 7, 2006] Added scripts/CMakeLists.txt Changed PNG_NO_ASSEMBLER_CODE to PNG_NO_MMX_CODE in scripts, like 1.4.0beta Version 1.2.15beta5 [December 7, 2006] Changed some instances of PNG_ASSEMBLER_* to PNG_MMX_* in pnggccrd.c Revised scripts/CMakeLists.txt Version 1.2.15beta6 [December 13, 2006] Revised scripts/CMakeLists.txt and configure.ac Version 1.2.15rc1 [December 18, 2006] Revised scripts/CMakeLists.txt Version 1.2.15rc2 [December 21, 2006] Added conditional #undef jmpbuf in pngtest.c to undo #define in AIX headers. Added scripts/makefile.nommx Version 1.2.15rc3 [December 25, 2006] Fixed shared library numbering error that was introduced in 1.2.15beta6. Version 1.2.15rc4 [December 27, 2006] Fixed handling of rgb_to_gray when png_ptr->color.gray isn't set. Version 1.2.15rc5 [December 31, 2006] Revised handling of rgb_to_gray. Version 1.2.15 [January 5, 2007] Added some (unsigned long) typecasts in pngtest.c to avoid printing errors. Version 1.2.16beta1 [January 6, 2007] Fix bugs in makefile.nommx Version 1.2.16beta2 [January 16, 2007] Revised scripts/CMakeLists.txt Version 1.2.16 [January 31, 2007] No changes. Version 1.2.17beta1 [March 6, 2007] Revised scripts/CMakeLists.txt to install both shared and static libraries. Deleted a redundant line from pngset.c. Version 1.2.17beta2 [April 26, 2007] Relocated misplaced test for png_ptr == NULL in pngpread.c Change "==" to "&" for testing PNG_RGB_TO_GRAY_ERR & PNG_RGB_TO_GRAY_WARN flags. Changed remaining instances of PNG_ASSEMBLER_* to PNG_MMX_* Added pngerror() when write_IHDR fails in deflateInit2(). Added "const" to some array declarations. Mention examples of libpng usage in the libpng*.txt and libpng.3 documents. Version 1.2.17rc1 [May 4, 2007] No changes. Version 1.2.17rc2 [May 8, 2007] Moved several PNG_HAVE_* macros out of PNG_INTERNAL because applications calling set_unknown_chunk_location() need them. Changed transformation flag from PNG_EXPAND_tRNS to PNG_EXPAND in png_set_expand_gray_1_2_4_to_8(). Added png_ptr->unknown_chunk to hold working unknown chunk data, so it can be free'ed in case of error. Revised unknown chunk handling in pngrutil.c and pngpread.c to use this structure. Version 1.2.17rc3 [May 8, 2007] Revised symbol-handling in configure script. Version 1.2.17rc4 [May 10, 2007] Revised unknown chunk handling to avoid storing unknown critical chunks. Version 1.0.25 [May 15, 2007] Version 1.2.17 [May 15, 2007] Added "png_ptr->num_trans=0" before error return in png_handle_tRNS, to eliminate a vulnerability (CVE-2007-2445, CERT VU#684664) Version 1.0.26 [May 15, 2007] Version 1.2.18 [May 15, 2007] Reverted the libpng-1.2.17rc3 change to symbol-handling in configure script Version 1.2.19beta1 [May 18, 2007] Changed "const static" to "static PNG_CONST" everywhere, mostly undoing change of libpng-1.2.17beta2. Changed other "const" to "PNG_CONST" Changed some handling of unused parameters, to avoid compiler warnings. "if (unused == NULL) return;" becomes "unused = unused". Version 1.2.19beta2 [May 18, 2007] Only use the valid bits of tRNS value in png_do_expand() (Brian Cartier) Version 1.2.19beta3 [May 19, 2007] Add some "png_byte" typecasts in png_check_keyword() and write new_key instead of key in zTXt chunk (Kevin Ryde). Version 1.2.19beta4 [May 21, 2007] Add png_snprintf() function and use it in place of sprint() for improved defense against buffer overflows. Version 1.2.19beta5 [May 21, 2007] Fixed png_handle_tRNS() to only use the valid bits of tRNS value. Changed handling of more unused parameters, to avoid compiler warnings. Removed some PNG_CONST in pngwutil.c to avoid compiler warnings. Version 1.2.19beta6 [May 22, 2007] Added some #ifdef PNG_MMX_CODE_SUPPORTED where needed in pngvcrd.c Added a special "_MSC_VER" case that defines png_snprintf to _snprintf Version 1.2.19beta7 [May 22, 2007] Squelched png_squelch_warnings() in pnggccrd.c and added an #ifdef PNG_MMX_CODE_SUPPORTED block around the declarations that caused the warnings that png_squelch_warnings was squelching. Version 1.2.19beta8 [May 22, 2007] Removed __MMX__ from test in pngconf.h. Version 1.2.19beta9 [May 23, 2007] Made png_squelch_warnings() available via PNG_SQUELCH_WARNINGS macro. Revised png_squelch_warnings() so it might work. Updated makefile.sgcc and makefile.solaris; added makefile.solaris-x86. Version 1.2.19beta10 [May 24, 2007] Resquelched png_squelch_warnings(), use "__attribute__((used))" instead. Version 1.4.0beta1 [April 20, 2006] Enabled iTXt support (changes png_struct, thus requires so-number change). Cleaned up PNG_ASSEMBLER_CODE_SUPPORTED vs PNG_MMX_CODE_SUPPORTED Eliminated PNG_1_0_X and PNG_1_2_X macros. Removed deprecated functions png_read_init, png_write_init, png_info_init, png_permit_empty_plte, png_set_gray_1_2_4_to_8, png_check_sig, and removed the deprecated macro PNG_MAX_UINT. Moved "PNG_INTERNAL" parts of png.h and pngconf.h into pngintrn.h Removed many WIN32_WCE #ifdefs (Cosmin). Reduced dependency on C-runtime library when on Windows (Simon-Pierre) Replaced sprintf() with png_sprintf() (Simon-Pierre) Version 1.4.0beta2 [April 20, 2006] Revised makefiles and configure to avoid making links to libpng.so.* Moved some leftover MMX-related defines from pngconf.h to pngintrn.h Updated scripts/pngos2.def, pngw32.def, and projects/wince/png32ce.def Version 1.4.0beta3 [May 10, 2006] Updated scripts/pngw32.def to comment out MMX functions. Added PNG_NO_GET_INT_32 and PNG_NO_SAVE_INT_32 macros. Scripts/libpng.pc.in contained "configure" style version info and would not work with makefiles. Revised pngconf.h and added pngconf.h.in, so makefiles and configure can pass defines to libpng and applications. Version 1.4.0beta4 [May 11, 2006] Revised configure.ac, Makefile.am, and many of the makefiles to write their defines in pngconf.h. Version 1.4.0beta5 [May 15, 2006] Added a missing semicolon in Makefile.am and Makefile.in Deleted extraneous square brackets from configure.ac Version 1.4.0beta6 [June 2, 2006] Increased sprintf buffer from 50 to 52 chars in pngrutil.c to avoid buffer overflow. Changed sonum from 0 to 1. Removed unused prototype for png_check_sig() from png.h Version 1.4.0beta7 [June 16, 2006] Exported png_write_sig (Cosmin). Optimized buffer in png_handle_cHRM() (Cosmin). Set pHYs = 2835 x 2835 pixels per meter, and added sCAL = 0.352778e-3 x 0.352778e-3 meters, in pngtest.png (Cosmin). Added png_set_benign_errors(), png_benign_error(), png_chunk_benign_error(). Added typedef for png_int_32 and png_uint_32 on 64-bit systems. Added "(unsigned long)" typecast on png_uint_32 variables in printf lists. Version 1.4.0beta8 [June 22, 2006] Added demonstration of user chunk support in pngtest.c, to support the public sTER chunk and a private vpAg chunk. Version 1.4.0beta9 [July 3, 2006] Removed ordinals from scripts/pngw32.def and removed png_info_int and png_set_gray_1_2_4_to_8 entries. Inline call of png_get_uint_32() in png_get_uint_31(). Use png_get_uint_31() to get vpAg width and height in pngtest.c Removed WINCE and Netware projects. Removed standalone Y2KINFO file. Version 1.4.0beta10 [July 12, 2006] Eliminated automatic copy of pngconf.h to pngconf.h.in from configure and some makefiles, because it was not working reliably. Instead, distribute pngconf.h.in along with pngconf.h and cause configure and some of the makefiles to update pngconf.h from pngconf.h.in. Added pngconf.h to DEPENDENCIES in Makefile.am Version 1.4.0beta11 [August 19, 2006] Removed AC_FUNC_MALLOC from configure.ac. Added a warning when writing iCCP profile with mismatched profile length. Patched pnggccrd.c to assemble on x86_64 platforms. Moved chunk header reading into a separate function png_read_chunk_header() in pngrutil.c. The chunk header (len+sig) is now serialized in a single operation (Cosmin). Implemented support for I/O states. Added png_ptr member io_state, and functions png_get_io_chunk_name() and png_get_io_state() in pngget.c (Cosmin). Added png_get_io_chunk_name and png_get_io_state to scripts/*.def (Cosmin). Renamed scripts/pngw32.* to scripts/pngwin.* (Cosmin). Removed the include directories and libraries from CFLAGS and LDFLAGS in scripts/makefile.gcc (Cosmin). Used png_save_uint_32() to set vpAg width and height in pngtest.c (Cosmin). Cast to proper type when getting/setting vpAg units in pngtest.c (Cosmin). Added pngintrn.h to the Visual C++ projects (Cosmin). Removed scripts/list (Cosmin). Updated copyright year in scripts/pngwin.def (Cosmin). Removed PNG_TYPECAST_NULL and used standard NULL consistently (Cosmin). Disallowed the user to redefine png_size_t, and enforced a consistent use of png_size_t across libpng (Cosmin). Changed the type of png_ptr->rowbytes, PNG_ROWBYTES() and friends to png_size_t (Cosmin). Removed png_convert_size() and replaced png_sizeof with sizeof (Cosmin). Removed some unnecessary type casts (Cosmin). Changed prototype of png_get_compression_buffer_size() and png_set_compression_buffer_size() to work with png_size_t instead of png_uint_32 (Cosmin). Removed png_memcpy_check() and png_memset_check() (Cosmin). Fixed a typo (png_byte --> png_bytep) in libpng.3 and libpng.txt (Cosmin). Clarified that png_zalloc() does not clear the allocated memory, and png_zalloc() and png_zfree() cannot be PNGAPI (Cosmin). Renamed png_mem_size_t to png_alloc_size_t, fixed its definition in pngconf.h, and used it in all memory allocation functions (Cosmin). Renamed pngintrn.h to pngpriv.h, added a comment at the top of the file mentioning that the symbols declared in that file are private, and updated the scripts and the Visual C++ projects accordingly (Cosmin). Removed circular references between pngconf.h and pngconf.h.in in scripts/makefile.vc*win32 (Cosmin). Removing trailing '.' from the warning and error messages (Cosmin). Added pngdefs.h that is built by makefile or configure, instead of pngconf.h.in (Glenn). Detect and fix attempt to write wrong iCCP profile length. Version 1.4.0beta12 [October 19, 2006] Changed "logical" to "bitwise" in the documentation. Work around Intel-Mac compiler bug by setting PNG_NO_MMX_CODE in pngconf.h Add a typecast to stifle compiler warning in pngrutil.c Version 1.4.0beta13 [November 10, 2006] Fix potential buffer overflow in sPLT chunk handler. Fix Makefile.am to not try to link to noexistent files. Version 1.4.0beta14 [November 15, 2006] Check all exported functions for NULL png_ptr. Version 1.4.0beta15 [November 17, 2006] Relocated two misplaced tests for NULL png_ptr. Built Makefile.in with automake-1.9.6 instead of 1.9.2. Build configure with autoconf-2.60 instead of 2.59 Add "install: all" in Makefile.am so "configure; make install" will work. Version 1.4.0beta16 [November 17, 2006] Added a typecast in png_zalloc(). Version 1.4.0beta17 [December 4, 2006] Changed "new_key[79] = '\0';" to "(*new_key)[79] = '\0';" in pngwutil.c Add "png_bytep" typecast to profile while calculating length in pngwutil.c Version 1.4.0beta18 [December 7, 2006] Added scripts/CMakeLists.txt Version 1.4.0beta19 [May 16, 2007] Revised scripts/CMakeLists.txt Rebuilt configure and Makefile.in with newer tools. Added conditional #undef jmpbuf in pngtest.c to undo #define in AIX headers. Added scripts/makefile.nommx Version 1.4.0beta20 [July 9, 2008] Moved several PNG_HAVE_* macros from pngpriv.h to png.h because applications calling set_unknown_chunk_location() need them. Moved several macro definitions from pngpriv.h to pngconf.h Merge with changes to the 1.2.X branch, as of 1.2.30beta04. Deleted all use of the MMX assembler code and Intel-licensed optimizations. Revised makefile.mingw Version 1.4.0beta21 [July 21, 2008] Moved local array "chunkdata" from pngrutil.c to the png_struct, so it will be freed by png_read_destroy() in case of a read error (Kurt Christensen). Version 1.4.0beta22 [July 21, 2008] Change "purpose" and "buffer" to png_ptr->chunkdata to avoid memory leaking. Version 1.4.0beta23 [July 22, 2008] Change "chunkdata = NULL" to "png_ptr->chunkdata = NULL" several places in png_decompress_chunk(). Version 1.4.0beta24 [July 25, 2008] Change all remaining "chunkdata" to "png_ptr->chunkdata" in png_decompress_chunk(), and remove "chunkdata" from parameter list. Put a call to png_check_chunk_name() in png_read_chunk_header(). Revised png_check_chunk_name() to reject a name with a lowercase 3rd byte. Removed two calls to png_check_chunk_name() occurring later in the process. Define PNG_NO_ERROR_NUMBERS by default in pngconf.h Version 1.4.0beta25 [July 30, 2008] Added a call to png_check_chunk_name() in pngpread.c Reverted png_check_chunk_name() to accept a name with a lowercase 3rd byte. Added png_push_have_buffer() function to pngpread.c Eliminated PNG_BIG_ENDIAN_SUPPORTED and associated png_get_* macros. Made inline expansion of png_get_*() optional with PNG_USE_READ_MACROS. Eliminated all PNG_USELESS_TESTS and PNG_CORRECT_PALETTE_SUPPORTED code. Synced contrib directory and configure files with libpng-1.2.30beta06. Eliminated no-longer-used pngdefs.h (but it's still built in the makefiles) Relocated a misplaced "#endif /* PNG_NO_WRITE_FILTER */" in pngwutil.c Version 1.4.0beta26 [August 4, 2008] Removed png_push_have_buffer() function in pngpread.c. It increased the compiled library size slightly. Changed "-Wall" to "-W -Wall" in the CFLAGS in all makefiles (Cosmin Truta) Declared png_ptr "volatile" in pngread.c and pngwrite.c to avoid warnings. Updated contrib/visupng/cexcept.h to version 2.0.1 Added PNG_LITERAL_CHARACTER macros for #, [, and ]. Version 1.4.0beta27 [August 5, 2008] Revised usage of PNG_LITERAL_SHARP in pngerror.c. Moved newline character from individual png_debug messages into the png_debug macros. Allow user to #define their own png_debug, png_debug1, and png_debug2. Version 1.4.0beta28 [August 5, 2008] Revised usage of PNG_LITERAL_SHARP in pngerror.c. Added PNG_STRING_NEWLINE macro Version 1.4.0beta29 [August 9, 2008] Revised usage of PNG_STRING_NEWLINE to work on non-ISO compilers. Added PNG_STRING_COPYRIGHT macro. Added non-ISO versions of png_debug macros. Version 1.4.0beta30 [August 14, 2008] Added premultiplied alpha feature (Volker Wiendl). Version 1.4.0beta31 [August 18, 2008] Moved png_set_premultiply_alpha from pngtrans.c to pngrtran.c Removed extra crc check at the end of png_handle_cHRM(). Bug introduced in libpng-1.4.0beta20. Version 1.4.0beta32 [August 19, 2008] Added PNG_WRITE_FLUSH_SUPPORTED block around new png_flush() call. Revised PNG_NO_STDIO version of png_write_flush() Version 1.4.0beta33 [August 20, 2008] Added png_get|set_chunk_cache_max() to limit the total number of sPLT, text, and unknown chunks that can be stored. Version 1.4.0beta34 [September 6, 2008] Shortened tIME_string to 29 bytes in pngtest.c Fixed off-by-one error introduced in png_push_read_zTXt() function in libpng-1.2.30beta04/pngpread.c (Harald van Dijk) Version 1.4.0beta35 [October 6, 2008] Changed "trans_values" to "trans_color". Changed so-number from 0 to 14. Some OS do not like 0. Revised makefile.darwin to fix shared library numbering. Change png_set_gray_1_2_4_to_8() to png_set_expand_gray_1_2_4_to_8() in example.c (debian bug report) Version 1.4.0beta36 [October 25, 2008] Sync with tEXt vulnerability fix in libpng-1.2.33rc02. Version 1.4.0beta37 [November 13, 2008] Added png_check_cHRM in png.c and moved checking from pngget.c, pngrutil.c, and pngwrite.c Version 1.4.0beta38 [November 22, 2008] Added check for zero-area RGB cHRM triangle in png_check_cHRM() and png_check_cHRM_fixed(). Version 1.4.0beta39 [November 23, 2008] Revised png_warning() to write its message on standard output by default when warning_fn is NULL. Version 1.4.0beta40 [November 24, 2008] Eliminated png_check_cHRM(). Instead, always use png_check_cHRM_fixed(). In png_check_cHRM_fixed(), ensure white_y is > 0, and removed redundant check for all-zero coordinates that is detected by the triangle check. Version 1.4.0beta41 [November 26, 2008] Fixed string vs pointer-to-string error in png_check_keyword(). Rearranged test expressions in png_check_cHRM_fixed() to avoid internal overflows. Added PNG_NO_CHECK_cHRM conditional. Version 1.4.0beta42, 43 [December 1, 2008] Merge png_debug with version 1.2.34beta04. Version 1.4.0beta44 [December 6, 2008] Removed redundant check for key==NULL before calling png_check_keyword() to ensure that new_key gets initialized and removed extra warning (Merge with version 1.2.34beta05 -- Arvan Pritchard). Version 1.4.0beta45 [December 9, 2008] In png_write_png(), respect the placement of the filler bytes in an earlier call to png_set_filler() (Jim Barry). Version 1.4.0beta46 [December 10, 2008] Undid previous change and added PNG_TRANSFORM_STRIP_FILLER_BEFORE and PNG_TRANSFORM_STRIP_FILLER_AFTER conditionals and deprecated PNG_TRANSFORM_STRIP_FILLER (Jim Barry). Version 1.4.0beta47 [December 15, 2008] Support for dithering was disabled by default, because it has never been well tested and doesn't work very well. The code has not been removed, however, and can be enabled by building libpng with PNG_READ_DITHER_SUPPORTED defined. Version 1.4.0beta48 [February 14, 2009] Added new exported function png_calloc(). Combined several instances of png_malloc(); png_memset() into png_calloc(). Removed prototype for png_freeptr() that was added in libpng-1.4.0beta24 but was never defined. Version 1.4.0beta49 [February 28, 2009] Added png_fileno() macro to pngconf.h, used in pngwio.c Corrected order of #ifdef's in png_debug definition in png.h Fixed bug introduced in libpng-1.4.0beta48 with the memset arguments for pcal_params. Fixed order of #ifdef directives in the png_debug defines in png.h (bug introduced in libpng-1.2.34/1.4.0beta29). Revised comments in png_set_read_fn() and png_set_write_fn(). Version 1.4.0beta50 [March 18, 2009] Use png_calloc() instead of png_malloc() to allocate big_row_buf when reading an interlaced file, to avoid a possible UMR. Undid revision of PNG_NO_STDIO version of png_write_flush(). Users having trouble with fflush() can build with PNG_NO_WRITE_FLUSH defined or supply their own flush_fn() replacement. Revised libpng*.txt and png.h documentation about use of png_write_flush() and png_set_write_fn(). Removed fflush() from pngtest.c. Added "#define PNG_NO_WRITE_FLUSH" to contrib/pngminim/encoder/pngusr.h Version 1.4.0beta51 [March 21, 2009] Removed new png_fileno() macro from pngconf.h . Version 1.4.0beta52 [March 27, 2009] Relocated png_do_chop() ahead of building gamma tables in pngrtran.c This avoids building 16-bit gamma tables unnecessarily. Removed fflush() from pngtest.c. Added "#define PNG_NO_WRITE_FLUSH" to contrib/pngminim/encoder/pngusr.h Added a section on differences between 1.0.x and 1.2.x to libpng.3/libpng.txt Version 1.4.0beta53 [April 1, 2009] Removed some remaining MMX macros from pngpriv.h Fixed potential memory leak of "new_name" in png_write_iCCP() (Ralph Giles) Version 1.4.0beta54 [April 13, 2009] Added "ifndef PNG_SKIP_SETJMP_CHECK" block in pngconf.h to allow application code writers to bypass the check for multiple inclusion of setjmp.h when they know that it is safe to ignore the situation. Eliminated internal use of setjmp() in pngread.c and pngwrite.c Reordered ancillary chunks in pngtest.png to be the same as what pngtest now produces, and made some cosmetic changes to pngtest output. Eliminated deprecated png_read_init_3() and png_write_init_3() functions. Version 1.4.0beta55 [April 15, 2009] Simplified error handling in pngread.c and pngwrite.c by putting the new png_read_cleanup() and png_write_cleanup() functions inline. Version 1.4.0beta56 [April 25, 2009] Renamed "user_chunk_data" to "my_user_chunk_data" in pngtest.c to suppress "shadowed declaration" warning from gcc-4.3.3. Renamed "gamma" to "png_gamma" in pngset.c to avoid "shadowed declaration" warning about a global "gamma" variable in math.h on some platforms. Version 1.4.0beta57 [May 2, 2009] Removed prototype for png_freeptr() that was added in libpng-1.4.0beta24 but was never defined (again). Rebuilt configure scripts with autoconf-2.63 instead of 2.62 Removed pngprefs.h and MMX from makefiles Version 1.4.0beta58 [May 14, 2009] Changed pngw32.def to pngwin.def in makefile.mingw (typo was introduced in beta57). Clarified usage of sig_bit versus sig_bit_p in example.c (Vincent Torri) Version 1.4.0beta59 [May 15, 2009] Reformatted sources in libpng style (3-space indentation, comment format) Fixed typo in libpng docs (PNG_FILTER_AVE should be PNG_FILTER_AVG) Added sections about the git repository and our coding style to the documentation Relocated misplaced #endif in pngwrite.c, sCAL chunk handler. Version 1.4.0beta60 [May 19, 2009] Conditionally compile png_read_finish_row() which is not used by progressive readers. Added contrib/pngminim/preader to demonstrate building minimal progressive decoder, based on contrib/gregbook with embedded libpng and zlib. Version 1.4.0beta61 [May 20, 2009] In contrib/pngminim/*, renamed "makefile.std" to "makefile", since there is only one makefile in those directories, and revised the README files accordingly. More reformatting of comments, mostly to capitalize sentences. Version 1.4.0beta62 [June 2, 2009] Added "#define PNG_NO_WRITE_SWAP" to contrib/pngminim/encoder/pngusr.h and "define PNG_NO_READ_SWAP" to decoder/pngusr.h and preader/pngusr.h Reformatted several remaining "else statement" into two lines. Added a section to the libpng documentation about using png_get_io_ptr() in configure scripts to detect the presence of libpng. Version 1.4.0beta63 [June 15, 2009] Revised libpng*.txt and libpng.3 to mention calling png_set_IHDR() multiple times and to specify the sample order in the tRNS chunk, because the ISO PNG specification has a typo in the tRNS table. Changed several PNG_UNKNOWN_CHUNK_SUPPORTED to PNG_HANDLE_AS_UNKNOWN_SUPPORTED, to make the png_set_keep mechanism available for ignoring known chunks even when not saving unknown chunks. Adopted preference for consistent use of "#ifdef" and "#ifndef" versus "#if defined()" and "if !defined()" where possible. Version 1.4.0beta64 [June 24, 2009] Eliminated PNG_LEGACY_SUPPORTED code. Moved the various unknown chunk macro definitions outside of the PNG_READ|WRITE_ANCILLARY_CHUNK_SUPPORTED blocks. Version 1.4.0beta65 [June 26, 2009] Added a reference to the libpng license in each file. Version 1.4.0beta66 [June 27, 2009] Refer to the libpng license instead of the libpng license in each file. Version 1.4.0beta67 [July 6, 2009] Relocated INVERT_ALPHA within png_read_png() and png_write_png(). Added high-level API transform PNG_TRANSFORM_GRAY_TO_RGB. Added an "xcode" project to the projects directory (Alam Arias). Version 1.4.0beta68 [July 19, 2009] Avoid some tests in filter selection in pngwutil.c Version 1.4.0beta69 [July 25, 2009] Simplified the new filter-selection test. This runs faster in the common "PNG_ALL_FILTERS" and PNG_FILTER_NONE cases. Removed extraneous declaration from the new call to png_read_gray_to_rgb() (bug introduced in libpng-1.4.0beta67). Fixed up xcode project (Alam Arias) Added a prototype for png_64bit_product() in png.c Version 1.4.0beta70 [July 27, 2009] Avoid a possible NULL dereference in debug build, in png_set_text_2(). (bug introduced in libpng-0.95, discovered by Evan Rouault) Version 1.4.0beta71 [July 29, 2009] Rebuilt configure scripts with autoconf-2.64. Version 1.4.0beta72 [August 1, 2009] Replaced *.tar.lzma with *.tar.xz in distribution. Get the xz codec from . Version 1.4.0beta73 [August 1, 2009] Reject attempt to write iCCP chunk with negative embedded profile length (JD Chen) (CVE-2009-5063). Version 1.4.0beta74 [August 8, 2009] Changed png_ptr and info_ptr member "trans" to "trans_alpha". Version 1.4.0beta75 [August 21, 2009] Removed an extra png_debug() recently added to png_write_find_filter(). Fixed incorrect #ifdef in pngset.c regarding unknown chunk support. Version 1.4.0beta76 [August 22, 2009] Moved an incorrectly located test in png_read_row() in pngread.c Version 1.4.0beta77 [August 27, 2009] Removed lpXYZ.tar.bz2 (with CRLF), KNOWNBUG, libpng-x.y.z-KNOWNBUG.txt, and the "noconfig" files from the distribution. Moved CMakeLists.txt from scripts into the main libpng directory. Various bugfixes and improvements to CMakeLists.txt (Philip Lowman) Version 1.4.0beta78 [August 31, 2009] Converted all PNG_NO_* tests to PNG_*_SUPPORTED everywhere except pngconf.h Eliminated PNG_NO_FREE_ME and PNG_FREE_ME_SUPPORTED macros. Use png_malloc plus a loop instead of png_calloc() to initialize row_pointers in png_read_png(). Version 1.4.0beta79 [September 1, 2009] Eliminated PNG_GLOBAL_ARRAYS and PNG_LOCAL_ARRAYS; always use local arrays. Eliminated PNG_CALLOC_SUPPORTED macro and always provide png_calloc(). Version 1.4.0beta80 [September 17, 2009] Removed scripts/libpng.icc Changed typecast of filler from png_byte to png_uint_16 in png_set_filler(). (Dennis Gustafsson) Fixed typo introduced in beta78 in pngtest.c ("#if def " should be "#ifdef ") Version 1.4.0beta81 [September 23, 2009] Eliminated unused PNG_FLAG_FREE_* defines from pngpriv.h Expanded TAB characters in pngrtran.c Removed PNG_CONST from all "PNG_CONST PNG_CHNK" declarations to avoid compiler complaints about doubly declaring things "const". Changed all "#if [!]defined(X)" to "if[n]def X" where possible. Eliminated unused png_ptr->row_buf_size Version 1.4.0beta82 [September 25, 2009] Moved redundant IHDR checking into new png_check_IHDR() in png.c and report all errors found in the IHDR data. Eliminated useless call to png_check_cHRM() from pngset.c Version 1.4.0beta83 [September 25, 2009] Revised png_check_IHDR() to eliminate bogus complaint about filter_type. Version 1.4.0beta84 [September 30, 2009] Fixed some inconsistent indentation in pngconf.h Revised png_check_IHDR() to add a test for width variable less than 32-bit. Version 1.4.0beta85 [October 1, 2009] Revised png_check_IHDR() again, to check info_ptr members instead of the contents of the returned parameters. Version 1.4.0beta86 [October 9, 2009] Updated the "xcode" project (Alam Arias). Eliminated a shadowed declaration of "pp" in png_handle_sPLT(). Version 1.4.0rc01 [October 19, 2009] Trivial cosmetic changes. Version 1.4.0beta87 [October 30, 2009] Moved version 1.4.0 back into beta. Version 1.4.0beta88 [October 30, 2009] Revised libpng*.txt section about differences between 1.2.x and 1.4.0 because most of the new features have now been ported back to 1.2.41 Version 1.4.0beta89 [November 1, 2009] More bugfixes and improvements to CMakeLists.txt (Philip Lowman) Removed a harmless extra png_set_invert_alpha() from pngwrite.c Apply png_user_chunk_cache_max within png_decompress_chunk(). Merged libpng-1.2.41.txt with libpng-1.4.0.txt where appropriate. Version 1.4.0beta90 [November 2, 2009] Removed all remaining WIN32_WCE #ifdefs except those involving the time.h "tm" structure Version 1.4.0beta91 [November 3, 2009] Updated scripts/pngw32.def and projects/wince/png32ce.def Copied projects/wince/png32ce.def to the scripts directory. Added scripts/makefile.wce Patched ltmain.sh for wince support. Added PNG_CONVERT_tIME_SUPPORTED macro. Version 1.4.0beta92 [November 4, 2009] Make inclusion of time.h in pngconf.h depend on PNG_CONVERT_tIME_SUPPORTED Make #define PNG_CONVERT_tIME_SUPPORTED depend on PNG_WRITE_tIME_SUPPORTED Revised libpng*.txt to describe differences from 1.2.40 to 1.4.0 (instead of differences from 1.2.41 to 1.4.0) Version 1.4.0beta93 [November 7, 2009] Added PNG_DEPSTRUCT, PNG_DEPRECATED, PNG_USE_RESULT, PNG_NORETURN, and PNG_ALLOCATED macros to detect deprecated direct access to the png_struct or info_struct members and other deprecated usage in applications (John Bowler). Updated scripts/makefile* to add "-DPNG_CONFIGURE_LIBPNG" to CFLAGS, to prevent warnings about direct access to png structs by libpng functions while building libpng. They need to be tested, especially those using compilers other than gcc. Updated projects/visualc6 and visualc71 with "/d PNG_CONFIGURE_LIBPNG". They should work but still need to be updated to remove references to pnggccrd.c or pngvcrd.c and ASM building. Added README.txt to the beos, cbuilder5, netware, and xcode projects warning that they need to be updated, to remove references to pnggccrd.c and pngvcrd.c and to depend on pngpriv.h Removed three direct references to read_info_ptr members in pngtest.c that were detected by the new PNG_DEPSTRUCT macro. Moved the png_debug macro definitions and the png_read_destroy(), png_write_destroy() and png_far_to_near() prototypes from png.h to pngpriv.h (John Bowler) Moved the synopsis lines for png_read_destroy(), png_write_destroy() png_debug(), png_debug1(), and png_debug2() from libpng.3 to libpngpf.3. Version 1.4.0beta94 [November 9, 2009] Removed the obsolete, unused pnggccrd.c and pngvcrd.c files. Updated CMakeLists.txt to add "-DPNG_CONFIGURE_LIBPNG" to the definitions. Removed dependency of pngtest.o on pngpriv.h in the makefiles. Only #define PNG_DEPSTRUCT, etc. in pngconf.h if not already defined. Version 1.4.0beta95 [November 10, 2009] Changed png_check_sig() to !png_sig_cmp() in contrib programs. Added -DPNG_CONFIGURE_LIBPNG to contrib/pngminm/*/makefile Changed png_check_sig() to !png_sig_cmp() in contrib programs. Corrected the png_get_IHDR() call in contrib/gregbook/readpng2.c Changed pngminim/*/gather.sh to stop trying to remove pnggccrd.c and pngvcrd.c Added dependency on pngpriv.h in contrib/pngminim/*/makefile Version 1.4.0beta96 [November 12, 2009] Renamed scripts/makefile.wce to scripts/makefile.cegcc Revised Makefile.am to use libpng.sys while building libpng.so so that only PNG_EXPORT functions are exported. Removed the deprecated png_check_sig() function/macro. Removed recently removed function names from scripts/*.def Revised pngtest.png to put chunks in the same order written by pngtest (evidently the same change made in libpng-1.0beta54 was lost). Added PNG_PRIVATE macro definition in pngconf.h for possible future use. Version 1.4.0beta97 [November 13, 2009] Restored pngtest.png to the libpng-1.4.0beta7 version. Removed projects/beos and netware.txt; no one seems to be supporting them. Revised Makefile.in Version 1.4.0beta98 [November 13, 2009] Added the "xcode" project to zip distributions, Fixed a typo in scripts/pngwin.def introduced in beta97. Version 1.4.0beta99 [November 14, 2009] Moved libpng-config.in and libpng.pc-configure.in out of the scripts directory, to libpng-config.in and libpng-pc.in, respectively, and modified Makefile.am and configure.ac accordingly. Now "configure" needs nothing from the "scripts" directory. Avoid redefining PNG_CONST in pngconf.h Version 1.4.0beta100 [November 14, 2009] Removed ASM builds from projects/visualc6 and projects/visualc71 Removed scripts/makefile.nommx and makefile.vcawin32 Revised CMakeLists.txt to account for new location of libpng-config.in and libpng-pc.in Updated INSTALL to reflect removal and relocation of files. Version 1.4.0beta101 [November 14, 2009] Restored the binary files (*.jpg, *.png, some project files) that were accidentally deleted from the zip and 7z distributions when the xcode project was added. Version 1.4.0beta102 [November 18, 2009] Added libpng-config.in and libpng-pc.in to the zip and 7z distributions. Fixed a typo in projects/visualc6/pngtest.dsp, introduced in beta100. Moved descriptions of makefiles and other scripts out of INSTALL into scripts/README.txt Updated the copyright year in scripts/pngwin.rc from 2006 to 2009. Version 1.4.0beta103 [November 21, 2009] Removed obsolete comments about ASM from projects/visualc71/README_zlib.txt Align row_buf on 16-byte boundary in memory. Restored the PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED guard around the call to png_flush() after png_write_IEND(). See 1.4.0beta32, 1.4.0beta50 changes above and 1.2.30, 1.2.30rc01 and rc03 in 1.2.41 CHANGES. Someone needs this feature. Make the 'png_jmpbuf' macro expand to a call that records the correct longjmp function as well as returning a pointer to the setjmp jmp_buf buffer, and marked direct access to jmpbuf 'deprecated'. (John Bowler) Version 1.4.0beta104 [November 22, 2009] Removed png_longjmp_ptr from scripts/*.def and libpng.3 Rebuilt configure scripts with autoconf-2.65 Version 1.4.0beta105 [November 25, 2009] Use fast integer PNG_DIVIDE_BY_255() or PNG_DIVIDE_BY_65535() to accomplish alpha premultiplication when PNG_READ_COMPOSITE_NODIV_SUPPORTED is defined. Changed "/255" to "/255.0" in background calculations to make it clear that the 255 is used as a double. Version 1.4.0beta106 [November 27, 2009] Removed premultiplied alpha feature. Version 1.4.0beta107 [December 4, 2009] Updated README Added "#define PNG_NO_PEDANTIC_WARNINGS" in the libpng source files. Removed "-DPNG_CONFIGURE_LIBPNG" from the makefiles and projects. Revised scripts/makefile.netbsd, makefile.openbsd, and makefile.sco to put png.h and pngconf.h in $prefix/include, like the other scripts, instead of in $prefix/include/libpng. Also revised makefile.sco to put them in $prefix/include/libpng15 instead of in $prefix/include/libpng/libpng15. Version 1.4.0beta108 [December 11, 2009] Removed leftover "-DPNG_CONFIGURE_LIBPNG" from contrib/pngminim/*/makefile Relocated png_do_chop() to its original position in pngrtran.c; the change in version 1.2.41beta08 caused transparency to be handled wrong in some 16-bit datastreams (Yusaku Sugai). Version 1.4.0beta109 [December 13, 2009] Added "bit_depth" parameter to the private png_build_gamma_table() function. Pass bit_depth=8 to png_build_gamma_table() when bit_depth is 16 but the PNG_16_TO_8 transform has been set, to avoid unnecessary build of 16-bit tables. Version 1.4.0rc02 [December 20, 2009] Declared png_cleanup_needed "volatile" in pngread.c and pngwrite.c Version 1.4.0rc03 [December 22, 2009] Renamed libpng-pc.in back to libpng.pc.in and revised CMakeLists.txt (revising the change in 1.4.0beta99) Version 1.4.0rc04 [December 25, 2009] Swapped PNG_UNKNOWN_CHUNKS_SUPPORTED and PNG_HANDLE_AS_UNKNOWN_SUPPORTED in pngset.c to be consistent with other changes in version 1.2.38. Version 1.4.0rc05 [December 25, 2009] Changed "libpng-pc.in" to "libpng.pc.in" in configure.ac, configure, and Makefile.in to be consistent with changes in libpng-1.4.0rc03 Version 1.4.0rc06 [December 29, 2009] Reverted the gamma_table changes from libpng-1.4.0beta109. Fixed some indentation errors. Version 1.4.0rc07 [January 1, 2010] Revised libpng*.txt and libpng.3 about 1.2.x->1.4.x differences. Use png_calloc() instead of png_malloc(); png_memset() in pngrutil.c Update copyright year to 2010. Version 1.4.0rc08 [January 2, 2010] Avoid deprecated references to png_ptr-io_ptr and png_ptr->error_ptr in pngtest.c Version 1.4.0 [January 3, 2010] No changes. Version 1.4.1beta01 [January 8, 2010] Updated CMakeLists.txt for consistent indentation and to avoid an unclosed if-statement warning (Philip Lowman). Revised Makefile.am and Makefile.in to remove references to Y2KINFO, KNOWNBUG, and libpng.la (Robert Schwebel). Revised the makefiles to install the same files and symbolic links as configure, except for libpng.la and libpng14.la. Make png_set|get_compression_buffer_size() available even when PNG_WRITE_SUPPORTED is not enabled. Revised Makefile.am and Makefile.in to simplify their maintenance. Revised scripts/makefile.linux to install a link to libpng14.so.14.1 Version 1.4.1beta02 [January 9, 2010] Revised the rest of the makefiles to install a link to libpng14.so.14.1 Version 1.4.1beta03 [January 10, 2010] Removed png_set_premultiply_alpha() from scripts/*.def Version 1.4.1rc01 [January 16, 2010] No changes. Version 1.4.1beta04 [January 23, 2010] Revised png_decompress_chunk() to improve speed and memory usage when decoding large chunks. Added png_set|get_chunk_malloc_max() functions. Version 1.4.1beta05 [January 26, 2010] Relocated "int k" declaration in pngtest.c to minimize its scope. Version 1.4.1beta06 [January 28, 2010] Revised png_decompress_chunk() to use a two-pass method suggested by John Bowler. Version 1.4.1beta07 [February 6, 2010] Folded some long lines in the source files. Added definable PNG_USER_CHUNK_CACHE_MAX, PNG_USER_CHUNK_MALLOC_MAX, and a PNG_USER_LIMITS_SUPPORTED flag. Eliminated use of png_ptr->irowbytes and reused the slot in png_ptr as png_ptr->png_user_chunk_malloc_max. Revised png_push_save_buffer() to do fewer but larger png_malloc() calls. Version 1.4.1beta08 [February 6, 2010] Minor cleanup and updating of dates and copyright year. Version 1.5.0beta01 [February 7, 2010] Moved declaration of png_struct into private pngstruct.h and png_info into pnginfo.h Version 1.4.1beta09 and 1.5.0beta02 [February 7, 2010] Reverted to original png_push_save_buffer() code. Version 1.4.1beta10 and 1.5.0beta03 [February 8, 2010] Return allocated "old_buffer" in png_push_save_buffer() before calling png_error(), to avoid a potential memory leak. Updated configure script to use SO number 15. Version 1.5.0beta04 [February 9, 2010] Removed malformed "incomplete struct declaration" of png_info from png.h Version 1.5.0beta05 [February 12, 2010] Removed PNG_DEPSTRUCT markup in pngstruct.h and pnginfo.h, and undid the linewrapping that it entailed. Revised comments in pngstruct.h and pnginfo.h and added pointers to the libpng license. Changed PNG_INTERNAL to PNG_EXPOSE_INTERNAL_STRUCTURES Removed the cbuilder5 project, which has not been updated to 1.4.0. Version 1.4.1beta12 and 1.5.0beta06 [February 14, 2010] Fixed type declaration of png_get_chunk_malloc_max() in pngget.c (Daisuke Nishikawa) Version 1.5.0beta07 [omitted] Version 1.5.0beta08 [February 19, 2010] Changed #ifdef PNG_NO_STDIO_SUPPORTED to #ifdef PNG_NO_CONSOLE_IO_SUPPORTED wherever png_snprintf() is used to construct error and warning messages. Noted in scripts/makefile.mingw that it expects to be run under MSYS. Removed obsolete unused MMX-querying support from contrib/gregbook Added exported png_longjmp() function. Removed the AIX redefinition of jmpbuf in png.h Added -D_ALLSOURCE in configure.ac, makefile.aix, and CMakeLists.txt when building on AIX. Version 1.5.0beta09 [February 19, 2010] Removed -D_ALLSOURCE from configure.ac, makefile.aix, and CMakeLists.txt. Changed the name of png_ptr->jmpbuf to png_ptr->png_jmpbuf in pngstruct.h Version 1.5.0beta10 [February 25, 2010] Removed unused gzio.c from contrib/pngminim gather and makefile scripts Removed replacement error handlers from contrib/gregbook. Because of the new png_longjmp() function they are no longer needed. Version 1.5.0beta11 [March 6, 2010] Removed checking for already-included setjmp.h from pngconf.h Fixed inconsistent indentations and made numerous cosmetic changes. Revised the "SEE ALSO" style of libpng.3, libpngpf.3, and png.5 Version 1.5.0beta12 [March 9, 2010] Moved "#include png.h" inside pngpriv.h and removed "#include png.h" from the source files, along with "#define PNG_EXPOSE_INTERNAL_STRUCTURES" and "#define PNG_NO_PEDANTIC_WARNINGS" (John Bowler). Created new pngdebug.h and moved debug definitions there. Version 1.5.0beta13 [March 10, 2010] Protect pngstruct.h, pnginfo.h, and pngdebug.h from being included twice. Revise the "#ifdef" blocks in png_inflate() so it will compile when neither PNG_USER_CHUNK_MALLOC_MAX nor PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED is defined. Removed unused png_measure_compressed_chunk() from pngpriv.h and libpngpf.3 Moved the 'config.h' support from pngconf.h to pngpriv.h Removed PNGAPI from the png_longjmp_ptr typedef. Eliminated dependence of pngtest.c on the private pngdebug.h file. Make all png_debug macros into *unterminated* statements or expressions (i.e. a trailing ';' must always be added) and correct the format statements in various png_debug messages. Version 1.5.0beta14 [March 14, 2010] Removed direct access to png_ptr->io_ptr from the Windows code in pngtest.c Revised Makefile.am to account for recent additions and replacements. Corrected CE and OS/2 DEF files (scripts/png*def) for symbols removed and added ordinal numbers to the Windows DEF file and corrected the duplicated ordinal numbers on CE symbols that are commented out. Added back in export symbols that can be present in the Windows build but are disabled by default. PNG_EXPORT changed to include an 'ordinal' field for DEF file generation. PNG_CALLBACK added to make callback definitions uniform. PNGAPI split into PNGCAPI (base C form), PNGAPI (exports) and PNGCBAPI (callbacks), and appropriate changes made to all files. Cygwin builds re-hinged to allow procedure call standard changes and to remove the need for the DEF file (fixes build on Cygwin). Enabled 'attribute' warnings that are relevant to library APIs and callbacks. Changed rules for generation of the various symbol files and added a new rule for a DEF file (which is also added to the distribution). Updated the symbol file generation to stop it adding spurious spaces to EOL (coming from preprocessor macro expansion). Added a facility to join tokens in the output and rewrite *.dfn to use this. Eliminated scripts/*.def in favor of libpng.def; updated projects/visualc71 and removed scripts/makefile.cygwin. Made PNG_BUILD_DLL safe: it can be set whenever a DLL is being built. Removed the include of sys/types.h - apparently unnecessary now on the platforms on which it happened (all but Mac OS and RISC OS). Moved the Mac OS test into pngpriv.h (the only place it is used.) Version 1.5.0beta15 [March 17, 2010] Added symbols.chk target to Makefile.am to validate the symbols in png.h against the new DEF file scripts/symbols.def. Changed the default DEF file back to pngwin.def. Removed makefile.mingw. Eliminated PNG_NO_EXTERN and PNG_ALL_EXTERN Version 1.5.0beta16 [April 1, 2010] Make png_text_struct independent of PNG_iTXt_SUPPORTED, so that fields are initialized in all configurations. The READ/WRITE macros (PNG_(READ|WRITE)_iTXt_SUPPORTED) still function as before to disable code to actually read or write iTXt chunks and iTXt_SUPPORTED can be used to detect presence of either read or write support (but it is probably better to check for the one actually required - read or write.) Combined multiple png_warning() calls for a single error. Restored the macro definition of png_check_sig(). Version 1.5.0beta17 [April 17, 2010] Added some "(long)" typecasts to printf calls in png_handle_cHRM(). Documented the fact that png_set_dither() was disabled since libpng-1.4.0. Reenabled png_set_dither() but renamed it to png_set_quantize() to reflect more accurately what it actually does. At the same time, renamed the PNG_DITHER_[RED,GREEN_BLUE]_BITS macros to PNG_QUANTIZE_[RED,GREEN,BLUE]_BITS. Added some "(long)" typecasts to printf calls in png_handle_cHRM(). Freeze build-time only configuration in the build. In all prior versions of libpng most configuration options controlled by compiler #defines had to be repeated by the application code that used libpng. This patch changes this so that compilation options that can only be changed at build time are frozen in the build. Options that are compiler dependent (and those that are system dependent) are evaluated each time - pngconf.h holds these. Options that can be changed per-file in the application are in png.h. Frozen options are in the new installed header file pnglibconf.h (John Bowler) Removed the xcode project because it has not been updated to work with libpng-1.5.0. Removed the ability to include optional pngusr.h Version 1.5.0beta18 [April 17, 2010] Restored the ability to include optional pngusr.h Moved replacements for png_error() and png_warning() from the contrib/pngminim project to pngerror.c, for use when warnings or errors are disabled via PNG_NO_WARN or PNG_NO_ERROR_TEXT, to avoid storing unneeded error/warning text. Updated contrib/pngminim project to work with the new pnglibconf.h Added some PNG_NO_* defines to contrib/pngminim/*/pngusr.h to save space. Version 1.5.0beta19 [April 24, 2010] Added PNG_{READ,WRITE}_INT_FUNCTIONS_SUPPORTED. This allows the functions to read and write ints to be disabled independently of PNG_USE_READ_MACROS, which allows libpng to be built with the functions even though the default is to use the macros - this allows applications to choose at app build time whether or not to use macros (previously impossible because the functions weren't in the default build.) Changed Windows calling convention back to __cdecl for API functions. For Windows/x86 platforms only: __stdcall is no longer needed for Visual Basic, so libpng-1.5.0 uses __cdecl throughout (both API functions and callbacks) on Windows/x86 platforms. Replaced visualc6 and visualc71 projects with new vstudio project Relaxed the overly-restrictive permissions of some files. Version 1.5.0beta20 [April 24, 2010] Relaxed more overly-restrictive permissions of some files. Version 1.5.0beta21 [April 27, 2010] Removed some unwanted binary bytes and changed CRLF to NEWLINE in the new vstudio project files, and some trivial editing of some files in the scripts directory. Set PNG_NO_READ_BGR, PNG_NO_IO_STATE, and PNG_NO_TIME_RFC1123 in contrib/pngminim/decoder/pngusr.h to make a smaller decoder application. Version 1.5.0beta22 [April 28, 2010] Fixed dependencies of GET_INT_32 - it does not require READ_INT_FUNCTIONS because it has a macro equivalent. Improved the options.awk script; added an "everything off" option. Revised contrib/pngminim to use the "everything off" option in pngusr.dfa. Version 1.5.0beta23 [April 29, 2010] Corrected PNG_REMOVED macro to take five arguments. The macro was documented with two arguments (name,ordinal), however the symbol checking .dfn files assumed five arguments. The five argument form seems more useful so it is changed to that. Corrected PNG_UNKNOWN_CHUNKS_SUPPORTED to PNG_HANDLE_AS_UNKNOWN_SUPPORTED in gregbook/readpng2.c Corrected protection of png_get_user_transform_ptr. The API declaration in png.h is removed if both READ and WRITE USER_TRANSFORM are turned off but was left defined in pngtrans.c Added logunsupported=1 to cause pnglibconf.h to document disabled options. This makes the installed pnglibconf.h more readable but causes no other change. The intention is that users of libpng will find it easier to understand if an API they need is missing. Include png_reset_zstream() in png.c only when PNG_READ_SUPPORTED is defined. Removed dummy_inflate.c from contrib/pngminim/encoder Removed contrib/pngminim/*/gather.sh; gathering is now done in the makefile. Version 1.5.0beta24 [May 7, 2010] Use bitwise "&" instead of arithmetic mod in pngrutil.c calculation of the offset of the png_ptr->rowbuf pointer into png_ptr->big_row_buf. Added more blank lines for readability. Version 1.5.0beta25 [June 18, 2010] In pngpread.c: png_push_have_row() add check for new_row > height Removed the now-redundant check for out-of-bounds new_row from example.c Version 1.5.0beta26 [June 18, 2010] In pngpread.c: png_push_process_row() add check for too many rows. Version 1.5.0beta27 [June 18, 2010] Removed the check added in beta25 as it is now redundant. Version 1.5.0beta28 [June 20, 2010] Rewrote png_process_IDAT_data to consistently treat extra data as warnings and handle end conditions more cleanly. Removed the new (beta26) check in png_push_process_row(). Version 1.5.0beta29 [June 21, 2010] Revised scripts/options.awk to work on Sunos (but still doesn't work) Added comment to options.awk and contrib/pngminim/*/makefile to try nawk. Version 1.5.0beta30 [June 22, 2010] Stop memory leak when reading a malformed sCAL chunk. Version 1.5.0beta31 [June 26, 2010] Revised pngpread.c patch of beta28 to avoid an endless loop. Removed some trailing blanks. Version 1.5.0beta32 [June 26, 2010] Removed leftover scripts/options.patch and scripts/options.rej Version 1.5.0beta33 [July 6, 3010] Made FIXED and FLOATING options consistent in the APIs they enable and disable. Corrected scripts/options.awk to handle both command line options and options specified in the .dfa files. Changed char *msg to PNG_CONST char *msg in pngrutil.c Make png_set_sRGB_gAMA_and_cHRM set values using either the fixed or floating point APIs, but not both. Reversed patch to remove error handler when the jmp_buf is stored in the main program structure, not the png_struct. The error handler is needed because the default handler in libpng will always use the jmp_buf in the library control structure; this is never set. The gregbook code is a useful example because, even though it uses setjmp/longjmp, it shows how error handling can be implemented using control mechanisms not directly supported by libpng. The technique will work correctly with mechanisms such as Microsoft Structure Exceptions or C++ exceptions (compiler willing - note that gcc does not by default support interworking of C and C++ error handling.) Reverted changes to call png_longjmp in contrib/gregbook where it is not appropriate. If mainprog->jmpbuf is used by setjmp, then png_longjmp cannot be used. Changed "extern PNG_EXPORT" to "PNG_EXPORT" in png.h (Jan Nijtmans) Changed "extern" to "PNG_EXTERN" in pngpriv.h (except for the 'extern "C" {') Version 1.5.0beta34 [July 12, 2010] Put #ifndef PNG_EXTERN, #endif around the define PNG_EXTERN in pngpriv.h Version 1.5.0beta35 [July 24, 2010] Removed some newly-added TAB characters. Added -DNO_PNG_SNPRINTF to CFLAGS in scripts/makefile.dj2 Moved the definition of png_snprintf() outside of the enclosing #ifdef blocks in pngconf.h Version 1.5.0beta36 [July 29, 2010] Patches by John Bowler: Fixed point APIs are now supported throughout (no missing APIs). Internal fixed point arithmetic support exists for all internal floating point operations. sCAL validates the floating point strings it is passed. Safe, albeit rudimentary, Watcom support is provided by PNG_API_RULE==2 Two new APIs exist to get the number of passes without turning on the PNG_INTERLACE transform and to get the number of rows in the current pass. A new test program, pngvalid.c, validates the gamma code. Errors in the 16-bit gamma correction (overflows) have been corrected. cHRM chunk testing is done consistently (previously the floating point API bypassed it, because the test really didn't work on FP, now the test is performed on the actual values to be stored in the PNG file so it works in the FP case too.) Most floating point APIs now simply call the fixed point APIs after converting the values to the fixed point form used in the PNG file. The standard headers no longer include zlib.h, which is currently only required for pngstruct.h and can therefore be internal. Revised png_get_int_32 to undo the PNG two's complement representation of negative numbers. Version 1.5.0beta37 [July 30, 2010] Added a typecast in png_get_int_32() in png.h and pngrutil.h to avoid a compiler warning. Replaced oFFs 0,0 with oFFs -10,20 in pngtest.png Version 1.5.0beta38 [July 31, 2010] Implemented remaining "_fixed" functions. Corrected a number of recently introduced warnings mostly resulting from safe but uncast assignments to shorter integers. Also added a zlib VStudio release library project because the latest zlib Official Windows build does not include such a thing. Revised png_get_int_16() to be similar to png_get_int_32(). Restored projects/visualc71. Version 1.5.0beta39 [August 2, 2010] VisualC/GCC warning fixes, VisualC build fixes The changes include support for function attributes in VC in addition to those already present in GCC - necessary because without these some warnings are unavoidable. Fixes include signed/unsigned fixes in pngvalid and checks with gcc -Wall -Wextra -Wunused. VC requires function attributes on function definitions as well as declarations, PNG_FUNCTION has been added to enable this and the relevant function definitions changed. Version 1.5.0beta40 [August 6, 2010] Correct use of _WINDOWS_ in pngconf.h Removed png_mem_ #defines; they are no longer used. Added the sRGB chunk to pngtest.png Version 1.5.0beta41 [August 11, 2010] Added the cHRM chunk to pngtest.png Don't try to use version-script with cygwin/mingw. Revised contrib/gregbook to work under cygwin/mingw. Version 1.5.0beta42 [August 18, 2010] Add .dll.a to the list of extensions to be symlinked by Makefile.am (Yaakov) Made all API functions that have const arguments and constant string literal pointers declare them (John Bowler). Version 1.5.0beta43 [August 20, 2010] Removed spurious tabs, shorten long lines (no source change) Also added scripts/chkfmt to validate the format of all the files that can reasonably be validated (it is suggested to run "make distclean" before checking, because some machine generated files have long lines.) Reformatted the CHANGES file to be more consistent throughout. Made changes to address various issues identified by GCC, mostly signed/unsigned and shortening problems on assignment but also a few difficult to optimize (for GCC) loops. Fixed non-GCC fixed point builds. In png.c a declaration was misplaced in an earlier update. Fixed to declare the auto variables at the head. Use cexcept.h in pngvalid.c. Version 1.5.0beta44 [August 24, 2010] Updated CMakeLists.txt to use CMAKE_INSTALL_LIBDIR variable; useful for installing libpng in /usr/lib64 (Funda Wang). Revised CMakeLists.txt to put the man pages in share/man/man* not man/man* Revised CMakeLists.txt to make symlinks instead of copies when installing. Changed PNG_LIB_NAME from pngNN to libpngNN in CMakeLists.txt (Philip Lowman) Implemented memory checks within pngvalid Reformatted/rearranged pngvalid.c to assist use of progressive reader. Check interlaced images in pngvalid Clarified pngusr.h comments in pnglibconf.dfa Simplified the pngvalid error-handling code now that cexcept.h is in place. Implemented progressive reader in pngvalid.c for standard tests Implemented progressive read in pngvalid.c gamma tests Turn on progressive reader in pngvalid.c by default and tidy code. Version 1.5.0beta45 [August 26, 2010] Added an explicit make step to projects/vstudio for pnglibconf.h Also corrected zlib.vcxproj into which Visual Studio had introduced what it calls an "authoring error". The change to make pnglibconf.h simply copies the file; in the future it may actually generate the file from scripts/pnglibconf.dfa as the other build systems do. Changed pngvalid to work when floating point APIs are disabled Renamed the prebuilt scripts/pnglibconf.h to scripts/pnglibconf.h.prebuilt Supply default values for PNG_USER_PRIVATEBUILD and PNG_USER_DLLFNAME_POSTFIX in pngpriv.h in case the user neglected to define them in their pngusr.h Version 1.5.0beta46 [August 28, 2010] Added new private header files to libpng_sources in CMakeLists.txt Added PNG_READ_16BIT, PNG_WRITE_16BIT, and PNG_16BIT options. Added reference to scripts/pnglibconf.h.prebuilt in the visualc71 project. Version 1.5.0beta47 [September 11, 2010] Fixed a number of problems with 64-bit compilation reported by Visual Studio 2010 (John Bowler). Version 1.5.0beta48 [October 4, 2010] Updated CMakeLists.txt (Philip Lowman). Revised autogen.sh to recognize and use $AUTOCONF, $AUTOMAKE, $AUTOHEADER, $AUTOPOINT, $ACLOCAL and $LIBTOOLIZE Fixed problem with symbols creation in Makefile.am which was assuming that all versions of ccp write to standard output by default (Martin Banky). The bug was introduced in libpng-1.2.9beta5. Removed unused mkinstalldirs. Version 1.5.0beta49 [October 8, 2010] Undid Makefile.am revision of 1.5.0beta48. Version 1.5.0beta50 [October 14, 2010] Revised Makefile.in to account for mkinstalldirs being removed. Added some "(unsigned long)" typecasts in printf statements in pngvalid.c. Suppressed a compiler warning in png_handle_sPLT(). Check for out-of-range text compression mode in png_set_text(). Version 1.5.0beta51 [October 15, 2010] Changed embedded dates to "(PENDING RELEASE) in beta releases (and future rc releases) to minimize the difference between releases. Version 1.5.0beta52 [October 16, 2010] Restored some of the embedded dates (in png.h, png.c, documentation, etc.) Version 1.5.0beta53 [October 18, 2010] Updated INSTALL to mention using "make maintainer-clean" and to remove obsolete statement about a custom ltmain.sh Disabled "color-tests" by default in Makefile.am so it will work with automake versions earlier than 1.11.1 Use document name "libpng-manual.txt" instead of "libpng-.txt" to simplify version differences. Removed obsolete remarks about setjmp handling from INSTALL. Revised and renamed the typedef in png.h and png.c that was designed to catch library and header mismatch. Version 1.5.0beta54 [November 10, 2010] Require 48 bytes, not 64 bytes, for big_row_buf in overflow checks. Used a consistent structure for the pngget.c functions. Version 1.5.0beta55 [November 21, 2010] Revised png_get_uint_32, png_get_int_32, png_get_uint_16 (Cosmin) Moved reading of file signature into png_read_sig (Cosmin) Fixed atomicity of chunk header serialization (Cosmin) Added test for io_state in pngtest.c (Cosmin) Added "#!/bin/sh" at the top of contrib/pngminim/*/gather.sh scripts. Changes to remove gcc warnings (John Bowler) Certain optional gcc warning flags resulted in warnings in libpng code. With these changes only -Wconversion and -Wcast-qual cannot be turned on. Changes are trivial rearrangements of code. -Wconversion is not possible for pngrutil.c (because of the widespread use of += et al on variables smaller than (int) or (unsigned int)) and -Wcast-qual is not possible with pngwio.c and pngwutil.c because the 'write' callback and zlib compression both fail to declare their input buffers with 'const'. Version 1.5.0beta56 [December 7, 2010] Added the private PNG_UNUSED() macro definition in pngpriv.h. Added some commentary about PNG_EXPORT in png.h and pngconf.h Revised PNG_EXPORT() macro and added PNG_EXPORTA() macro, with the objective of simplifying and improving the cosmetic appearance of png.h. Fixed some incorrect "=" macro names in pnglibconf.dfa Included documentation of changes in 1.5.0 from 1.4.x in libpng-manual.txt Version 1.5.0beta57 [December 9, 2010] Documented the pngvalid gamma error summary with additional comments and print statements. Improved missing symbol handling in checksym.awk; symbols missing in both the old and new files can now be optionally ignored, treated as errors or warnings. Removed references to pngvcrd.c and pnggccrd.c from the vstudio project. Updated "libpng14" to "libpng15" in the visualc71 project. Enabled the strip16 tests in pngvalid.` Don't display test results (except PASS/FAIL) when running "make test". Instead put them in pngtest-log.txt Added "--with-zprefix=" to configure.ac Updated the prebuilt configuration files to autoconf version 2.68 Version 1.5.0beta58 [December 19, 2010] Fixed interlace image handling and add test cases (John Bowler) Fixed the clean rule in Makefile.am to remove pngtest-log.txt Made minor changes to work around warnings in gcc 3.4 Version 1.5.0rc01 [December 27, 2010] No changes. Version 1.5.0rc02 [December 27, 2010] Eliminated references to the scripts/*.def files in project/visualc71. Version 1.5.0rc03 [December 28, 2010] Eliminated scripts/*.def and revised Makefile.am accordingly Version 1.5.0rc04 [December 29, 2010] Fixed bug in background transformation handling in pngrtran.c (it was looking for the flag in png_ptr->transformations instead of in png_ptr->flags) (David Raymond). Version 1.5.0rc05 [December 31, 2010] Fixed typo in a comment in CMakeLists.txt (libpng14 => libpng15) (Cosmin) Version 1.5.0rc06 [January 4, 2011] Changed the new configure option "zprefix=string" to "zlib-prefix=string" Version 1.5.0rc07 [January 4, 2011] Updated copyright year. Version 1.5.0 [January 6, 2011] No changes. version 1.5.1beta01 [January 8, 2011] Added description of png_set_crc_action() to the manual. Added a note in the manual that the type of the iCCP profile was changed from png_charpp to png_bytepp in png_get_iCCP(). This change happened in version 1.5.0beta36 but is not noted in the CHANGES. Similarly, it was changed from png_charpp to png_const_bytepp in png_set_iCCP(). Ensure that png_rgb_to_gray ignores palette mapped images, if libpng internally happens to call it with one, and fixed a failure to handle palette mapped images correctly. This fixes CVE-2690. Version 1.5.1beta02 [January 14, 2011] Fixed a bug in handling of interlaced images (bero at arklinux.org). Updated CMakeLists.txt (Clifford Yapp) Version 1.5.1beta03 [January 14, 2011] Fixed typecasting of some png_debug() statements (Cosmin) Version 1.5.1beta04 [January 16, 2011] Updated documentation of png_set|get_tRNS() (Thomas Klausner). Mentioned in the documentation that applications must #include "zlib.h" if they need access to anything in zlib.h, and that a number of macros such as png_memset() are no longer accessible by applications. Corrected pngvalid gamma test "sample" function to access all of the color samples of each pixel, instead of sampling the red channel three times. Prefixed variable names index, div, exp, gamma with "png_" to avoid "shadow" warnings, and (mistakenly) changed png_exp() to exp(). Version 1.5.1beta05 [January 16, 2011] Changed variable names png_index, png_div, png_exp, and png_gamma to char_index, divisor, exp_b10, and gamma_val, respectively, and changed exp() back to png_exp(). Version 1.5.1beta06 [January 20, 2011] Prevent png_push_crc_skip() from hanging while reading an unknown chunk or an over-large compressed zTXt chunk with the progressive reader. Eliminated more GCC "shadow" warnings. Revised png_fixed() in png.c to avoid compiler warning about reaching the end without returning anything. Version 1.5.1beta07 [January 22, 2011] In the manual, describe the png_get_IHDR() arguments in the correct order. Added const_png_structp and const_png_infop types, and used them in prototypes for most png_get_*() functions. Version 1.5.1beta08 [January 23, 2011] Added png_get_io_chunk_type() and deprecated png_get_io_chunk_name() Added synopses for the IO_STATE functions and other missing synopses to the manual. Removed the synopses from libpngpf.3 because they were out of date and no longer useful. Better information can be obtained by reading the prototypes and comments in pngpriv.h Attempted to fix cpp on Solaris with S. Studio 12 cc, fix build Added a make macro DFNCPP that is a CPP that will accept the tokens in a .dfn file and adds configure stuff to test for such a CPP. ./configure should fail if one is not available. Corrected const_png_ in png.h to png_const_ to avoid polluting the namespace. Added png_get_current_row_number and png_get_current_pass_number for the benefit of the user transform callback. Added png_process_data_pause and png_process_data_skip for the benefit of progressive readers that need to stop data processing or want to optimize skipping of unread data (e.g., if the reader marks a chunk to be skipped.) Version 1.5.1beta09 [January 24, 2011] Enhanced pngvalid, corrected an error in gray_to_rgb, corrected doc error. pngvalid contains tests of transforms, which tests are currently disabled because they are incompletely tested. gray_to_rgb was failing to expand the bit depth for smaller bit depth images; this seems to be a long standing error and resulted, apparently, in invalid output (CVE-2011-0408, CERT VU#643140). The documentation did not accurately describe what libpng really does when converting RGB to gray. Version 1.5.1beta10 [January 27, 2010] Fixed incorrect examples of callback prototypes in the manual, that were introduced in libpng-1.0.0. In addition the order of the png_get_uint macros with respect to the relevant function definitions has been reversed. This helps the preprocessing of the symbol files be more robust. Furthermore, the symbol file preprocessing now uses -DPNG_NO_USE_READ_MACROS even when the library may actually be built with PNG_USE_READ_MACROS; this stops the read macros interfering with the symbol file format. Made the manual, synopses, and function prototypes use the function argument names file_gamma, int_file_gamma, and srgb_intent consistently. Version 1.5.1beta11 [January 28, 2011] Changed PNG_UNUSED from "param=param;" to "{if(param){}}". Corrected local variable type in new API png_process_data_skip() The type was self-evidently incorrect but only causes problems on 64-bit architectures. Added transform tests to pngvalid and simplified the arguments. Version 1.5.1rc01 [January 29, 2011] No changes. Version 1.5.1rc02 [January 31, 2011] Added a request in the manual that applications do not use "png_" or "PNG_" to begin any of their own symbols. Changed PNG_UNUSED to "(void)param;" and updated the commentary in pngpriv.h Version 1.5.1 [February 3, 2011] No changes. Version 1.5.2beta01 [February 13, 2011] More -Wshadow fixes for older gcc compilers. Older gcc versions apparently check formal parameters names in function declarations (as well as definitions) to see if they match a name in the global namespace. Revised PNG_EXPORTA macro to not use an empty parameter, to accommodate the old VisualC++ preprocessor. Turned on interlace handling in png_read_png(). Fixed gcc pedantic warnings. Handle longjmp in Cygwin. Fixed png_get_current_row_number() in the interlaced case. Cleaned up ALPHA flags and transformations. Implemented expansion to 16 bits. Version 1.5.2beta02 [February 19, 2011] Fixed mistake in the descriptions of user read_transform and write_transform function prototypes in the manual. The row_info struct is png_row_infop. Reverted png_get_current_row_number() to previous (1.5.2beta01) behavior. Corrected png_get_current_row_number documentation Fixed the read/write row callback documentation. This documents the current behavior, where the callback is called after every row with information pertaining to the next row. Version 1.5.2beta03 [March 3, 2011] Fixed scripts/makefile.vcwin32 Updated contrib/pngsuite/README to add the word "modify". Define PNG_ALLOCATED to blank when _MSC_VER<1300. Version 1.5.2rc01 [March 19, 2011] Define remaining attributes to blank when MSC_VER<1300. ifdef out mask arrays in pngread.c when interlacing is not supported. Version 1.5.2rc02 [March 22, 2011] Added a hint to try CPP=/bin/cpp if "cpp -E" fails in scripts/pnglibconf.mak and in contrib/pngminim/*/makefile, eg., on SunOS 5.10, and removed "strip" from the makefiles. Fixed a bug (present since libpng-1.0.7) that makes png_handle_sPLT() fail to compile when PNG_NO_POINTER_INDEXING is defined (Chubanov Kirill) Version 1.5.2rc03 [March 24, 2011] Don't include standard header files in png.h while building the symbol table, to avoid cpp failure on SunOS (introduced PNG_BUILDING_SYMBOL_TABLE macro). Version 1.5.2 [March 31, 2011] No changes. Version 1.5.3beta01 [April 1, 2011] Re-initialize the zlib compressor before compressing non-IDAT chunks. Added API functions (png_set_text_compression_level() and four others) to set parameters for zlib compression of non-IDAT chunks. Version 1.5.3beta02 [April 3, 2011] Updated scripts/symbols.def with new API functions. Only compile the new zlib re-initializing code when text or iCCP is supported, using PNG_WRITE_COMPRESSED_TEXT_SUPPORTED macro. Improved the optimization of the zlib CMF byte (see libpng-1.2.6beta03). Optimize the zlib CMF byte in non-IDAT compressed chunks Version 1.5.3beta03 [April 16, 2011] Fixed gcc -ansi -pedantic compile. A strict ANSI system does not have snprintf, and the "__STRICT_ANSI__" detects that condition more reliably than __STDC__ (John Bowler). Removed the PNG_PTR_NORETURN attribute because it too dangerous. It tells the compiler that a user supplied callback (the error handler) does not return, yet there is no guarantee in practice that the application code will correctly implement the error handler because the compiler only issues a warning if there is a mistake (John Bowler). Removed the no-longer-used PNG_DEPSTRUCT macro. Updated the zlib version to 1.2.5 in the VStudio project. Fixed 64-bit builds where png_uint_32 is smaller than png_size_t in pngwutil.c (John Bowler). Fixed bug with stripping the filler or alpha channel when writing, that was introduced in libpng-1.5.2beta01 (bug report by Andrew Church). Version 1.5.3beta04 [April 27, 2011] Updated pngtest.png with the new zlib CMF optimization. Cleaned up conditional compilation code and of background/gamma handling Internal changes only except a new option to avoid compiling the png_build_grayscale_palette API (which is not used at all internally.) The main change is to move the transform tests (READ_TRANSFORMS, WRITE_TRANSFORMS) up one level to the caller of the APIs. This avoids calls to spurious functions if all transforms are disabled and slightly simplifies those functions. Pngvalid modified to handle this. A minor change is to stop the strip_16 and expand_16 interfaces from disabling each other; this allows the future alpha premultiplication code to use 16-bit intermediate values while still producing 8-bit output. png_do_background and png_do_gamma have been simplified to take a single pointer to the png_struct rather than pointers to every item required from the png_struct. This makes no practical difference to the internal code. A serious bug in the pngvalid internal routine 'standard_display_init' has been fixed - this failed to initialize the red channel and accidentally initialized the alpha channel twice. Changed png_struct jmp_buf member name from png_jmpbuf to tmp_jmpbuf to avoid a possible clash with the png_jmpbuf macro on some platforms. Version 1.5.3beta05 [May 6, 2011] Added the "_POSIX_SOURCE" feature test macro to ensure libpng sees the correct API. _POSIX_SOURCE is defined in pngpriv.h, pngtest.c and pngvalid.c to ensure that POSIX conformant systems disable non-POSIX APIs. Removed png_snprintf and added formatted warning messages. This change adds internal APIs to allow png_warning messages to have parameters without requiring the host OS to implement snprintf. As a side effect the dependency of the tIME-supporting RFC1132 code on stdio is removed and PNG_NO_WARNINGS does actually work now. Pass "" instead of '\0' to png_default_error() in png_err(). This mistake was introduced in libpng-1.2.20beta01. This fixes CVE-2011-2691. Added PNG_WRITE_OPTIMIZE_CMF_SUPPORTED macro to make the zlib "CMF" byte optimization configurable. IDAT compression failed if preceded by a compressed text chunk (bug introduced in libpng-1.5.3beta01-02). This was because the attempt to reset the zlib stream in png_write_IDAT happened after the first IDAT chunk had been deflated - much too late. In this change internal functions were added to claim/release the z_stream and, hopefully, make the code more robust. Also deflateEnd checking is added - previously libpng would ignore an error at the end of the stream. Version 1.5.3beta06 [May 8, 2011] Removed the -D_ALL_SOURCE from definitions for AIX in CMakeLists.txt Implemented premultiplied alpha support: png_set_alpha_mode API Version 1.5.3beta07 [May 11, 2011] Added expand_16 support to the high level interface. Added named value and 'flag' gamma support to png_set_gamma. Made a minor change from the previous (unreleased) ABI/API to hide the exact value used for Macs - it's not a good idea to embed this in the ABI! Moved macro definitions for PNG_HAVE_IHDR, PNG_HAVE_PLTE, and PNG_AFTER_IDAT from pngpriv.h to png.h because they must be visible to applications that call png_set_unknown_chunks(). Check for up->location !PNG_AFTER_IDAT when writing unknown chunks before IDAT. Version 1.5.3beta08 [May 16, 2011] Improved "pngvalid --speed" to exclude more of pngvalid from the time. Documented png_set_alpha_mode(), other changes in libpng.3/libpng-manual.txt The cHRM chunk now sets the defaults for png_set_rgb_to_gray() (when negative parameters are supplied by the caller), while in the absence of cHRM sRGB/Rec 709 values are still used. This introduced a divide-by-zero bug in png_handle_cHRM(). The bKGD chunk no longer overwrites the background value set by png_set_background(), allowing the latter to be used before the file header is read. It never performed any useful function to override the default anyway. Added memory overwrite and palette image checks to pngvalid.c Previously palette image code was poorly checked. Since the transformation code has a special palette path in most cases this was a severe weakness. Minor cleanup and some extra checking in pngrutil.c and pngrtran.c. When expanding an indexed image, always expand to RGBA if transparency is present. Version 1.5.3beta09 [May 17, 2011] Reversed earlier 1.5.3 change of transformation order; move png_expand_16 back where it was. The change doesn't work because it requires 16-bit gamma tables when the code only generates 8-bit ones. This fails silently; the libpng code just doesn't do any gamma correction. Moving the tests back leaves the old, inaccurate, 8-bit gamma calculations, but these are clearly better than none! Version 1.5.3beta10 [May 20, 2011] png_set_background() and png_expand_16() did not work together correctly. This problem is present in 1.5.2; if png_set_background is called with need_expand false and the matching 16 bit color libpng erroneously just treats it as an 8-bit color because of where png_do_expand_16 is in the transform list. This simple fix reduces the supplied colour to 8-bits, so it gets smashed, but this is better than the current behavior. Added tests for expand16, more fixes for palette image tests to pngvalid. Corrects the code for palette image tests and disables attempts to validate palette colors. Version 1.5.3rc01 [June 3, 2011] No changes. Version 1.5.3rc02 [June 8, 2011] Fixed uninitialized memory read in png_format_buffer() (Bug report by Frank Busse, CVE-2011-2501, related to CVE-2004-0421). Version 1.5.3beta11 [June 11, 2011] Fixed png_handle_sCAL which is broken in 1.5. This fixes CVE 2011-2692. Added sCAL to pngtest.png Revised documentation about png_set_user_limits() to say that it also affects png writing. Revised handling of png_set_user_limits() so that it can increase the limit beyond the PNG_USER_WIDTH|HEIGHT_MAX; previously it could only reduce it. Make the 16-to-8 scaling accurate. Dividing by 256 with no rounding is wrong (high by one) 25% of the time. Dividing by 257 with rounding is wrong in 128 out of 65536 cases. Getting the right answer all the time without division is easy. Added "_SUPPORTED" to the PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION macro. Added projects/owatcom, an IDE project for OpenWatcom to replace scripts/makefile.watcom. This project works with OpenWatcom 1.9. The IDE autogenerates appropriate makefiles (libpng.mk) for batch processing. The project is configurable, unlike the Visual Studio project, so long as the developer has an awk. Changed png_set_gAMA to limit the gamma value range so that the inverse of the stored value cannot overflow the fixed point representation, and changed other things OpenWatcom warns about. Revised pngvalid.c to test PNG_ALPHA_MODE_SUPPORTED correctly. This allows pngvalid to build when ALPHA_MODE is not supported, which is required if it is to build on libpng 1.4. Removed string/memory macros that are no longer used and are not necessarily fully supportable, particularly png_strncpy and png_snprintf. Added log option to pngvalid.c and attempted to improve gamma messages. Version 1.5.3 [omitted] People found the presence of a beta release following an rc release to be confusing; therefore we bump the version to libpng-1.5.4beta01 and there will be no libpng-1.5.3 release. Version 1.5.4beta01 [June 14, 2011] Made it possible to undefine PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED to get the same (inaccurate) output as libpng-1.5.2 and earlier. Moved definitions of PNG_HAVE_IHDR, PNG_AFTER_IDAT, and PNG_HAVE_PLTE outside of an unknown-chunk block in png.h because they are also needed for other uses. Version 1.5.4beta02 [June 14, 2011] Fixed and clarified LEGACY 16-to-8 scaling code. Added png_set_chop_16() API, to match inaccurate results from previous libpng versions. Removed the ACCURATE and LEGACY options (they are no longer useable) Use the old scaling method for background if png_set_chop_16() was called. Made png_set_chop_16() API removeable by disabling PNG_CHOP_16_TO_8_SUPPORTED Version 1.5.4beta03 [June 15, 2011] Fixed a problem in png_do_expand_palette() exposed by optimization in 1.5.3beta06 Also removed a spurious and confusing "trans" member ("trans") from png_info. The palette expand optimization prevented expansion to an intermediate RGBA form if tRNS was present but alpha was marked to be stripped; this exposed a check for tRNS in png_do_expand_palette() which is inconsistent with the code elsewhere in libpng. Correction to the expand_16 code; removed extra instance of png_set_scale_16_to_8 from pngpriv.h Version 1.5.4beta04 [June 16, 2011] Added a missing "#ifdef PNG_READ_BACKGROUND_SUPPORTED/#endif" in pngrtran.c Added PNG_TRANSFORM_CHOP_16 to the high-level read transforms. Made PNG_READ_16_TO_8_ACCURATE_SCALE configurable again. If this is not enabled, png_set_strip_16() and png_do_scale_16_to_8() aren't built. Revised contrib/visupng, gregbook, and pngminim to demonstrate chop_16_to_8 Version 1.5.4beta05 [June 16, 2011] Renamed png_set_strip_16() to png_set_scale_16() and renamed png_set_chop_16() to png_set_strip(16) in an attempt to minimize the behavior changes between libpng14 and libpng15. Version 1.5.4beta06 [June 18, 2011] Fixed new bug that was causing both strip_16 and scale_16 to be applied. Version 1.5.4beta07 [June 19, 2011] Fixed pngvalid, simplified macros, added checking for 0 in sCAL. The ACCURATE scale macro is no longer defined in 1.5 - call the png_scale_16_to_8 API. Made sure that PNG_READ_16_TO_8 is still defined if the png_strip_16_to_8 API is present. png_check_fp_number now maintains some state so that positive, negative and zero values are identified. sCAL uses these to be strictly spec conformant. Version 1.5.4beta08 [June 23, 2011] Fixed pngvalid if ACCURATE_SCALE is defined. Updated scripts/pnglibconf.h.prebuilt. Version 1.5.4rc01 [June 30, 2011] Define PNG_ALLOCATED to "restrict" only if MSC_VER >= 1400. Version 1.5.4 [July 7, 2011] No changes. Version 1.5.5beta01 [July 13, 2011] Fixed some typos and made other minor changes in the manual. Updated contrib/pngminus/makefile.std (Samuli Souminen) Version 1.5.5beta02 [July 14, 2011] Revised Makefile.am and Makefile.in to look in the right directory for pnglibconf.h.prebuilt Version 1.5.5beta03 [July 27, 2011] Enabled compilation with g++ compiler. This compiler does not recognize the file extension, so it always compiles with C++ rules. Made minor changes to pngrutil.c to cast results where C++ expects it but C does not. Minor editing of libpng.3 and libpng-manual.txt. Version 1.5.5beta04 [July 29, 2011] Revised CMakeLists.txt (Clifford Yapp) Updated commentary about the png_rgb_to_gray() default coefficients in the manual and in pngrtran.c Version 1.5.5beta05 [August 17, 2011] Prevent unexpected API exports from non-libpng DLLs on Windows. The "_DLL" is removed from the test of whether a DLL is being built (this erroneously caused the libpng APIs to be marked as DLL exports in static builds under Microsoft Visual Studio). Almost all of the libpng building configuration is moved from pngconf.h to pngpriv.h, but PNG_DLL_EXPORT remains in pngconf.h, though, so that it is colocated with the import definition (it is no longer used anywhere in the installed headers). The VStudio project definitions have been cleaned up: "_USRDLL" has been removed from the static library builds (this was incorrect), and PNG_USE_DLL has been added to pngvalid to test the functionality (pngtest does not supply it, deliberately). The spurious "_EXPORTS" has been removed from the libpng build (all these errors were a result of copy/paste between project configurations.) Added new types and internal functions for CIE RGB end point handling to pngpriv.h (functions yet to be implemented). Version 1.5.5beta06 [August 26, 2011] Ensure the CMAKE_LIBRARY_OUTPUT_DIRECTORY is set in CMakeLists.txt (Clifford Yap) Fixes to rgb_to_gray and cHRM XYZ APIs (John Bowler): The rgb_to_gray code had errors when combined with gamma correction. Some pixels were treated as true grey when they weren't and such pixels and true grey ones were not gamma corrected (the original value of the red component was used instead). APIs to get and set cHRM using color space end points have been added and the rgb_to_gray code that defaults based on cHRM, and the divide-by-zero bug in png_handle_cHRM (CERT VU#477046, CVE-2011-3328, introduced in 1.5.4) have been corrected. A considerable number of tests has been added to pngvalid for the rgb_to_gray transform. Arithmetic errors in rgb_to_gray whereby the calculated gray value was truncated to the bit depth rather than rounded have been fixed except in the 8-bit non-gamma-corrected case (where consistency seems more important than correctness.) The code still has considerable inaccuracies in the 8-bit case because 8-bit linear arithmetic is used. Version 1.5.5beta07 [September 7, 2011] Added "$(ARCH)" option to makefile.darwin Added SunOS support to configure.ac and Makefile.am Changed png_chunk_benign_error() to png_warning() in png.c, in png_XYZ_from_xy_checked(). Version 1.5.5beta08 [September 10, 2011] Fixed 64-bit compilation errors (gcc). The errors fixed relate to conditions where types that are 32 bits in the GCC 32-bit world (uLong and png_size_t) become 64 bits in the 64-bit world. This produces potential truncation errors which the compiler correctly flags. Relocated new HAVE_SOLARIS_LD definition in configure.ac Constant changes for 64-bit compatibility (removal of L suffixes). The 16-bit cases still use "L" as we don't have a 16-bit test system. Version 1.5.5rc01 [September 15, 2011] Removed "L" suffixes in pngpriv.h Version 1.5.5 [September 22, 2011] No changes. Version 1.5.6beta01 [September 22, 2011] Fixed some 64-bit type conversion warnings in pngrtran.c Moved row_info from png_struct to a local variable. The various interlace mask arrays have been made into arrays of bytes and made PNG_CONST and static (previously some arrays were marked PNG_CONST and some weren't). Additional checks have been added to the transform code to validate the pixel depths after the transforms on both read and write. Removed some redundant code from pngwrite.c, in png_destroy_write_struct(). Changed chunk reading/writing code to use png_uint_32 instead of png_byte[4]. This removes the need to allocate temporary strings for chunk names on the stack in the read/write code. Unknown chunk handling still uses the string form because this is exposed in the API. Version 1.5.6beta02 [September 26, 2011] Added a note in the manual the png_read_update_info() must be called only once with a particular info_ptr. Fixed a typo in the definition of the new PNG_STRING_FROM_CHUNK(s,c) macro. Version 1.5.6beta03 [September 28, 2011] Revised test-pngtest.sh to report FAIL when pngtest fails. Added "--strict" option to pngtest, to report FAIL when the failure is only because the resulting valid files are different. Revised CMakeLists.txt to work with mingw and removed some material from CMakeLists.txt that is no longer useful in libpng-1.5. Version 1.5.6beta04 [October 5, 2011] Fixed typo in Makefile.in and Makefile.am ("-M Wl" should be "-M -Wl")." Version 1.5.6beta05 [October 12, 2011] Speed up png_combine_row() for interlaced images. This reduces the generality of the code, allowing it to be optimized for Adam7 interlace. The masks passed to png_combine_row() are now generated internally, avoiding some code duplication and localizing the interlace handling somewhat. Align png_struct::row_buf - previously it was always unaligned, caused by a bug in the code that attempted to align it; the code needs to subtract one from the pointer to take account of the filter byte prepended to each row. Optimized png_combine_row() when rows are aligned. This gains a small percentage for 16-bit and 32-bit pixels in the typical case where the output row buffers are appropriately aligned. The optimization was not previously possible because the png_struct buffer was always misaligned. Fixed bug in png_write_chunk_header() debug print, introduced in 1.5.6beta01. Version 1.5.6beta06 [October 17, 2011] Removed two redundant tests for uninitialized row. Fixed a relatively harmless memory overwrite in compressed text writing with a 1 byte zlib buffer. Add ability to call png_read_update_info multiple times to pngvalid.c. Fixes for multiple calls to png_read_update_info. These fixes attend to most of the errors revealed in pngvalid, however doing the gamma work twice results in inaccuracies that can't be easily fixed. There is now a warning in the code if this is going to happen. Turned on multiple png_read_update_info in pngvalid transform tests. Prevent libpng from overwriting unused bits at the end of the image when it is not byte aligned, while reading. Prior to libpng-1.5.6 libpng would overwrite the partial byte at the end of each row if the row width was not an exact multiple of 8 bits and the image is not interlaced. Version 1.5.6beta07 [October 21, 2011] Made png_ptr->prev_row an aligned pointer into png_ptr->big_prev_row (Mans Rullgard). Version 1.5.6rc01 [October 26, 2011] Changed misleading "Missing PLTE before cHRM" warning to "Out of place cHRM" Version 1.5.6rc02 [October 27, 2011] Added LSR() macro to defend against buggy compilers that evaluate non-taken code branches and complain about out-of-range shifts. Version 1.5.6rc03 [October 28, 2011] Renamed the LSR() macro to PNG_LSR() and added PNG_LSL() macro. Fixed compiler warnings with Intel and MSYS compilers. The logical shift fix for Microsoft Visual C is required by other compilers, so this enables that fix for all compilers when using compile-time constants. Under MSYS 'byte' is a name declared in a system header file, so we changed the name of a local variable to avoid the warnings that result. Added #define PNG_ALIGN_TYPE PNG_ALIGN_NONE to contrib/pngminim/*/pngusr.h Version 1.5.6 [November 3, 2011] No changes. Version 1.5.7beta01 [November 4, 2011] Added support for ARM processor, when decoding all PNG up-filtered rows and any other-filtered rows with 3 or 4 bytes per pixel (Mans Rullgard). Fixed bug in pngvalid on early allocation failure; fixed type cast in pngmem.c; pngvalid would attempt to call png_error() if the allocation of a png_struct or png_info failed. This would probably have led to a crash. The pngmem.c implementation of png_malloc() included a cast to png_size_t which would fail on large allocations on 16-bit systems. Fix for the preprocessor of the Intel C compiler. The preprocessor splits adjacent @ signs with a space; this changes the concatenation token from @-@-@ to PNG_JOIN; that should work with all compiler preprocessors. Paeth filter speed improvements from work by Siarhei Siamashka. This changes the 'Paeth' reconstruction function to improve the GCC code generation on x86. The changes are only part of the suggested ones; just the changes that definitely improve speed and remain simple. The changes also slightly increase the clarity of the code. Version 1.5.7beta02 [November 11, 2011] Check compression_type parameter in png_get_iCCP and remove spurious casts. The compression_type parameter is always assigned to, so must be non-NULL. The cast of the profile length potentially truncated the value unnecessarily on a 16-bit int system, so the cast of the (byte) compression type to (int) is specified by ANSI-C anyway. Fixed FP division by zero in pngvalid.c; the 'test_pixel' code left the sBIT fields in the test pixel as 0, which resulted in a floating point division by zero which was irrelevant but causes systems where FP exceptions cause a crash. Added code to pngvalid to turn on FP exceptions if the appropriate glibc support is there to ensure this is tested in the future. Updated scripts/pnglibconf.mak and scripts/makefile.std to handle the new PNG_JOIN macro. Added versioning to pnglibconf.h comments. Simplified read/write API initial version; basic read/write tested on a variety of images, limited documentation (in the header file.) Installed more accurate linear to sRGB conversion tables. The slightly modified tables reduce the number of 16-bit values that convert to an off-by-one 8-bit value. The "makesRGB.c" code that was used to generate the tables is now in a contrib/sRGBtables sub-directory. Version 1.5.7beta03 [November 17, 2011] Removed PNG_CONST from the sRGB table declarations in pngpriv.h and png.c Added run-time detection of NEON support. Added contrib/libtests; includes simplified API test and timing test and a color conversion utility for rapid checking of failed 'pngstest' results. Multiple transform bug fixes plus a work-round for double gamma correction. libpng does not support more than one transform that requires linear data at once - if this is tried typically the results is double gamma correction. Since the simplified APIs can need rgb to gray combined with a compose operation it is necessary to do one of these outside the main libpng transform code. This check-in also contains fixes to various bugs in the simplified APIs themselves and to some bugs in compose and rgb to gray (on palette) itself. Fixes for C++ compilation using g++ When libpng source is compiled using g++. The compiler imposes C++ rules on the C source; thus it is desirable to make the source work with either C or C++ rules without throwing away useful error information. This change adds png_voidcast to allow C semantic (void*) cases or the corresponding C++ static_cast operation, as appropriate. Added --noexecstack to assembler file compilation. GCC does not set this on assembler compilation, even though it does on C compilation. This creates security issues if assembler code is enabled; the work-around is to set it by default in the flags for $(CCAS) Work around compilers that don't support declaration of const data. Some compilers fault 'extern const' data declarations (because the data is not initialized); this turns on const-ness only for compilers where this is known to work. Version 1.5.7beta04 [November 17, 2011] Since the gcc driver does not recognize the --noexecstack flag, we must use the -Wa prefix to have it passed through to the assembler. Also removed a duplicate setting of this flag. Added files that were omitted from the libpng-1.5.7beta03 zip distribution. Version 1.5.7beta05 [November 25, 2011] Removed "zTXt" from warning in generic chunk decompression function. Validate time settings passed to png_set_tIME() and png_convert_to_rfc1123() (Frank Busse). Note: This prevented CVE-2015-7981 from affecting libpng-1.5.7 and later. Added MINGW support to CMakeLists.txt Reject invalid compression flag or method when reading the iTXt chunk. Backed out 'simplified' API changes. The API seems too complex and there is a lack of consensus or enthusiasm for the proposals. The API also reveals significant bugs inside libpng (double gamma correction and the known bug of being unable to retrieve a corrected palette). It seems better to wait until the bugs, at least, are corrected. Moved pngvalid.c into contrib/libtests Rebuilt Makefile.in, configure, etc., with autoconf-2.68 Version 1.5.7rc01 [December 1, 2011] Replaced an "#if" with "#ifdef" in pngrtran.c Revised #if PNG_DO_BC block in png.c (use #ifdef and add #else) Version 1.5.7rc02 [December 5, 2011] Revised project files and contrib/pngvalid/pngvalid.c to account for the relocation of pngvalid into contrib/libtests. Revised pngconf.h to use " __declspec(restrict)" only when MSC_VER >= 1400, as in libpng-1.5.4. Put CRLF line endings in the owatcom project files. Version 1.5.7rc03 [December 7, 2011] Updated CMakeLists.txt to account for the relocation of pngvalid.c Version 1.5.7 [December 15, 2011] Minor fixes to pngvalid.c for gcc 4.6.2 compatibility to remove warnings reported by earlier versions. Fixed minor memset/sizeof errors in pngvalid.c. Version 1.6.0beta01 [December 15, 2011] Removed machine-generated configure files from the GIT repository (they will continue to appear in the tarball distributions and in the libpng15 and earlier GIT branches). Restored the new 'simplified' API, which was started in libpng-1.5.7beta02 but later deleted from libpng-1.5.7beta05. Added example programs for the new 'simplified' API. Added ANSI-C (C90) headers and require them, and take advantage of the change. Also fixed some of the projects/* and contrib/* files that needed updates for libpng16 and the move of pngvalid.c. With this change the required ANSI-C header files are assumed to exist: the implementation must provide float.h, limits.h, stdarg.h and stddef.h and libpng relies on limits.h and stddef.h existing and behaving as defined (the other two required headers aren't used). Non-ANSI systems that don't have stddef.h or limits.h will have to provide an appropriate fake containing the relevant types and #defines. Dropped support for 16-bit platforms. The use of FAR/far has been eliminated and the definition of png_alloc_size_t is now controlled by a flag so that 'small size_t' systems can select it if necessary. Libpng 1.6 may not currently work on such systems -- it seems likely that it will ask 'malloc' for more than 65535 bytes with any image that has a sufficiently large row size (rather than simply failing to read such images). New tools directory containing tools used to generate libpng code. Fixed race conditions in parallel make builds. With higher degrees of parallelism during 'make' the use of the same temporary file names such as 'dfn*' can result in a race where a temporary file from one arm of the build is deleted or overwritten in another arm. This changes the temporary files for suffix rules to always use $* and ensures that the non-suffix rules use unique file names. Version 1.6.0beta02 [December 21, 2011] Correct configure builds where build and source directories are separate. The include path of 'config.h' was erroneously made relative in pngvalid.c in libpng 1.5.7. Version 1.6.0beta03 [December 22, 2011] Start-up code size improvements, error handler flexibility. These changes alter how the tricky allocation of the initial png_struct and png_info structures are handled. png_info is now handled in pretty much the same way as everything else, except that the allocations handle NULL return silently. png_struct is changed in a similar way on allocation and on deallocation a 'safety' error handler is put in place (which should never be required). The error handler itself is changed to permit mismatches in the application and libpng error buffer size; however, this means a silent change to the API to return the jmp_buf if the size doesn't match the size from the libpng compilation; libpng now allocates the memory and this may fail. Overall these changes result in slight code size reductions; however, this is a reduction in code that is always executed so is particularly valuable. Overall on a 64-bit system the libpng DLL decreases in code size by 1733 bytes. pngerror.o increases in size by about 465 bytes because of the new functionality. Added png_convert_to_rfc1123_buffer() and deprecated png_convert_to_rfc1123() to avoid including a spurious buffer in the png_struct. Version 1.6.0beta04 [December 30, 2011] Regenerated configure scripts with automake-1.11.2 Eliminated png_info_destroy(). It is now used only in png.c and only calls one other internal function and memset(). Enabled png_get_sCAL_fixed() if floating point APIs are enabled. Previously it was disabled whenever internal fixed point arithmetic was selected, which meant it didn't exist even on systems where FP was available but not preferred. Added pngvalid.c compile time checks for const APIs. Implemented 'restrict' for png_info and png_struct. Because of the way libpng works both png_info and png_struct are always accessed via a single pointer. This means adding C99 'restrict' to the pointer gives the compiler some opportunity to optimize the code. This change allows that. Moved AC_MSG_CHECKING([if libraries can be versioned]) later to the proper location in configure.ac (Gilles Espinasse). Changed png_memcpy to C assignment where appropriate. Changed all those uses of png_memcpy that were doing a simple assignment to assignments (all those cases where the thing being copied is a non-array C L-value). Added some error checking to png_set_*() routines. Removed the reference to the non-exported function png_memcpy() from example.c. Fixed the Visual C 64-bit build - it requires jmp_buf to be aligned, but it had become misaligned. Revised contrib/pngminus/pnm2png.c to avoid warnings when png_uint_32 and unsigned long are of different sizes. Version 1.6.0beta05 [January 15, 2012] Updated manual with description of the simplified API (copied from png.h) Fix bug in pngerror.c: some long warnings were being improperly truncated (CVE-2011-3464, bug introduced in libpng-1.5.3beta05). Version 1.6.0beta06 [January 24, 2012] Added palette support to the simplified APIs. This commit changes some of the macro definitions in png.h, app code may need corresponding changes. Increased the formatted warning buffer to 192 bytes. Added color-map support to simplified API. This is an initial version for review; the documentation has not yet been updated. Fixed Min/GW uninstall to remove libpng.dll.a Version 1.6.0beta07 [January 28, 2012] Eliminated Intel icc/icl compiler warnings. The Intel (GCC derived) compiler issues slightly different warnings from those issued by the current versions of GCC. This eliminates those warnings by adding/removing casts and small code rewrites. Updated configure.ac from autoupdate: added --enable-werror option. Also some layout regularization and removal of introduced tab characters (replaced with 3-character indentation). Obsolete macros identified by autoupdate have been removed; the replacements are all in 2.59 so the pre-req hasn't been changed. --enable-werror checks for support for -Werror (or the given argument) in the compiler. This mimics the gcc configure option by allowing -Werror to be turned on safely; without the option the tests written in configure itself fail compilation because they cause compiler warnings. Rewrote autogen.sh to run autoreconf instead of running tools one-by-one. Conditionalize the install rules for MINGW and CYGWIN in CMakeLists.txt and set CMAKE_LIBRARY_OUTPUT_DIRECTORY to "lib" on all platforms (C. Yapp). Freeze libtool files in the 'scripts' directory. This version of autogen.sh attempts to dissuade people from running it when it is not, or should not, be necessary. In fact, autogen.sh does not work when run in a libpng directory extracted from a tar distribution anymore. You must run it in a GIT clone instead. Added two images to contrib/pngsuite (1-bit and 2-bit transparent grayscale), and renamed three whose names were inconsistent with those in pngsuite/README.txt. Version 1.6.0beta08 [February 1, 2012] Fixed Image::colormap misalignment in pngstest.c Check libtool/libtoolize version number (2.4.2) in configure.ac Divide test-pngstest.sh into separate pngstest runs for basic and transparent images. Moved automake options to AM_INIT_AUTOMAKE in configure.ac Added color-tests, silent-rules (Not yet implemented in Makefile.am) and version checking to configure.ac Improved pngstest speed by not doing redundant tests and add const to the background parameter of png_image_finish_read. The --background option is now done automagically only when required, so that command-line option no longer exists. Cleaned up pngpriv.h to consistently declare all functions and data. Also eliminated PNG_CONST_DATA, which is apparently not needed but we can't be sure until it is gone. Added symbol prefixing that allows all the libpng external symbols to be prefixed (suggested by Reuben Hawkins). Updated "ftbb*.png" list in the owatcom and vstudio projects. Fixed 'prefix' builds on clean systems. The generation of pngprefix.h should not require itself. Updated INSTALL to explain that autogen.sh must be run in a GIT clone, not in a libpng directory extracted from a tar distribution. Version 1.6.0beta09 [February 1, 2012] Reverted the prebuilt configure files to libpng-1.6.0beta05 condition. Version 1.6.0beta10 [February 3, 2012] Added Z_SOLO for zlib-1.2.6+ and correct pngstest tests Updated list of test images in CMakeLists.txt Updated the prebuilt configure files to current condition. Revised INSTALL information about autogen.sh; it works in tar distributions. Version 1.6.0beta11 [February 16, 2012] Fix character count in pngstest command in projects/owatcom/pngstest.tgt Revised test-pngstest.sh to report PASS/FAIL for each image. Updated documentation about the simplified API. Corrected estimate of error in libpng png_set_rgb_to_gray API. The API is extremely inaccurate for sRGB conversions because it uses an 8-bit intermediate linear value and it does not use the sRGB transform, so it suffers from the known instability in gamma transforms for values close to 0 (see Poynton). The net result is that the calculation has a maximum error of 14.99/255; 0.5/255^(1/2.2). pngstest now uses 15 for the permitted 8-bit error. This may still not be enough because of arithmetic error. Removed some unused arrays (with #ifdef) from png_read_push_finish_row(). Fixed a memory overwrite bug in simplified read of RGB PNG with non-linear gamma Also bugs in the error checking in pngread.c and changed quite a lot of the checks in pngstest.c to be correct; either correctly written or not over-optimistic. The pngstest changes are insufficient to allow all possible RGB transforms to be passed; pngstest cmppixel needs to be rewritten to make it clearer which errors it allows and then changed to permit known inaccuracies. Removed tests for no-longer-used *_EMPTY_PLTE_SUPPORTED from pngstruct.h Fixed fixed/float API export conditionals. 1) If FIXED_POINT or FLOATING_POINT options were switched off, png.h ended up with lone ';' characters. This is not valid ANSI-C outside a function. The ';' characters have been moved inside the definition of PNG_FP_EXPORT and PNG_FIXED_EXPORT. 2) If either option was switched off, the declaration of the corresponding functions were completely omitted, even though some of them are still used internally. The result is still valid, but produces warnings from gcc with some warning options (including -Wall). The fix is to cause png.h to declare the functions with PNG_INTERNAL_FUNCTION when png.h is included from pngpriv.h. Check for invalid palette index while reading paletted PNG. When one is found, issue a warning and increase png_ptr->num_palette accordingly. Apps are responsible for checking to see if that happened. Version 1.6.0beta12 [February 18, 2012] Do not increase num_palette on invalid_index. Relocated check for invalid palette index to pngrtran.c, after unpacking the sub-8-bit pixels. Fixed CVE-2011-3026 buffer overrun bug. This bug was introduced when iCCP chunk support was added at libpng-1.0.6. Deal more correctly with the test on iCCP chunk length. Also removed spurious casts that may hide problems on 16-bit systems. Version 1.6.0beta13 [February 24, 2012] Eliminated redundant png_push_read_tEXt|zTXt|iTXt|unknown code from pngpread.c and use the sequential png_handle_tEXt, etc., in pngrutil.c; now that png_ptr->buffer is inaccessible to applications, the special handling is no longer useful. Added PNG_SAFE_LIMITS feature to pnglibconf.dfa, pngpriv.h, and new pngusr.dfa to reset the user limits to safe ones if PNG_SAFE_LIMITS is defined. To enable, use "CPPFLAGS=-DPNG_SAFE_LIMITS_SUPPORTED=1" on the configure command or put #define PNG_SAFE_LIMITS_SUPPORTED in pnglibconf.h.prebuilt and pnglibconf.h. Version 1.6.0beta14 [February 27, 2012] Added information about the new limits in the manual. Updated Makefile.in Version 1.6.0beta15 [March 2, 2012] Removed unused "current_text" members of png_struct and the png_free() of png_ptr->current_text from pngread.c Rewrote pngstest.c for substantial speed improvement. Fixed transparent pixel and 16-bit rgb tests in pngstest and removed a spurious check in pngwrite.c Added PNG_IMAGE_FLAG_FAST for the benefit of applications that store intermediate files, or intermediate in-memory data, while processing image data with the simplified API. The option makes the files larger but faster to write and read. pngstest now uses this by default; this can be disabled with the --slow option. Improved pngstest fine tuning of error numbers, new test file generator. The generator generates images that test the full range of sample values, allow the error numbers in pngstest to be tuned and checked. makepng also allows generation of images with extra chunks, although this is still work-in-progress. Added check for invalid palette index while reading. Fixed some bugs in ICC profile writing. The code should now accept all potentially valid ICC profiles and reject obviously invalid ones. It now uses png_error() to do so rather than casually writing a PNG without the necessary color data. Removed whitespace from the end of lines in all source files and scripts. Version 1.6.0beta16 [March 6, 2012] Relocated palette-index checking function from pngrutil.c to pngtrans.c Added palette-index checking while writing. Changed png_inflate() and calling routines to avoid overflow problems. This is an intermediate check-in that solves the immediate problems and introduces one performance improvement (avoiding a copy via png_ptr->zbuf.) Further changes will be made to make ICC profile handling more secure. Fixed build warnings (MSVC, GCC, GCC v3). Cygwin GCC with default options declares 'index' as a global, causing a warning if it is used as a local variable. GCC 64-bit warns about assigning a (size_t) (unsigned 64-bit) to an (int) (signed 32-bit). MSVC, however, warns about using the unary '-' operator on an unsigned value (even though it is well defined by ANSI-C to be ~x+1). The padding calculation was changed to use a different method. Removed the tests on png_ptr->pass. Added contrib/libtests/tarith.c to test internal arithmetic functions from png.c. This is a libpng maintainer program used to validate changes to the internal arithmetic functions. Made read 'inflate' handling like write 'deflate' handling. The read code now claims and releases png_ptr->zstream, like the write code. The bug whereby the progressive reader failed to release the zstream is now fixed, all initialization is delayed, and the code checks for changed parameters on deflate rather than always calling deflatedEnd/deflateInit. Validate the zTXt strings in pngvalid. Added code to validate the windowBits value passed to deflateInit2(). If the call to deflateInit2() is wrong a png_warning will be issued (in fact this is harmless, but the PNG data produced may be sub-optimal). Version 1.6.0beta17 [March 10, 2012] Fixed PNG_LIBPNG_BUILD_BASE_TYPE definition. Reject all iCCP chunks after the first, even if the first one is invalid. Deflate/inflate was reworked to move common zlib calls into single functions [rw]util.c. A new shared keyword check routine was also added and the 'zbuf' is no longer allocated on progressive read. It is now possible to call png_inflate() incrementally. A warning is no longer issued if the language tag or translated keyword in the iTXt chunk has zero length. If benign errors are disabled use maximum window on ancillary inflate. This works round a bug introduced in 1.5.4 where compressed ancillary chunks could end up with a too-small windowBits value in the deflate header. Version 1.6.0beta18 [March 16, 2012] Issue a png_benign_error() instead of png_warning() about bad palette index. In pngtest, treat benign errors as errors if "-strict" is present. Fixed an off-by-one error in the palette index checking function. Fixed a compiler warning under Cygwin (Windows-7, 32-bit system) Revised example.c to put text strings in a temporary character array instead of directly assigning string constants to png_textp members. This avoids compiler warnings when -Wwrite-strings is enabled. Added output flushing to aid debugging under Visual Studio. Unfortunately this is necessary because the VS2010 output window otherwise simply loses the error messages on error (they weren't flushed to the window before the process exited, apparently!) Added configuration support for benign errors and changed the read default. Also changed some warnings in the iCCP and sRGB handling from to benign errors. Configuration now makes read benign errors warnings and write benign errors to errors by default (thus changing the behavior on read). The simplified API always forces read benign errors to warnings (regardless of the system default, unless this is disabled in which case the simplified API can't be built.) Version 1.6.0beta19 [March 18, 2012] Work around for duplicate row start calls; added warning messages. This turns on PNG_FLAG_DETECT_UNINITIALIZED to detect app code that fails to call one of the 'start' routines (not enabled in libpng-1.5 because it is technically an API change, since it did normally work before.) It also makes duplicate calls to png_read_start_row (an internal function called at the start of the image read) benign, as they were before changes to use png_inflate_claim. Somehow webkit is causing this to happen; this is probably a mis-feature in the zlib changes so this commit is only a work-round. Removed erroneous setting of DETECT_UNINITIALIZED and added more checks. The code now does a png_error if an attempt is made to do the row initialization twice; this is an application error and it has serious consequences because the transform data in png_struct is changed by each call. Added application error reporting and added chunk names to read benign errors; also added --strict to pngstest - not enabled yet because a warning is produced. Avoid the double gamma correction warning in the simplified API. This allows the --strict option to pass in the pngstest checks Version 1.6.0beta20 [March 29, 2012] Changed chunk handler warnings into benign errors, incrementally load iCCP Added checksum-icc.c to contrib/tools Prevent PNG_EXPAND+PNG_SHIFT doing the shift twice. Recognize known sRGB ICC profiles while reading; prefer writing the iCCP profile over writing the sRGB chunk, controlled by the PNG_sRGB_PROFILE_CHECKS option. Revised png_set_text_2() to avoid potential memory corruption (fixes CVE-2011-3048, also known as CVE-2012-3425). Version 1.6.0beta21 [April 27, 2012] Revised scripts/makefile.darwin: use system zlib; remove quotes around architecture list; add missing ppc architecture; add architecture options to shared library link; don't try to create a shared lib based on missing RELEASE variable. Enable png_set_check_for_invalid_index() for both read and write. Removed #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED in pngpriv.h around declaration of png_handle_unknown(). Added -lssp_nonshared in a comment in scripts/makefile.freebsd and changed deprecated NOOBJ and NOPROFILE to NO_OBJ and NO_PROFILE. Version 1.6.0beta22 [May 23, 2012] Removed need for -Wno-cast-align with clang. clang correctly warns on alignment increasing pointer casts when -Wcast-align is passed. This fixes the cases that clang warns about either by eliminating the casts from png_bytep to png_uint_16p (pngread.c), or, for pngrutil.c where the cast is previously verified or pngstest.c where it is OK, by introducing new png_aligncast macros to do the cast in a way that clang accepts. Version 1.6.0beta23 [June 6, 2012] Revised CMakeLists.txt to not attempt to make a symlink under mingw. Made fixes for new optimization warnings from gcc 4.7.0. The compiler performs an optimization which is safe; however it then warns about it. Changing the type of 'palette_number' in pngvalid.c removes the warning. Do not depend upon a GCC feature macro being available for use in generating the linker mapfile symbol prefix. Improved performance of new do_check_palette_indexes() function (only update the value when it actually increases, move test for whether the check is wanted out of the function. Version 1.6.0beta24 [June 7, 2012] Don't check palette indexes if num_palette is 0 (as it can be in MNG files). Version 1.6.0beta25 [June 16, 2012] Revised png_set_keep_unknown_chunks() so num_chunks < 0 means ignore all unknown chunks and all known chunks except for IHDR, PLTE, tRNS, IDAT, and IEND. Previously it only meant ignore all unknown chunks, the same as num_chunks == 0. Revised png_image_skip_unused_chunks() to provide a list of chunks to be processed instead of a list of chunks to ignore. Revised contrib/gregbook/readpng2.c accordingly. Version 1.6.0beta26 [July 10, 2012] Removed scripts/makefile.cegcc from the *.zip and *.7z distributions; it depends on configure, which is not included in those archives. Moved scripts/chkfmt to contrib/tools. Changed "a+w" to "u+w" in Makefile.in to fix CVE-2012-3386. Version 1.6.0beta27 [August 11, 2012] Do not compile PNG_DEPRECATED, PNG_ALLOC and PNG_PRIVATE when __GNUC__ < 3. Do not use __restrict when GNUC is <= 3.1 Removed references to png_zalloc() and png_zfree() from the manual. Fixed configurations where floating point is completely disabled. Because of the changes to support symbol prefixing PNG_INTERNAL_FUNCTION declares floating point APIs during libpng builds even if they are completely disabled. This requires the png floating point types (png_double*) to be declared even though the functions are never actually defined. This change provides a dummy definition so that the declarations work, yet any implementation will fail to compile because of an incomplete type. Re-eliminated the use of strcpy() in pngtest.c. An unnecessary use of strcpy() was accidentally re-introduced in libpng16; this change replaces it with strncpy(). Eliminated use of png_sizeof(); use sizeof() instead. Use a consistent style for (sizeof type) and (sizeof (array)) Cleanup of png_set_filler(). This function does very different things on read and write. In libpng 1.6 the two cases can be distinguished and considerable code cleanup, and extra error checking, is possible. This makes calls on the write side that have no effect be ignored with a png_app_error(), which can be disabled in the app using png_set_benign_errors(), and removes the spurious use of usr_channels on the read side. Insist on autotools 1.12.1 for git builds because there are security issues with 1.12 and insisting on anything less would allow 1.12 to be used. Removed info_ptr->signature[8] from WRITE-only builds. Add some conditions for compiling png_fixed(). This is a small function but it requires "-lm" on some platforms. Cause pngtest --strict to fail on any warning from libpng (not just errors) and cause it not to fail at the comparison step if libpng lacks support for writing chunks that it reads from the input (currently only implemented for compressed text chunks). Make all three "make check" test programs work without READ or WRITE support. Now "make check" will succeed even if libpng is compiled with -DPNG_NO_READ or -DPNG_NO_WRITE. The tests performed are reduced, but the basic reading and writing of a PNG file is always tested by one or more of the tests. Consistently use strlen(), memset(), memcpy(), and memcmp() instead of the png_strlen(), png_memset(), png_memcpy(), and png_memcmp() macros. Removed the png_sizeof(), png_strlen(), png_memset(), png_memcpy(), and png_memcmp() macros. Work around gcc 3.x and Microsoft Visual Studio 2010 complaints. Both object to the split initialization of num_chunks. Version 1.6.0beta28 [August 29, 2012] Unknown handling fixes and clean up. This adds more correct option control of the unknown handling, corrects the pre-existing bug where the per-chunk 'keep' setting is ignored and makes it possible to skip IDAT chunks in the sequential reader (broken in earlier 1.6 versions). There is a new test program, test-unknown.c, which is a work in progress (not currently part of the test suite). Comments in the header files now explain how the unknown handling works. Allow fine grain control of unknown chunk APIs. This change allows png_set_keep_unknown_chunks() to be turned off if not required and causes both read and write to behave appropriately (on read this is only possible if the user callback is used to handle unknown chunks). The change also removes the support for storing unknown chunks in the info_struct if the only unknown handling enabled is via the callback, allowing libpng to be configured with callback reading and none of the unnecessary code. Corrected fix for unknown handling in pngtest. This reinstates the libpng handling of unknown chunks other than vpAg and sTER (including unsafe-to-copy chunks which were dropped before) and eliminates the repositioning of vpAg and sTER in pngtest.png by changing pngtest.png (so the chunks are where libpng would put them). Added "tunknown" test and corrected a logic error in png_handle_unknown() when SAVE support is absent. Moved the shell test scripts for contrib/libtests from the libpng top directory to contrib/libtests. png_handle_unknown() must always read or skip the chunk, if SAVE_UNKNOWN_CHUNKS is turned off *and* the application does not set a user callback an unknown chunk will not be read, leading to a read error, which was revealed by the "tunknown" test. Cleaned up and corrected ICC profile handling. contrib/libtests/makepng: corrected 'rgb' and 'gray' cases. profile_error messages could be truncated; made a correct buffer size calculation and adjusted pngerror.c appropriately. png_icc_check_* checking improved; changed the functions to receive the correct color type of the PNG on read or write and check that it matches the color space of the profile (despite what the comments said before, there is danger in assuming the app will cope correctly with an RGB profile on a grayscale image and, since it violates the PNG spec, allowing it is certain to produce inconsistent app behavior and might even cause app crashes.) Check that profiles contain the tags needed to process the PNG (tags all required by the ICC spec). Removed unused PNG_STATIC from pngpriv.h. Version 1.6.0beta29 [September 4, 2012] Fixed the simplified API example programs to add the *colormap parameter to several of he API and improved the error message if the version field is not set. Added contrib/examples/* to the *.zip and *.7z distributions. Updated simplified API synopses and description of the png_image structure in the manual. Made makepng and pngtest produce identical PNGs, add "--relaxed" option to pngtest. The "--relaxed" option turns off the benign errors that are enabled by default in pre-RC builds. makepng can now write ICC profiles where the length has not been extended to a multiple of 4, and pngtest now intercepts all libpng errors, allowing the previously-introduced "--strict test" on no warnings to actually work. Improved ICC profile handling including cHRM chunk generation and fixed Cygwin+MSVC build errors. The ICC profile handling now includes more checking. Several errors that caused rejection of the profile are now handled with a warning in such a way that the invalid profiles will be read by default in release (but not pre-RC) builds but will not be written by default. The easy part of handling the cHRM chunk is written, where the ICC profile contains the required data. The more difficult part plus guessing a gAMA value requires code to pass selected RGB values through the profile. Version 1.6.0beta30 [October 24, 2012] Changed ICC profile matrix/vector types to not depend on array type rules. By the ANSI-C standard the new types should be identical to the previous versions, and all known versions of gcc tested with the previous versions except for GCC-4.2.1 work with this version. The change makes the ANSI-C rule that const applied to an array of elements applies instead to the elements in the array moot by explicitly applying const to the base elements of the png_icc_matrix and png_icc_vector types. The accidental (harmless) 'const' previously applied to the parameters of two of the functions have also been removed. Added a work around for GCC 4.2 optimization bug. Marked the broken (bad white point) original HP sRGB profiles correctly and correct comments. Added -DZ_SOLO to contrib/pngminim/*/makefile to work with zlib-1.2.7 Use /MDd for vstudio debug builds. Also added pngunkown to the vstudio builds, fixed build errors and corrected a minor exit code error in pngvalid if the 'touch' file name is invalid. Add updated WARNING file to projects/vstudio from libpng 1.5/vstudio Fixed build when using #define PNG_NO_READ_GAMMA in png_do_compose() in pngrtran.c (Domani Hannes). Version 1.6.0beta31 [November 1, 2012] Undid the erroneous change to vstudio/pngvalid build in libpng-1.6.0beta30. Made pngvalid so that it will build outside the libpng source tree. Made builds -DPNG_NO_READ_GAMMA compile (the unit tests still fail). Made PNG_NO_READ_GAMMA switch off interfaces that depend on READ_GAMMA. Prior to 1.6.0 switching off READ_GAMMA did unpredictable things to the interfaces that use it (specifically, png_do_background in 1.4 would simply display composite for grayscale images but do composition with the incorrect arithmetic for color ones). In 1.6 the semantic of -DPNG_NO_READ_GAMMA is changed to simply disable any interface that depends on it; this obliges people who set it to consider whether they really want it off if they happen to use any of the interfaces in question (typically most users who disable it won't). Fixed GUIDs in projects/vstudio. Some were duplicated or missing, resulting in VS2010 having to update the files. Removed non-working ICC profile support code that was mostly added to libpng-1.6.0beta29 and beta30. There was too much code for too little gain; implementing full ICC color correction may be desirable but is left up to applications. Version 1.6.0beta32 [November 25, 2012] Fixed an intermittent SEGV in pngstest due to an uninitialized array element. Added the ability for contrib/libtests/makepng.c to make a PNG with just one color. This is useful for debugging pngstest color inaccuracy reports. Fixed error checking in the simplified write API (Olaf van der Spek) Made png_user_version_check() ok to use with libpng version 1.10.x and later. Version 1.6.0beta33 [December 15, 2012] Fixed typo in png.c (PNG_SET_CHUNK_MALLOC_MAX should be PNG_CHUNK_MALLOC_MAX) that causes the MALLOC_MAX limit not to work (John Bowler) Change png_warning() to png_app_error() in pngwrite.c and comment the fall-through condition. Change png_warning() to png_app_warning() in png_write_tRNS(). Rearranged the ARM-NEON optimizations: Isolated the machine specific code to the hardware subdirectory and added comments to pngrutil.c so that implementors of other optimizations know what to do. Fixed cases of unquoted DESTDIR in Makefile.am Rebuilt Makefile.in, etc., with autoconf-2.69 and automake-1.12.5. Version 1.6.0beta34 [December 19, 2012] Cleaned up whitespace in the synopsis portion of the manpage "libpng.3" Disassembled the version number in scripts/options.awk (necessary for building on SunOs). Version 1.6.0beta35 [December 23, 2012] Made default Zlib compression settings be configurable. This adds #defines to pnglibconf.h to control the defaults. Fixed Windows build issues, enabled ARM compilation. Various warnings issued by earlier versions of GCC fixed for Cygwin and Min/GW (which both use old GCCs.) ARM support is enabled by default in zlib.props (unsupported by Microsoft) and ARM compilation is made possible by deleting the check for x86. The test programs cannot be run because they are not signed. Version 1.6.0beta36 [January 2, 2013] Discontinued distributing libpng-1.x.x.tar.bz2. Discontinued distributing libpng-1.7.0-1.6.0-diff.txt and similar. Rebuilt configure with autoconf-2.69 (inadvertently not done in beta33) Fixed 'make distcheck' on SUN OS - libpng.so was not being removed Version 1.6.0beta37 [January 10, 2013] Fixed conceivable but difficult to repro overflow. Also added two test programs to generate and test a PNG which should have the problem. Version 1.6.0beta39 [January 19, 2013] Again corrected attempt at overflow detection in png_set_unknown_chunks() (CVE-2013-7353). Added overflow detection in png_set_sPLT() and png_set_text_2() (CVE-2013-7354). Version 1.6.0beta40 [January 20, 2013] Use consistent handling of overflows in text, sPLT and unknown png_set_* APIs Version 1.6.0rc01 [January 26, 2013] No changes. Version 1.6.0rc02 [February 4, 2013] Added png_get_palette_max() function. Version 1.6.0rc03 [February 5, 2013] Fixed the png_get_palette_max API. Version 1.6.0rc04 [February 7, 2013] Turn serial tests back on (recently turned off by autotools upgrade). Version 1.6.0rc05 [February 8, 2013] Update manual about png_get_palette_max(). Version 1.6.0rc06 [February 9, 2013] Fixed missing dependency in --prefix builds The intermediate internal 'prefix.h' file can only be generated correctly after pnglibconf.h, however the dependency was not in Makefile.am. The symptoms are unpredictable depending on the order make chooses to build pngprefix.h and pnglibconf.h, often the error goes unnoticed because there is a system pnglibconf.h to use instead. Version 1.6.0rc07 [February 10, 2013] Enclosed the new png_get_palette_max in #ifdef PNG_GET_PALETTE_MAX_SUPPORTED block, and revised pnglibconf.h and pnglibconf.h.prebuilt accordingly. Version 1.6.0rc08 [February 10, 2013] Fix typo in png.h #ifdef Version 1.6.0 [February 14, 2013] No changes. Version 1.6.1beta01 [February 16, 2013] Made symbol prefixing work with the ARM neon optimizations. Also allow pngpriv.h to be included for preprocessor definitions only, so it can be used in non-C/C++ files. Back ported from libpng 1.7. Made sRGB check numbers consistent. Ported libpng 1.5 options.awk/dfn file handling to 1.6, fixed one bug. Removed cc -E workround, corrected png_get_palette_max API Tested on SUN OS cc 5.9, which demonstrates the tokenization problem previously avoided by using /lib/cpp. Since all .dfn output is now protected in double quotes unless it is to be macro substituted the fix should work everywhere. Enabled parallel tests - back ported from libpng-1.7. scripts/pnglibconf.dfa formatting improvements back ported from libpng17. Fixed a race condition in the creation of the build 'scripts' directory while building with a parallel make. Use approved/supported Android method to check for NEON, use Linux/POSIX 1003.1 API to check /proc/self/auxv avoiding buffer allocation and other library calls (ported from libpng15). Version 1.6.1beta02 [February 19, 2013] Use parentheses more consistently in "#if defined(MACRO)" tests. Folded long lines. Reenabled code to allow zero length PLTE chunks for MNG. Version 1.6.1beta03 [February 22, 2013] Fixed ALIGNED_MEMORY support. Added a new configure option: --enable-arm-neon=always will stop the run-time checks. New checks within arm/arm_init.c will cause the code not to be compiled unless __ARM_NEON__ is set. This should make it fail safe (if someone asks for it on then the build will fail if it can't be done.) Updated the INSTALL document. Version 1.6.1beta04 [February 27, 2013] Revised INSTALL to recommend using CPPFLAGS instead of INCLUDES. Revised scripts/makefile.freebsd to respect ZLIBLIB and ZLIBINC. Revised scripts/dfn.awk to work with the buggy MSYS awk that has trouble with CRLF line endings. Version 1.6.1beta05 [March 1, 2013] Avoid a possible memory leak in contrib/gregbook/readpng.c Version 1.6.1beta06 [March 4, 2013] Better documentation of unknown handling API interactions. Corrected Android builds and corrected libpng.vers with symbol prefixing. It also makes those tests compile and link on Android. Added an API png_set_option() to set optimization options externally, providing an alternative and general solution for the non-portable run-time tests used by the ARM Neon code, using the PNG_ARM_NEON option. The order of settings vs options in pnglibconf.h is reversed to allow settings to depend on options and options can now set (or override) the defaults for settings. Version 1.6.1beta07 [March 7, 2013] Corrected simplified API default gamma for color-mapped output, added a flag to change default. In 1.6.0 when the simplified API was used to produce color-mapped output from an input image with no gamma information the gamma assumed for the input could be different from that assumed for non-color-mapped output. In particular 16-bit depth input files were assumed to be sRGB encoded, whereas in the 'direct' case they were assumed to have linear data. This was an error. The fix makes the simplified API treat all input files the same way and adds a new flag to the png_image::flags member to allow the application/user to specify that 16-bit files contain sRGB data rather than the default linear. Fixed bugs in the pngpixel and makepng test programs. Version 1.6.1beta08 [March 7, 2013] Fixed CMakelists.txt to allow building a single variant of the library (Claudio Bley): Introduced a PNG_LIB_TARGETS variable that lists all activated library targets. It is an error if this variable ends up empty, ie. you have to build at least one library variant. Made the *_COPY targets only depend on library targets actually being build. Use PNG_LIB_TARGETS to unify a code path. Changed the CREATE_SYMLINK macro to expect the full path to a file as the first argument. When symlinking the filename component of that path is determined and used as the link target. Use copy_if_different in the CREATE_SYMLINK macro. Version 1.6.1beta09 [March 13, 2013] Eliminated two warnings from the Intel C compiler. The warnings are technically valid, although a reasonable treatment of division would show it to be incorrect. Version 1.6.1rc01 [March 21, 2013] No changes. Version 1.6.1 [March 28, 2013] No changes. Version 1.6.2beta01 [April 14, 2013] Updated documentation of 1.5.x to 1.6.x changes in iCCP chunk handling. Fixed incorrect warning of excess deflate data. End condition - the warning would be produced if the end of the deflate stream wasn't read in the last row. The warning is harmless. Corrected the test on user transform changes on read. It was in the png_set of the transform function, but that doesn't matter unless the transform function changes the rowbuf size, and that is only valid if transform_info is called. Corrected a misplaced closing bracket in contrib/libtests/pngvalid.c (Flavio Medeiros). Corrected length written to uncompressed iTXt chunks (Samuli Suominen). Bug was introduced in libpng-1.6.0. Version 1.6.2rc01 [April 18, 2013] Added contrib/tools/fixitxt.c, to repair the erroneous iTXt chunk length written by libpng-1.6.0 and 1.6.1. Disallow storing sRGB information when the sRGB is not supported. Version 1.6.2rc02 [April 18, 2013] Merge pngtest.c with libpng-1.7.0 Version 1.6.2rc03 [April 22, 2013] Trivial spelling cleanup. Version 1.6.2rc04 and 1.6.2rc05 [omitted] Version 1.6.2rc06 [April 24, 2013] Reverted to version 1.6.2rc03. Recent changes to arm/neon support have been ported to libpng-1.7.0beta09 and will reappear in version 1.6.3beta01. Version 1.6.2 [April 25, 2013] No changes. Version 1.6.3beta01 [April 25, 2013] Revised stack marking in arm/filter_neon.S and configure.ac. Ensure that NEON filter stuff is completely disabled when switched 'off'. Previously the ARM NEON specific files were still built if the option was switched 'off' as opposed to being explicitly disabled. Version 1.6.3beta02 [April 26, 2013] Test for 'arm*' not just 'arm' in the host_cpu configure variable. Rebuilt the configure scripts. Version 1.6.3beta03 [April 30, 2013] Expanded manual paragraph about writing private chunks, particularly the need to call png_set_keep_unknown_chunks() when writing them. Avoid dereferencing NULL pointer possibly returned from png_create_write_struct() (Andrew Church). Version 1.6.3beta05 [May 9, 2013] Calculate our own zlib windowBits when decoding rather than trusting the CMF bytes in the PNG datastream. Added an option to force maximum window size for inflating, which was the behavior of libpng15 and earlier, via a new PNG_MAXIMUM_INFLATE_WINDOW option for png_set_options(). Added png-fix-itxt and png-fix-too-far-back to the built programs and removed warnings from the source code and timepng that are revealed as a result. Detect wrong libpng versions linked to png-fix-too-far-back, which currently only works with libpng versions that can be made to reliably fail when the deflate data contains an out-of-window reference. This means only 1.6 and later. Fixed gnu issues: g++ needs a static_cast, gcc 4.4.7 has a broken warning message which it is easier to work round than ignore. Updated contrib/pngminus/pnm2png.c (Paul Stewart): Check for EOF Ignore "#" delimited comments in input file to pnm2png.c. Fixed whitespace handling Added a call to png_set_packing() Initialize dimension values so if sscanf fails at least we have known invalid values. Attempt to detect configuration issues with png-fix-too-far-back, which requires both the correct libpng and the correct zlib to function correctly. Check ZLIB_VERNUM for mismatches, enclose #error in quotes Added information in the documentation about problems with and fixes for the bad CRC and bad iTXt chunk situations. Version 1.6.3beta06 [May 12, 2013] Allow contrib/pngminus/pnm2png.c to compile without WRITE_INVERT and WRITE_PACK supported (writes error message that it can't read P1 or P4 PBM files). Improved png-fix-too-far-back usage message, added --suffix option. Revised contrib/pngminim/*/makefile to generate pnglibconf.h with the right zlib header files. Separated CPPFLAGS and CFLAGS in contrib/pngminim/*/makefile Version 1.6.3beta07 [June 8, 2013] Removed a redundant test in png_set_IHDR(). Added set(CMAKE_CONFIGURATION_TYPES ...) to CMakeLists.txt (Andrew Hundt) Deleted set(CMAKE_BUILD_TYPE) block from CMakeLists.txt Enclose the prototypes for the simplified write API in #ifdef PNG_STDIO_SUPPORTED/#endif Make ARM NEON support work at compile time (not just configure time). This moves the test on __ARM_NEON__ into pngconf.h to avoid issues when using a compiler that compiles for multiple architectures at one time. Removed PNG_FILTER_OPTIMIZATIONS and PNG_ARM_NEON_SUPPORTED from pnglibconf.h, allowing more of the decisions to be made internally (pngpriv.h) during the compile. Without this, symbol prefixing is broken under certain circumstances on ARM platforms. Now only the API parts of the optimizations ('check' vs 'api') are exposed in the public header files except that the new setting PNG_ARM_NEON_OPT documents how libpng makes the decision about whether or not to use the optimizations. Protect symbol prefixing against CC/CPPFLAGS/CFLAGS usage. Previous iOS/Xcode fixes for the ARM NEON optimizations moved the test on __ARM_NEON__ from configure time to compile time. This breaks symbol prefixing because the definition of the special png_init_filter_functions call was hidden at configure time if the relevant compiler arguments are passed in CFLAGS as opposed to CC. This change attempts to avoid all the confusion that would result by declaring the init function even when it is not used, so that it will always get prefixed. Version 1.6.3beta08 [June 18, 2013] Revised libpng.3 so that "doclifter" can process it. Version 1.6.3beta09 [June 27, 2013] Revised example.c to illustrate use of PNG_DEFAULT_sRGB and PNG_GAMMA_MAC_18 as parameters for png_set_gamma(). These have been available since libpng-1.5.4. Renamed contrib/tools/png-fix-too-far-back.c to pngfix.c and revised it to check all compressed chunks known to libpng. Version 1.6.3beta10 [July 5, 2013] Updated documentation to show default behavior of benign errors correctly. Only compile ARM code when PNG_READ_SUPPORTED is defined. Fixed undefined behavior in contrib/tools/pngfix.c and added new strip option. pngfix relied on undefined behavior and even a simple change from gcc to g++ caused it to fail. The new strip option 'unsafe' has been implemented and is the default if --max is given. Option names have been clarified, with --strip=transform now stripping the bKGD chunk, which was stripped previously with --strip=unused. Added all documented chunk types to pngpriv.h Unified pngfix.c source with libpng17. Version 1.6.3rc01 [July 11, 2013] No changes. Version 1.6.3 [July 18, 2013] Revised manual about changes in iTXt chunk handling made in libpng-1.6.0. Added "/* SAFE */" comments in pngrutil.c and pngrtran.c where warnings may be erroneously issued by code-checking applications. Version 1.6.4beta01 [August 21, 2013] Added information about png_set_options() to the manual. Delay calling png_init_filter_functions() until a row with nonzero filter is found. Version 1.6.4beta02 [August 30, 2013] Fixed inconsistent conditional compilation of png_chunk_unknown_handling() prototype, definition, and usage. Made it depend on PNG_HANDLE_AS_UNKNOWN_SUPPORTED everywhere. Version 1.6.4rc01 [September 5, 2013] No changes. Version 1.6.4 [September 12, 2013] No changes. Version 1.6.5 [September 14, 2013] Removed two stray lines of code from arm/arm_init.c. Version 1.6.6 [September 16, 2013] Removed two stray lines of code from arm/arm_init.c, again. Version 1.6.7beta01 [September 30, 2013] Revised unknown chunk code to correct several bugs in the NO_SAVE_/NO_WRITE combination Allow HANDLE_AS_UNKNOWN to work when other options are configured off. Also fixed the pngminim makefiles to work when $(MAKEFLAGS) contains stuff which terminates the make options (as by default in recent versions of Gentoo). Avoid up-cast warnings in pngvalid.c. On ARM the alignment requirements of png_modifier are greater than that of png_store and as a consequence compilation of pngvalid.c results in a warning about increased alignment requirements because of the bare cast to (png_modifier*). The code is safe, because the pointer is known to point to a stack allocated png_modifier, but this change avoids the warning. Fixed default behavior of ARM_NEON_API. If the ARM NEON API option was compiled without the CHECK option it defaulted to on, not off. Check user callback behavior in pngunknown.c. Previous versions compiled if SAVE_UNKNOWN was not available but did nothing since the callback was never implemented. Merged pngunknown.c with 1.7 version and back ported 1.7 improvements/fixes Version 1.6.7beta02 [October 12, 2013] Made changes for compatibility with automake 1.14: 1) Added the 'compile' program to the list of programs that must be cleaned in autogen.sh 2) Added 'subdir-objects' which causes .c files in sub-directories to be compiled such that the corresponding .o files are also in the sub-directory. This is because automake 1.14 warns that the current behavior of compiling to the top level directory may be removed in the future. 3) Updated dependencies on pnglibconf.h to match the new .o locations and added all the files in contrib/libtests and contrib/tools that depend on pnglibconf.h 4) Added 'BUILD_SOURCES = pnglibconf.h'; this is the automake recommended way of handling the dependencies of sources that are machine generated; unfortunately it only works if the user does 'make all' or 'make check', so the dependencies (3) are still required. Cleaned up (char*) casts of zlib messages. The latest version of the Intel C compiler complains about casting a string literal as (char*), so copied the treatment of z_const from the library code into pngfix.c Simplified error message code in pngunknown. The simplification has the useful side effect of avoiding a bogus warning generated by the latest version of the Intel C compiler (it objects to condition ? string-literal : string-literal). Make autogen.sh work with automake 1.13 as well as 1.14. Do this by always removing the 1.14 'compile' script but never checking for it. Version 1.6.7beta03 [October 19, 2013] Added ARMv8 support (James Yu ). Added file arm/filter_neon_intrinsics.c; enable with -mfpu=neon. Revised pngvalid to generate size images with as many filters as it can manage, limited by the number of rows. Cleaned up ARM NEON compilation handling. The tests are now in pngpriv.h and detect the broken GCC compilers. Version 1.6.7beta04 [October 26, 2013] Allow clang derived from older GCC versions to use ARM intrinsics. This causes all clang builds that use -mfpu=neon to use the intrinsics code, not the assembler code. This has only been tested on iOS 7. It may be necessary to exclude some earlier clang versions but this seems unlikely. Changed NEON implementation selection mechanism. This allows assembler or intrinsics to be turned on at compile time during the build by defining PNG_ARM_NEON_IMPLEMENTATION to the correct value (2 or 1). This macro is undefined by default and the build type is selected in pngpriv.h. Version 1.6.7rc01 [November 2, 2013] No changes. Version 1.6.7rc02 [November 7, 2013] Fixed #include in filter_neon_intrinsics.c and ctype macros. The ctype char checking macros take an unsigned char argument, not a signed char. Version 1.6.7 [November 14, 2013] No changes. Version 1.6.8beta01 [November 24, 2013] Moved prototype for png_handle_unknown() in pngpriv.h outside of the #ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED/#endif block. Added "-Wall" to CFLAGS in contrib/pngminim/*/makefile Conditionally compile some unused functions reported by -Wall in pngminim. Fixed 'minimal' builds. Various obviously useful minimal configurations don't build because of missing contrib/libtests test programs and overly complex dependencies in scripts/pnglibconf.dfa. This change adds contrib/conftest/*.dfa files that can be used in automatic build scripts to ensure that these configurations continue to build. Enabled WRITE_INVERT and WRITE_PACK in contrib/pngminim/encoder. Fixed pngvalid 'fail' function declaration on the Intel C Compiler. This reverts to the previous 'static' implementation and works round the 'unused static function' warning by using PNG_UNUSED(). Version 1.6.8beta02 [November 30, 2013] Removed or marked PNG_UNUSED some harmless "dead assignments" reported by clang scan-build. Changed tabs to 3 spaces in png_debug macros and changed '"%s"m' to '"%s" m' to improve portability among compilers. Changed png_free_default() to free() in pngtest.c Version 1.6.8rc01 [December 12, 2013] Tidied up pngfix inits and fixed pngtest no-write builds. Version 1.6.8rc02 [December 14, 2013] Handle zero-length PLTE chunk or NULL palette with png_error() instead of png_chunk_report(), which by default issues a warning rather than an error, leading to later reading from a NULL pointer (png_ptr->palette) in png_do_expand_palette(). This is CVE-2013-6954 and VU#650142. Libpng-1.6.1 through 1.6.7 are vulnerable. Libpng-1.6.0 and earlier do not have this bug. Version 1.6.8 [December 19, 2013] No changes. Version 1.6.9beta01 [December 26, 2013] Bookkeeping: Moved functions around (no changes). Moved transform function definitions before the place where they are called so that they can be made static. Move the intrapixel functions and the grayscale palette builder out of the png?tran.c files. The latter isn't a transform function and is no longer used internally, and the former MNG specific functions are better placed in pngread/pngwrite.c Made transform implementation functions static. This makes the internal functions called by png_do_{read|write}_transformations static. On an x86-64 DLL build (Gentoo Linux) this reduces the size of the text segment of the DLL by 1208 bytes, about 0.6%. It also simplifies maintenance by removing the declarations from pngpriv.h and allowing easier changes to the internal interfaces. Rebuilt configure scripts with automake-1.14.1 and autoconf-2.69 in the tar distributions. Version 1.6.9beta02 [January 1, 2014] Added checks for libpng 1.5 to pngvalid.c. This supports the use of this version of pngvalid in libpng 1.5 Merged with pngvalid.c from libpng-1.7 changes to create a single pngvalid.c Removed #error macro from contrib/tools/pngfix.c (Thomas Klausner). Merged pngrio.c, pngtrans.c, pngwio.c, and pngerror.c with libpng-1.7.0 Merged libpng-1.7.0 changes to make no-interlace configurations work with test programs. Revised pngvalid.c to support libpng 1.5, which does not support the PNG_MAXIMUM_INFLATE_WINDOW option, so #define it out when appropriate in pngvalid.c Allow unversioned links created on install to be disabled in configure. In configure builds 'make install' changes/adds links like png.h and libpng.a to point to the newly installed, versioned, files (e.g. libpng17/png.h and libpng17.a). Three new configure options and some rearrangement of Makefile.am allow creation of these links to be disabled. Version 1.6.9beta03 [January 10, 2014] Removed potentially misleading warning from png_check_IHDR(). Version 1.6.9beta04 [January 20, 2014] Updated scripts/makefile.* to use CPPFLAGS (Cosmin). Added clang attribute support (Cosmin). Version 1.6.9rc01 [January 28, 2014] No changes. Version 1.6.9rc02 [January 30, 2014] Quiet an uninitialized memory warning from VC2013 in png_get_png(). Version 1.6.9 [February 6, 2014] Version 1.6.10beta01 [February 9, 2014] Backported changes from libpng-1.7.0beta30 and beta31: Fixed a large number of instances where PNGCBAPI was omitted from function definitions. Added pngimage test program for png_read_png() and png_write_png() with two new test scripts. Removed dependence on !PNG_READ_EXPAND_SUPPORTED for calling png_set_packing() in png_read_png(). Fixed combination of ~alpha with shift. On read invert alpha, processing occurred after shift processing, which causes the final values to be outside the range that should be produced by the shift. Reversing the order on read makes the two transforms work together correctly and mirrors the order used on write. Do not read invalid sBIT chunks. Previously libpng only checked sBIT values on write, so a malicious PNG writer could therefore cause the read code to return an invalid sBIT chunk, which might lead to application errors or crashes. Such chunks are now skipped (with chunk_benign_error). Make png_read_png() and png_write_png() prototypes in png.h depend upon PNG_READ_SUPPORTED and PNG_WRITE_SUPPORTED. Support builds with unsupported PNG_TRANSFORM_* values. All of the PNG_TRANSFORM_* values are always defined in png.h and, because they are used for both read and write in some cases, it is not reliable to #if out ones that are totally unsupported. This change adds error detection in png_read_image() and png_write_image() to do a png_app_error() if the app requests something that cannot be done and it adds corresponding code to pngimage.c to handle such options by not attempting to test them. Version 1.6.10beta02 [February 23, 2014] Moved redefines of png_error(), png_warning(), png_chunk_error(), and png_chunk_warning() from pngpriv.h to png.h to make them visible to libpng-calling applications. Moved OS dependent code from arm/arm_init.c, to allow the included implementation of the ARM NEON discovery function to be set at build-time and provide sample implementations from the current code in the contrib/arm-neon subdirectory. The __linux__ code has also been changed to compile and link on Android by using /proc/cpuinfo, and the old linux code is in contrib/arm-neon/linux-auxv.c. The new code avoids POSIX and Linux dependencies apart from opening /proc/cpuinfo and is C90 compliant. Check for info_ptr == NULL early in png_read_end() so we don't need to run all the png_handle_*() and depend on them to return if info_ptr == NULL. This improves the performance of png_read_end(png_ptr, NULL) and makes it more robust against future programming errors. Check for __has_extension before using it in pngconf.h, to support older Clang versions (Jeremy Sequoia). Treat CRC error handling with png_set_crc_action(), instead of with png_set_benign_errors(), which has been the case since libpng-1.6.0beta18. Use a user warning handler in contrib/gregbook/readpng2.c instead of default, so warnings will be put on stderr even if libpng has CONSOLE_IO disabled. Added png_ptr->process_mode = PNG_READ_IDAT_MODE in png_push_read_chunk after recognizing the IDAT chunk, which avoids an infinite loop while reading a datastream whose first IDAT chunk is of zero-length. This fixes CERT VU#684412 and CVE-2014-0333. Don't recognize known sRGB profiles as sRGB if they have been hacked, but don't reject them and don't issue a copyright violation warning. Version 1.6.10beta03 [February 25, 2014] Moved some documentation from png.h to libpng.3 and libpng-manual.txt Minor editing of contrib/arm-neon/README and contrib/examples/*.c Version 1.6.10rc01 [February 27, 2014] Fixed typos in the manual and in scripts/pnglibconf.dfa (CFLAGS -> CPPFLAGS and PNG_USR_CONFIG -> PNG_USER_CONFIG). Version 1.6.10rc02 [February 28, 2014] Removed unreachable return statement after png_chunk_error() in pngrutil.c Version 1.6.10rc03 [March 4, 2014] Un-deprecated png_data_freer(). Version 1.6.10 [March 6, 2014] No changes. Version 1.6.11beta01 [March 17, 2014] Use "if (value != 0)" instead of "if (value)" consistently. Changed ZlibSrcDir from 1.2.5 to 1.2.8 in projects/vstudio. Moved configuration information from the manual to the INSTALL file. Version 1.6.11beta02 [April 6, 2014] Removed #if/#else/#endif from inside two pow() calls in pngvalid.c because they were handled improperly by Portland Group's PGI-14.1 - PGI-14.3 when using its "__builtin_pow()" function. Silence 'unused parameter' build warnings (Cosmin Truta). $(CP) is now used alongside $(RM_F). Also, use 'copy' instead of 'cp' where applicable, and applied other minor makefile changes (Cosmin). Don't warn about invalid dimensions exceeding user limits (Cosmin). Allow an easy replacement of the default pre-built configuration header with a custom header, via the make PNGLIBCONF_H_PREBUILT macro (Cosmin). Version 1.6.11beta03 [April 6, 2014] Fixed a typo in pngrutil.c, introduced in libpng-1.5.6, that interferes with "blocky" expansion of sub-8-bit interlaced PNG files (Eric Huss). Optionally use __builtin_bswap16() in png_do_swap(). Version 1.6.11beta04 [April 19, 2014] Made progressive reading of interlaced images consistent with the behavior of the sequential reader and consistent with the manual, by moving some code out of the PNG_READ_INTERLACING_SUPPORTED blocks. The row_callback now receives the proper pass number and unexpanded rows, when png_combine_row() isn't built or used, and png_set_interlace_handling() is not called. Allow PNG_sRGB_PROFILE_CHECKING = (-1) to mean no sRGB profile checking. Version 1.6.11beta05 [April 26, 2014] Do not reject ICC V2 profiles that lack padding (Kai-Uwe Behrmann). Relocated closing bracket of the sRGB profile test loop to avoid getting "Not recognizing known sRGB profile that has been edited" warning for ICC V2 profiles that lack the MD5 signature in the profile header. Version 1.6.11beta06 [May 19, 2014] Added PNG_SKIP_sRGB_CHECK_PROFILE choice for png_set_option(). Version 1.6.11rc01 [May 27, 2014] No changes. Version 1.6.11rc02 [June 3, 2014] Test ZLIB_VERNUM instead of PNG_ZLIB_VERNUM in contrib/tools/pngfix.c Version 1.6.11 [June 5, 2014] No changes. Version 1.6.12rc01 [June 6, 2014] Relocated new code from 1.6.11beta06 in png.c to a point after the declarations (Max Stepin). Version 1.6.12rc02 [June 7, 2014] Changed file permissions of contrib/tools/intgamma.sh, test-driver, and compile from 0644 to 0755 (Cosmin). Version 1.6.12rc03 [June 8, 2014] Ensure "__has_attribute()" macro exists before trying to use it with old clang compilers (MacPorts Ticket #43939). Version 1.6.12 [June 12, 2014] No changes. Version 1.6.13beta01 [July 4, 2014] Quieted -Wsign-compare and -Wclobber compiler warnings in contrib/pngminus/*.c Added "(void) png_ptr;" where needed in contrib/gregbook to quiet compiler complaints about unused pointers. Split a long output string in contrib/gregbook/rpng2-x.c. Added "PNG_SET_OPTION" requirement for sRGB chunk support to pnglibconf.dfa, Needed for write-only support (John Bowler). Changed "if defined(__ARM_NEON__)" to "if (defined(__ARM_NEON__) || defined(__ARM_NEON))" (James Wu). Fixed clang no-warning builds: png_digit was defined but never used. Version 1.6.13beta02 [July 21, 2014] Fixed an incorrect separator ("/" should be "\") in scripts/makefile.vcwin32 (bug report from Wolfgang S. Kechel). Bug was introduced in libpng-1.6.11. Also fixed makefile.bc32, makefile.bor, makefile.msc, makefile.intel, and makefile.tc3 similarly. Version 1.6.13beta03 [August 3, 2014] Removed scripts/makefile.elf. It has not worked since libpng-1.5.0beta14 due to elimination of the PNG_FUNCTION_EXPORT and PNG_DATA_EXPORT definitions from pngconf.h. Ensure that CMakeLists.txt makes the target "lib" directory before making symbolic link into it (SourceForge bug report #226 by Rolf Timmermans). Version 1.6.13beta04 [August 8, 2014] Added opinion that the ECCN (Export Control Classification Number) for libpng is EAR99 to the README file. Eliminated use of "$<" in makefile explicit rules, when copying $PNGLIBCONF_H_PREBUILT. This does not work on some versions of make; bug introduced in libpng version 1.6.11. Version 1.6.13rc01 [August 14, 2014] Made "ccopts" agree with "CFLAGS" in scripts/makefile.hp* and makefile.*sunu Version 1.6.13 [August 21, 2014] No changes. Version 1.6.14beta01 [September 14, 2014] Guard usage of png_ptr->options with #ifdef PNG_SET_OPTION_SUPPORTED. Do not build contrib/tools/pngfix.c when PNG_SETJMP_NOT_SUPPORTED, to allow "make" to complete without setjmp support (bug report by Claudio Fontana) Add "#include " to contrib/tools/pngfix.c (John Bowler) Version 1.6.14beta02 [September 18, 2014] Use nanosleep() instead of usleep() in contrib/gregbook/rpng2-x.c because usleep() is deprecated. Define usleep() in contrib/gregbook/rpng2-x.c if not already defined in unistd.h and nanosleep() is not available; fixes error introduced in libpng-1.6.13. Disable floating point exception handling in pngvalid.c when PNG_FLOATING_ARITHMETIC is not supported (bug report by "zootus at users.sourceforge.net"). Version 1.6.14beta03 [September 19, 2014] Define FE_DIVBYZERO, FE_INVALID, and FE_OVERFLOW in pngvalid.c if not already defined. Revert floating point exception handling in pngvalid.c to version 1.6.14beta01 behavior. Version 1.6.14beta04 [September 27, 2014] Fixed incorrect handling of the iTXt compression flag in pngrutil.c (bug report by Shunsaku Hirata). Bug was introduced in libpng-1.6.0. Version 1.6.14beta05 [October 1, 2014] Added "option READ_iCCP enables READ_COMPRESSED_TEXT" to pnglibconf.dfa Version 1.6.14beta06 [October 5, 2014] Removed unused "text_len" parameter from private function png_write_zTXt(). Conditionally compile some code in png_deflate_claim(), when PNG_WARNINGS_SUPPORTED and PNG_ERROR_TEXT_SUPPORTED are disabled. Replaced repeated code in pngpread.c with PNG_PUSH_SAVE_BUFFER_IF_FULL. Added "chunk iTXt enables TEXT" and "chunk zTXt enables TEXT" to pnglibconf.dfa. Removed "option READ_COMPRESSED_TEXT enables READ_TEXT" from pnglibconf.dfa, to make it possible to configure a libpng that supports iCCP but not TEXT. Version 1.6.14beta07 [October 7, 2014] Removed "option WRITE_COMPRESSED_TEXT enables WRITE_TEXT" from pnglibconf.dfa Only mark text chunks as written after successfully writing them. Version 1.6.14rc01 [October 15, 2014] Fixed some typos in comments. Version 1.6.14rc02 [October 17, 2014] Changed png_convert_to_rfc_1123() to png_convert_to_rfc_1123_buffer() in the manual, to reflect the change made in libpng-1.6.0. Updated README file to explain that direct access to the png_struct and info_struct members has not been permitted since libpng-1.5.0. Version 1.6.14 [October 23, 2014] No changes. Version 1.6.15beta01 [October 29, 2014] Changed "if (!x)" to "if (x == 0)" and "if (x)" to "if (x != 0)" Simplified png_free_data(). Added missing "ptr = NULL" after some instances of png_free(). Version 1.6.15beta02 [November 1, 2014] Changed remaining "if (!x)" to "if (x == 0)" and "if (x)" to "if (x != 0)" Version 1.6.15beta03 [November 3, 2014] Added PNG_USE_ARM_NEON configuration flag (Marcin Juszkiewicz). Version 1.6.15beta04 [November 4, 2014] Removed new PNG_USE_ARM_NEON configuration flag and made a one-line revision to configure.ac to support ARM on aarch64 instead (John Bowler). Version 1.6.15beta05 [November 5, 2014] Use png_get_libpng_ver(NULL) instead of PNG_LIBPNG_VER_STRING in example.c, pngtest.c, and applications in the contrib directory. Fixed an out-of-range read in png_user_version_check() (Bug report from Qixue Xiao, CVE-2015-8540). Simplified and future-proofed png_user_version_check(). Fixed GCC unsigned int->float warnings. Various versions of GCC seem to generate warnings when an unsigned value is implicitly converted to double. This is probably a GCC bug but this change avoids the issue by explicitly converting to (int) where safe. Free all allocated memory in pngimage. The file buffer cache was left allocated at the end of the program, harmless but it causes memory leak reports from clang. Fixed array size calculations to avoid warnings. At various points in the code the number of elements in an array is calculated using sizeof. This generates a compile time constant of type (size_t) which is then typically assigned to an (unsigned int) or (int). Some versions of GCC on 64-bit systems warn about the apparent narrowing, even though the same compiler does apparently generate the correct, in-range, numeric constant. This adds appropriate, safe, casts to make the warnings go away. Version 1.6.15beta06 [November 6, 2014] Reverted use png_get_libpng_ver(NULL) instead of PNG_LIBPNG_VER_STRING in the manual, example.c, pngtest.c, and applications in the contrib directory. It was incorrect advice. Version 1.6.15beta07 [November 7, 2014] Removed #ifdef PNG_16BIT_SUPPORTED/#endif around png_product2(); it is needed by png_reciprocal2(). Added #ifdef PNG_16BIT_SUPPORTED/#endif around png_log16bit() and png_do_swap(). Changed all "#endif /* PNG_FEATURE_SUPPORTED */" to "#endif /* FEATURE */" Version 1.6.15beta08 [November 8, 2014] More housecleaning in *.h Version 1.6.15rc01 [November 13, 2014] Version 1.6.15rc02 [November 14, 2014] The macros passed in the command line to Borland make were ignored if similarly-named macros were already defined in makefiles. This behavior is different from POSIX make and other make programs. Surround the macro definitions with ifndef guards (Cosmin). Version 1.6.15rc03 [November 16, 2014] Added "-D_CRT_SECURE_NO_WARNINGS" to CFLAGS in scripts/makefile.vcwin32. Removed the obsolete $ARCH variable from scripts/makefile.darwin. Version 1.6.15 [November 20, 2014] No changes. Version 1.6.16beta01 [December 14, 2014] Added ".align 2" to arm/filter_neon.S to support old GAS assemblers that don't do alignment correctly. Revised Makefile.am and scripts/symbols.dfn to work with MinGW/MSYS (Bob Friesenhahn). Version 1.6.16beta02 [December 15, 2014] Revised Makefile.am and scripts/*.dfn again to work with MinGW/MSYS; renamed scripts/*.dfn to scripts/*.c (John Bowler). Version 1.6.16beta03 [December 21, 2014] Quiet a "comparison always true" warning in pngstest.c (John Bowler). Version 1.6.16rc01 [December 21, 2014] Restored a test on width that was removed from png.c at libpng-1.6.9 (Bug report by Alex Eubanks, CVE-2015-0973). Version 1.6.16rc02 [December 21, 2014] Undid the update to pngrutil.c in 1.6.16rc01. Version 1.6.16rc03 [December 21, 2014] Fixed an overflow in png_combine_row() with very wide interlaced images (Bug report and fix by John Bowler, CVE-2014-9495). Version 1.6.16 [December 22, 2014] No changes. Version 1.6.17beta01 [January 29, 2015] Removed duplicate PNG_SAFE_LIMITS_SUPPORTED handling from pngconf.h Corrected the width limit calculation in png_check_IHDR(). Removed user limits from pngfix. Also pass NULL pointers to png_read_row to skip the unnecessary row de-interlace stuff. Added testing of png_set_packing() to pngvalid.c Regenerated configure scripts in the *.tar distributions with libtool-2.4.4 Implement previously untested cases of libpng transforms in pngvalid.c Fixed byte order in png_do_read_filler() with 16-bit input. Previously the high and low bytes of the filler, from png_set_filler() or from png_set_add_alpha(), were read in the wrong order. Made the check for out-of-range values in png_set_tRNS() detect values that are exactly 2^bit_depth, and work on 16-bit platforms. Merged some parts of libpng-1.6.17beta01 and libpng-1.7.0beta47. Added #ifndef __COVERITY__ where needed in png.c, pngrutil.c and pngset.c to avoid warnings about dead code. Added "& 0xff" to many instances of expressions that are typecast to (png_byte), to avoid Coverity warnings. Version 1.6.17beta02 [February 7, 2015] Work around one more Coverity-scan dead-code warning. Do not build png_product2() when it is unused. Version 1.6.17beta03 [February 17, 2015] Display user limits in the output from pngtest. Eliminated the PNG_SAFE_LIMITS macro and restored the 1-million-column and 1-million-row default limits in pnglibconf.dfa, that can be reset by the user at build time or run time. This provides a more robust defense against DOS and as-yet undiscovered overflows. Version 1.6.17beta04 [February 21, 2015] Added PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED macro, on by default. Allow user to call png_get_IHDR() with NULL arguments (Reuben Hawkins). Rebuilt configure scripts with automake-1.15 and libtool-2.4.6 Version 1.6.17beta05 [February 25, 2015] Restored compiling of png_reciprocal2 with PNG_NO_16BIT. Version 1.6.17beta06 [February 27, 2015] Moved png_set_filter() prototype into a PNG_WRITE_SUPPORTED block of png.h. Avoid runtime checks when converting integer to png_byte with Visual Studio (Sergey Kosarevsky) Version 1.6.17rc01 [March 4, 2015] No changes. Version 1.6.17rc02 [March 9, 2015] Removed some comments that the configure script did not handle properly from scripts/pnglibconf.dfa and pnglibconf.h.prebuilt. Free the unknown_chunks structure even when it contains no data. Version 1.6.17rc03 [March 12, 2015] Updated CMakeLists.txt to add OSX framework, change YES/NO to ON/OFF for consistency, and remove some useless tests (Alexey Petruchik). Version 1.6.17rc04 [March 16, 2015] Remove pnglibconf.h, pnglibconf.c, and pnglibconf.out instead of pnglibconf.* in "make clean" (Cosmin). Fix bug in calculation of maxbits, in png_write_sBIT, introduced in libpng-1.6.17beta01 (John Bowler). Version 1.6.17rc05 [March 21, 2015] Define PNG_FILTER_* and PNG_FILTER_VALUE_* in png.h even when WRITE is not supported (John Bowler). This fixes an error introduced in libpng-1.6.17beta06. Reverted "& 0xff" additions of version 1.6.17beta01. Libpng passes the Coverity scan without them. Version 1.6.17rc06 [March 23, 2015] Remove pnglibconf.dfn and pnglibconf.pre with "make clean". Reformatted some "&0xff" instances to "& 0xff". Fixed simplified 8-bit-linear to sRGB alpha. The calculated alpha value was wrong. It's not clear if this affected the final stored value; in the obvious code path the upper and lower 8-bits of the alpha value were identical and the alpha was truncated to 8-bits rather than dividing by 257 (John Bowler). Version 1.6.17 [March 26, 2015] No changes. Version 1.6.18beta01 [April 1, 2015] Removed PNG_SET_CHUNK_[CACHE|MALLOC]_LIMIT_SUPPORTED macros. They have been combined with PNG_SET_USER_LIMITS_SUPPORTED (resolves bug report by Andrew Church). Fixed rgb_to_gray checks and added tRNS checks to pngvalid.c. This fixes some arithmetic errors that caused some tests to fail on some 32-bit platforms (Bug reports by Peter Breitenlohner [i686] and Petr Gajdos [i586]). Version 1.6.18beta02 [April 26, 2015] Suppressed some warnings from the Borland C++ 5.5.1/5.82 compiler (Bug report by Viktor Szakats). Version 1.6.18beta03 [May 6, 2015] Replaced "unexpected" with an integer (0xabadca11) in pngset.c where a long was expected, to avoid a compiler warning when PNG_DEBUG > 1. Added contrib/examples/simpleover.c, to demonstrate how to handle alpha compositing of multiple images, using the "simplified API" and an example PNG generation tool, contrib/examples/genpng.c (John Bowler). Version 1.6.18beta04 [May 20, 2015] PNG_RELEASE_BUILD replaces tests where the code depended on the build base type and can be defined on the command line, allowing testing in beta builds (John Bowler). Avoid Coverity issue 80858 (REVERSE NULL) in pngtest.c PNG_DEBUG builds. Avoid a harmless potential integer overflow in png_XYZ_from_xy() (Bug report from Christopher Ferris). Version 1.6.18beta05 [May 31, 2015] Backport filter selection code from libpng-1.7.0beta51, to combine sub_row, up_row, avg_row, and paeth_row into try_row and tst_row. Changed png_voidcast(), etc., to voidcast(), etc., in contrib/tools/pngfix.c to avoid confusion with the libpng private macros. Fixed old cut&paste bug in the weighted filter selection code in pngwutil.c, introduced in libpng-0.95, March 1997. Version 1.6.18beta06 [June 1, 2015] Removed WRITE_WEIGHTED_FILTERED code, to save a few kbytes of the compiled library size. It never worked properly and as far as we can tell, no one uses it. The png_set_filter_heuristics() and png_set_filter_heuristics_fixed() APIs are retained but deprecated and do nothing. Version 1.6.18beta07 [June 6, 2015] Removed non-working progressive reader 'skip' function. This function has apparently never been used. It was implemented to support back-door modification of png_struct in libpng-1.4.x but (because it does nothing and cannot do anything) was apparently never tested (John Bowler). Fixed cexcept.h in which GCC 5 now reports that one of the auto variables in the Try macro needs to be volatile to prevent value being lost over the setjmp (John Bowler). Fixed NO_WRITE_FILTER and -Wconversion build breaks (John Bowler). Fix g++ build breaks (John Bowler). Quieted some Coverity issues in pngfix.c, png-fix-itxt.c, pngvalid.c, pngstest.c, and pngimage.c. Most seem harmless, but png-fix-itxt would only work with iTXt chunks with length 255 or less. Added #ifdef's to contrib/examples programs so people don't try to compile them without the minimum required support enabled (suggested by Flavio Medeiros). Version 1.6.18beta08 [June 30, 2015] Eliminated the final two Coverity defects (insecure temporary file handling in contrib/libtests/pngstest.c; possible overflow of unsigned char in contrib/tools/png-fix-itxt.c). To use the "secure" file handling, define PNG_USE_MKSTEMP, otherwise "tmpfile()" will be used. Removed some unused WEIGHTED_FILTER macros from png.h and pngstruct.h Version 1.6.18beta09 [July 5, 2015] Removed some useless typecasts from contrib/tools/png-fix-itxt.c Fixed a new signed-unsigned comparison in pngrtran.c (Max Stepin). Replaced arbitrary use of 'extern' with #define PNG_LINKAGE_*. To preserve API compatibility, the new defines all default to "extern" (requested by Jan Nijtmans). Version 1.6.18rc01 [July 9, 2015] Belatedly added Mans Rullgard and James Yu to the list of Contributing Authors. Version 1.6.18rc02 [July 12, 2015] Restored unused FILTER_HEURISTIC macros removed at libpng-1.6.18beta08 to png.h to avoid compatibility warnings. Version 1.6.18rc03 [July 15, 2015] Minor changes to the man page Version 1.6.18 [July 23, 2015] No changes. Version 1.6.19beta01 [July 30, 2015] Updated obsolete information about the simplified API macros in the manual pages (Bug report by Arc Riley). Avoid potentially dereferencing NULL info_ptr in png_info_init_3(). Rearranged png.h to put the major sections in the same order as in libpng17. Eliminated unused PNG_COST_SHIFT, PNG_WEIGHT_SHIFT, PNG_COST_FACTOR, and PNG_WEIGHT_FACTOR macros. Suppressed some warnings from the Borland C++ 5.5.1/5.82 compiler (Bug report by Viktor Szakats). Several warnings remain and are unavoidable, where we test for overflow. Fixed potential leak of png_pixels in contrib/pngminus/pnm2png.c Fixed uninitialized variable in contrib/gregbook/rpng2-x.c Version 1.6.19beta02 [August 19, 2015] Moved config.h.in~ from the "libpng_autotools_files" list to the "libpng_autotools_extra" list in autogen.sh because it was causing a false positive for missing files (bug report by Robert C. Seacord). Removed unreachable "break" statements in png.c, pngread.c, and pngrtran.c to suppress clang warnings (Bug report by Viktor Szakats). Fixed some bad links in the man page. Changed "n bit" to "n-bit" in comments. Added signed/unsigned 16-bit safety net. This removes the dubious 0x8000 flag definitions on 16-bit systems. They aren't supported yet the defs *probably* work, however it seems much safer to do this and be advised if anyone, contrary to advice, is building libpng 1.6 on a 16-bit system. It also adds back various switch default clauses for GCC; GCC errors out if they are not present (with an appropriately high level of warnings). Safely convert num_bytes to a png_byte in png_set_sig_bytes() (Robert Seacord). Fixed the recently reported 1's complement security issue by replacing the value that is illegal in the PNG spec, in both signed and unsigned values, with 0. Illegal unsigned values (anything greater than or equal to 0x80000000) can still pass through, but since these are not illegal in ANSI-C (unlike 0x80000000 in the signed case) the checking that occurs later can catch them (John Bowler). Version 1.6.19beta03 [September 26, 2015] Fixed png_save_int_32 when int is not 2's complement (John Bowler). Updated libpng16 with all the recent test changes from libpng17, including changes to pngvalid.c to ensure that the original, distributed, version of contrib/visupng/cexcept.h can be used (John Bowler). pngvalid contains the correction to the use of SAVE/STORE_ UNKNOWN_CHUNKS; a bug revealed by changes in libpng 1.7. More tests contain the --strict option to detect warnings and the pngvalid-standard test has been corrected so that it does not turn on progressive-read. There is a separate test which does that. (John Bowler) Also made some signed/unsigned fixes. Make pngstest error limits version specific. Splitting the machine generated error structs out to a file allows the values to be updated without changing pngstest.c itself. Since libpng 1.6 and 1.7 have slightly different error limits this simplifies maintenance. The makepngs.sh script has also been updated to more accurately reflect current problems in libpng 1.7 (John Bowler). Incorporated new test PNG files into make check. tests/pngstest-* are changed so that the new test files are divided into 8 groups by gamma and alpha channel. These tests have considerably better code and pixel-value coverage than contrib/pngsuite; however,coverage is still incomplete (John Bowler). Removed the '--strict' in 1.6 because of the double-gamma-correction warning, updated pngstest-errors.h for the errors detected with the new contrib/testspngs PNG test files (John Bowler). Version 1.6.19beta04 [October 15, 2015] Worked around rgb-to-gray issues in libpng 1.6. The previous attempts to ignore the errors in the code aren't quite enough to deal with the 'channel selection' encoding added to libpng 1.7; abort. pngvalid.c is changed to drop this encoding in prior versions. Fixed 'pow' macros in pngvalid.c. It is legal for 'pow' to be a macro, therefore the argument list cannot contain preprocessing directives. Make sure pow is a function where this happens. This is a minimal safe fix, the issue only arises in non-performance-critical code (bug report by Curtis Leach, fix by John Bowler). Added sPLT support to pngtest.c Version 1.6.19rc01 [October 23, 2015] No changes. Version 1.6.19rc02 [October 31, 2015] Prevent setting or writing over-length PLTE chunk (Cosmin Truta). Silently truncate over-length PLTE chunk while reading. Libpng incorrectly calculated the output rowbytes when the application decreased either the number of channels or the bit depth (or both) in a user transform. This was safe; libpng overallocated buffer space (potentially by quite a lot; up to 4 times the amount required) but, from 1.5.4 on, resulted in a png_error (John Bowler). Version 1.6.19rc03 [November 3, 2015] Fixed some inconsequential cut-and-paste typos in png_set_cHRM_XYZ_fixed(). Clarified COPYRIGHT information to state explicitly that versions are derived from previous versions. Removed much of the long list of previous versions from png.h and libpng.3. Version 1.6.19rc04 [November 5, 2015] Fixed new bug with CRC error after reading an over-length palette (bug report by Cosmin Truta) (CVE-2015-8126). Version 1.6.19 [November 12, 2015] Cleaned up coding style in png_handle_PLTE(). Version 1.6.20beta01 [November 20, 2015] Avoid potential pointer overflow/underflow in png_handle_sPLT() and png_handle_pCAL() (Bug report by John Regehr). Version 1.6.20beta02 [November 23, 2015] Fixed incorrect implementation of png_set_PLTE() that uses png_ptr not info_ptr, that left png_set_PLTE() open to the CVE-2015-8126 vulnerability. Fixes CVE-2015-8472. Version 1.6.20beta03 [November 24, 2015] Backported tests from libpng-1.7.0beta69. Version 1.6.20rc01 [November 26, 2015] Fixed an error in handling of bad zlib CMINFO field in pngfix, found by American Fuzzy Lop, reported by Brian Carpenter. inflate() doesn't immediately fault a bad CMINFO field; instead a 'too far back' error happens later (at least some times). pngfix failed to limit CMINFO to the allowed values but then assumed that window_bits was in range, triggering an assert. The bug is mostly harmless; the PNG file cannot be fixed. Version 1.6.20rc02 [November 29, 2015] In libpng 1.6 zlib initialization was changed to use the window size in the zlib stream, not a fixed value. This causes some invalid images, where CINFO is too large, to display 'correctly' if the rest of the data is valid. This provides a workaround for zlib versions where the error arises (ones that support the API change to use the window size in the stream). Version 1.6.20 [December 3, 2015] No changes. Version 1.6.21beta01 [December 11, 2015] Fixed syntax "$(command)" in tests/pngstest that some shells other than bash could not parse (Bug report by Nelson Beebe). Use `command` instead. Version 1.6.21beta02 [December 14, 2015] Moved png_check_keyword() from pngwutil.c to pngset.c Removed LE/BE dependencies in pngvalid, to 'fix' the current problem in the BigEndian tests by not testing it, making the BE code the same as the LE version. Fixes to pngvalid for various reduced build configurations (eliminate unused statics) and a fix for the case in rgb_to_gray when the digitize option reduces graylo to 0, producing a large error. Version 1.6.21beta03 [December 18, 2015] Widened the 'limit' check on the internally calculated error limits in the 'DIGITIZE' case (the code used prior to 1.7 for rgb_to_gray error checks) and changed the check to only operate in non-release builds (base build type not RC or RELEASE.) Fixed undefined behavior in pngvalid.c, undefined because (png_byte) << shift is undefined if it changes the signed bit (because png_byte is promoted to int). The libpng exported functions png_get_uint_32 and png_get_uint_16 handle this. (Bug reported by David Drysdale as a result of reports from UBSAN in clang 3.8). This changes pngvalid to use BE random numbers; this used to produce errors but these should not be fixed as a result of the previous changes. Version 1.6.21rc01 [January 4, 2016] In projects/vstudio, combined readme.txt and WARNING into README.txt Version 1.6.21rc02 [January 7, 2016] Relocated assert() in contrib/tools/pngfix.c, bug found by American Fuzzy Lop, reported by Brian Carpenter. Marked 'limit' UNUSED in transform_range_check(). This only affects release builds. Version 1.6.21 [January 15, 2016] Worked around a false-positive Coverity issue in pngvalid.c. Version 1.6.22beta01 [January 23, 2016] Changed PNG_USE_MKSTEMP to __COVERITY__ to select alternate "tmpfile()" implementation in contrib/libtests/pngstest.c Fixed NO_STDIO build of pngunknown.c to skip calling png_init_io() if there is no stdio.h support. Added a png_image_write_to_memory() API and a number of assist macros to allow an application that uses the simplified API write to bypass stdio and write directly to memory. Added some warnings (png.h) and some check code to detect *possible* overflow in the ROW_STRIDE and simplified image SIZE macros. This disallows image width/height/format that *might* overflow. This is a quiet API change that limits in-memory image size (uncompressed) to less than 4GByte and image row size (stride) to less than 2GByte. Revised workaround for false-positive Coverity issue in pngvalid.c. Version 1.6.22beta02 [February 8, 2016] Only use exit(77) in configure builds. Corrected error in PNG_IMAGE_PNG_SIZE_MAX. This new macro underreported the palette size because it failed to take into account that the memory palette has to be expanded to full RGB when it is written to PNG. Updated CMakeLists.txt, added supporting scripts/gen*.cmake.in and test.cmake.in (Roger Leigh). Relaxed limit checks on gamma values in pngrtran.c. As suggested in the comments gamma values outside the range currently permitted by png_set_alpha_mode are useful for HDR data encoding. These values are already permitted by png_set_gamma so it is reasonable caution to extend the png_set_alpha_mode range as HDR imaging systems are starting to emerge. Version 1.6.22beta03 [March 9, 2016] Added a common-law trademark notice and export control information to the LICENSE file, png.h, and the man page. Restored "& 0xff" in png_save_uint_16() and png_save_uint_32() that were accidentally removed from libpng-1.6.17. Changed PNG_INFO_cHNK and PNG_FREE_cHNK from 0xnnnn to 0xnnnnU in png.h (Robert C. Seacord). Removed dubious "#if INT_MAX" test from png.h that was added to libpng-1.6.19beta02 (John Bowler). Add ${INCLUDES} in scripts/genout.cmake.in (Bug report by Nixon Kwok). Updated LICENSE to say files in the contrib directory are not necessarily under the libpng license, and that some makefiles have other copyright owners. Added INTEL-SSE2 support (Mike Klein and Matt Sarett, Google, Inc.). Made contrib/libtests/timepng more robust. The code no longer gives up/fails on invalid PNG data, it just skips it (with error messages). The code no longer fails on PNG files with data beyond IEND. Options exist to use png_read_png (reading the whole image, not by row) and, in that case, to apply any of the supported transforms. This makes for more realistic testing; the decoded data actually gets used in a meaningful fashion (John Bowler). Fixed some misleading indentation (Krishnaraj Bhat). Version 1.6.22beta04 [April 5, 2016] Force GCC compilation to C89 if needed (Dagobert Michelsen). SSE filter speed improvements for bpp=3: memcpy-free implementations of load3() / store3(). call load3() only when needed at the end of a scanline. Version 1.6.22beta05 [April 27, 2016] Added PNG_FAST_FILTERS macro (defined as PNG_FILTER_NONE|PNG_FILTER_SUB|PNG_FILTER_UP). Various fixes for contrib/libtests/timepng.c Moved INTEL-SSE code from pngpriv.h into contrib/intel/intel_sse.patch. Fixed typo (missing underscore) in #define PNG_READ_16_TO_8_SUPPORTED (Bug report by Y.Ohashik). Version 1.6.22beta06 [May 5, 2016] Rebased contrib/intel_sse.patch. Quieted two Coverity issues in contrib/libtests/timepng.c. Fixed issues with scripts/genout.cmake.in (David Capello, Nixon Kwok): Added support to use multiple directories in ZLIBINCDIR variable, Fixed CMAKE_C_FLAGS with multiple values when genout is compiled on MSVC, Fixed pnglibconf.c compilation on OS X including the sysroot path. Version 1.6.22rc01 [May 14, 2016] No changes. Version 1.6.22rc02 [May 16, 2016] Removed contrib/timepng from default build; it does not build on platforms that don't supply clock_gettime(). Version 1.6.22rc03 [May 17, 2016] Restored contrib/timepng to default build but check for the presence of clock_gettime() in configure.ac and Makefile.am. Version 1.6.22 [May 26, 2016] No changes. Version 1.6.23beta01 [May 29, 2016] Stop a potential memory leak in png_set_tRNS() (Bug report by Ted Ying). Fixed the progressive reader to handle empty first IDAT chunk properly (patch by Timothy Nikkel). This bug was introduced in libpng-1.6.0 and only affected the libpng16 branch. Added tests in pngvalid.c to check zero-length IDAT chunks in various positions. Fixed the sequential reader to handle these more robustly (John Bowler). Version 1.6.23rc01 [June 2, 2016] Corrected progressive read input buffer in pngvalid.c. The previous version the code invariably passed just one byte at a time to libpng. The intent was to pass a random number of bytes in the range 0..511. Moved sse2 prototype from pngpriv.h to contrib/intel/intel_sse.patch. Added missing ")" in pngerror.c (Matt Sarrett). Version 1.6.23rc02 [June 4, 2016] Fixed undefined behavior in png_push_save_buffer(). Do not call memcpy() with a null source, even if count is zero (Leon Scroggins III). Version 1.6.23 [June 9, 2016] Fixed bad link to RFC2083 in png.5 (Nikola Forro). Version 1.6.24beta01 [June 11, 2016] Avoid potential overflow of the PNG_IMAGE_SIZE macro. This macro is not used within libpng, but is used in some of the examples. Version 1.6.24beta02 [June 23, 2016] Correct filter heuristic overflow handling. This was broken when the write filter code was moved out-of-line; if there is a single filter and the heuristic sum overflows the calculation of the filtered line is not completed. In versions prior to 1.6 the code was duplicated in-line and the check not performed, so the filter operation completed; however, in the multi-filter case where the sum is performed the 'none' filter would be selected if all the sums overflowed, even if it wasn't in the filter list. The fix to the first problem is simply to provide PNG_SIZE_MAX as the current lmins sum value; this means the sum can never exceed it and overflows silently. A reasonable compiler that does choose to inline the code will simply eliminate the sum check. The fix to the second problem is to use high precision arithmetic (this is implemented in 1.7), however a simple safe fix here is to chose the lowest numbered filter in the list from png_set_filter (this only works if the first problem is also fixed) (John Bowler). Use a more efficient absolute value calculation on SSE2 (Matthieu Darbois). Fixed the case where PNG_IMAGE_BUFFER_SIZE can overflow in the application as a result of the application using an increased 'row_stride'; previously png_image_finish_read only checked for overflow on the base calculation of components. (I.e. it checked for overflow of a 32-bit number on the total number of pixel components in the output format, not the possibly padded row length and not the number of bytes, which for linear formats is twice the number of components.) MSVC does not like '-(unsigned)', so replaced it with 0U-(unsigned) MSVC does not like (uInt) = -(unsigned) (i.e. as an initializer), unless the conversion is explicitly invoked by a cast. Put the SKIP definition in the correct place. It needs to come after the png.h include (see all the other .c files in contrib/libtests) because it depends on PNG_LIBPNG_VER. Removed the three compile warning options from the individual project files into the zlib.props globals. It increases the warning level from 4 to All and adds a list of the warnings that need to be turned off. This is semi-documentary; the intent is to tell libpng users which warnings have been examined and judged non-fixable at present. The warning about structure padding is fixable, but it would be a significant change (moving structure members around). Version 1.6.24beta03 [July 4, 2016] Optimized absolute value calculation in filter selection, similar to code in the PAETH decoder in pngrutil.c. Build with PNG_USE_ABS to use this. Added pngcp to the build together with a pngcp.dfa configuration test. Added high resolution timing to pngcp. Added "Common linking failures" section to INSTALL. Relocated misplaced #endif in png.c sRGB profile checking. Fixed two Coverity issues in pngcp.c. Version 1.6.24beta04 [July 8, 2016] Avoid filter-selection heuristic sum calculations in cases where only one filter is a candidate for selection. This trades off code size (added private png_setup_*_row_only() functions) for speed. Version 1.6.24beta05 [July 13, 2016] Fixed some indentation to comply with our coding style. Added contrib/tools/reindent. Version 1.6.24beta06 [July 18, 2016] Fixed more indentation to comply with our coding style. Eliminated unnecessary tests of boolean png_isaligned() vs 0. Version 1.6.24rc01 [July 25, 2016] No changes. Version 1.6.24rc02 [August 1, 2016] Conditionally compile SSE2 headers in contrib/intel/intel_sse.patch Conditionally compile png_decompress_chunk(). Version 1.6.24rc03 [August 2, 2016] Conditionally compile ARM_NEON headers in pngpriv.h Updated contrib/intel/intel_sse.patch Version 1.6.24[August 4, 2016] No changes. Version 1.6.25beta01 [August 12, 2016] Reject oversized iCCP profile immediately. Cleaned up PNG_DEBUG compile of pngtest.c. Conditionally compile png_inflate(). Version 1.6.25beta02 [August 18, 2016] Don't install pngcp; it conflicts with pngcp in the pngtools package. Minor editing of INSTALL, (whitespace, added copyright line) Version 1.6.25rc01 [August 24, 2016] No changes. Version 1.6.25rc02 [August 29, 2016] Added MIPS support (Mandar Sahastrabuddhe ). Only the UP filter is currently implemented. Version 1.6.25rc03 [August 29, 2016] Rebased contrib/intel/intel_sse.patch after the MIPS implementation. Version 1.6.25rc04 [August 30, 2016] Added MIPS support for SUB, AVG, and PAETH filters (Mandar Sahastrabuddhe). Version 1.6.25rc05 [August 30, 2016] Rebased contrib/intel/intel_sse.patch after the MIPS implementation update.. Version 1.6.25 [September 1, 2016] No changes. Version 1.6.26beta01 [September 26, 2016] Fixed handling zero length IDAT in pngfix (bug report by Agostino Sarubbo, bugfix by John Bowler). Do not issue a png_error() on read in png_set_pCAL() because png_handle_pCAL has allocated memory that libpng needs to free. Conditionally compile png_set_benign_errors() in pngread.c and pngtest.c Issue a png_benign_error instead of a png_error on ADLER32 mismatch while decoding compressed data chunks. Changed PNG_ZLIB_VERNUM to ZLIB_VERNUM in pngpriv.h, pngstruct.h, and pngrutil.c. If CRC handling of critical chunks has been set to PNG_CRC_QUIET_USE, ignore the ADLER32 checksum in the IDAT chunk as well as the chunk CRCs. Issue png_benign_error() on ADLER32 checksum mismatch instead of png_error(). Add tests/badcrc.png and tests/badadler.png to tests/pngtest. Merged pngtest.c with libpng-1.7.0beta84/pngtest.c Version 1.6.26beta02 [October 1, 2016] Updated the documentation about CRC and ADLER32 handling. Quieted 117 warnings from clang-3.8 in pngtrans.c, pngread.c, pngwrite.c, pngunknown.c, and pngvalid.c. Quieted 58 (out of 144) -Wconversion compiler warnings by changing flag definitions in pngpriv.h from 0xnnnn to 0xnnnnU and trivial changes in png.c, pngread.c, and pngwutil.c. Version 1.6.26beta03 [October 2, 2016] Removed contrib/libtests/*.orig and *.rej that slipped into the tarballs. Quieted the 86 remaining -Wconversion compiler warnings by revising the png_isaligned() macro and trivial changes in png.c, pngerror.c, pngget.c, pngmem.c, pngset.c, pngrtran.c, pngrutil.c, pngwtran.c, pngwrite.c, and pngwutil.c. Version 1.6.26beta04 [October 3, 2016] Quieted (bogus?) clang warnings about "absolute value has no effect" when PNG_USE_ABS is defined. Fixed offsets in contrib/intel/intel_sse.patch Version 1.6.26beta05 [October 6, 2016] Changed integer constant 4294967294 to unsigned 4294967294U in pngconf.h to avoid a signed/unsigned compare in the preprocessor. Version 1.6.26beta06 [October 7, 2016] Use zlib-1.2.8.1 inflateValidate() instead of inflateReset2() to optionally avoid ADLER32 evaluation. Version 1.6.26rc01 [October 12, 2016] No changes. Version 1.6.26 [October 20, 2016] Cosmetic change, "ptr != 0" to "ptr != NULL" in png.c and pngrutil.c Despammed email addresses (replaced "@" with " at "). Version 1.6.27beta01 [November 2, 2016] Restrict the new ADLER32-skipping to IDAT chunks. It broke iCCP chunk handling: an erroneous iCCP chunk would throw a png_error and reject the entire PNG image instead of rejecting just the iCCP chunk with a warning, if built with zlib-1.2.8.1. Version 1.6.27rc01 [December 27, 2016] Control ADLER32 checking with new PNG_IGNORE_ADLER32 option. Fixes an endless loop when handling erroneous ADLER32 checksums; bug introduced in libpng-1.6.26. Removed the use of a macro containing the pre-processor 'defined' operator. It is unclear whether this is valid; a macro that "generates" 'defined' is not permitted, but the use of the word "generates" within the C90 standard seems to imply more than simple substitution of an expression itself containing a well-formed defined operation. Added ARM support to CMakeLists.txt (Andreas Franek). Version 1.6.27 [December 29, 2016] Fixed a potential null pointer dereference in png_set_text_2() (bug report and patch by Patrick Keshishian, CVE-2016-10087). Version 1.6.28rc01 [January 3, 2017] Fixed arm/aarch64 detection in CMakeLists.txt (Gianfranco Costamagna). Added option to Cmake build allowing a custom location of zlib to be specified in a scenario where libpng is being built as a subproject alongside zlib by another project (Sam Serrels). Changed png_ptr->options from a png_byte to png_uint_32, to accommodate up to 16 options. Version 1.6.28rc02 [January 4, 2017] Added "include(GNUInstallDirs)" to CMakeLists.txt (Gianfranco Costamagna). Moved SSE2 optimization code into the main libpng source directory. Configure libpng with "configure --enable-intel-sse" or compile libpng with "-DPNG_INTEL_SSE" in CPPFLAGS to enable it. Version 1.6.28rc03 [January 4, 2017] Backed out the SSE optimization and last CMakeLists.txt to allow time for QA. Version 1.6.28 [January 5, 2017] No changes. Version 1.6.29beta01 [January 12, 2017] Readded "include(GNUInstallDirs)" to CMakeLists.txt (Gianfranco Costamagna). Moved SSE2 optimization code into the main libpng source directory. Configure libpng with "configure --enable-intel-sse" or compile libpng with "-DPNG_INTEL_SSE" in CPPFLAGS to enable it. Simplified conditional compilation in pngvalid.c, for AIX (Michael Felt). Version 1.6.29beta02 [February 22, 2017] Avoid conditional directives that break statements in pngrutil.c (Romero Malaquias) The contrib/examples/pngtopng.c recovery code was in the wrong "if" branches; the comments were correct. Added code for PowerPC VSX optimisation (Vadim Barkov). Version 1.6.29beta03 [March 1, 2017] Avoid potential overflow of shift operations in png_do_expand() (Aaron Boxer). Change test ZLIB_VERNUM >= 0x1281 to ZLIB_VERNUM >= 0x1290 in pngrutil.c because Solaris 11 distributes zlib-1.2.8.f that is older than 1.2.8.1, as suggested in zlib FAQ, item 24. Suppress clang warnings about implicit sign changes in png.c Version 1.6.29 [March 16, 2017] No changes. Version 1.6.30beta01 [April 1, 2017] Added missing "$(CPPFLAGS)" to the compile line for c.pic.o in makefile.linux and makefile.solaris-x86 (Cosmin). Revised documentation of png_get_error_ptr() in the libpng manual. Silence clang -Wcomma and const drop warnings (Viktor Szakats). Update Sourceforge URLs in documentation (https instead of http). Version 1.6.30beta02 [April 22, 2017] Document need to check for integer overflow when allocating a pixel buffer for multiple rows in contrib/gregbook, contrib/pngminus, example.c, and in the manual (suggested by Jaeseung Choi). This is similar to the bug reported against pngquant in CVE-2016-5735. Removed reference to the obsolete PNG_SAFE_LIMITS macro in the documentation. Version 1.6.30beta03 [May 22, 2017] Check for integer overflow in contrib/visupng and contrib/tools/genpng. Do not double evaluate CMAKE_SYSTEM_PROCESSOR in CMakeLists.txt. Test CMAKE_HOST_WIN32 instead of WIN32 in CMakeLists.txt. Fix some URL in documentation. Version 1.6.30beta04 [June 7, 2017] Avoid writing an empty IDAT when the last IDAT exactly fills the compression buffer (bug report by Brian Baird). This bug was introduced in libpng-1.6.0. Version 1.6.30rc01 [June 14, 2017] No changes. Version 1.6.30rc02 [June 25, 2017] Update copyright year in pnglibconf.h, make ltmain.sh executable. Add a reference to the libpng.download site in README. Version 1.6.30 [June 28, 2017] No changes. Version 1.6.31beta01 [July 5, 2017] Guard the definition of _POSIX_SOURCE in pngpriv.h (AIX already defines it; bug report by Michael Felt). Revised pngpriv.h to work around failure to compile arm/filter_neon.S ("typedef" directive is unrecognized by the assembler). The problem was introduced in libpng-1.6.30beta01. Added "Requires: zlib" to libpng.pc.in (Pieter Neerincx). Added special case for FreeBSD in arm/filter_neon.S (Maya Rashish). Version 1.6.31beta02 [July 8, 2017] Added instructions for disabling hardware optimizations in INSTALL. Added "--enable-hardware-optimizations" configuration flag to enable or disable all hardware optimizations with one flag. Version 1.6.31beta03 [July 9, 2017] Updated CMakeLists.txt to add INTEL_SSE and MIPS_MSA platforms. Changed "int" to "png_size_t" in intel/filter_sse2.c to prevent possible integer overflow (Bug report by John Bowler). Quieted "declaration after statement" warnings in intel/filter_sse2.c. Added scripts/makefile-linux-opt, which has hardware optimizations enabled. Version 1.6.31beta04 [July 11, 2017] Removed one of the GCC-7.1.0 'strict-overflow' warnings that result when integers appear on both sides of a compare. Worked around the others by forcing the strict-overflow setting in the relevant functions to a level where they are not reported (John Bowler). Changed "FALL THROUGH" comments to "FALLTHROUGH" because GCC doesn't like the space. Worked around some C-style casts from (void*) because g++ 5.4.0 objects to them. Increased the buffer size for 'sprint' to pass the gcc 7.1.0 'sprint overflow' check that is on by default with -Wall -Wextra. Version 1.6.31beta05 [July 13, 2017] Added eXIf chunk support. Version 1.6.31beta06 [July 17, 2017] Added a minimal eXIf chunk (with Orientation and FocalLengthIn35mmFilm tags) to pngtest.png. Version 1.6.31beta07 [July 18, 2017] Revised the eXIf chunk in pngtest.png to fix "Bad IFD1 Directory" warning. Version 1.6.31rc01 [July 19, 2017] No changes. Version 1.6.31rc02 [July 25, 2017] Fixed typo in example.c (png_free_image should be png_image_free) (Bug report by John Smith) Version 1.6.31 [July 27, 2017] No changes. Version 1.6.32beta01 [July 31, 2017] Avoid possible NULL dereference in png_handle_eXIf when benign_errors are allowed. Avoid leaking the input buffer "eXIf_buf". Eliminated png_ptr->num_exif member from pngstruct.h and added num_exif to arguments for png_get_eXIf() and png_set_eXIf(). Added calls to png_handle_eXIf(() in pngread.c and png_write_eXIf() in pngwrite.c, and made various other fixes to png_write_eXIf(). Changed name of png_get_eXIF and png_set_eXIf() to png_get_eXIf_1() and png_set_eXIf_1(), respectively, to avoid breaking API compatibility with libpng-1.6.31. Version 1.6.32beta02 [August 1, 2017] Updated contrib/libtests/pngunknown.c with eXIf chunk. Version 1.6.32beta03 [August 2, 2017] Initialized btoa[] in pngstest.c Stop memory leak when returning from png_handle_eXIf() with an error (Bug report from the OSS-fuzz project). Version 1.6.32beta04 [August 2, 2017] Replaced local eXIf_buf with info_ptr->eXIf_buf in png_handle_eXIf(). Update libpng.3 and libpng-manual.txt about eXIf functions. Version 1.6.32beta05 [August 2, 2017] Restored png_get_eXIf() and png_set_eXIf() to maintain API compatibility. Version 1.6.32beta06 [August 2, 2017] Removed png_get_eXIf_1() and png_set_eXIf_1(). Version 1.6.32beta07 [August 3, 2017] Check length of all chunks except IDAT against user limit to fix an OSS-fuzz issue (Fixes CVE-2017-12652). Version 1.6.32beta08 [August 3, 2017] Check length of IDAT against maximum possible IDAT size, accounting for height, rowbytes, interlacing and zlib/deflate overhead. Restored png_get_eXIf_1() and png_set_eXIf_1(), because strlen(eXIf_buf) does not work (the eXIf chunk data can contain zeroes). Version 1.6.32beta09 [August 3, 2017] Require cmake-2.8.8 in CMakeLists.txt. Revised symlink creation, no longer using deprecated cmake LOCATION feature (Clifford Yapp). Fixed five-byte error in the calculation of IDAT maximum possible size. Version 1.6.32beta10 [August 5, 2017] Moved chunk-length check into a png_check_chunk_length() private function (Suggested by Max Stepin). Moved bad pngs from tests to contrib/libtests/crashers Moved testing of bad pngs into a separate tests/pngtest-badpngs script Added the --xfail (expected FAIL) option to pngtest.c. It writes XFAIL in the output but PASS for the libpng test. Require cmake-3.0.2 in CMakeLists.txt (Clifford Yapp). Fix "const" declaration info_ptr argument to png_get_eXIf_1() and the num_exif argument to png_get_eXIf_1() (Github Issue 171). Version 1.6.32beta11 [August 7, 2017] Added "eXIf" to "chunks_to_ignore[]" in png_set_keep_unknown_chunks(). Added huge_IDAT.png and empty_ancillary_chunks.png to testpngs/crashers. Make pngtest --strict, --relax, --xfail options imply -m (multiple). Removed unused chunk_name parameter from png_check_chunk_length(). Relocated setting free_me for eXIf data, to stop an OSS-fuzz leak. Initialize profile_header[] in png_handle_iCCP() to fix OSS-fuzz issue. Initialize png_ptr->row_buf[0] to 255 in png_read_row() to fix OSS-fuzz UMR. Attempt to fix a UMR in png_set_text_2() to fix OSS-fuzz issue. Increase minimum zlib stream from 9 to 14 in png_handle_iCCP(), to account for the minimum 'deflate' stream, and relocate the test to a point after the keyword has been read. Check that the eXIf chunk has at least 2 bytes and begins with "II" or "MM". Version 1.6.32rc01 [August 18, 2017] Added a set of "huge_xxxx_chunk.png" files to contrib/testpngs/crashers, one for each known chunk type, with length = 2GB-1. Check for 0 return from png_get_rowbytes() and added some (size_t) typecasts in contrib/pngminus/*.c to stop some Coverity issues (162705, 162706, and 162707). Renamed chunks in contrib/testpngs/crashers to avoid having files whose names differ only in case; this causes problems with some platforms (github issue #172). Version 1.6.32rc02 [August 22, 2017] Added contrib/oss-fuzz directory which contains files used by the oss-fuzz project (https://github.com/google/oss-fuzz/tree/master/projects/libpng). Version 1.6.32 [August 24, 2017] No changes. Version 1.6.33beta01 [August 28, 2017] Added PNGMINUS_UNUSED macro to contrib/pngminus/p*.c and added missing parenthesis in contrib/pngminus/pnm2png.c (bug report by Christian Hesse). Fixed off-by-one error in png_do_check_palette_indexes() (Bug report by Mick P., Source Forge Issue #269). Version 1.6.33beta02 [September 3, 2017] Initialize png_handler.row_ptr in contrib/oss-fuzz/libpng_read_fuzzer.cc to fix shortlived oss-fuzz issue 3234. Compute a larger limit on IDAT because some applications write a deflate buffer for each row (Bug report by Andrew Church). Use current date (DATE) instead of release-date (RDATE) in last changed date of contrib/oss-fuzz files. Enabled ARM support in CMakeLists.txt (Bernd Kuhls). Version 1.6.33beta03 [September 14, 2017] Fixed incorrect typecast of some arguments to png_malloc() and png_calloc() that were png_uint_32 instead of png_alloc_size_t (Bug report by "irwir" in Github libpng issue #175). Use pnglibconf.h.prebuilt when building for ANDROID with cmake (Github issue 162, by rcdailey). Version 1.6.33rc01 [September 20, 2017] Initialize memory allocated by png_inflate to zero, using memset, to stop an oss-fuzz "use of uninitialized value" detection in png_set_text_2() due to truncated iTXt or zTXt chunk. Initialize memory allocated by png_read_buffer to zero, using memset, to stop an oss-fuzz "use of uninitialized value" detection in png_icc_check_tag_table() due to truncated iCCP chunk. Removed a redundant test (suggested by "irwir" in Github issue #180). Version 1.6.33rc02 [September 23, 2017] Added an interlaced version of each file in contrib/pngsuite. Relocate new memset() call in pngrutil.c. Removed more redundant tests (suggested by "irwir" in Github issue #180). Add support for loading images with associated alpha in the Simplified API (Samuel Williams). Version 1.6.33 [September 28, 2017] Revert contrib/oss-fuzz/libpng_read_fuzzer.cc to libpng-1.6.32 state. Initialize png_handler.row_ptr in contrib/oss-fuzz/libpng_read_fuzzer.cc Add end_info structure and png_read_end() to the libpng fuzzer. Version 1.6.34 [September 29, 2017] Removed contrib/pngsuite/i*.png; some of them caused test failures. Version 1.6.35beta01 [March 6, 2018] Restored 21 of the contrib/pngsuite/i*.png, which do not cause test failures. Placed the remainder in contrib/pngsuite/interlaced/i*.png. Added calls to png_set_*() transforms commonly used by browsers to the fuzzer. Removed some unnecessary brackets in pngrtran.c Fixed miscellaneous typos (Patch by github user "luzpaz"). Change "ASM C" to "C ASM" in CMakeLists.txt Fixed incorrect handling of bKGD chunk in sub-8-bit files (Cosmin) Added hardware optimization directories to zip and 7z distributions. Fixed incorrect bitmask for options. Fixed many spelling typos. Version 1.6.35beta02 [March 28, 2018] Make png_get_iCCP consistent with man page (allow compression-type argument to be NULL, bug report by Lenard Szolnoki). Version 1.6.35 [July 15, 2018] Replaced the remaining uses of png_size_t with size_t (Cosmin) Fixed the calculation of row_factor in png_check_chunk_length (reported by Thuan Pham in SourceForge issue #278) Added missing parentheses to a macro definition (suggested by "irwir" in GitHub issue #216) Version 1.6.36 [December 1, 2018] Optimized png_do_expand_palette for ARM processors. Improved performance by around 10-22% on a recent ARM Chromebook. (Contributed by Richard Townsend, ARM Holdings) Fixed manipulation of machine-specific optimization options. (Contributed by Vicki Pfau) Used memcpy instead of manual pointer arithmetic on Intel SSE2. (Contributed by Samuel Williams) Fixed build errors with MSVC on ARM64. (Contributed by Zhijie Liang) Fixed detection of libm in CMakeLists. (Contributed by Cameron Cawley) Fixed incorrect creation of pkg-config file in CMakeLists. (Contributed by Kyle Bentley) Fixed the CMake build on Windows MSYS by avoiding symlinks. Fixed a build warning on OpenBSD. (Contributed by Theo Buehler) Fixed various typos in comments. (Contributed by "luz.paz") Raised the minimum required CMake version from 3.0.2 to 3.1. Removed yet more of the vestigial support for pre-ANSI C compilers. Removed ancient makefiles for ancient systems that have been broken across all previous libpng-1.6.x versions. Removed the Y2K compliance statement and the export control information. Applied various code style and documentation fixes. Version 1.6.37 [April 14, 2019] Fixed a use-after-free vulnerability (CVE-2019-7317) in png_image_free. Fixed a memory leak in the ARM NEON implementation of png_do_expand_palette. Fixed a memory leak in pngtest.c. Fixed two vulnerabilities (CVE-2018-14048, CVE-2018-14550) in contrib/pngminus; refactor. Changed the license of contrib/pngminus to MIT; refresh makefile and docs. (Contributed by Willem van Schaik) Fixed a typo in the libpng license v2. (Contributed by Miguel Ojeda) Added makefiles for AddressSanitizer-enabled builds. Cleaned up various makefiles. Version 1.6.38 [September 14, 2022] Added configurations and scripts for continuous integration. Fixed various errors in the handling of tRNS, hIST and eXIf. Implemented many stability improvements across all platforms. Updated the internal documentation. Version 1.6.39 [November 20, 2022] Changed the error handler of oversized chunks (i.e. larger than PNG_USER_CHUNK_MALLOC_MAX) from png_chunk_error to png_benign_error. Fixed a buffer overflow error in contrib/tools/pngfix. Fixed a memory leak (CVE-2019-6129) in contrib/tools/pngcp. Disabled the ARM Neon optimizations by default in the CMake file, following the default behavior of the configure script. Allowed configure.ac to work with the trunk version of autoconf. Removed the support for "install" targets from the legacy makefiles; removed the obsolete makefile.cegcc. Cleaned up the code and updated the internal documentation. Version 1.6.40 [June 21, 2023] Fixed the eXIf chunk multiplicity checks. Fixed a memory leak in pCAL processing. Corrected the validity report about tRNS inside png_get_valid(). Fixed various build issues on *BSD, Mac and Windows. Updated the configurations and the scripts for continuous integration. Cleaned up the code, the build scripts, and the documentation. Version 1.6.41 [January 24, 2024] Added SIMD-optimized code for the LoongArch LSX hardware. (Contributed by GuXiWei, JinBo and ZhangLixia) Fixed the run-time discovery of MIPS MSA hardware. (Contributed by Sui Jingfeng) Fixed an off-by-one error in the function png_do_check_palette_indexes(), which failed to recognize errors that might have existed in the first column of a broken palette-encoded image. This was a benign regression accidentally introduced in libpng-1.6.33. No pixel was harmed. (Contributed by Adam Richter; reviewed by John Bowler) Fixed, improved and modernized the contrib/pngminus programs, i.e., png2pnm.c and pnm2png.c Removed old and peculiar portability hacks that were meant to silence warnings issued by gcc version 7.1 alone. (Contributed by John Bowler) Fixed and modernized the CMake file, and raised the minimum required CMake version from 3.1 to 3.6. (Contributed by Clinton Ingram, Timothy Lyanguzov, Tyler Kropp, et al.) Allowed the configure script to disable the building of auxiliary tools and tests, thus catching up with the CMake file. (Contributed by Carlo Bramini) Fixed a build issue on Mac. (Contributed by Zixu Wang) Moved the Autoconf macro files to scripts/autoconf. Moved the CMake files (except for the main CMakeLists.txt) to scripts/cmake and moved the list of their contributing authors to scripts/cmake/AUTHORS.md Updated the CI configurations and scripts. Relicensed the CI scripts to the MIT License. Improved the test coverage. (Contributed by John Bowler) Version 1.6.42 [January 29, 2024] Fixed the implementation of the macro function png_check_sig(). This was an API regression, introduced in libpng-1.6.41. (Reported by Matthieu Darbois) Fixed and updated the libpng manual. Version 1.6.43 [February 23, 2024] Fixed the row width check in png_check_IHDR(). This corrected a bug that was specific to the 16-bit platforms, and removed a spurious compiler warning from the 64-bit builds. (Reported by Jacek Caban; fixed by John Bowler) Added eXIf chunk support to the push-mode reader in pngpread.c. (Contributed by Chris Blume) Added contrib/pngexif for the benefit of the users who would like to inspect the content of eXIf chunks. Added contrib/conftest/basic.dfa, a basic build-time configuration. (Contributed by John Bowler) Fixed a preprocessor condition in pngread.c that broke build-time configurations like contrib/conftest/pngcp.dfa. (Contributed by John Bowler) Added CMake build support for LoongArch LSX. (Contributed by GuXiWei) Fixed a CMake build error that occurred under a peculiar state of the dependency tree. This was a regression introduced in libpng-1.6.41. (Contributed by Dan Rosser) Marked the installed libpng headers as system headers in CMake. (Contributed by Benjamin Buch) Updated the build support for RISCOS. (Contributed by Cameron Cawley) Updated the makefiles to allow cross-platform builds to initialize conventional make variables like AR and ARFLAGS. Added various improvements to the CI scripts in areas like version consistency verification and text linting. Added version consistency verification to pngtest.c also. Send comments/corrections/commendations to png-mng-implement at lists.sf.net. Subscription is required; visit https://lists.sourceforge.net/lists/listinfo/png-mng-implement to subscribe. libpng-1.6.43/CMakeLists.txt000066400000000000000000001301141456606525400156350ustar00rootroot00000000000000 # CMakeLists.txt - CMake lists for libpng # # Copyright (c) 2018-2024 Cosmin Truta. # Copyright (c) 2007-2018 Glenn Randers-Pehrson. # Originally written by Christian Ehrlicher, 2007. # # Use, modification and distribution are subject to # the same licensing terms and conditions as libpng. # Please see the copyright notice in png.h or visit # http://libpng.org/pub/png/src/libpng-LICENSE.txt # # For copyright and licensing purposes, please see # the accompanying file scripts/cmake/AUTHORS.md # # SPDX-License-Identifier: libpng-2.0 cmake_minimum_required(VERSION 3.6) set(PNGLIB_MAJOR 1) set(PNGLIB_MINOR 6) set(PNGLIB_REVISION 43) set(PNGLIB_SUBREVISION 0) #set(PNGLIB_SUBREVISION "git") set(PNGLIB_VERSION ${PNGLIB_MAJOR}.${PNGLIB_MINOR}.${PNGLIB_REVISION}) set(PNGLIB_ABI_VERSION ${PNGLIB_MAJOR}${PNGLIB_MINOR}) set(PNGLIB_SHARED_VERSION ${PNGLIB_ABI_VERSION}.${PNGLIB_REVISION}.${PNGLIB_SUBREVISION}) project(libpng VERSION ${PNGLIB_VERSION} LANGUAGES C ASM) if(POLICY CMP0074) # Allow find_package() to use the ZLIB_ROOT variable, if available. cmake_policy(SET CMP0074 NEW) endif() include(CheckCSourceCompiles) include(GNUInstallDirs) # Allow the users to specify an application-specific API prefix for libpng # vendoring purposes. A standard libpng build should have no such prefix. set(PNG_PREFIX "" CACHE STRING "Prefix to prepend to the API function names") # Allow the users to override the postfix appended to debug library file names. # Previously, we used to set CMAKE_DEBUG_POSTFIX globally. That variable should # not be cached, however, because doing so would affect all projects processed # after libpng, in unexpected and undesirable ways. set(PNG_DEBUG_POSTFIX "d" CACHE STRING "Postfix to append to library file names under the Debug configuration") # Allow the users to import their own extra configuration settings. set(DFA_XTRA "" CACHE FILEPATH "File containing extra configuration settings") # Allow the users to switch on/off various library build types. option(PNG_SHARED "Build libpng as a shared library" ON) option(PNG_STATIC "Build libpng as a static library" ON) if(APPLE) option(PNG_FRAMEWORK "Build libpng as a framework bundle" ON) endif() # Allow the users to switch on/off the auxiliary build and test artifacts. # These artifacts are NOT part of libpng proper, and are subject to change # at any time. option(PNG_TESTS "Build the libpng tests" ON) # Same as above, but for the third-party tools. # Although these tools are targetted at development environments only, # the users are allowed to override the option to build by default. if (ANDROID OR IOS) option(PNG_TOOLS "Build the libpng tools" OFF) else() option(PNG_TOOLS "Build the libpng tools" ON) endif() # Maintain backwards compatibility with the deprecated option PNG_EXECUTABLES. option(PNG_EXECUTABLES "[Deprecated; please use PNG_TOOLS]" ON) if(NOT PNG_EXECUTABLES) message(DEPRECATION "The option PNG_EXECUTABLES has been deprecated in favour of PNG_TOOLS") if(PNG_TOOLS) message(AUTHOR_WARNING "Setting PNG_TOOLS to ${PNG_EXECUTABLES}, to stay compatible with PNG_EXECUTABLES") set(PNG_TOOLS "${PNG_EXECUTABLES}") endif() endif() # Allow the users to configure various compilation options. option(PNG_DEBUG "Enable debug output" OFF) option(PNG_HARDWARE_OPTIMIZATIONS "Enable hardware optimizations" ON) # Allow the users to specify a custom location of zlib. # This option is deprecated, and no longer needed with CMake 3.12 and newer. # Under the CMake policy CMP0074, if zlib is being built alongside libpng as a # subproject, its location can be passed on to CMake via the ZLIB_ROOT variable. option(PNG_BUILD_ZLIB "Custom zlib location, else find_package is used" OFF) if(NOT PNG_BUILD_ZLIB) find_package(ZLIB REQUIRED) elseif(POLICY CMP0074) if("x${ZLIB_ROOT}" STREQUAL "x") message(DEPRECATION "The option PNG_BUILD_ZLIB has been deprecated; please use ZLIB_ROOT instead") else() message(SEND_ERROR "The option PNG_BUILD_ZLIB=${PNG_BUILD_ZLIB} and " "the variable ZLIB_ROOT=\"${ZLIB_ROOT}\" are mutually exclusive") endif() endif() if(UNIX AND NOT APPLE AND NOT BEOS AND NOT HAIKU AND NOT EMSCRIPTEN) find_library(M_LIBRARY m) if(M_LIBRARY) set(M_LIBRARY m) else() set(M_LIBRARY "") endif() else() # libm is not available or not needed. endif() # CMake currently sets CMAKE_SYSTEM_PROCESSOR to one of x86_64 or arm64 on macOS, # based upon the OS architecture, not the target architecture. As such, we need # to check CMAKE_OSX_ARCHITECTURES to identify which hardware-specific flags to # enable. Note that this will fail if you attempt to build a universal binary in # a single CMake invocation. if (APPLE AND CMAKE_OSX_ARCHITECTURES) set(TARGET_ARCH ${CMAKE_OSX_ARCHITECTURES}) else() set(TARGET_ARCH ${CMAKE_SYSTEM_PROCESSOR}) endif() if(PNG_HARDWARE_OPTIMIZATIONS) # Set definitions and sources for ARM. if(TARGET_ARCH MATCHES "^(ARM|arm|aarch)") if(TARGET_ARCH MATCHES "^(ARM64|arm64|aarch64)") set(PNG_ARM_NEON_POSSIBLE_VALUES on off) set(PNG_ARM_NEON "on" CACHE STRING "Enable ARM NEON optimizations: on|off; on is default") else() set(PNG_ARM_NEON_POSSIBLE_VALUES check on off) set(PNG_ARM_NEON "off" CACHE STRING "Enable ARM NEON optimizations: check|on|off; off is default") endif() set_property(CACHE PNG_ARM_NEON PROPERTY STRINGS ${PNG_ARM_NEON_POSSIBLE_VALUES}) list(FIND PNG_ARM_NEON_POSSIBLE_VALUES ${PNG_ARM_NEON} index) if(index EQUAL -1) message(FATAL_ERROR "PNG_ARM_NEON must be one of [${PNG_ARM_NEON_POSSIBLE_VALUES}]") elseif(NOT PNG_ARM_NEON STREQUAL "off") set(libpng_arm_sources arm/arm_init.c arm/filter_neon_intrinsics.c arm/palette_neon_intrinsics.c) if(NOT MSVC) list(APPEND libpng_arm_sources arm/filter_neon.S) endif() if(PNG_ARM_NEON STREQUAL "on") add_definitions(-DPNG_ARM_NEON_OPT=2) elseif(PNG_ARM_NEON STREQUAL "check") add_definitions(-DPNG_ARM_NEON_CHECK_SUPPORTED) endif() else() add_definitions(-DPNG_ARM_NEON_OPT=0) endif() endif() # Set definitions and sources for PowerPC. if(TARGET_ARCH MATCHES "^(powerpc|ppc64)") set(PNG_POWERPC_VSX_POSSIBLE_VALUES on off) set(PNG_POWERPC_VSX "on" CACHE STRING "Enable POWERPC VSX optimizations: on|off; on is default") set_property(CACHE PNG_POWERPC_VSX PROPERTY STRINGS ${PNG_POWERPC_VSX_POSSIBLE_VALUES}) list(FIND PNG_POWERPC_VSX_POSSIBLE_VALUES ${PNG_POWERPC_VSX} index) if(index EQUAL -1) message(FATAL_ERROR "PNG_POWERPC_VSX must be one of [${PNG_POWERPC_VSX_POSSIBLE_VALUES}]") elseif(NOT PNG_POWERPC_VSX STREQUAL "off") set(libpng_powerpc_sources powerpc/powerpc_init.c powerpc/filter_vsx_intrinsics.c) if(PNG_POWERPC_VSX STREQUAL "on") add_definitions(-DPNG_POWERPC_VSX_OPT=2) endif() else() add_definitions(-DPNG_POWERPC_VSX_OPT=0) endif() endif() # Set definitions and sources for Intel. if(TARGET_ARCH MATCHES "^(i[3-6]86|x86|AMD64)") set(PNG_INTEL_SSE_POSSIBLE_VALUES on off) set(PNG_INTEL_SSE "on" CACHE STRING "Enable INTEL_SSE optimizations: on|off; on is default") set_property(CACHE PNG_INTEL_SSE PROPERTY STRINGS ${PNG_INTEL_SSE_POSSIBLE_VALUES}) list(FIND PNG_INTEL_SSE_POSSIBLE_VALUES ${PNG_INTEL_SSE} index) if(index EQUAL -1) message(FATAL_ERROR "PNG_INTEL_SSE must be one of [${PNG_INTEL_SSE_POSSIBLE_VALUES}]") elseif(NOT PNG_INTEL_SSE STREQUAL "off") set(libpng_intel_sources intel/intel_init.c intel/filter_sse2_intrinsics.c) if(PNG_INTEL_SSE STREQUAL "on") add_definitions(-DPNG_INTEL_SSE_OPT=1) endif() else() add_definitions(-DPNG_INTEL_SSE_OPT=0) endif() endif() # Set definitions and sources for MIPS. if(TARGET_ARCH MATCHES "^(mipsel|mips64el)") set(PNG_MIPS_MSA_POSSIBLE_VALUES on off) set(PNG_MIPS_MSA "on" CACHE STRING "Enable MIPS_MSA optimizations: on|off; on is default") set_property(CACHE PNG_MIPS_MSA PROPERTY STRINGS ${PNG_MIPS_MSA_POSSIBLE_VALUES}) list(FIND PNG_MIPS_MSA_POSSIBLE_VALUES ${PNG_MIPS_MSA} index_msa) if(index_msa EQUAL -1) message(FATAL_ERROR "PNG_MIPS_MSA must be one of [${PNG_MIPS_MSA_POSSIBLE_VALUES}]") endif() set(PNG_MIPS_MMI_POSSIBLE_VALUES on off) set(PNG_MIPS_MMI "on" CACHE STRING "Enable MIPS_MMI optimizations: on|off; on is default") set_property(CACHE PNG_MIPS_MMI PROPERTY STRINGS ${PNG_MIPS_MMI_POSSIBLE_VALUES}) list(FIND PNG_MIPS_MMI_POSSIBLE_VALUES ${PNG_MIPS_MMI} index_mmi) if(index_mmi EQUAL -1) message(FATAL_ERROR "PNG_MIPS_MMI must be one of [${PNG_MIPS_MMI_POSSIBLE_VALUES}]") endif() if(PNG_MIPS_MSA STREQUAL "on" AND PNG_MIPS_MMI STREQUAL "on") set(libpng_mips_sources mips/mips_init.c mips/filter_msa_intrinsics.c mips/filter_mmi_inline_assembly.c) add_definitions(-DPNG_MIPS_MSA_OPT=2) add_definitions(-DPNG_MIPS_MMI_OPT=1) elseif(PNG_MIPS_MSA STREQUAL "on") set(libpng_mips_sources mips/mips_init.c mips/filter_msa_intrinsics.c) add_definitions(-DPNG_MIPS_MSA_OPT=2) add_definitions(-DPNG_MIPS_MMI_OPT=0) elseif(PNG_MIPS_MMI STREQUAL "on") set(libpng_mips_sources mips/mips_init.c mips/filter_mmi_inline_assembly.c) add_definitions(-DPNG_MIPS_MSA_OPT=0) add_definitions(-DPNG_MIPS_MMI_OPT=1) else() add_definitions(-DPNG_MIPS_MSA_OPT=0) add_definitions(-DPNG_MIPS_MMI_OPT=0) endif() endif() # Set definitions and sources for LoongArch. if(TARGET_ARCH MATCHES "^(loongarch)") include(CheckCCompilerFlag) set(PNG_LOONGARCH_LSX_POSSIBLE_VALUES on off) set(PNG_LOONGARCH_LSX "on" CACHE STRING "Enable LOONGARCH_LSX optimizations: on|off; on is default") set_property(CACHE PNG_LOONGARCH_LSX PROPERTY STRINGS ${PNG_LOONGARCH_LSX_POSSIBLE_VALUES}) list(FIND PNG_LOONGARCH_LSX_POSSIBLE_VALUES ${PNG_LOONGARCH_LSX} index) if(index EQUAL -1) message(FATAL_ERROR "PNG_LOONGARCH_LSX must be one of [${PNG_LOONGARCH_LSX_POSSIBLE_VALUES}]") elseif(NOT PNG_LOONGARCH_LSX STREQUAL "off") CHECK_C_COMPILER_FLAG("-mlsx" COMPILER_SUPPORTS_LSX) if(COMPILER_SUPPORTS_LSX) set(libpng_loongarch_sources loongarch/loongarch_lsx_init.c loongarch/filter_lsx_intrinsics.c) set_source_files_properties(${libpng_loongarch_sources} PROPERTIES COMPILE_FLAGS "-mlsx") add_definitions(-DPNG_LOONGARCH_LSX_OPT=1) else() message(FATAL_ERROR "Compiler does not support -mlsx option") endif() else() add_definitions(-DPNG_LOONGARCH_LSX_OPT=0) endif() endif() else(PNG_HARDWARE_OPTIMIZATIONS) # Set definitions and sources for ARM. if(TARGET_ARCH MATCHES "^(ARM|arm|aarch)") add_definitions(-DPNG_ARM_NEON_OPT=0) endif() # Set definitions and sources for PowerPC. if(TARGET_ARCH MATCHES "^(powerpc|ppc64)") add_definitions(-DPNG_POWERPC_VSX_OPT=0) endif() # Set definitions and sources for Intel. if(TARGET_ARCH MATCHES "^(i[3-6]86|x86|AMD64)") add_definitions(-DPNG_INTEL_SSE_OPT=0) endif() # Set definitions and sources for MIPS. if(TARGET_ARCH MATCHES "^(mipsel|mips64el)") add_definitions(-DPNG_MIPS_MSA_OPT=0) endif() # Set definitions and sources for LoongArch. if(TARGET_ARCH MATCHES "^(loongarch)") add_definitions(-DPNG_LOONGARCH_LSX_OPT=0) endif() endif(PNG_HARDWARE_OPTIMIZATIONS) option(ld-version-script "Enable linker version script" ON) if(ld-version-script AND NOT ANDROID AND NOT APPLE) # Check if LD supports linker scripts. file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/conftest.map" " VERS_1 { global: sym1; local: *; }; VERS_2 { global: sym2; main; } VERS_1; ") set(_SAVED_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) if(NOT CMAKE_HOST_SOLARIS) # Avoid using CMAKE_SHARED_LIBRARY_C_FLAGS in version script checks on # Solaris, because of an incompatibility with the Solaris link editor. list(APPEND CMAKE_REQUIRED_FLAGS ${CMAKE_SHARED_LIBRARY_C_FLAGS}) endif() list(APPEND CMAKE_REQUIRED_FLAGS "-Wl,--version-script='${CMAKE_CURRENT_BINARY_DIR}/conftest.map'") check_c_source_compiles(" void sym1(void) {} void sym2(void) {} int main(void) { return 0; } " HAVE_LD_VERSION_SCRIPT) if(NOT HAVE_LD_VERSION_SCRIPT) set(CMAKE_REQUIRED_FLAGS ${_SAVED_CMAKE_REQUIRED_FLAGS}) if(NOT CMAKE_HOST_SOLARIS) # Again, avoid using CMAKE_SHARED_LIBRARY_C_FLAGS in version script # checks on Solaris. list(APPEND CMAKE_REQUIRED_FLAGS ${CMAKE_SHARED_LIBRARY_C_FLAGS}) endif() list(APPEND CMAKE_REQUIRED_FLAGS "-Wl,-M -Wl,${CMAKE_CURRENT_BINARY_DIR}/conftest.map") check_c_source_compiles(" void sym1(void) {} void sym2(void) {} int main(void) { return 0; } " HAVE_SOLARIS_LD_VERSION_SCRIPT) endif() set(CMAKE_REQUIRED_FLAGS ${_SAVED_CMAKE_REQUIRED_FLAGS}) file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/conftest.map") endif() # Find an AWK language processor. # Start with specific AWK implementations like gawk and nawk, which are # known to work with our scripts, then fall back to the system awk. find_program(AWK NAMES gawk nawk awk) if(AWK) message(STATUS "Found AWK program: ${AWK}") else() message(STATUS "Could not find an AWK-compatible program") endif() include_directories(${CMAKE_CURRENT_BINARY_DIR}) if(NOT AWK OR ANDROID OR IOS) # No awk available to generate sources; use pre-built pnglibconf.h configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.h.prebuilt ${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h) add_custom_target(png_genfiles) else() # Copy the awk scripts, converting their line endings to Unix (LF) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/checksym.awk ${CMAKE_CURRENT_BINARY_DIR}/scripts/checksym.awk @ONLY NEWLINE_STYLE LF) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/options.awk ${CMAKE_CURRENT_BINARY_DIR}/scripts/options.awk @ONLY NEWLINE_STYLE LF) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/dfn.awk ${CMAKE_CURRENT_BINARY_DIR}/scripts/dfn.awk @ONLY NEWLINE_STYLE LF) # Generate .chk from .out with awk: # generate_chk(INPUT inputfile OUTPUT outputfile [DEPENDS dep1 [dep2...]]) function(generate_chk) set(options) set(oneValueArgs INPUT OUTPUT) set(multiValueArgs DEPENDS) cmake_parse_arguments(_GC "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) if(NOT _GC_INPUT) message(FATAL_ERROR "generate_chk: Missing INPUT argument") endif() if(NOT _GC_OUTPUT) message(FATAL_ERROR "generate_chk: Missing OUTPUT argument") endif() add_custom_command(OUTPUT "${_GC_OUTPUT}" COMMAND "${CMAKE_COMMAND}" "-DINPUT=${_GC_INPUT}" "-DOUTPUT=${_GC_OUTPUT}" -P "${CMAKE_CURRENT_BINARY_DIR}/scripts/cmake/genchk.cmake" DEPENDS "${_GC_INPUT}" ${_GC_DEPENDS} WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") endfunction() # Generate .out from .c with awk # generate_out(INPUT inputfile OUTPUT outputfile [DEPENDS dep1 [dep2...]]) function(generate_out) set(options) set(oneValueArgs INPUT OUTPUT) set(multiValueArgs DEPENDS) cmake_parse_arguments(_GO "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) if(NOT _GO_INPUT) message(FATAL_ERROR "generate_out: Missing INPUT argument") endif() if(NOT _GO_OUTPUT) message(FATAL_ERROR "generate_out: Missing OUTPUT argument") endif() add_custom_command(OUTPUT "${_GO_OUTPUT}" COMMAND "${CMAKE_COMMAND}" "-DINPUT=${_GO_INPUT}" "-DOUTPUT=${_GO_OUTPUT}" -P "${CMAKE_CURRENT_BINARY_DIR}/scripts/cmake/genout.cmake" DEPENDS "${_GO_INPUT}" ${_GO_DEPENDS} WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") endfunction() # Generate specific source file with awk # generate_source(OUTPUT outputfile [DEPENDS dep1 [dep2...]]) function(generate_source) set(options) set(oneValueArgs OUTPUT) set(multiValueArgs DEPENDS) cmake_parse_arguments(_GSO "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) if(NOT _GSO_OUTPUT) message(FATAL_ERROR "generate_source: Missing OUTPUT argument") endif() add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${_GSO_OUTPUT}" COMMAND "${CMAKE_COMMAND}" "-DOUTPUT=${_GSO_OUTPUT}" -P "${CMAKE_CURRENT_BINARY_DIR}/scripts/cmake/gensrc.cmake" DEPENDS ${_GSO_DEPENDS} WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") endfunction() # Copy file # generate_copy(INPUT inputfile OUTPUT outputfile [DEPENDS dep1 [dep2...]]) function(generate_copy) set(options) set(oneValueArgs INPUT OUTPUT) set(multiValueArgs DEPENDS) cmake_parse_arguments(_GCO "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) if(NOT _GCO_INPUT) message(FATAL_ERROR "generate_copy: Missing INPUT argument") endif() if(NOT _GCO_OUTPUT) message(FATAL_ERROR "generate_copy: Missing OUTPUT argument") endif() add_custom_command(OUTPUT "${_GCO_OUTPUT}" COMMAND "${CMAKE_COMMAND}" -E remove "${_GCO_OUTPUT}" COMMAND "${CMAKE_COMMAND}" -E copy "${_GCO_INPUT}" "${_GCO_OUTPUT}" DEPENDS "${source}" ${_GCO_DEPENDS}) endfunction() # Generate scripts/pnglibconf.h generate_source(OUTPUT "scripts/pnglibconf.c" DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.dfa" "${CMAKE_CURRENT_BINARY_DIR}/scripts/options.awk" "${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h") add_custom_target(png_scripts_pnglibconf_c DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/scripts/pnglibconf.c") # Generate pnglibconf.c generate_source(OUTPUT "pnglibconf.c" DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.dfa" "${CMAKE_CURRENT_BINARY_DIR}/scripts/options.awk" "${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h") add_custom_target(pnglibconf_c DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.c") if(PNG_PREFIX) set(PNGLIBCONF_H_EXTRA_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/scripts/prefix.out" "${CMAKE_CURRENT_SOURCE_DIR}/scripts/macro.lst") set(PNGPREFIX_H_EXTRA_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/scripts/intprefix.out") endif() generate_out(INPUT "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.c" OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out" DEPENDS pnglibconf_c) add_custom_target(pnglibconf_out DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out") # Generate pnglibconf.h generate_source(OUTPUT "pnglibconf.h" DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out" pnglibconf_out ${PNGLIBCONF_H_EXTRA_DEPENDS}) add_custom_target(pnglibconf_h DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h") generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/intprefix.c" OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/intprefix.out" DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h" pnglibconf_h) add_custom_target(png_scripts_intprefix_out DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/scripts/intprefix.out") generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/prefix.c" OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/prefix.out" DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/png.h" "${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h" "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out" pnglibconf_out) add_custom_target(png_scripts_prefix_out DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/scripts/prefix.out") # Generate pngprefix.h generate_source(OUTPUT "pngprefix.h" DEPENDS ${PNGPREFIX_H_EXTRA_DEPENDS}) add_custom_target(pngprefix_h DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pngprefix.h") generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/sym.c" OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out" DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h" pnglibconf_h) add_custom_target(png_scripts_sym_out DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out") generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/symbols.c" OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out" DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/png.h" "${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h" "${CMAKE_CURRENT_SOURCE_DIR}/scripts/pnglibconf.h.prebuilt") add_custom_target(png_scripts_symbols_out DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out") generate_out(INPUT "${CMAKE_CURRENT_SOURCE_DIR}/scripts/vers.c" OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out" DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/png.h" "${CMAKE_CURRENT_SOURCE_DIR}/pngconf.h" "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h" pnglibconf_h) add_custom_target(png_scripts_vers_out DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out") generate_chk(INPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out" OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.chk" DEPENDS png_scripts_symbols_out "${CMAKE_CURRENT_BINARY_DIR}/scripts/checksym.awk" "${CMAKE_CURRENT_SOURCE_DIR}/scripts/symbols.def") add_custom_target(png_scripts_symbols_chk DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.chk") generate_copy(INPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out" OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/libpng.sym" DEPENDS png_scripts_sym_out) generate_copy(INPUT "${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out" OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/libpng.vers" DEPENDS png_scripts_vers_out) add_custom_target(png_genvers DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/libpng.vers") add_custom_target(png_gensym DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/libpng.sym") add_custom_target(png_genprebuilt COMMAND "${CMAKE_COMMAND}" "-DOUTPUT=scripts/pnglibconf.h.prebuilt" -P "${CMAKE_CURRENT_BINARY_DIR}/scripts/cmake/gensrc.cmake" WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") # A single target handles generation of all generated files. add_custom_target(png_genfiles DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/libpng.sym" png_gensym "${CMAKE_CURRENT_BINARY_DIR}/libpng.vers" png_genvers "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.c" pnglibconf_c "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h" pnglibconf_h "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.out" pnglibconf_out "${CMAKE_CURRENT_BINARY_DIR}/pngprefix.h" pngprefix_h "${CMAKE_CURRENT_BINARY_DIR}/scripts/intprefix.out" png_scripts_intprefix_out "${CMAKE_CURRENT_BINARY_DIR}/scripts/pnglibconf.c" png_scripts_pnglibconf_c "${CMAKE_CURRENT_BINARY_DIR}/scripts/prefix.out" png_scripts_prefix_out "${CMAKE_CURRENT_BINARY_DIR}/scripts/sym.out" png_scripts_sym_out "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.chk" png_scripts_symbols_chk "${CMAKE_CURRENT_BINARY_DIR}/scripts/symbols.out" png_scripts_symbols_out "${CMAKE_CURRENT_BINARY_DIR}/scripts/vers.out" png_scripts_vers_out) endif(NOT AWK OR ANDROID OR IOS) # List the source code files. set(libpng_public_hdrs png.h pngconf.h "${CMAKE_CURRENT_BINARY_DIR}/pnglibconf.h" ) set(libpng_private_hdrs pngpriv.h pngdebug.h pnginfo.h pngstruct.h ) if(AWK AND NOT ANDROID AND NOT IOS) list(APPEND libpng_private_hdrs "${CMAKE_CURRENT_BINARY_DIR}/pngprefix.h") endif() set(libpng_sources ${libpng_public_hdrs} ${libpng_private_hdrs} png.c pngerror.c pngget.c pngmem.c pngpread.c pngread.c pngrio.c pngrtran.c pngrutil.c pngset.c pngtrans.c pngwio.c pngwrite.c pngwtran.c pngwutil.c ${libpng_arm_sources} ${libpng_intel_sources} ${libpng_mips_sources} ${libpng_powerpc_sources} ${libpng_loongarch_sources} ) set(pngtest_sources pngtest.c ) set(pngvalid_sources contrib/libtests/pngvalid.c ) set(pngstest_sources contrib/libtests/pngstest.c ) set(pngunknown_sources contrib/libtests/pngunknown.c ) set(pngimage_sources contrib/libtests/pngimage.c ) set(pngfix_sources contrib/tools/pngfix.c ) set(png_fix_itxt_sources contrib/tools/png-fix-itxt.c ) if(MSVC OR (WIN32 AND (CMAKE_C_COMPILER_ID MATCHES "Clang"))) add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE) add_definitions(-D_CRT_SECURE_NO_DEPRECATE) endif() if(PNG_DEBUG) add_definitions(-DPNG_DEBUG) endif() # Now build our targets. # Initialize the list of libpng library targets. set(PNG_LIBRARY_TARGETS "") # Initialize the libpng library file names. if(UNIX OR (WIN32 AND NOT CMAKE_SHARED_LIBRARY_PREFIX STREQUAL "") OR (WIN32 AND NOT CMAKE_STATIC_LIBRARY_PREFIX STREQUAL "")) # We are on a Unix or Unix-like toolchain like the GNU toolchain on Windows. # Library file names are expected to have an implicit prefix such as "lib". # Let CMake prepend and append its usual prefixes and suffixes by default. set(PNG_SHARED_OUTPUT_NAME "png${PNGLIB_ABI_VERSION}") set(PNG_STATIC_OUTPUT_NAME "png${PNGLIB_ABI_VERSION}") else() # We are, most likely, on a Windows toolchain like MSVC, Clang on Windows, # Borland/Embarcadero, etc. We need to specify the "libpng" name explicitly. # We also need to use a custom suffix, in order to distinguish between the # shared import library name and the static library name. set(PNG_SHARED_OUTPUT_NAME "libpng${PNGLIB_ABI_VERSION}") set(PNG_STATIC_OUTPUT_NAME "libpng${PNGLIB_ABI_VERSION}_static") endif() if(PNG_SHARED) add_library(png_shared SHARED ${libpng_sources}) add_dependencies(png_shared png_genfiles) list(APPEND PNG_LIBRARY_TARGETS png_shared) set_target_properties(png_shared PROPERTIES OUTPUT_NAME "${PNG_SHARED_OUTPUT_NAME}" DEBUG_POSTFIX "${PNG_DEBUG_POSTFIX}" VERSION "${PNGLIB_SHARED_VERSION}" SOVERSION "${PNGLIB_ABI_VERSION}") if(UNIX AND AWK) if(HAVE_LD_VERSION_SCRIPT) set_target_properties(png_shared PROPERTIES LINK_FLAGS "-Wl,--version-script='${CMAKE_CURRENT_BINARY_DIR}/libpng.vers'") elseif(HAVE_SOLARIS_LD_VERSION_SCRIPT) set_target_properties(png_shared PROPERTIES LINK_FLAGS "-Wl,-M -Wl,'${CMAKE_CURRENT_BINARY_DIR}/libpng.vers'") endif() endif() if(APPLE) # Avoid CMake's implicit compile definition "png_shared_EXPORTS". set_target_properties(png_shared PROPERTIES DEFINE_SYMBOL "") elseif(WIN32) # Use the explicit compile definition "PNG_BUILD_DLL" for Windows DLLs. set_target_properties(png_shared PROPERTIES DEFINE_SYMBOL PNG_BUILD_DLL) endif() target_include_directories(png_shared PUBLIC $) target_include_directories(png_shared SYSTEM INTERFACE $) target_link_libraries(png_shared PUBLIC ZLIB::ZLIB ${M_LIBRARY}) endif() if(PNG_STATIC) add_library(png_static STATIC ${libpng_sources}) add_dependencies(png_static png_genfiles) list(APPEND PNG_LIBRARY_TARGETS png_static) set_target_properties(png_static PROPERTIES OUTPUT_NAME "${PNG_STATIC_OUTPUT_NAME}" DEBUG_POSTFIX "${PNG_DEBUG_POSTFIX}") target_include_directories(png_static PUBLIC $) target_include_directories(png_static SYSTEM INTERFACE $) target_link_libraries(png_static PUBLIC ZLIB::ZLIB ${M_LIBRARY}) endif() if(PNG_FRAMEWORK AND NOT APPLE) message(AUTHOR_WARNING "Setting PNG_FRAMEWORK to OFF, as it only applies to Apple systems") set(PNG_FRAMEWORK OFF) endif() if(PNG_FRAMEWORK) add_library(png_framework SHARED ${libpng_sources}) add_dependencies(png_framework png_genfiles) list(APPEND PNG_LIBRARY_TARGETS png_framework) set_target_properties(png_framework PROPERTIES FRAMEWORK TRUE FRAMEWORK_VERSION "${PNGLIB_VERSION}" MACOSX_FRAMEWORK_SHORT_VERSION_STRING "${PNGLIB_MAJOR}.${PNGLIB_MINOR}" MACOSX_FRAMEWORK_BUNDLE_VERSION "${PNGLIB_VERSION}" MACOSX_FRAMEWORK_IDENTIFIER "org.libpng.libpng" XCODE_ATTRIBUTE_INSTALL_PATH "@rpath" PUBLIC_HEADER "${libpng_public_hdrs}" OUTPUT_NAME "png" DEBUG_POSTFIX "${PNG_DEBUG_POSTFIX}") # Avoid CMake's implicit compile definition "-Dpng_framework_EXPORTS". set_target_properties(png_framework PROPERTIES DEFINE_SYMBOL "") target_include_directories(png_framework PUBLIC $) target_include_directories(png_framework SYSTEM INTERFACE $) target_link_libraries(png_framework PUBLIC ZLIB::ZLIB ${M_LIBRARY}) endif() if(NOT PNG_LIBRARY_TARGETS) message(SEND_ERROR "No library variant selected to build. " "Please enable at least one of the following options: " "PNG_SHARED, PNG_STATIC, PNG_FRAMEWORK") endif() if(PNG_TESTS AND PNG_SHARED) enable_testing() function(png_add_test) set(options) set(oneValueArgs NAME COMMAND) set(multiValueArgs OPTIONS FILES) cmake_parse_arguments(_PAT "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) if(NOT _PAT_NAME) message(FATAL_ERROR "png_add_test: Missing NAME argument") endif() if(NOT _PAT_COMMAND) message(FATAL_ERROR "png_add_test: Missing COMMAND argument") endif() set(TEST_OPTIONS "${_PAT_OPTIONS}") set(TEST_FILES "${_PAT_FILES}") configure_file("${CMAKE_CURRENT_SOURCE_DIR}/scripts/cmake/test.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/tests/${_PAT_NAME}.cmake" @ONLY) add_test(NAME "${_PAT_NAME}" COMMAND "${CMAKE_COMMAND}" "-DLIBPNG=$" "-DTEST_COMMAND=$" -P "${CMAKE_CURRENT_BINARY_DIR}/tests/${_PAT_NAME}.cmake") endfunction() # Find test PNG files by globbing, but sort lists to ensure # consistency between different filesystems. file(GLOB PNGSUITE_PNGS "${CMAKE_CURRENT_SOURCE_DIR}/contrib/pngsuite/*.png") list(SORT PNGSUITE_PNGS) file(GLOB TEST_PNGS "${CMAKE_CURRENT_SOURCE_DIR}/contrib/testpngs/*.png") list(SORT TEST_PNGS) set(PNGTEST_PNG "${CMAKE_CURRENT_SOURCE_DIR}/pngtest.png") add_executable(pngtest ${pngtest_sources}) target_link_libraries(pngtest PRIVATE png_shared) png_add_test(NAME pngtest COMMAND pngtest FILES "${PNGTEST_PNG}") add_executable(pngvalid ${pngvalid_sources}) target_link_libraries(pngvalid PRIVATE png_shared) png_add_test(NAME pngvalid-gamma-16-to-8 COMMAND pngvalid OPTIONS --gamma-16-to-8) png_add_test(NAME pngvalid-gamma-alpha-mode COMMAND pngvalid OPTIONS --gamma-alpha-mode) png_add_test(NAME pngvalid-gamma-background COMMAND pngvalid OPTIONS --gamma-background) png_add_test(NAME pngvalid-gamma-expand16-alpha-mode COMMAND pngvalid OPTIONS --gamma-alpha-mode --expand16) png_add_test(NAME pngvalid-gamma-expand16-background COMMAND pngvalid OPTIONS --gamma-background --expand16) png_add_test(NAME pngvalid-gamma-expand16-transform COMMAND pngvalid OPTIONS --gamma-transform --expand16) png_add_test(NAME pngvalid-gamma-sbit COMMAND pngvalid OPTIONS --gamma-sbit) png_add_test(NAME pngvalid-gamma-threshold COMMAND pngvalid OPTIONS --gamma-threshold) png_add_test(NAME pngvalid-gamma-transform COMMAND pngvalid OPTIONS --gamma-transform) png_add_test(NAME pngvalid-progressive-interlace-standard COMMAND pngvalid OPTIONS --standard --progressive-read --interlace) png_add_test(NAME pngvalid-progressive-size COMMAND pngvalid OPTIONS --size --progressive-read) png_add_test(NAME pngvalid-progressive-standard COMMAND pngvalid OPTIONS --standard --progressive-read) png_add_test(NAME pngvalid-standard COMMAND pngvalid OPTIONS --standard) png_add_test(NAME pngvalid-transform COMMAND pngvalid OPTIONS --transform) add_executable(pngstest ${pngstest_sources}) target_link_libraries(pngstest PRIVATE png_shared) foreach(gamma_type 1.8 linear none sRGB) foreach(alpha_type none alpha) set(PNGSTEST_FILES) foreach(test_png ${TEST_PNGS}) string(REGEX MATCH "-linear[-.]" TEST_PNG_LINEAR "${test_png}") string(REGEX MATCH "-sRGB[-.]" TEST_PNG_SRGB "${test_png}") string(REGEX MATCH "-1.8[-.]" TEST_PNG_G18 "${test_png}") string(REGEX MATCH "-alpha-" TEST_PNG_ALPHA "${test_png}") set(TEST_PNG_VALID TRUE) if(TEST_PNG_ALPHA) if(NOT alpha_type STREQUAL "alpha") set(TEST_PNG_VALID FALSE) endif() else() if(alpha_type STREQUAL "alpha") set(TEST_PNG_VALID FALSE) endif() endif() if(TEST_PNG_LINEAR) if(NOT gamma_type STREQUAL "linear") set(TEST_PNG_VALID FALSE) endif() elseif(TEST_PNG_SRGB) if(NOT gamma_type STREQUAL "sRGB") set(TEST_PNG_VALID FALSE) endif() elseif(TEST_PNG_G18) if(NOT gamma_type STREQUAL "1.8") set(TEST_PNG_VALID FALSE) endif() else() if(NOT gamma_type STREQUAL "none") set(TEST_PNG_VALID FALSE) endif() endif() if(TEST_PNG_VALID) list(APPEND PNGSTEST_FILES "${test_png}") endif() endforeach() # Should already be sorted, but sort anyway to be certain. list(SORT PNGSTEST_FILES) png_add_test(NAME pngstest-${gamma_type}-${alpha_type} COMMAND pngstest OPTIONS --tmpfile "${gamma_type}-${alpha_type}-" --log FILES ${PNGSTEST_FILES}) endforeach() endforeach() add_executable(pngunknown ${pngunknown_sources}) target_link_libraries(pngunknown PRIVATE png_shared) png_add_test(NAME pngunknown-discard COMMAND pngunknown OPTIONS --strict default=discard FILES "${PNGTEST_PNG}") png_add_test(NAME pngunknown-IDAT COMMAND pngunknown OPTIONS --strict default=discard IDAT=save FILES "${PNGTEST_PNG}") png_add_test(NAME pngunknown-if-safe COMMAND pngunknown OPTIONS --strict default=if-safe FILES "${PNGTEST_PNG}") png_add_test(NAME pngunknown-sAPI COMMAND pngunknown OPTIONS --strict bKGD=save cHRM=save gAMA=save all=discard iCCP=save sBIT=save sRGB=save FILES "${PNGTEST_PNG}") png_add_test(NAME pngunknown-save COMMAND pngunknown OPTIONS --strict default=save FILES "${PNGTEST_PNG}") png_add_test(NAME pngunknown-sTER COMMAND pngunknown OPTIONS --strict sTER=if-safe FILES "${PNGTEST_PNG}") png_add_test(NAME pngunknown-vpAg COMMAND pngunknown OPTIONS --strict vpAg=if-safe FILES "${PNGTEST_PNG}") add_executable(pngimage ${pngimage_sources}) target_link_libraries(pngimage PRIVATE png_shared) png_add_test(NAME pngimage-quick COMMAND pngimage OPTIONS --list-combos --log FILES ${PNGSUITE_PNGS}) png_add_test(NAME pngimage-full COMMAND pngimage OPTIONS --exhaustive --list-combos --log FILES ${PNGSUITE_PNGS}) endif() if(PNG_SHARED AND PNG_TOOLS) add_executable(pngfix ${pngfix_sources}) target_link_libraries(pngfix PRIVATE png_shared) set(PNG_BIN_TARGETS pngfix) add_executable(png-fix-itxt ${png_fix_itxt_sources}) target_link_libraries(png-fix-itxt PRIVATE ZLIB::ZLIB ${M_LIBRARY}) list(APPEND PNG_BIN_TARGETS png-fix-itxt) endif() # Create a symlink from src to dest (if possible), or, alternatively, # copy src to dest if different. function(create_symlink DEST_FILE) cmake_parse_arguments(_SYM "" "FILE;TARGET" "" ${ARGN}) if(NOT _SYM_FILE AND NOT _SYM_TARGET) message(FATAL_ERROR "create_symlink: Missing FILE or TARGET argument") endif() if(_SYM_FILE AND _SYM_TARGET) message(FATAL_ERROR "create_symlink: " "The arguments FILE (${_SYM_FILE}) and TARGET (${_SYM_TARGET}) " "are mutually-exclusive") endif() if(_SYM_FILE) # If we don't need to symlink something that's coming from a build target, # we can go ahead and symlink/copy at configure time. if(CMAKE_HOST_WIN32 AND NOT CYGWIN) execute_process(COMMAND "${CMAKE_COMMAND}" -E copy_if_different ${_SYM_FILE} ${DEST_FILE} WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") else() execute_process(COMMAND "${CMAKE_COMMAND}" -E create_symlink ${_SYM_FILE} ${DEST_FILE} WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") endif() endif() if(_SYM_TARGET) # We need to use generator expressions, which can be a bit tricky. # For simplicity, make the symlink a POST_BUILD step, and use the TARGET # signature of add_custom_command. if(CMAKE_HOST_WIN32 AND NOT CYGWIN) add_custom_command(TARGET ${_SYM_TARGET} POST_BUILD COMMAND "${CMAKE_COMMAND}" -E copy_if_different $/$ $/${DEST_FILE}) else() add_custom_command(TARGET ${_SYM_TARGET} POST_BUILD COMMAND "${CMAKE_COMMAND}" -E create_symlink $ $/${DEST_FILE}) endif() endif() endfunction() # Create source generation scripts. configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/cmake/genchk.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/scripts/cmake/genchk.cmake @ONLY) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/cmake/genout.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/scripts/cmake/genout.cmake @ONLY) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/scripts/cmake/gensrc.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/scripts/cmake/gensrc.cmake @ONLY) # libpng is a library so default to 'lib' if(NOT DEFINED CMAKE_INSTALL_LIBDIR) set(CMAKE_INSTALL_LIBDIR lib) endif() # Create pkgconfig files. # We use the same files like ./configure, so we have to set its vars. # Only do this on Windows for Cygwin - the files don't make much sense # outside of a UNIX look-alike. if(NOT WIN32 OR CYGWIN OR MINGW) set(prefix ${CMAKE_INSTALL_PREFIX}) set(exec_prefix ${CMAKE_INSTALL_PREFIX}) set(libdir ${CMAKE_INSTALL_FULL_LIBDIR}) set(includedir ${CMAKE_INSTALL_FULL_INCLUDEDIR}) set(LIBS "-lz -lm") configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libpng.pc.in ${CMAKE_CURRENT_BINARY_DIR}/libpng${PNGLIB_ABI_VERSION}.pc @ONLY) create_symlink(libpng.pc FILE libpng${PNGLIB_ABI_VERSION}.pc) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libpng-config.in ${CMAKE_CURRENT_BINARY_DIR}/libpng${PNGLIB_ABI_VERSION}-config @ONLY) create_symlink(libpng-config FILE libpng${PNGLIB_ABI_VERSION}-config) endif() # Install. if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL) install(TARGETS ${PNG_LIBRARY_TARGETS} EXPORT libpng RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} FRAMEWORK DESTINATION ${CMAKE_INSTALL_LIBDIR}) if(PNG_SHARED) # Create a symlink for libpng.dll.a => libpng16.dll.a on Cygwin if(NOT WIN32 OR CYGWIN OR MINGW) create_symlink(libpng${CMAKE_SHARED_LIBRARY_SUFFIX} TARGET png_shared) install(FILES $/libpng${CMAKE_SHARED_LIBRARY_SUFFIX} DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() endif() if(PNG_STATIC) if(NOT WIN32 OR CYGWIN OR MINGW) create_symlink(libpng${CMAKE_STATIC_LIBRARY_SUFFIX} TARGET png_static) install(FILES $/libpng${CMAKE_STATIC_LIBRARY_SUFFIX} DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() endif() endif() if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL) install(FILES ${libpng_public_hdrs} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) install(FILES ${libpng_public_hdrs} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/libpng${PNGLIB_ABI_VERSION}) endif() if(NOT SKIP_INSTALL_EXECUTABLES AND NOT SKIP_INSTALL_ALL) if(NOT WIN32 OR CYGWIN OR MINGW) install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/libpng-config DESTINATION ${CMAKE_INSTALL_BINDIR}) install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/libpng${PNGLIB_ABI_VERSION}-config DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() endif() if(NOT SKIP_INSTALL_PROGRAMS AND NOT SKIP_INSTALL_ALL) install(TARGETS ${PNG_BIN_TARGETS} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL) # Install the man pages. install(FILES libpng.3 libpngpf.3 DESTINATION ${CMAKE_INSTALL_MANDIR}/man3) install(FILES png.5 DESTINATION ${CMAKE_INSTALL_MANDIR}/man5) # Install the pkg-config files. if(NOT CMAKE_HOST_WIN32 OR CYGWIN OR MINGW) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpng.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/libpng-config DESTINATION ${CMAKE_INSTALL_BINDIR}) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libpng${PNGLIB_ABI_VERSION}.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/libpng${PNGLIB_ABI_VERSION}-config DESTINATION ${CMAKE_INSTALL_BINDIR}) endif() endif() # Create an export file that CMake users can include() to import our targets. if(NOT SKIP_INSTALL_EXPORT AND NOT SKIP_INSTALL_ALL) install(EXPORT libpng DESTINATION ${CMAKE_INSTALL_LIBDIR}/libpng FILE libpng${PNGLIB_ABI_VERSION}.cmake) endif() # TODO: Create MSVC import lib for MinGW-compiled shared lib. # pexports libpng.dll > libpng.def # lib /def:libpng.def /machine:x86 libpng-1.6.43/INSTALL000066400000000000000000000454441456606525400141410ustar00rootroot00000000000000 Installing libpng Contents I. Simple installation II. Rebuilding the configure scripts III. Using scripts/makefile* IV. Using cmake V. Directory structure VI. Building with project files VII. Building with makefiles VIII. Configuring libpng for 16-bit platforms IX. Configuring for DOS X. Configuring for Medium Model XI. Prepending a prefix to exported symbols XII. Configuring for compiler xxx: XIII. Removing unwanted object code XIV. Enabling or disabling hardware optimizations XV. Changes to the build and configuration of libpng in libpng-1.5.x XVI. Setjmp/longjmp issues XVII. Common linking failures XVIII. Other sources of information about libpng I. Simple installation On Unix/Linux and similar systems, you can simply type ./configure [--prefix=/path] make check make install and ignore the rest of this document. "/path" is the path to the directory where you want to install the libpng "lib", "include", and "bin" subdirectories. If you downloaded a GIT clone, you will need to run ./autogen.sh before running ./configure, to create "configure" and "Makefile.in" which are not included in the GIT repository. Note that "configure" is only included in the "*.tar" distributions and not in the "*.zip" or "*.7z" distributions. If you downloaded one of those distributions, see "Building with project files" or "Building with makefiles", below. II. Rebuilding the configure scripts If configure does not work on your system, or if you have a need to change configure.ac or Makefile.am, and you have a reasonably up-to-date set of tools, running ./autogen.sh in a git clone before running ./configure may fix the problem. To be really sure that you aren't using any of the included pre-built scripts, especially if you are building from a tar distribution instead of a git distribution, do this: ./configure --enable-maintainer-mode make maintainer-clean ./autogen.sh --maintainer --clean ./autogen.sh --maintainer ./configure [--prefix=/path] [other options] make make install make check III. Using scripts/makefile* Instead, you can use one of the custom-built makefiles in the "scripts" directory cp scripts/pnglibconf.h.prebuilt pnglibconf.h cp scripts/makefile.system makefile make test make install The files that are presently available in the scripts directory are listed and described in scripts/README.txt. Or you can use one of the "projects" in the "projects" directory. Before installing libpng, you must first install zlib, if it is not already on your system. zlib can usually be found wherever you got libpng; otherwise go to https://zlib.net/. You can place zlib in the same directory as libpng or in another directory. If your system already has a preinstalled zlib you will still need to have access to the zlib.h and zconf.h include files that correspond to the version of zlib that's installed. If you wish to test with a particular zlib that is not first in the standard library search path, put ZLIBLIB, ZLIBINC, CPPFLAGS, LDFLAGS, and LD_LIBRARY_PATH in your environment before running "make test" or "make distcheck": ZLIBLIB=/path/to/lib export ZLIBLIB ZLIBINC=/path/to/include export ZLIBINC CPPFLAGS="-I$ZLIBINC" export CPPFLAGS LDFLAGS="-L$ZLIBLIB" export LDFLAGS LD_LIBRARY_PATH="$ZLIBLIB:$LD_LIBRARY_PATH" export LD_LIBRARY_PATH If you are using one of the makefile scripts, put ZLIBLIB and ZLIBINC in your environment and type make ZLIBLIB=$ZLIBLIB ZLIBINC=$ZLIBINC test IV. Using cmake If you want to use "cmake" (see www.cmake.org), type cmake . -DCMAKE_INSTALL_PREFIX=/path make make install As when using the simple configure method described above, "/path" points to the installation directory where you want to put the libpng "lib", "include", and "bin" subdirectories. V. Directory structure You can rename the directories that you downloaded (they might be called "libpng-x.y.z" or "libpngNN" and "zlib-1.2.8" or "zlib128") so that you have directories called "zlib" and "libpng". Your directory structure should look like this: .. (the parent directory) libpng (this directory) INSTALL (this file) README *.h, *.c => libpng source files CMakeLists.txt => "cmake" script ci ci_*.sh configuration files: configure.ac, configure, Makefile.am, Makefile.in, autogen.sh, config.guess, ltmain.sh, missing, libpng.pc.in, libpng-config.in, aclocal.m4, config.h.in, config.sub, depcomp, install-sh, mkinstalldirs, test-pngtest.sh, etc. contrib arm-neon, conftest, examples, gregbook, libtests, pngminim, pngminus, pngsuite, tools, visupng projects owatcom, visualc71, vstudio scripts makefile.* *.def (module definition files) etc. pngtest.png etc. zlib README, *.h, *.c, contrib, etc. If the line endings in the files look funny, you may wish to get the other distribution of libpng. It is available in both tar.gz (UNIX style line endings) and zip (DOS style line endings) formats. VI. Building with project files If you are building libpng with Microsoft Visual Studio, you can enter the directory projects\visualc71 or projects\vstudio and follow the instructions in README.txt. Otherwise, enter the zlib directory and follow the instructions in zlib/README, then come back here and run "configure" or choose the appropriate makefile in the scripts directory. VII. Building with makefiles Copy the file (or files) that you need from the scripts directory into this directory, for example UNIX example: cp scripts/makefile.std Makefile make Windows example: nmake -f scripts\makefile.vcwin32 Read the makefile to see if you need to change any source or target directories to match your preferences. Then read pnglibconf.dfa to see if you want to make any configuration changes. Then just run "make" which will create the libpng library in this directory and "make test" which will run a quick test that reads the "pngtest.png" file and writes a "pngout.png" file that should be identical to it. Look for "9782 zero samples" in the output of the test. For more confidence, you can run another test by typing "pngtest pngnow.png" and looking for "289 zero samples" in the output. Also, you can run "pngtest -m contrib/pngsuite/*.png" and compare your output with the result shown in contrib/pngsuite/README. Most of the makefiles used to allow you to run "make install" to put the library in its final resting place, but that feature is no longer supported. The only tested and supported manners to install libpng are the conventional build and install procedures driven by the configure script or by the CMake file. VIII. Configuring for DOS and other 16-bit platforms Officially, the support for 16-bit platforms has been removed. For DOS users who only have access to the lower 640K, you will have to limit zlib's memory usage via a png_set_compression_mem_level() call. See zlib.h or zconf.h in the zlib library for more information. You may be or may not be in luck if you target the "large" memory model, but all the smaller models ("small", "compact" and "medium") are known to be unworkable. For DOS users who have access beyond the lower 640K, a "flat" 32-bit DOS model (such as DJGPP) is strongly recommended. For DOS users who only have access to the lower 640K, you will have to limit zlib's memory usage via a png_set_compression_mem_level() call. You will also have to look into zconf.h to tell zlib (and thus libpng) that it cannot allocate more than 64K at a time. Even if you can, the memory won't be accessible. Therefore, you should limit zlib and libpng to 64K by defining MAXSEG_64K. IX. Prepending a prefix to exported symbols Starting with libpng-1.6.0, you can configure libpng (when using the "configure" script) to prefix all exported symbols by means of the configuration option "--with-libpng-prefix=FOO_", where FOO_ can be any string beginning with a letter and containing only uppercase and lowercase letters, digits, and the underscore (i.e., a C language identifier). This creates a set of macros in pnglibconf.h, so this is transparent to applications; their function calls get transformed by the macros to use the modified names. X. Configuring for compiler xxx: All includes for libpng are in pngconf.h. If you need to add, change or delete an include, this is the place to do it. The includes that are not needed outside libpng are placed in pngpriv.h, which is only used by the routines inside libpng itself. The files in libpng proper only include pngpriv.h and png.h, which in turn includes pngconf.h and, as of libpng-1.5.0, pnglibconf.h. As of libpng-1.5.0, pngpriv.h also includes three other private header files, pngstruct.h, pnginfo.h, and pngdebug.h, which contain material that previously appeared in the public headers. XI. Removing unwanted object code There are a bunch of #define's in pngconf.h that control what parts of libpng are compiled. All the defines end in _SUPPORTED. If you are never going to use a capability, you can change the #define to #undef before recompiling libpng and save yourself code and data space, or you can turn off individual capabilities with defines that begin with "PNG_NO_". In libpng-1.5.0 and later, the #define's are in pnglibconf.h instead. You can also turn all of the transforms and ancillary chunk capabilities off en masse with compiler directives that define PNG_NO_READ[or WRITE]_TRANSFORMS, or PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS, or all four, along with directives to turn on any of the capabilities that you do want. The PNG_NO_READ[or WRITE]_TRANSFORMS directives disable the extra transformations but still leave the library fully capable of reading and writing PNG files with all known public chunks. Use of the PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS directive produces a library that is incapable of reading or writing ancillary chunks. If you are not using the progressive reading capability, you can turn that off with PNG_NO_PROGRESSIVE_READ (don't confuse this with the INTERLACING capability, which you'll still have). All the reading and writing specific code are in separate files, so the linker should only grab the files it needs. However, if you want to make sure, or if you are building a stand alone library, all the reading files start with "pngr" and all the writing files start with "pngw". The files that don't match either (like png.c, pngtrans.c, etc.) are used for both reading and writing, and always need to be included. The progressive reader is in pngpread.c If you are creating or distributing a dynamically linked library (a .so or DLL file), you should not remove or disable any parts of the library, as this will cause applications linked with different versions of the library to fail if they call functions not available in your library. The size of the library itself should not be an issue, because only those sections that are actually used will be loaded into memory. XII. Enabling or disabling hardware optimizations Certain hardware capabilities, such as the Intel SSE instructions, are normally detected at run time. Enable them with configure options such as one of --enable-arm-neon=yes --enable-mips-msa=yes --enable-intel-sse=yes --enable-powerpc-vsx=yes or enable them all at once with --enable-hardware-optimizations=yes or, if you are not using "configure", you can use one or more of CPPFLAGS += "-DPNG_ARM_NEON" CPPFLAGS += "-DPNG_MIPS_MSA" CPPFLAGS += "-DPNG_INTEL_SSE" CPPFLAGS += "-DPNG_POWERPC_VSX" See for example scripts/makefile.linux-opt If you wish to avoid using them, you can disable them via the configure option --disable-hardware-optimizations to disable them all, or --enable-intel-sse=no to disable a particular one, or via compiler-command options such as CPPFLAGS += "-DPNG_ARM_NEON_OPT=0, -DPNG_MIPS_MSA_OPT=0, -DPNG_INTEL_SSE_OPT=0, -DPNG_POWERPC_VSX_OPT=0" If you are using cmake, hardware optimizations are "on" by default. To disable them, use cmake . -DPNG_ARM_NEON=no -DPNG_INTEL_SSE=no \ -DPNG_MIPS_MSA=no -DPNG_POWERPC_VSX=no or disable them all at once with cmake . -DPNG_HARDWARE_OPTIMIZATIONS=no XIII. Changes to the build and configuration of libpng in libpng-1.5.x Details of internal changes to the library code can be found in the CHANGES file and in the GIT repository logs. These will be of no concern to the vast majority of library users or builders; however, the few who configure libpng to a non-default feature set may need to change how this is done. There should be no need for library builders to alter build scripts if these use the distributed build support - configure or the makefiles - however, users of the makefiles may care to update their build scripts to build pnglibconf.h where the corresponding makefile does not do so. Building libpng with a non-default configuration has changed completely. The old method using pngusr.h should still work correctly even though the way pngusr.h is used in the build has been changed; however, library builders will probably want to examine the changes to take advantage of new capabilities and to simplify their build system. A. Specific changes to library configuration capabilities The exact mechanism used to control attributes of API functions has changed. A single set of operating system independent macro definitions is used and operating system specific directives are defined in pnglibconf.h As part of this the mechanism used to choose procedure call standards on those systems that allow a choice has been changed. At present this only affects certain Microsoft (DOS, Windows) and IBM (OS/2) operating systems running on Intel processors. As before, PNGAPI is defined where required to control the exported API functions; however, two new macros, PNGCBAPI and PNGCAPI, are used instead for callback functions (PNGCBAPI) and (PNGCAPI) for functions that must match a C library prototype (currently only png_longjmp_ptr, which must match the C longjmp function.) The new approach is documented in pngconf.h Despite these changes, libpng 1.5.0 only supports the native C function calling standard on those platforms tested so far ("__cdecl" on Microsoft Windows). This is because the support requirements for alternative calling conventions seem to no longer exist. Developers who find it necessary to set PNG_API_RULE to 1 should advise the mailing list (png-mng-implement) of this and library builders who use Openwatcom and therefore set PNG_API_RULE to 2 should also contact the mailing list. B. Changes to the configuration mechanism Prior to libpng-1.5.0 library builders who needed to configure libpng had either to modify the exported pngconf.h header file to add system specific configuration or had to write feature selection macros into pngusr.h and cause this to be included into pngconf.h by defining PNG_USER_CONFIG. The latter mechanism had the disadvantage that an application built without PNG_USER_CONFIG defined would see the unmodified, default, libpng API and thus would probably fail to link. These mechanisms still work in the configure build and in any makefile build that builds pnglibconf.h, although the feature selection macros have changed somewhat as described above. In 1.5.0, however, pngusr.h is processed only once, at the time the exported header file pnglibconf.h is built. pngconf.h no longer includes pngusr.h; therefore, pngusr.h is ignored after the build of pnglibconf.h and it is never included in an application build. The formerly used alternative of adding a list of feature macros to the CPPFLAGS setting in the build also still works; however, the macros will be copied to pnglibconf.h and this may produce macro redefinition warnings when the individual C files are compiled. All configuration now only works if pnglibconf.h is built from scripts/pnglibconf.dfa. This requires the program awk. Brian Kernighan (the original author of awk) maintains C source code of that awk and this and all known later implementations (often called by subtly different names - nawk and gawk for example) are adequate to build pnglibconf.h. The Sun Microsystems (now Oracle) program 'awk' is an earlier version and does not work; this may also apply to other systems that have a functioning awk called 'nawk'. Configuration options are now documented in scripts/pnglibconf.dfa. This file also includes dependency information that ensures a configuration is consistent; that is, if a feature is switched off, dependent features are also switched off. As a recommended alternative to using feature macros in pngusr.h a system builder may also define equivalent options in pngusr.dfa (or, indeed, any file) and add that to the configuration by setting DFA_XTRA to the file name. The makefiles in contrib/pngminim illustrate how to do this, and also illustrate a case where pngusr.h is still required. After you have built libpng, the definitions that were recorded in pnglibconf.h are available to your application (pnglibconf.h is included in png.h and gets installed alongside png.h and pngconf.h in your $PREFIX/include directory). Do not edit pnglibconf.h after you have built libpng, because than the settings would not accurately reflect the settings that were used to build libpng. XIV. Setjmp/longjmp issues Libpng uses setjmp()/longjmp() for error handling. Unfortunately setjmp() is known to be not thread-safe on some platforms and we don't know of any platform where it is guaranteed to be thread-safe. Therefore, if your application is going to be using multiple threads, you should configure libpng with PNG_NO_SETJMP in your pngusr.dfa file, with -DPNG_NO_SETJMP on your compile line, or with #undef PNG_SETJMP_SUPPORTED in your pnglibconf.h or pngusr.h. Starting with libpng-1.6.0, the library included a "simplified API". This requires setjmp/longjmp, so you must either build the library with PNG_SETJMP_SUPPORTED defined, or with PNG_SIMPLIFIED_READ_SUPPORTED and PNG_SIMPLIFIED_WRITE_SUPPORTED undefined. XV. Common linking failures If your application fails to find libpng or zlib entries while linking: Be sure "-lz" appears after "-lpng" on your linking command. Be sure you have built libpng, zlib, and your application for the same platform (e.g., 32-bit or 64-bit). If you are using the vstudio project, observe the WARNING in project/vstudio/README.txt. XVI. Other sources of information about libpng: Further information can be found in the README and libpng-manual.txt files, in the individual makefiles, in png.h, and the manual pages libpng.3 and png.5. Copyright (c) 2022 Cosmin Truta Copyright (c) 1998-2002,2006-2016 Glenn Randers-Pehrson This document is released under the libpng license. For conditions of distribution and use, see the disclaimer and license in png.h. libpng-1.6.43/LICENSE000066400000000000000000000123411456606525400141030ustar00rootroot00000000000000COPYRIGHT NOTICE, DISCLAIMER, and LICENSE ========================================= PNG Reference Library License version 2 --------------------------------------- * Copyright (c) 1995-2024 The PNG Reference Library Authors. * Copyright (c) 2018-2024 Cosmin Truta. * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson. * Copyright (c) 1996-1997 Andreas Dilger. * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. The software is supplied "as is", without warranty of any kind, express or implied, including, without limitation, the warranties of merchantability, fitness for a particular purpose, title, and non-infringement. In no event shall the Copyright owners, or anyone distributing the software, be liable for any damages or other liability, whether in contract, tort or otherwise, arising from, out of, or in connection with the software, or the use or other dealings in the software, even if advised of the possibility of such damage. Permission is hereby granted to use, copy, modify, and distribute this software, or portions hereof, for any purpose, without fee, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated, but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This Copyright notice may not be removed or altered from any source or altered source distribution. PNG Reference Library License version 1 (for libpng 0.5 through 1.6.35) ----------------------------------------------------------------------- libpng versions 1.0.7, July 1, 2000, through 1.6.35, July 15, 2018 are Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson, are derived from libpng-1.0.6, and are distributed according to the same disclaimer and license as libpng-1.0.6 with the following individuals added to the list of Contributing Authors: Simon-Pierre Cadieux Eric S. Raymond Mans Rullgard Cosmin Truta Gilles Vollant James Yu Mandar Sahastrabuddhe Google Inc. Vadim Barkov and with the following additions to the disclaimer: There is no warranty against interference with your enjoyment of the library or against infringement. There is no warranty that our efforts or the library will fulfill any of your particular purposes or needs. This library is provided with all faults, and the entire risk of satisfactory quality, performance, accuracy, and effort is with the user. Some files in the "contrib" directory and some configure-generated files that are distributed with libpng have other copyright owners, and are released under other open source licenses. libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from libpng-0.96, and are distributed according to the same disclaimer and license as libpng-0.96, with the following individuals added to the list of Contributing Authors: Tom Lane Glenn Randers-Pehrson Willem van Schaik libpng versions 0.89, June 1996, through 0.96, May 1997, are Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88, and are distributed according to the same disclaimer and license as libpng-0.88, with the following individuals added to the list of Contributing Authors: John Bowler Kevin Bracey Sam Bushell Magnus Holmgren Greg Roelofs Tom Tanner Some files in the "scripts" directory have other copyright owners, but are released under this license. libpng versions 0.5, May 1995, through 0.88, January 1996, are Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. For the purposes of this copyright and license, "Contributing Authors" is defined as the following set of individuals: Andreas Dilger Dave Martindale Guy Eric Schalnat Paul Schmidt Tim Wegner The PNG Reference Library is supplied "AS IS". The Contributing Authors and Group 42, Inc. disclaim all warranties, expressed or implied, including, without limitation, the warranties of merchantability and of fitness for any purpose. The Contributing Authors and Group 42, Inc. assume no liability for direct, indirect, incidental, special, exemplary, or consequential damages, which may result from the use of the PNG Reference Library, even if advised of the possibility of such damage. Permission is hereby granted to use, copy, modify, and distribute this source code, or portions hereof, for any purpose, without fee, subject to the following restrictions: 1. The origin of this source code must not be misrepresented. 2. Altered versions must be plainly marked as such and must not be misrepresented as being the original source. 3. This Copyright notice may not be removed or altered from any source or altered source distribution. The Contributing Authors and Group 42, Inc. specifically permit, without fee, and encourage the use of this source code as a component to supporting the PNG file format in commercial products. If you use this source code in a product, acknowledgment is not required but would be appreciated. libpng-1.6.43/Makefile.am000066400000000000000000000350211456606525400151320ustar00rootroot00000000000000# Makefile.am, the source file for Makefile.in (and hence Makefile), is # # Copyright (c) 2018-2024 Cosmin Truta # Copyright (c) 2004-2016 Glenn Randers-Pehrson # # This code is released under the libpng license. # For conditions of distribution and use, see the disclaimer # and license in png.h PNGLIB_BASENAME= libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@ ACLOCAL_AMFLAGS = -I scripts/autoconf # test programs - run on make check, make distcheck if ENABLE_TESTS check_PROGRAMS= pngtest pngunknown pngstest pngvalid pngimage pngcp if HAVE_CLOCK_GETTIME check_PROGRAMS += timepng endif else check_PROGRAMS= endif # Utilities - installed if ENABLE_TOOLS bin_PROGRAMS= pngfix png-fix-itxt else bin_PROGRAMS= endif # This ensures that pnglibconf.h gets built at the start of 'make all' or # 'make check', but it does not add dependencies to the individual programs, # this is done below. # # IMPORTANT: always add the object modules of new programs to the list below # because otherwise the sequence 'configure; make new-program' will *sometimes* # result in the installed (system) pnglibconf.h being used and the result is # always wrong and always very confusing. BUILT_SOURCES = pnglibconf.h if ENABLE_TESTS pngtest_SOURCES = pngtest.c pngtest_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la pngvalid_SOURCES = contrib/libtests/pngvalid.c pngvalid_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la pngstest_SOURCES = contrib/libtests/pngstest.c pngstest_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la pngunknown_SOURCES = contrib/libtests/pngunknown.c pngunknown_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la pngimage_SOURCES = contrib/libtests/pngimage.c pngimage_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la timepng_SOURCES = contrib/libtests/timepng.c timepng_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la pngcp_SOURCES = contrib/tools/pngcp.c pngcp_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la endif if ENABLE_TOOLS pngfix_SOURCES = contrib/tools/pngfix.c pngfix_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la png_fix_itxt_SOURCES = contrib/tools/png-fix-itxt.c endif # Generally these are single line shell scripts to run a test with a particular # set of parameters: if ENABLE_TESTS TESTS =\ tests/pngtest-all\ tests/pngvalid-gamma-16-to-8 tests/pngvalid-gamma-alpha-mode\ tests/pngvalid-gamma-background tests/pngvalid-gamma-expand16-alpha-mode\ tests/pngvalid-gamma-expand16-background\ tests/pngvalid-gamma-expand16-transform tests/pngvalid-gamma-sbit\ tests/pngvalid-gamma-threshold tests/pngvalid-gamma-transform\ tests/pngvalid-progressive-size\ tests/pngvalid-progressive-interlace-standard\ tests/pngvalid-transform\ tests/pngvalid-progressive-standard tests/pngvalid-standard\ tests/pngstest-1.8 tests/pngstest-1.8-alpha tests/pngstest-linear\ tests/pngstest-linear-alpha tests/pngstest-none tests/pngstest-none-alpha\ tests/pngstest-sRGB tests/pngstest-sRGB-alpha tests/pngunknown-IDAT\ tests/pngunknown-discard tests/pngunknown-if-safe tests/pngunknown-sAPI\ tests/pngunknown-sTER tests/pngunknown-save tests/pngunknown-vpAg\ tests/pngimage-quick tests/pngimage-full endif # man pages dist_man_MANS= libpng.3 libpngpf.3 png.5 # generate the -config scripts if required binconfigs= libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@-config EXTRA_SCRIPTS= libpng-config libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@-config bin_SCRIPTS= @binconfigs@ # rules to build libpng, only build the old library on request lib_LTLIBRARIES=libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la # EXTRA_LTLIBRARIES= libpng.la libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES = png.c pngerror.c\ pngget.c pngmem.c pngpread.c pngread.c pngrio.c pngrtran.c pngrutil.c\ pngset.c pngtrans.c pngwio.c pngwrite.c pngwtran.c pngwutil.c\ png.h pngconf.h pngdebug.h pnginfo.h pngpriv.h pngstruct.h pngusr.dfa if PNG_ARM_NEON libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES += arm/arm_init.c\ arm/filter_neon.S arm/filter_neon_intrinsics.c \ arm/palette_neon_intrinsics.c endif if PNG_MIPS_MSA libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES += mips/mips_init.c\ mips/filter_msa_intrinsics.c endif if PNG_MIPS_MMI if !PNG_MIPS_MSA libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES += mips/mips_init.c endif libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES += mips/filter_mmi_inline_assembly.c endif if PNG_INTEL_SSE libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES += intel/intel_init.c\ intel/filter_sse2_intrinsics.c endif if PNG_POWERPC_VSX libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES += powerpc/powerpc_init.c\ powerpc/filter_vsx_intrinsics.c endif if PNG_LOONGARCH_LSX noinst_LTLIBRARIES= libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx.la libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la_SOURCES = loongarch/loongarch_lsx_init.c\ loongarch/filter_lsx_intrinsics.c libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la_CFLAGS = -mlsx libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_LIBADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx.la # libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_DEPENDENCIES = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx.la endif nodist_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES = pnglibconf.h libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_LDFLAGS = -no-undefined -export-dynamic \ -version-number @PNGLIB_MAJOR@@PNGLIB_MINOR@:@PNGLIB_RELEASE@:0 if HAVE_LD_VERSION_SCRIPT # Versioned symbols and restricted exports if HAVE_SOLARIS_LD libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_LDFLAGS += -Wl,-M -Wl,libpng.vers else libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_LDFLAGS += -Wl,--version-script=libpng.vers endif libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_DEPENDENCIES = libpng.vers else # Only restricted exports when possible libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_LDFLAGS += -export-symbols libpng.sym libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_DEPENDENCIES = libpng.sym endif if PNG_LOONGARCH_LSX libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_DEPENDENCIES += libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx.la endif #distribute headers in /usr/include/libpng/* pkgincludedir= $(includedir)/$(PNGLIB_BASENAME) pkginclude_HEADERS= png.h pngconf.h nodist_pkginclude_HEADERS= pnglibconf.h # pkg-config stuff, note that libpng.pc is always required in order # to get the correct library pkgconfigdir = @pkgconfigdir@ pkgconfig_DATA = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.pc # Extra source distribution files, '${srcdir}' is used below to stop build files # from those directories being included. This only works if the configure is # not done in the source directory! EXTRA_DIST= \ ANNOUNCE AUTHORS CHANGES INSTALL LICENSE README TODO TRADEMARK \ pngtest.png pngbar.png pngnow.png pngbar.jpg autogen.sh \ ${srcdir}/ci ${srcdir}/contrib ${srcdir}/projects ${srcdir}/scripts \ $(TESTS) $(XFAIL_TESTS) tests/pngstest \ CMakeLists.txt example.c libpng-manual.txt SCRIPT_CLEANFILES=scripts/*.out scripts/*.chk CLEANFILES= *.tf? pngout.png libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.pc \ libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@-config libpng.vers libpng.sym \ check.new pnglibconf.h pngprefix.h symbols.new pngtest-log.txt \ pnglibconf.out pnglibconf.c pnglibconf.pre pnglibconf.dfn \ $(SCRIPT_CLEANFILES) MAINTAINERCLEANFILES = Makefile.in aclocal.m4 config.guess config.h.in \ config.sub configure depcomp install-sh ltmain.sh missing # PNG_COPTS give extra options for the C compiler to be used on all compilation # steps (unless targe_CFLAGS is specified; that will take precedence over # AM_CFLAGS) PNG_COPTS = @PNG_COPTS@ AM_CFLAGS = ${PNG_COPTS} # DFNCPP is normally just CPP - the C preprocessor - but on Solaris and maybe # other operating systems (NeXT?) the C preprocessor selected by configure # checks input tokens for validity - effectively it performs part of the ANSI-C # parsing - and therefore fails with the .df files. configure.ac has special # checks for this and sets DFNCPP appropriately. DFNCPP = @DFNCPP@ SUFFIXES = .chk .out $(PNGLIB_BASENAME).pc: libpng.pc cp libpng.pc $@ $(PNGLIB_BASENAME)-config: libpng-config cp libpng-config $@ scripts/sym.out scripts/vers.out: png.h pngconf.h pnglibconf.h scripts/prefix.out: png.h pngconf.h pnglibconf.out scripts/symbols.out: png.h pngconf.h $(srcdir)/scripts/pnglibconf.h.prebuilt scripts/intprefix.out: pnglibconf.h libpng.sym: scripts/sym.out rm -f $@ cp $? $@ libpng.vers: scripts/vers.out rm -f $@ cp $? $@ if DO_PNG_PREFIX # Rename functions in scripts/prefix.out with a PNG_PREFIX prefix. # Rename macros in scripts/macro.lst from PNG_PREFIXpng_ to PNG_ (the actual # implementation of the macro). pnglibconf.h: pnglibconf.out scripts/prefix.out scripts/macro.lst rm -f $@ $(AWK) 's==0 && NR>1{print prev}\ s==0{prev=$$0}\ s==1{print "#define", $$1, "@PNG_PREFIX@" $$1}\ s==2{print "#define @PNG_PREFIX@png_" $$1, "PNG_" $$1}\ END{print prev}' s=0 pnglibconf.out s=1 scripts/prefix.out\ s=2 ${srcdir}/scripts/macro.lst >pnglibconf.tf8 mv pnglibconf.tf8 $@ pngprefix.h: scripts/intprefix.out rm -f pngprefix.tf1 $(AWK) '{print "#define", $$1, "@PNG_PREFIX@" $$1}' $? >pngprefix.tf1 mv pngprefix.tf1 $@ else pnglibconf.h: pnglibconf.out rm -f $@ cp $? $@ pngprefix.h: # is empty :>$@ endif $(srcdir)/scripts/pnglibconf.h.prebuilt: @echo "Attempting to build $@" >&2 @echo "This is a machine generated file, but if you want to make" >&2 @echo "a new one simply make 'scripts/pnglibconf.out', copy that" >&2 @echo "AND set PNG_ZLIB_VERNUM to 0 (you MUST do this)" >&2 @exit 1 # The following is necessary to ensure that the local pnglibconf.h is used, not # an installed one (this can happen immediately after on a clean system if # 'make test' is the first thing the user does.) Only files which include # one of the png source files (typically png.h or pngpriv.h) need to be listed # here: pngtest.o: pnglibconf.h contrib/libtests/makepng.o: pnglibconf.h contrib/libtests/pngstest.o: pnglibconf.h contrib/libtests/pngunknown.o: pnglibconf.h contrib/libtests/pngimage.o: pnglibconf.h contrib/libtests/pngvalid.o: pnglibconf.h contrib/libtests/readpng.o: pnglibconf.h contrib/libtests/tarith.o: pnglibconf.h contrib/libtests/timepng.o: pnglibconf.h contrib/tools/makesRGB.o: pnglibconf.h contrib/tools/pngfix.o: pnglibconf.h contrib/tools/pngcp.o: pnglibconf.h # We must use -DPNG_NO_USE_READ_MACROS here even when the library may actually # be built with PNG_USE_READ_MACROS; this prevents the read macros from # interfering with the symbol file format. SYMBOL_CFLAGS = -DPNGLIB_LIBNAME='PNG@PNGLIB_MAJOR@@PNGLIB_MINOR@_0'\ -DPNGLIB_VERSION='@PNGLIB_VERSION@'\ -DSYMBOL_PREFIX='$(SYMBOL_PREFIX)'\ -DPNG_NO_USE_READ_MACROS -DPNG_BUILDING_SYMBOL_TABLE if DO_PNG_PREFIX SYMBOL_CFLAGS += -DPNG_PREFIX='@PNG_PREFIX@' endif .c.out: rm -f $@ $*.tf[12] test -d scripts || mkdir scripts || test -d scripts $(DFNCPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES)\ $(CPPFLAGS) $(SYMBOL_CFLAGS) $< > $*.tf1 $(AWK) -f "${srcdir}/scripts/dfn.awk" out="$*.tf2" $*.tf1 1>&2 rm -f $*.tf1 mv $*.tf2 $@ # The .c file for pnglibconf.h is machine generated pnglibconf.c: scripts/pnglibconf.dfa scripts/options.awk pngconf.h pngusr.dfa $(DFA_XTRA) rm -f $@ $*.tf[45] $(AWK) -f ${srcdir}/scripts/options.awk out=$*.tf4 version=search\ ${srcdir}/pngconf.h ${srcdir}/scripts/pnglibconf.dfa\ ${srcdir}/pngusr.dfa $(DFA_XTRA) 1>&2 $(AWK) -f ${srcdir}/scripts/options.awk out=$*.tf5 $*.tf4 1>&2 rm $*.tf4 mv $*.tf5 $@ # Symbol checks (.def and .out files should match) scripts/symbols.chk: scripts/checksym.awk scripts/symbols.def scripts/symbols.out .out.chk: rm -f $@ $*.new $(AWK) -f ${srcdir}/scripts/checksym.awk ${srcdir}/scripts/${*F}.def\ of="$*.new" $< >&2 mv $*.new $@ # used on demand to regenerate the standard header, CPPFLAGS should # be empty - no non-standard defines scripts/pnglibconf.c: scripts/pnglibconf.dfa scripts/options.awk pngconf.h rm -f $@ pnglibconf.tf[67] test -z "$(CPPFLAGS)" echo "com @PNGLIB_VERSION@ STANDARD API DEFINITION" |\ $(AWK) -f ${srcdir}/scripts/options.awk out=pnglibconf.tf6\ logunsupported=1 version=search ${srcdir}/pngconf.h -\ ${srcdir}/scripts/pnglibconf.dfa 1>&2 $(AWK) -f ${srcdir}/scripts/options.awk out=pnglibconf.tf7\ pnglibconf.tf6 1>&2 rm pnglibconf.tf6 mv pnglibconf.tf7 $@ $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_OBJECTS): png.h pngconf.h \ pnglibconf.h pngpriv.h pngdebug.h pnginfo.h pngstruct.h pngprefix.h test: check-am # Extra checks check: scripts/symbols.chk # Don't distribute the generated script files dist-hook: cd '$(top_distdir)'; rm -f $(SCRIPT_CLEANFILES) # Make links between installed files with release-specific names and the generic # file names. If this install rule is run the generic names will be deleted and # recreated - this has obvious issues for systems with multiple installations. install-header-links: @set -ex; cd '$(DESTDIR)$(includedir)'; for f in $(HEADERS); do \ rm -f "$$f"; $(LN_S) "$(PNGLIB_BASENAME)/$$f" "$$f"; done uninstall-header-links: cd '$(DESTDIR)$(includedir)'; rm -f $(HEADERS) install-libpng-pc: @set -ex; cd '$(DESTDIR)$(pkgconfigdir)'; rm -f libpng.pc; \ $(LN_S) '$(PNGLIB_BASENAME).pc' libpng.pc uninstall-libpng-pc: rm -f '$(DESTDIR)$(pkgconfigdir)/libpng.pc' # EXT_LIST is a list of the possibly library directory extensions, this exists # because we can't find a good way of discovering the file extensions that are # actually installed on a given system, so instead we check for every extension # we have seen. EXT_LIST = a dll.a so so.@PNGLIB_MAJOR@@PNGLIB_MINOR@.@PNGLIB_RELEASE@ la sl dylib install-library-links: @set -x; cd '$(DESTDIR)$(libdir)';\ for ext in $(EXT_LIST); do\ rm -f "libpng.$$ext";\ if test -f "$(PNGLIB_BASENAME).$$ext"; then\ $(LN_S) "$(PNGLIB_BASENAME).$$ext" "libpng.$$ext" || exit 1;\ fi;\ done uninstall-library-links: @set -x; cd '$(DESTDIR)$(libdir)'; for ext in $(EXT_LIST); do\ rm -f "libpng.$$ext"; done install-libpng-config: @set -ex; cd '$(DESTDIR)$(bindir)'; rm -f libpng-config; \ $(LN_S) '$(PNGLIB_BASENAME)-config' libpng-config uninstall-libpng-config: rm -f '$(DESTDIR)$(bindir)/libpng-config' if DO_INSTALL_LINKS # If --enable-unversioned-links is specified the header and lib file links # will be automatically made on a 'make install': install-data-hook: install-header-links uninstall-hook: uninstall-header-links install-exec-hook: install-library-links uninstall-hook: uninstall-library-links endif if DO_INSTALL_LIBPNG_PC # Likewise, --install-pc causes libpng.pc to be constructed: install-data-hook: install-libpng-pc uninstall-hook: uninstall-libpng-pc endif if DO_INSTALL_LIBPNG_CONFIG # And --install-config: install-exec-hook: install-libpng-config uninstall-hook: uninstall-libpng-config endif # The following addition ensures that 'make all' always builds the test programs # too. It used to, but some change either in libpng or configure stopped this # working. all-am: $(check_PROGRAMS) libpng-1.6.43/Makefile.in000066400000000000000000003205531456606525400151520ustar00rootroot00000000000000# Makefile.in generated by automake 1.16.5 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # Makefile.am, the source file for Makefile.in (and hence Makefile), is # # Copyright (c) 2018-2024 Cosmin Truta # Copyright (c) 2004-2016 Glenn Randers-Pehrson # # This code is released under the libpng license. # For conditions of distribution and use, see the disclaimer # and license in png.h VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @ENABLE_TESTS_TRUE@check_PROGRAMS = pngtest$(EXEEXT) \ @ENABLE_TESTS_TRUE@ pngunknown$(EXEEXT) pngstest$(EXEEXT) \ @ENABLE_TESTS_TRUE@ pngvalid$(EXEEXT) pngimage$(EXEEXT) \ @ENABLE_TESTS_TRUE@ pngcp$(EXEEXT) $(am__EXEEXT_1) @ENABLE_TESTS_TRUE@@HAVE_CLOCK_GETTIME_TRUE@am__append_1 = timepng @ENABLE_TOOLS_TRUE@bin_PROGRAMS = pngfix$(EXEEXT) \ @ENABLE_TOOLS_TRUE@ png-fix-itxt$(EXEEXT) @PNG_ARM_NEON_TRUE@am__append_2 = arm/arm_init.c\ @PNG_ARM_NEON_TRUE@ arm/filter_neon.S arm/filter_neon_intrinsics.c \ @PNG_ARM_NEON_TRUE@ arm/palette_neon_intrinsics.c @PNG_MIPS_MSA_TRUE@am__append_3 = mips/mips_init.c\ @PNG_MIPS_MSA_TRUE@ mips/filter_msa_intrinsics.c @PNG_MIPS_MMI_TRUE@@PNG_MIPS_MSA_FALSE@am__append_4 = mips/mips_init.c @PNG_MIPS_MMI_TRUE@am__append_5 = mips/filter_mmi_inline_assembly.c @PNG_INTEL_SSE_TRUE@am__append_6 = intel/intel_init.c\ @PNG_INTEL_SSE_TRUE@ intel/filter_sse2_intrinsics.c @PNG_POWERPC_VSX_TRUE@am__append_7 = powerpc/powerpc_init.c\ @PNG_POWERPC_VSX_TRUE@ powerpc/filter_vsx_intrinsics.c # Versioned symbols and restricted exports @HAVE_LD_VERSION_SCRIPT_TRUE@@HAVE_SOLARIS_LD_TRUE@am__append_8 = -Wl,-M -Wl,libpng.vers @HAVE_LD_VERSION_SCRIPT_TRUE@@HAVE_SOLARIS_LD_FALSE@am__append_9 = -Wl,--version-script=libpng.vers # Only restricted exports when possible @HAVE_LD_VERSION_SCRIPT_FALSE@am__append_10 = -export-symbols libpng.sym @PNG_LOONGARCH_LSX_TRUE@am__append_11 = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx.la @DO_PNG_PREFIX_TRUE@am__append_12 = -DPNG_PREFIX='@PNG_PREFIX@' subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/scripts/autoconf/libtool.m4 \ $(top_srcdir)/scripts/autoconf/ltoptions.m4 \ $(top_srcdir)/scripts/autoconf/ltsugar.m4 \ $(top_srcdir)/scripts/autoconf/ltversion.m4 \ $(top_srcdir)/scripts/autoconf/lt~obsolete.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ $(am__configure_deps) $(pkginclude_HEADERS) $(am__DIST_COMMON) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = libpng.pc libpng-config CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libdir)" \ "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man3dir)" \ "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(pkgconfigdir)" \ "$(DESTDIR)$(pkgincludedir)" "$(DESTDIR)$(pkgincludedir)" @ENABLE_TESTS_TRUE@@HAVE_CLOCK_GETTIME_TRUE@am__EXEEXT_1 = \ @ENABLE_TESTS_TRUE@@HAVE_CLOCK_GETTIME_TRUE@ timepng$(EXEEXT) PROGRAMS = $(bin_PROGRAMS) am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES) am__libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES_DIST = png.c \ pngerror.c pngget.c pngmem.c pngpread.c pngread.c pngrio.c \ pngrtran.c pngrutil.c pngset.c pngtrans.c pngwio.c pngwrite.c \ pngwtran.c pngwutil.c png.h pngconf.h pngdebug.h pnginfo.h \ pngpriv.h pngstruct.h pngusr.dfa arm/arm_init.c \ arm/filter_neon.S arm/filter_neon_intrinsics.c \ arm/palette_neon_intrinsics.c mips/mips_init.c \ mips/filter_msa_intrinsics.c mips/filter_mmi_inline_assembly.c \ intel/intel_init.c intel/filter_sse2_intrinsics.c \ powerpc/powerpc_init.c powerpc/filter_vsx_intrinsics.c am__dirstamp = $(am__leading_dot)dirstamp @PNG_ARM_NEON_TRUE@am__objects_1 = arm/arm_init.lo arm/filter_neon.lo \ @PNG_ARM_NEON_TRUE@ arm/filter_neon_intrinsics.lo \ @PNG_ARM_NEON_TRUE@ arm/palette_neon_intrinsics.lo @PNG_MIPS_MSA_TRUE@am__objects_2 = mips/mips_init.lo \ @PNG_MIPS_MSA_TRUE@ mips/filter_msa_intrinsics.lo @PNG_MIPS_MMI_TRUE@@PNG_MIPS_MSA_FALSE@am__objects_3 = \ @PNG_MIPS_MMI_TRUE@@PNG_MIPS_MSA_FALSE@ mips/mips_init.lo @PNG_MIPS_MMI_TRUE@am__objects_4 = mips/filter_mmi_inline_assembly.lo @PNG_INTEL_SSE_TRUE@am__objects_5 = intel/intel_init.lo \ @PNG_INTEL_SSE_TRUE@ intel/filter_sse2_intrinsics.lo @PNG_POWERPC_VSX_TRUE@am__objects_6 = powerpc/powerpc_init.lo \ @PNG_POWERPC_VSX_TRUE@ powerpc/filter_vsx_intrinsics.lo am_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_OBJECTS = png.lo pngerror.lo \ pngget.lo pngmem.lo pngpread.lo pngread.lo pngrio.lo \ pngrtran.lo pngrutil.lo pngset.lo pngtrans.lo pngwio.lo \ pngwrite.lo pngwtran.lo pngwutil.lo $(am__objects_1) \ $(am__objects_2) $(am__objects_3) $(am__objects_4) \ $(am__objects_5) $(am__objects_6) nodist_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_OBJECTS = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_OBJECTS = \ $(am_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_OBJECTS) \ $(nodist_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_LINK = $(LIBTOOL) $(AM_V_lt) \ --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_LDFLAGS) $(LDFLAGS) -o \ $@ libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la_LIBADD = am__libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la_SOURCES_DIST = \ loongarch/loongarch_lsx_init.c \ loongarch/filter_lsx_intrinsics.c @PNG_LOONGARCH_LSX_TRUE@am_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la_OBJECTS = loongarch/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la-loongarch_lsx_init.lo \ @PNG_LOONGARCH_LSX_TRUE@ loongarch/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la-filter_lsx_intrinsics.lo libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la_OBJECTS = \ $(am_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la_OBJECTS) libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la_LINK = $(LIBTOOL) $(AM_V_lt) \ --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \ $(CCLD) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ @PNG_LOONGARCH_LSX_TRUE@am_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la_rpath = am__png_fix_itxt_SOURCES_DIST = contrib/tools/png-fix-itxt.c @ENABLE_TOOLS_TRUE@am_png_fix_itxt_OBJECTS = \ @ENABLE_TOOLS_TRUE@ contrib/tools/png-fix-itxt.$(OBJEXT) png_fix_itxt_OBJECTS = $(am_png_fix_itxt_OBJECTS) png_fix_itxt_LDADD = $(LDADD) am__pngcp_SOURCES_DIST = contrib/tools/pngcp.c @ENABLE_TESTS_TRUE@am_pngcp_OBJECTS = contrib/tools/pngcp.$(OBJEXT) pngcp_OBJECTS = $(am_pngcp_OBJECTS) @ENABLE_TESTS_TRUE@pngcp_DEPENDENCIES = \ @ENABLE_TESTS_TRUE@ libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la am__pngfix_SOURCES_DIST = contrib/tools/pngfix.c @ENABLE_TOOLS_TRUE@am_pngfix_OBJECTS = contrib/tools/pngfix.$(OBJEXT) pngfix_OBJECTS = $(am_pngfix_OBJECTS) @ENABLE_TOOLS_TRUE@pngfix_DEPENDENCIES = \ @ENABLE_TOOLS_TRUE@ libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la am__pngimage_SOURCES_DIST = contrib/libtests/pngimage.c @ENABLE_TESTS_TRUE@am_pngimage_OBJECTS = \ @ENABLE_TESTS_TRUE@ contrib/libtests/pngimage.$(OBJEXT) pngimage_OBJECTS = $(am_pngimage_OBJECTS) @ENABLE_TESTS_TRUE@pngimage_DEPENDENCIES = \ @ENABLE_TESTS_TRUE@ libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la am__pngstest_SOURCES_DIST = contrib/libtests/pngstest.c @ENABLE_TESTS_TRUE@am_pngstest_OBJECTS = \ @ENABLE_TESTS_TRUE@ contrib/libtests/pngstest.$(OBJEXT) pngstest_OBJECTS = $(am_pngstest_OBJECTS) @ENABLE_TESTS_TRUE@pngstest_DEPENDENCIES = \ @ENABLE_TESTS_TRUE@ libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la am__pngtest_SOURCES_DIST = pngtest.c @ENABLE_TESTS_TRUE@am_pngtest_OBJECTS = pngtest.$(OBJEXT) pngtest_OBJECTS = $(am_pngtest_OBJECTS) @ENABLE_TESTS_TRUE@pngtest_DEPENDENCIES = \ @ENABLE_TESTS_TRUE@ libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la am__pngunknown_SOURCES_DIST = contrib/libtests/pngunknown.c @ENABLE_TESTS_TRUE@am_pngunknown_OBJECTS = \ @ENABLE_TESTS_TRUE@ contrib/libtests/pngunknown.$(OBJEXT) pngunknown_OBJECTS = $(am_pngunknown_OBJECTS) @ENABLE_TESTS_TRUE@pngunknown_DEPENDENCIES = \ @ENABLE_TESTS_TRUE@ libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la am__pngvalid_SOURCES_DIST = contrib/libtests/pngvalid.c @ENABLE_TESTS_TRUE@am_pngvalid_OBJECTS = \ @ENABLE_TESTS_TRUE@ contrib/libtests/pngvalid.$(OBJEXT) pngvalid_OBJECTS = $(am_pngvalid_OBJECTS) @ENABLE_TESTS_TRUE@pngvalid_DEPENDENCIES = \ @ENABLE_TESTS_TRUE@ libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la am__timepng_SOURCES_DIST = contrib/libtests/timepng.c @ENABLE_TESTS_TRUE@am_timepng_OBJECTS = \ @ENABLE_TESTS_TRUE@ contrib/libtests/timepng.$(OBJEXT) timepng_OBJECTS = $(am_timepng_OBJECTS) @ENABLE_TESTS_TRUE@timepng_DEPENDENCIES = \ @ENABLE_TESTS_TRUE@ libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la SCRIPTS = $(bin_SCRIPTS) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/png.Plo ./$(DEPDIR)/pngerror.Plo \ ./$(DEPDIR)/pngget.Plo ./$(DEPDIR)/pngmem.Plo \ ./$(DEPDIR)/pngpread.Plo ./$(DEPDIR)/pngread.Plo \ ./$(DEPDIR)/pngrio.Plo ./$(DEPDIR)/pngrtran.Plo \ ./$(DEPDIR)/pngrutil.Plo ./$(DEPDIR)/pngset.Plo \ ./$(DEPDIR)/pngtest.Po ./$(DEPDIR)/pngtrans.Plo \ ./$(DEPDIR)/pngwio.Plo ./$(DEPDIR)/pngwrite.Plo \ ./$(DEPDIR)/pngwtran.Plo ./$(DEPDIR)/pngwutil.Plo \ arm/$(DEPDIR)/arm_init.Plo arm/$(DEPDIR)/filter_neon.Plo \ arm/$(DEPDIR)/filter_neon_intrinsics.Plo \ arm/$(DEPDIR)/palette_neon_intrinsics.Plo \ contrib/libtests/$(DEPDIR)/pngimage.Po \ contrib/libtests/$(DEPDIR)/pngstest.Po \ contrib/libtests/$(DEPDIR)/pngunknown.Po \ contrib/libtests/$(DEPDIR)/pngvalid.Po \ contrib/libtests/$(DEPDIR)/timepng.Po \ contrib/tools/$(DEPDIR)/png-fix-itxt.Po \ contrib/tools/$(DEPDIR)/pngcp.Po \ contrib/tools/$(DEPDIR)/pngfix.Po \ intel/$(DEPDIR)/filter_sse2_intrinsics.Plo \ intel/$(DEPDIR)/intel_init.Plo \ loongarch/$(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la-filter_lsx_intrinsics.Plo \ loongarch/$(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la-loongarch_lsx_init.Plo \ mips/$(DEPDIR)/filter_mmi_inline_assembly.Plo \ mips/$(DEPDIR)/filter_msa_intrinsics.Plo \ mips/$(DEPDIR)/mips_init.Plo \ powerpc/$(DEPDIR)/filter_vsx_intrinsics.Plo \ powerpc/$(DEPDIR)/powerpc_init.Plo am__mv = mv -f CPPASCOMPILE = $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) LTCPPASCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CCASFLAGS) $(CCASFLAGS) AM_V_CPPAS = $(am__v_CPPAS_@AM_V@) am__v_CPPAS_ = $(am__v_CPPAS_@AM_DEFAULT_V@) am__v_CPPAS_0 = @echo " CPPAS " $@; am__v_CPPAS_1 = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES) \ $(nodist_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES) \ $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la_SOURCES) \ $(png_fix_itxt_SOURCES) $(pngcp_SOURCES) $(pngfix_SOURCES) \ $(pngimage_SOURCES) $(pngstest_SOURCES) $(pngtest_SOURCES) \ $(pngunknown_SOURCES) $(pngvalid_SOURCES) $(timepng_SOURCES) DIST_SOURCES = \ $(am__libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES_DIST) \ $(am__libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la_SOURCES_DIST) \ $(am__png_fix_itxt_SOURCES_DIST) $(am__pngcp_SOURCES_DIST) \ $(am__pngfix_SOURCES_DIST) $(am__pngimage_SOURCES_DIST) \ $(am__pngstest_SOURCES_DIST) $(am__pngtest_SOURCES_DIST) \ $(am__pngunknown_SOURCES_DIST) $(am__pngvalid_SOURCES_DIST) \ $(am__timepng_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac man3dir = $(mandir)/man3 man5dir = $(mandir)/man5 NROFF = nroff MANS = $(dist_man_MANS) DATA = $(pkgconfig_DATA) HEADERS = $(nodist_pkginclude_HEADERS) $(pkginclude_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \ config.h.in # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` AM_RECURSIVE_TARGETS = cscope check recheck am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)' RECHECK_LOGS = $(TEST_LOGS) TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \ $(srcdir)/config.h.in $(srcdir)/libpng-config.in \ $(srcdir)/libpng.pc.in AUTHORS INSTALL README TODO compile \ config.guess config.sub depcomp install-sh ltmain.sh missing \ test-driver DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__post_remove_distdir = $(am__remove_distdir) DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.xz GZIP_ENV = --best DIST_TARGETS = dist-xz dist-gzip # Exists only to be overridden by the user if desired. AM_DISTCHECK_DVI_TARGET = dvi distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print #distribute headers in /usr/include/libpng/* pkgincludedir = $(includedir)/$(PNGLIB_BASENAME) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCAS = @CCAS@ CCASDEPMODE = @CCASDEPMODE@ CCASFLAGS = @CCASFLAGS@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CSCOPE = @CSCOPE@ CTAGS = @CTAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ # DFNCPP is normally just CPP - the C preprocessor - but on Solaris and maybe # other operating systems (NeXT?) the C preprocessor selected by configure # checks input tokens for validity - effectively it performs part of the ANSI-C # parsing - and therefore fails with the .df files. configure.ac has special # checks for this and sets DFNCPP appropriately. DFNCPP = @DFNCPP@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ FILECMD = @FILECMD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PNGLIB_MAJOR = @PNGLIB_MAJOR@ PNGLIB_MINOR = @PNGLIB_MINOR@ PNGLIB_RELEASE = @PNGLIB_RELEASE@ PNGLIB_VERSION = @PNGLIB_VERSION@ # PNG_COPTS give extra options for the C compiler to be used on all compilation # steps (unless targe_CFLAGS is specified; that will take precedence over # AM_CFLAGS) PNG_COPTS = @PNG_COPTS@ PNG_PREFIX = @PNG_PREFIX@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ SYMBOL_PREFIX = @SYMBOL_PREFIX@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ # generate the -config scripts if required binconfigs = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@-config bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ # pkg-config stuff, note that libpng.pc is always required in order # to get the correct library pkgconfigdir = @pkgconfigdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ PNGLIB_BASENAME = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@ ACLOCAL_AMFLAGS = -I scripts/autoconf # This ensures that pnglibconf.h gets built at the start of 'make all' or # 'make check', but it does not add dependencies to the individual programs, # this is done below. # # IMPORTANT: always add the object modules of new programs to the list below # because otherwise the sequence 'configure; make new-program' will *sometimes* # result in the installed (system) pnglibconf.h being used and the result is # always wrong and always very confusing. BUILT_SOURCES = pnglibconf.h @ENABLE_TESTS_TRUE@pngtest_SOURCES = pngtest.c @ENABLE_TESTS_TRUE@pngtest_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la @ENABLE_TESTS_TRUE@pngvalid_SOURCES = contrib/libtests/pngvalid.c @ENABLE_TESTS_TRUE@pngvalid_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la @ENABLE_TESTS_TRUE@pngstest_SOURCES = contrib/libtests/pngstest.c @ENABLE_TESTS_TRUE@pngstest_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la @ENABLE_TESTS_TRUE@pngunknown_SOURCES = contrib/libtests/pngunknown.c @ENABLE_TESTS_TRUE@pngunknown_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la @ENABLE_TESTS_TRUE@pngimage_SOURCES = contrib/libtests/pngimage.c @ENABLE_TESTS_TRUE@pngimage_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la @ENABLE_TESTS_TRUE@timepng_SOURCES = contrib/libtests/timepng.c @ENABLE_TESTS_TRUE@timepng_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la @ENABLE_TESTS_TRUE@pngcp_SOURCES = contrib/tools/pngcp.c @ENABLE_TESTS_TRUE@pngcp_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la @ENABLE_TOOLS_TRUE@pngfix_SOURCES = contrib/tools/pngfix.c @ENABLE_TOOLS_TRUE@pngfix_LDADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la @ENABLE_TOOLS_TRUE@png_fix_itxt_SOURCES = contrib/tools/png-fix-itxt.c # Generally these are single line shell scripts to run a test with a particular # set of parameters: @ENABLE_TESTS_TRUE@TESTS = \ @ENABLE_TESTS_TRUE@ tests/pngtest-all\ @ENABLE_TESTS_TRUE@ tests/pngvalid-gamma-16-to-8 tests/pngvalid-gamma-alpha-mode\ @ENABLE_TESTS_TRUE@ tests/pngvalid-gamma-background tests/pngvalid-gamma-expand16-alpha-mode\ @ENABLE_TESTS_TRUE@ tests/pngvalid-gamma-expand16-background\ @ENABLE_TESTS_TRUE@ tests/pngvalid-gamma-expand16-transform tests/pngvalid-gamma-sbit\ @ENABLE_TESTS_TRUE@ tests/pngvalid-gamma-threshold tests/pngvalid-gamma-transform\ @ENABLE_TESTS_TRUE@ tests/pngvalid-progressive-size\ @ENABLE_TESTS_TRUE@ tests/pngvalid-progressive-interlace-standard\ @ENABLE_TESTS_TRUE@ tests/pngvalid-transform\ @ENABLE_TESTS_TRUE@ tests/pngvalid-progressive-standard tests/pngvalid-standard\ @ENABLE_TESTS_TRUE@ tests/pngstest-1.8 tests/pngstest-1.8-alpha tests/pngstest-linear\ @ENABLE_TESTS_TRUE@ tests/pngstest-linear-alpha tests/pngstest-none tests/pngstest-none-alpha\ @ENABLE_TESTS_TRUE@ tests/pngstest-sRGB tests/pngstest-sRGB-alpha tests/pngunknown-IDAT\ @ENABLE_TESTS_TRUE@ tests/pngunknown-discard tests/pngunknown-if-safe tests/pngunknown-sAPI\ @ENABLE_TESTS_TRUE@ tests/pngunknown-sTER tests/pngunknown-save tests/pngunknown-vpAg\ @ENABLE_TESTS_TRUE@ tests/pngimage-quick tests/pngimage-full # man pages dist_man_MANS = libpng.3 libpngpf.3 png.5 EXTRA_SCRIPTS = libpng-config libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@-config bin_SCRIPTS = @binconfigs@ # rules to build libpng, only build the old library on request lib_LTLIBRARIES = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la # EXTRA_LTLIBRARIES= libpng.la libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES = png.c pngerror.c \ pngget.c pngmem.c pngpread.c pngread.c pngrio.c pngrtran.c \ pngrutil.c pngset.c pngtrans.c pngwio.c pngwrite.c pngwtran.c \ pngwutil.c png.h pngconf.h pngdebug.h pnginfo.h pngpriv.h \ pngstruct.h pngusr.dfa $(am__append_2) $(am__append_3) \ $(am__append_4) $(am__append_5) $(am__append_6) \ $(am__append_7) @PNG_LOONGARCH_LSX_TRUE@noinst_LTLIBRARIES = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx.la @PNG_LOONGARCH_LSX_TRUE@libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la_SOURCES = loongarch/loongarch_lsx_init.c\ @PNG_LOONGARCH_LSX_TRUE@ loongarch/filter_lsx_intrinsics.c @PNG_LOONGARCH_LSX_TRUE@libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la_CFLAGS = -mlsx @PNG_LOONGARCH_LSX_TRUE@libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_LIBADD = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx.la # libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_DEPENDENCIES = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx.la nodist_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES = pnglibconf.h libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_LDFLAGS = -no-undefined \ -export-dynamic -version-number \ @PNGLIB_MAJOR@@PNGLIB_MINOR@:@PNGLIB_RELEASE@:0 \ $(am__append_8) $(am__append_9) $(am__append_10) @HAVE_LD_VERSION_SCRIPT_FALSE@libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_DEPENDENCIES = \ @HAVE_LD_VERSION_SCRIPT_FALSE@ libpng.sym $(am__append_11) @HAVE_LD_VERSION_SCRIPT_TRUE@libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_DEPENDENCIES = \ @HAVE_LD_VERSION_SCRIPT_TRUE@ libpng.vers $(am__append_11) pkginclude_HEADERS = png.h pngconf.h nodist_pkginclude_HEADERS = pnglibconf.h pkgconfig_DATA = libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.pc # Extra source distribution files, '${srcdir}' is used below to stop build files # from those directories being included. This only works if the configure is # not done in the source directory! EXTRA_DIST = \ ANNOUNCE AUTHORS CHANGES INSTALL LICENSE README TODO TRADEMARK \ pngtest.png pngbar.png pngnow.png pngbar.jpg autogen.sh \ ${srcdir}/ci ${srcdir}/contrib ${srcdir}/projects ${srcdir}/scripts \ $(TESTS) $(XFAIL_TESTS) tests/pngstest \ CMakeLists.txt example.c libpng-manual.txt SCRIPT_CLEANFILES = scripts/*.out scripts/*.chk CLEANFILES = *.tf? pngout.png libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.pc \ libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@-config libpng.vers libpng.sym \ check.new pnglibconf.h pngprefix.h symbols.new pngtest-log.txt \ pnglibconf.out pnglibconf.c pnglibconf.pre pnglibconf.dfn \ $(SCRIPT_CLEANFILES) MAINTAINERCLEANFILES = Makefile.in aclocal.m4 config.guess config.h.in \ config.sub configure depcomp install-sh ltmain.sh missing AM_CFLAGS = ${PNG_COPTS} SUFFIXES = .chk .out # We must use -DPNG_NO_USE_READ_MACROS here even when the library may actually # be built with PNG_USE_READ_MACROS; this prevents the read macros from # interfering with the symbol file format. SYMBOL_CFLAGS = -DPNGLIB_LIBNAME='PNG@PNGLIB_MAJOR@@PNGLIB_MINOR@_0' \ -DPNGLIB_VERSION='@PNGLIB_VERSION@' \ -DSYMBOL_PREFIX='$(SYMBOL_PREFIX)' -DPNG_NO_USE_READ_MACROS \ -DPNG_BUILDING_SYMBOL_TABLE $(am__append_12) # EXT_LIST is a list of the possibly library directory extensions, this exists # because we can't find a good way of discovering the file extensions that are # actually installed on a given system, so instead we check for every extension # we have seen. EXT_LIST = a dll.a so so.@PNGLIB_MAJOR@@PNGLIB_MINOR@.@PNGLIB_RELEASE@ la sl dylib all: $(BUILT_SOURCES) config.h $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: .SUFFIXES: .chk .out .S .c .lo .log .o .obj .test .test$(EXEEXT) .trs am--refresh: Makefile @: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): config.h: stamp-h1 @test -f $@ || rm -f stamp-h1 @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 libpng.pc: $(top_builddir)/config.status $(srcdir)/libpng.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ libpng-config: $(top_builddir)/config.status $(srcdir)/libpng-config.in cd $(top_builddir) && $(SHELL) ./config.status $@ install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p \ || test -f $$p1 \ ; then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' \ -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' \ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list clean-checkPROGRAMS: @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } arm/$(am__dirstamp): @$(MKDIR_P) arm @: > arm/$(am__dirstamp) arm/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) arm/$(DEPDIR) @: > arm/$(DEPDIR)/$(am__dirstamp) arm/arm_init.lo: arm/$(am__dirstamp) arm/$(DEPDIR)/$(am__dirstamp) arm/filter_neon.lo: arm/$(am__dirstamp) arm/$(DEPDIR)/$(am__dirstamp) arm/filter_neon_intrinsics.lo: arm/$(am__dirstamp) \ arm/$(DEPDIR)/$(am__dirstamp) arm/palette_neon_intrinsics.lo: arm/$(am__dirstamp) \ arm/$(DEPDIR)/$(am__dirstamp) mips/$(am__dirstamp): @$(MKDIR_P) mips @: > mips/$(am__dirstamp) mips/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) mips/$(DEPDIR) @: > mips/$(DEPDIR)/$(am__dirstamp) mips/mips_init.lo: mips/$(am__dirstamp) mips/$(DEPDIR)/$(am__dirstamp) mips/filter_msa_intrinsics.lo: mips/$(am__dirstamp) \ mips/$(DEPDIR)/$(am__dirstamp) mips/filter_mmi_inline_assembly.lo: mips/$(am__dirstamp) \ mips/$(DEPDIR)/$(am__dirstamp) intel/$(am__dirstamp): @$(MKDIR_P) intel @: > intel/$(am__dirstamp) intel/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) intel/$(DEPDIR) @: > intel/$(DEPDIR)/$(am__dirstamp) intel/intel_init.lo: intel/$(am__dirstamp) \ intel/$(DEPDIR)/$(am__dirstamp) intel/filter_sse2_intrinsics.lo: intel/$(am__dirstamp) \ intel/$(DEPDIR)/$(am__dirstamp) powerpc/$(am__dirstamp): @$(MKDIR_P) powerpc @: > powerpc/$(am__dirstamp) powerpc/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) powerpc/$(DEPDIR) @: > powerpc/$(DEPDIR)/$(am__dirstamp) powerpc/powerpc_init.lo: powerpc/$(am__dirstamp) \ powerpc/$(DEPDIR)/$(am__dirstamp) powerpc/filter_vsx_intrinsics.lo: powerpc/$(am__dirstamp) \ powerpc/$(DEPDIR)/$(am__dirstamp) libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@.la: $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_OBJECTS) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_DEPENDENCIES) $(EXTRA_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_DEPENDENCIES) $(AM_V_CCLD)$(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_LINK) -rpath $(libdir) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_OBJECTS) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_LIBADD) $(LIBS) loongarch/$(am__dirstamp): @$(MKDIR_P) loongarch @: > loongarch/$(am__dirstamp) loongarch/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) loongarch/$(DEPDIR) @: > loongarch/$(DEPDIR)/$(am__dirstamp) loongarch/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la-loongarch_lsx_init.lo: \ loongarch/$(am__dirstamp) loongarch/$(DEPDIR)/$(am__dirstamp) loongarch/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la-filter_lsx_intrinsics.lo: \ loongarch/$(am__dirstamp) loongarch/$(DEPDIR)/$(am__dirstamp) libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx.la: $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la_OBJECTS) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la_DEPENDENCIES) $(EXTRA_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la_DEPENDENCIES) $(AM_V_CCLD)$(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la_LINK) $(am_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la_rpath) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la_OBJECTS) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la_LIBADD) $(LIBS) contrib/tools/$(am__dirstamp): @$(MKDIR_P) contrib/tools @: > contrib/tools/$(am__dirstamp) contrib/tools/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) contrib/tools/$(DEPDIR) @: > contrib/tools/$(DEPDIR)/$(am__dirstamp) contrib/tools/png-fix-itxt.$(OBJEXT): contrib/tools/$(am__dirstamp) \ contrib/tools/$(DEPDIR)/$(am__dirstamp) png-fix-itxt$(EXEEXT): $(png_fix_itxt_OBJECTS) $(png_fix_itxt_DEPENDENCIES) $(EXTRA_png_fix_itxt_DEPENDENCIES) @rm -f png-fix-itxt$(EXEEXT) $(AM_V_CCLD)$(LINK) $(png_fix_itxt_OBJECTS) $(png_fix_itxt_LDADD) $(LIBS) contrib/tools/pngcp.$(OBJEXT): contrib/tools/$(am__dirstamp) \ contrib/tools/$(DEPDIR)/$(am__dirstamp) pngcp$(EXEEXT): $(pngcp_OBJECTS) $(pngcp_DEPENDENCIES) $(EXTRA_pngcp_DEPENDENCIES) @rm -f pngcp$(EXEEXT) $(AM_V_CCLD)$(LINK) $(pngcp_OBJECTS) $(pngcp_LDADD) $(LIBS) contrib/tools/pngfix.$(OBJEXT): contrib/tools/$(am__dirstamp) \ contrib/tools/$(DEPDIR)/$(am__dirstamp) pngfix$(EXEEXT): $(pngfix_OBJECTS) $(pngfix_DEPENDENCIES) $(EXTRA_pngfix_DEPENDENCIES) @rm -f pngfix$(EXEEXT) $(AM_V_CCLD)$(LINK) $(pngfix_OBJECTS) $(pngfix_LDADD) $(LIBS) contrib/libtests/$(am__dirstamp): @$(MKDIR_P) contrib/libtests @: > contrib/libtests/$(am__dirstamp) contrib/libtests/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) contrib/libtests/$(DEPDIR) @: > contrib/libtests/$(DEPDIR)/$(am__dirstamp) contrib/libtests/pngimage.$(OBJEXT): contrib/libtests/$(am__dirstamp) \ contrib/libtests/$(DEPDIR)/$(am__dirstamp) pngimage$(EXEEXT): $(pngimage_OBJECTS) $(pngimage_DEPENDENCIES) $(EXTRA_pngimage_DEPENDENCIES) @rm -f pngimage$(EXEEXT) $(AM_V_CCLD)$(LINK) $(pngimage_OBJECTS) $(pngimage_LDADD) $(LIBS) contrib/libtests/pngstest.$(OBJEXT): contrib/libtests/$(am__dirstamp) \ contrib/libtests/$(DEPDIR)/$(am__dirstamp) pngstest$(EXEEXT): $(pngstest_OBJECTS) $(pngstest_DEPENDENCIES) $(EXTRA_pngstest_DEPENDENCIES) @rm -f pngstest$(EXEEXT) $(AM_V_CCLD)$(LINK) $(pngstest_OBJECTS) $(pngstest_LDADD) $(LIBS) pngtest$(EXEEXT): $(pngtest_OBJECTS) $(pngtest_DEPENDENCIES) $(EXTRA_pngtest_DEPENDENCIES) @rm -f pngtest$(EXEEXT) $(AM_V_CCLD)$(LINK) $(pngtest_OBJECTS) $(pngtest_LDADD) $(LIBS) contrib/libtests/pngunknown.$(OBJEXT): \ contrib/libtests/$(am__dirstamp) \ contrib/libtests/$(DEPDIR)/$(am__dirstamp) pngunknown$(EXEEXT): $(pngunknown_OBJECTS) $(pngunknown_DEPENDENCIES) $(EXTRA_pngunknown_DEPENDENCIES) @rm -f pngunknown$(EXEEXT) $(AM_V_CCLD)$(LINK) $(pngunknown_OBJECTS) $(pngunknown_LDADD) $(LIBS) contrib/libtests/pngvalid.$(OBJEXT): contrib/libtests/$(am__dirstamp) \ contrib/libtests/$(DEPDIR)/$(am__dirstamp) pngvalid$(EXEEXT): $(pngvalid_OBJECTS) $(pngvalid_DEPENDENCIES) $(EXTRA_pngvalid_DEPENDENCIES) @rm -f pngvalid$(EXEEXT) $(AM_V_CCLD)$(LINK) $(pngvalid_OBJECTS) $(pngvalid_LDADD) $(LIBS) contrib/libtests/timepng.$(OBJEXT): contrib/libtests/$(am__dirstamp) \ contrib/libtests/$(DEPDIR)/$(am__dirstamp) timepng$(EXEEXT): $(timepng_OBJECTS) $(timepng_DEPENDENCIES) $(EXTRA_timepng_DEPENDENCIES) @rm -f timepng$(EXEEXT) $(AM_V_CCLD)$(LINK) $(timepng_OBJECTS) $(timepng_LDADD) $(LIBS) install-binSCRIPTS: $(bin_SCRIPTS) @$(NORMAL_INSTALL) @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n' \ -e 'h;s|.*|.|' \ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) { files[d] = files[d] " " $$1; \ if (++n[d] == $(am__install_max)) { \ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ else { print "f", d "/" $$4, $$1 } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binSCRIPTS: @$(NORMAL_UNINSTALL) @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 's,.*/,,;$(transform)'`; \ dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir) mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f arm/*.$(OBJEXT) -rm -f arm/*.lo -rm -f contrib/libtests/*.$(OBJEXT) -rm -f contrib/tools/*.$(OBJEXT) -rm -f intel/*.$(OBJEXT) -rm -f intel/*.lo -rm -f loongarch/*.$(OBJEXT) -rm -f loongarch/*.lo -rm -f mips/*.$(OBJEXT) -rm -f mips/*.lo -rm -f powerpc/*.$(OBJEXT) -rm -f powerpc/*.lo distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/png.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngerror.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngget.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngmem.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngpread.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngread.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngrio.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngrtran.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngrutil.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngset.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngtest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngtrans.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngwio.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngwrite.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngwtran.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngwutil.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@arm/$(DEPDIR)/arm_init.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@arm/$(DEPDIR)/filter_neon.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@arm/$(DEPDIR)/filter_neon_intrinsics.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@arm/$(DEPDIR)/palette_neon_intrinsics.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@contrib/libtests/$(DEPDIR)/pngimage.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@contrib/libtests/$(DEPDIR)/pngstest.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@contrib/libtests/$(DEPDIR)/pngunknown.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@contrib/libtests/$(DEPDIR)/pngvalid.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@contrib/libtests/$(DEPDIR)/timepng.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@contrib/tools/$(DEPDIR)/png-fix-itxt.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@contrib/tools/$(DEPDIR)/pngcp.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@contrib/tools/$(DEPDIR)/pngfix.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@intel/$(DEPDIR)/filter_sse2_intrinsics.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@intel/$(DEPDIR)/intel_init.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@loongarch/$(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la-filter_lsx_intrinsics.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@loongarch/$(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la-loongarch_lsx_init.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@mips/$(DEPDIR)/filter_mmi_inline_assembly.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@mips/$(DEPDIR)/filter_msa_intrinsics.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@mips/$(DEPDIR)/mips_init.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@powerpc/$(DEPDIR)/filter_vsx_intrinsics.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@powerpc/$(DEPDIR)/powerpc_init.Plo@am__quote@ # am--include-marker $(am__depfiles_remade): @$(MKDIR_P) $(@D) @echo '# dummy' >$@-t && $(am__mv) $@-t $@ am--depfiles: $(am__depfiles_remade) .S.o: @am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCCAS_TRUE@ $(CPPASCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCCAS_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(CPPASCOMPILE) -c -o $@ $< .S.obj: @am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCCAS_TRUE@ $(CPPASCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCCAS_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(CPPASCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .S.lo: @am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCCAS_TRUE@ $(LTCPPASCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCCAS_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(LTCPPASCOMPILE) -c -o $@ $< .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: @am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ @am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ @am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< loongarch/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la-loongarch_lsx_init.lo: loongarch/loongarch_lsx_init.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la_CFLAGS) $(CFLAGS) -MT loongarch/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la-loongarch_lsx_init.lo -MD -MP -MF loongarch/$(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la-loongarch_lsx_init.Tpo -c -o loongarch/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la-loongarch_lsx_init.lo `test -f 'loongarch/loongarch_lsx_init.c' || echo '$(srcdir)/'`loongarch/loongarch_lsx_init.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) loongarch/$(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la-loongarch_lsx_init.Tpo loongarch/$(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la-loongarch_lsx_init.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='loongarch/loongarch_lsx_init.c' object='loongarch/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la-loongarch_lsx_init.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la_CFLAGS) $(CFLAGS) -c -o loongarch/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la-loongarch_lsx_init.lo `test -f 'loongarch/loongarch_lsx_init.c' || echo '$(srcdir)/'`loongarch/loongarch_lsx_init.c loongarch/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la-filter_lsx_intrinsics.lo: loongarch/filter_lsx_intrinsics.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la_CFLAGS) $(CFLAGS) -MT loongarch/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la-filter_lsx_intrinsics.lo -MD -MP -MF loongarch/$(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la-filter_lsx_intrinsics.Tpo -c -o loongarch/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la-filter_lsx_intrinsics.lo `test -f 'loongarch/filter_lsx_intrinsics.c' || echo '$(srcdir)/'`loongarch/filter_lsx_intrinsics.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) loongarch/$(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la-filter_lsx_intrinsics.Tpo loongarch/$(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la-filter_lsx_intrinsics.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='loongarch/filter_lsx_intrinsics.c' object='loongarch/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la-filter_lsx_intrinsics.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la_CFLAGS) $(CFLAGS) -c -o loongarch/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la-filter_lsx_intrinsics.lo `test -f 'loongarch/filter_lsx_intrinsics.c' || echo '$(srcdir)/'`loongarch/filter_lsx_intrinsics.c mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs -rm -rf arm/.libs arm/_libs -rm -rf intel/.libs intel/_libs -rm -rf loongarch/.libs loongarch/_libs -rm -rf mips/.libs mips/_libs -rm -rf powerpc/.libs powerpc/_libs distclean-libtool: -rm -f libtool config.lt install-man3: $(dist_man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(dist_man_MANS)'; \ test -n "$(man3dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man3dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man3dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.3[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man3dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man3dir)" || exit $$?; }; \ done; } uninstall-man3: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man3dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.3[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man3dir)'; $(am__uninstall_files_from_dir) install-man5: $(dist_man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(dist_man_MANS)'; \ test -n "$(man5dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man5dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man5dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.5[a-z]*$$/p'; \ fi; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man5dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man5dir)" || exit $$?; }; \ done; } uninstall-man5: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man5dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.5[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man5dir)'; $(am__uninstall_files_from_dir) install-pkgconfigDATA: $(pkgconfig_DATA) @$(NORMAL_INSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ done uninstall-pkgconfigDATA: @$(NORMAL_UNINSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) install-nodist_pkgincludeHEADERS: $(nodist_pkginclude_HEADERS) @$(NORMAL_INSTALL) @list='$(nodist_pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \ done uninstall-nodist_pkgincludeHEADERS: @$(NORMAL_UNINSTALL) @list='$(nodist_pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir) install-pkgincludeHEADERS: $(pkginclude_HEADERS) @$(NORMAL_INSTALL) @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(pkgincludedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)" || exit 1; \ fi; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \ done uninstall-pkgincludeHEADERS: @$(NORMAL_UNINSTALL) @list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgincludedir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscope: cscope.files test ! -s cscope.files \ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) clean-cscope: -rm -f cscope.files cscope.files: clean-cscope cscopelist cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ if test -n "$(PACKAGE_BUGREPORT)"; then \ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: $(check_PROGRAMS) @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ trs_list=`for i in $$bases; do echo $$i.trs; done`; \ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all $(check_PROGRAMS) @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? tests/pngtest-all.log: tests/pngtest-all @p='tests/pngtest-all'; \ b='tests/pngtest-all'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) tests/pngvalid-gamma-16-to-8.log: tests/pngvalid-gamma-16-to-8 @p='tests/pngvalid-gamma-16-to-8'; \ b='tests/pngvalid-gamma-16-to-8'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) tests/pngvalid-gamma-alpha-mode.log: tests/pngvalid-gamma-alpha-mode @p='tests/pngvalid-gamma-alpha-mode'; \ b='tests/pngvalid-gamma-alpha-mode'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) tests/pngvalid-gamma-background.log: tests/pngvalid-gamma-background @p='tests/pngvalid-gamma-background'; \ b='tests/pngvalid-gamma-background'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) tests/pngvalid-gamma-expand16-alpha-mode.log: tests/pngvalid-gamma-expand16-alpha-mode @p='tests/pngvalid-gamma-expand16-alpha-mode'; \ b='tests/pngvalid-gamma-expand16-alpha-mode'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) tests/pngvalid-gamma-expand16-background.log: tests/pngvalid-gamma-expand16-background @p='tests/pngvalid-gamma-expand16-background'; \ b='tests/pngvalid-gamma-expand16-background'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) tests/pngvalid-gamma-expand16-transform.log: tests/pngvalid-gamma-expand16-transform @p='tests/pngvalid-gamma-expand16-transform'; \ b='tests/pngvalid-gamma-expand16-transform'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) tests/pngvalid-gamma-sbit.log: tests/pngvalid-gamma-sbit @p='tests/pngvalid-gamma-sbit'; \ b='tests/pngvalid-gamma-sbit'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) tests/pngvalid-gamma-threshold.log: tests/pngvalid-gamma-threshold @p='tests/pngvalid-gamma-threshold'; \ b='tests/pngvalid-gamma-threshold'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) tests/pngvalid-gamma-transform.log: tests/pngvalid-gamma-transform @p='tests/pngvalid-gamma-transform'; \ b='tests/pngvalid-gamma-transform'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) tests/pngvalid-progressive-size.log: tests/pngvalid-progressive-size @p='tests/pngvalid-progressive-size'; \ b='tests/pngvalid-progressive-size'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) tests/pngvalid-progressive-interlace-standard.log: tests/pngvalid-progressive-interlace-standard @p='tests/pngvalid-progressive-interlace-standard'; \ b='tests/pngvalid-progressive-interlace-standard'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) tests/pngvalid-transform.log: tests/pngvalid-transform @p='tests/pngvalid-transform'; \ b='tests/pngvalid-transform'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) tests/pngvalid-progressive-standard.log: tests/pngvalid-progressive-standard @p='tests/pngvalid-progressive-standard'; \ b='tests/pngvalid-progressive-standard'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) tests/pngvalid-standard.log: tests/pngvalid-standard @p='tests/pngvalid-standard'; \ b='tests/pngvalid-standard'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) tests/pngstest-1.8.log: tests/pngstest-1.8 @p='tests/pngstest-1.8'; \ b='tests/pngstest-1.8'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) tests/pngstest-1.8-alpha.log: tests/pngstest-1.8-alpha @p='tests/pngstest-1.8-alpha'; \ b='tests/pngstest-1.8-alpha'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) tests/pngstest-linear.log: tests/pngstest-linear @p='tests/pngstest-linear'; \ b='tests/pngstest-linear'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) tests/pngstest-linear-alpha.log: tests/pngstest-linear-alpha @p='tests/pngstest-linear-alpha'; \ b='tests/pngstest-linear-alpha'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) tests/pngstest-none.log: tests/pngstest-none @p='tests/pngstest-none'; \ b='tests/pngstest-none'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) tests/pngstest-none-alpha.log: tests/pngstest-none-alpha @p='tests/pngstest-none-alpha'; \ b='tests/pngstest-none-alpha'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) tests/pngstest-sRGB.log: tests/pngstest-sRGB @p='tests/pngstest-sRGB'; \ b='tests/pngstest-sRGB'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) tests/pngstest-sRGB-alpha.log: tests/pngstest-sRGB-alpha @p='tests/pngstest-sRGB-alpha'; \ b='tests/pngstest-sRGB-alpha'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) tests/pngunknown-IDAT.log: tests/pngunknown-IDAT @p='tests/pngunknown-IDAT'; \ b='tests/pngunknown-IDAT'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) tests/pngunknown-discard.log: tests/pngunknown-discard @p='tests/pngunknown-discard'; \ b='tests/pngunknown-discard'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) tests/pngunknown-if-safe.log: tests/pngunknown-if-safe @p='tests/pngunknown-if-safe'; \ b='tests/pngunknown-if-safe'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) tests/pngunknown-sAPI.log: tests/pngunknown-sAPI @p='tests/pngunknown-sAPI'; \ b='tests/pngunknown-sAPI'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) tests/pngunknown-sTER.log: tests/pngunknown-sTER @p='tests/pngunknown-sTER'; \ b='tests/pngunknown-sTER'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) tests/pngunknown-save.log: tests/pngunknown-save @p='tests/pngunknown-save'; \ b='tests/pngunknown-save'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) tests/pngunknown-vpAg.log: tests/pngunknown-vpAg @p='tests/pngunknown-vpAg'; \ b='tests/pngunknown-vpAg'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) tests/pngimage-quick.log: tests/pngimage-quick @p='tests/pngimage-quick'; \ b='tests/pngimage-quick'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) tests/pngimage-full.log: tests/pngimage-full @p='tests/pngimage-full'; \ b='tests/pngimage-full'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.test$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am distdir-am: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) dist-zstd: distdir tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst $(am__post_remove_distdir) dist-tarZ: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__post_remove_distdir) dist dist-all: $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ *.tar.zst*) \ zstd -dc $(distdir).tar.zst | $(am__untar) ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build/sub \ && ../../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ --srcdir=../.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-am all-am: Makefile $(PROGRAMS) $(LTLIBRARIES) $(SCRIPTS) $(MANS) $(DATA) \ $(HEADERS) config.h install-binPROGRAMS: install-libLTLIBRARIES install-checkPROGRAMS: install-libLTLIBRARIES installdirs: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(pkgincludedir)" "$(DESTDIR)$(pkgincludedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-am install-exec: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) -rm -f arm/$(DEPDIR)/$(am__dirstamp) -rm -f arm/$(am__dirstamp) -rm -f contrib/libtests/$(DEPDIR)/$(am__dirstamp) -rm -f contrib/libtests/$(am__dirstamp) -rm -f contrib/tools/$(DEPDIR)/$(am__dirstamp) -rm -f contrib/tools/$(am__dirstamp) -rm -f intel/$(DEPDIR)/$(am__dirstamp) -rm -f intel/$(am__dirstamp) -rm -f loongarch/$(DEPDIR)/$(am__dirstamp) -rm -f loongarch/$(am__dirstamp) -rm -f mips/$(DEPDIR)/$(am__dirstamp) -rm -f mips/$(am__dirstamp) -rm -f powerpc/$(DEPDIR)/$(am__dirstamp) -rm -f powerpc/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) @DO_INSTALL_LIBPNG_CONFIG_FALSE@@DO_INSTALL_LINKS_FALSE@install-exec-hook: @DO_INSTALL_LIBPNG_PC_FALSE@@DO_INSTALL_LINKS_FALSE@install-data-hook: @DO_INSTALL_LIBPNG_CONFIG_FALSE@@DO_INSTALL_LIBPNG_PC_FALSE@@DO_INSTALL_LINKS_FALSE@uninstall-hook: clean: clean-am clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \ clean-libLTLIBRARIES clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f ./$(DEPDIR)/png.Plo -rm -f ./$(DEPDIR)/pngerror.Plo -rm -f ./$(DEPDIR)/pngget.Plo -rm -f ./$(DEPDIR)/pngmem.Plo -rm -f ./$(DEPDIR)/pngpread.Plo -rm -f ./$(DEPDIR)/pngread.Plo -rm -f ./$(DEPDIR)/pngrio.Plo -rm -f ./$(DEPDIR)/pngrtran.Plo -rm -f ./$(DEPDIR)/pngrutil.Plo -rm -f ./$(DEPDIR)/pngset.Plo -rm -f ./$(DEPDIR)/pngtest.Po -rm -f ./$(DEPDIR)/pngtrans.Plo -rm -f ./$(DEPDIR)/pngwio.Plo -rm -f ./$(DEPDIR)/pngwrite.Plo -rm -f ./$(DEPDIR)/pngwtran.Plo -rm -f ./$(DEPDIR)/pngwutil.Plo -rm -f arm/$(DEPDIR)/arm_init.Plo -rm -f arm/$(DEPDIR)/filter_neon.Plo -rm -f arm/$(DEPDIR)/filter_neon_intrinsics.Plo -rm -f arm/$(DEPDIR)/palette_neon_intrinsics.Plo -rm -f contrib/libtests/$(DEPDIR)/pngimage.Po -rm -f contrib/libtests/$(DEPDIR)/pngstest.Po -rm -f contrib/libtests/$(DEPDIR)/pngunknown.Po -rm -f contrib/libtests/$(DEPDIR)/pngvalid.Po -rm -f contrib/libtests/$(DEPDIR)/timepng.Po -rm -f contrib/tools/$(DEPDIR)/png-fix-itxt.Po -rm -f contrib/tools/$(DEPDIR)/pngcp.Po -rm -f contrib/tools/$(DEPDIR)/pngfix.Po -rm -f intel/$(DEPDIR)/filter_sse2_intrinsics.Plo -rm -f intel/$(DEPDIR)/intel_init.Plo -rm -f loongarch/$(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la-filter_lsx_intrinsics.Plo -rm -f loongarch/$(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la-loongarch_lsx_init.Plo -rm -f mips/$(DEPDIR)/filter_mmi_inline_assembly.Plo -rm -f mips/$(DEPDIR)/filter_msa_intrinsics.Plo -rm -f mips/$(DEPDIR)/mips_init.Plo -rm -f powerpc/$(DEPDIR)/filter_vsx_intrinsics.Plo -rm -f powerpc/$(DEPDIR)/powerpc_init.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-hdr distclean-libtool distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-nodist_pkgincludeHEADERS \ install-pkgconfigDATA install-pkgincludeHEADERS @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-data-hook install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-binSCRIPTS \ install-libLTLIBRARIES @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-exec-hook install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man3 install-man5 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f ./$(DEPDIR)/png.Plo -rm -f ./$(DEPDIR)/pngerror.Plo -rm -f ./$(DEPDIR)/pngget.Plo -rm -f ./$(DEPDIR)/pngmem.Plo -rm -f ./$(DEPDIR)/pngpread.Plo -rm -f ./$(DEPDIR)/pngread.Plo -rm -f ./$(DEPDIR)/pngrio.Plo -rm -f ./$(DEPDIR)/pngrtran.Plo -rm -f ./$(DEPDIR)/pngrutil.Plo -rm -f ./$(DEPDIR)/pngset.Plo -rm -f ./$(DEPDIR)/pngtest.Po -rm -f ./$(DEPDIR)/pngtrans.Plo -rm -f ./$(DEPDIR)/pngwio.Plo -rm -f ./$(DEPDIR)/pngwrite.Plo -rm -f ./$(DEPDIR)/pngwtran.Plo -rm -f ./$(DEPDIR)/pngwutil.Plo -rm -f arm/$(DEPDIR)/arm_init.Plo -rm -f arm/$(DEPDIR)/filter_neon.Plo -rm -f arm/$(DEPDIR)/filter_neon_intrinsics.Plo -rm -f arm/$(DEPDIR)/palette_neon_intrinsics.Plo -rm -f contrib/libtests/$(DEPDIR)/pngimage.Po -rm -f contrib/libtests/$(DEPDIR)/pngstest.Po -rm -f contrib/libtests/$(DEPDIR)/pngunknown.Po -rm -f contrib/libtests/$(DEPDIR)/pngvalid.Po -rm -f contrib/libtests/$(DEPDIR)/timepng.Po -rm -f contrib/tools/$(DEPDIR)/png-fix-itxt.Po -rm -f contrib/tools/$(DEPDIR)/pngcp.Po -rm -f contrib/tools/$(DEPDIR)/pngfix.Po -rm -f intel/$(DEPDIR)/filter_sse2_intrinsics.Plo -rm -f intel/$(DEPDIR)/intel_init.Plo -rm -f loongarch/$(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la-filter_lsx_intrinsics.Plo -rm -f loongarch/$(DEPDIR)/libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@lsx_la-loongarch_lsx_init.Plo -rm -f mips/$(DEPDIR)/filter_mmi_inline_assembly.Plo -rm -f mips/$(DEPDIR)/filter_msa_intrinsics.Plo -rm -f mips/$(DEPDIR)/mips_init.Plo -rm -f powerpc/$(DEPDIR)/filter_vsx_intrinsics.Plo -rm -f powerpc/$(DEPDIR)/powerpc_init.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \ uninstall-libLTLIBRARIES uninstall-man \ uninstall-nodist_pkgincludeHEADERS uninstall-pkgconfigDATA \ uninstall-pkgincludeHEADERS @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) uninstall-hook uninstall-man: uninstall-man3 uninstall-man5 .MAKE: all check check-am install install-am install-data-am \ install-exec install-exec-am install-strip uninstall-am .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles am--refresh check \ check-TESTS check-am clean clean-binPROGRAMS \ clean-checkPROGRAMS clean-cscope clean-generic \ clean-libLTLIBRARIES clean-libtool clean-noinstLTLIBRARIES \ cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \ dist-gzip dist-hook dist-lzip dist-shar dist-tarZ dist-xz \ dist-zip dist-zstd distcheck distclean distclean-compile \ distclean-generic distclean-hdr distclean-libtool \ distclean-tags distcleancheck distdir distuninstallcheck dvi \ dvi-am html html-am info info-am install install-am \ install-binPROGRAMS install-binSCRIPTS install-data \ install-data-am install-data-hook install-dvi install-dvi-am \ install-exec install-exec-am install-exec-hook install-html \ install-html-am install-info install-info-am \ install-libLTLIBRARIES install-man install-man3 install-man5 \ install-nodist_pkgincludeHEADERS install-pdf install-pdf-am \ install-pkgconfigDATA install-pkgincludeHEADERS install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am recheck tags tags-am \ uninstall uninstall-am uninstall-binPROGRAMS \ uninstall-binSCRIPTS uninstall-hook uninstall-libLTLIBRARIES \ uninstall-man uninstall-man3 uninstall-man5 \ uninstall-nodist_pkgincludeHEADERS uninstall-pkgconfigDATA \ uninstall-pkgincludeHEADERS .PRECIOUS: Makefile $(PNGLIB_BASENAME).pc: libpng.pc cp libpng.pc $@ $(PNGLIB_BASENAME)-config: libpng-config cp libpng-config $@ scripts/sym.out scripts/vers.out: png.h pngconf.h pnglibconf.h scripts/prefix.out: png.h pngconf.h pnglibconf.out scripts/symbols.out: png.h pngconf.h $(srcdir)/scripts/pnglibconf.h.prebuilt scripts/intprefix.out: pnglibconf.h libpng.sym: scripts/sym.out rm -f $@ cp $? $@ libpng.vers: scripts/vers.out rm -f $@ cp $? $@ # Rename functions in scripts/prefix.out with a PNG_PREFIX prefix. # Rename macros in scripts/macro.lst from PNG_PREFIXpng_ to PNG_ (the actual # implementation of the macro). @DO_PNG_PREFIX_TRUE@pnglibconf.h: pnglibconf.out scripts/prefix.out scripts/macro.lst @DO_PNG_PREFIX_TRUE@ rm -f $@ @DO_PNG_PREFIX_TRUE@ $(AWK) 's==0 && NR>1{print prev}\ @DO_PNG_PREFIX_TRUE@ s==0{prev=$$0}\ @DO_PNG_PREFIX_TRUE@ s==1{print "#define", $$1, "@PNG_PREFIX@" $$1}\ @DO_PNG_PREFIX_TRUE@ s==2{print "#define @PNG_PREFIX@png_" $$1, "PNG_" $$1}\ @DO_PNG_PREFIX_TRUE@ END{print prev}' s=0 pnglibconf.out s=1 scripts/prefix.out\ @DO_PNG_PREFIX_TRUE@ s=2 ${srcdir}/scripts/macro.lst >pnglibconf.tf8 @DO_PNG_PREFIX_TRUE@ mv pnglibconf.tf8 $@ @DO_PNG_PREFIX_TRUE@pngprefix.h: scripts/intprefix.out @DO_PNG_PREFIX_TRUE@ rm -f pngprefix.tf1 @DO_PNG_PREFIX_TRUE@ $(AWK) '{print "#define", $$1, "@PNG_PREFIX@" $$1}' $? >pngprefix.tf1 @DO_PNG_PREFIX_TRUE@ mv pngprefix.tf1 $@ @DO_PNG_PREFIX_FALSE@pnglibconf.h: pnglibconf.out @DO_PNG_PREFIX_FALSE@ rm -f $@ @DO_PNG_PREFIX_FALSE@ cp $? $@ @DO_PNG_PREFIX_FALSE@pngprefix.h: # is empty @DO_PNG_PREFIX_FALSE@ :>$@ $(srcdir)/scripts/pnglibconf.h.prebuilt: @echo "Attempting to build $@" >&2 @echo "This is a machine generated file, but if you want to make" >&2 @echo "a new one simply make 'scripts/pnglibconf.out', copy that" >&2 @echo "AND set PNG_ZLIB_VERNUM to 0 (you MUST do this)" >&2 @exit 1 # The following is necessary to ensure that the local pnglibconf.h is used, not # an installed one (this can happen immediately after on a clean system if # 'make test' is the first thing the user does.) Only files which include # one of the png source files (typically png.h or pngpriv.h) need to be listed # here: pngtest.o: pnglibconf.h contrib/libtests/makepng.o: pnglibconf.h contrib/libtests/pngstest.o: pnglibconf.h contrib/libtests/pngunknown.o: pnglibconf.h contrib/libtests/pngimage.o: pnglibconf.h contrib/libtests/pngvalid.o: pnglibconf.h contrib/libtests/readpng.o: pnglibconf.h contrib/libtests/tarith.o: pnglibconf.h contrib/libtests/timepng.o: pnglibconf.h contrib/tools/makesRGB.o: pnglibconf.h contrib/tools/pngfix.o: pnglibconf.h contrib/tools/pngcp.o: pnglibconf.h .c.out: rm -f $@ $*.tf[12] test -d scripts || mkdir scripts || test -d scripts $(DFNCPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES)\ $(CPPFLAGS) $(SYMBOL_CFLAGS) $< > $*.tf1 $(AWK) -f "${srcdir}/scripts/dfn.awk" out="$*.tf2" $*.tf1 1>&2 rm -f $*.tf1 mv $*.tf2 $@ # The .c file for pnglibconf.h is machine generated pnglibconf.c: scripts/pnglibconf.dfa scripts/options.awk pngconf.h pngusr.dfa $(DFA_XTRA) rm -f $@ $*.tf[45] $(AWK) -f ${srcdir}/scripts/options.awk out=$*.tf4 version=search\ ${srcdir}/pngconf.h ${srcdir}/scripts/pnglibconf.dfa\ ${srcdir}/pngusr.dfa $(DFA_XTRA) 1>&2 $(AWK) -f ${srcdir}/scripts/options.awk out=$*.tf5 $*.tf4 1>&2 rm $*.tf4 mv $*.tf5 $@ # Symbol checks (.def and .out files should match) scripts/symbols.chk: scripts/checksym.awk scripts/symbols.def scripts/symbols.out .out.chk: rm -f $@ $*.new $(AWK) -f ${srcdir}/scripts/checksym.awk ${srcdir}/scripts/${*F}.def\ of="$*.new" $< >&2 mv $*.new $@ # used on demand to regenerate the standard header, CPPFLAGS should # be empty - no non-standard defines scripts/pnglibconf.c: scripts/pnglibconf.dfa scripts/options.awk pngconf.h rm -f $@ pnglibconf.tf[67] test -z "$(CPPFLAGS)" echo "com @PNGLIB_VERSION@ STANDARD API DEFINITION" |\ $(AWK) -f ${srcdir}/scripts/options.awk out=pnglibconf.tf6\ logunsupported=1 version=search ${srcdir}/pngconf.h -\ ${srcdir}/scripts/pnglibconf.dfa 1>&2 $(AWK) -f ${srcdir}/scripts/options.awk out=pnglibconf.tf7\ pnglibconf.tf6 1>&2 rm pnglibconf.tf6 mv pnglibconf.tf7 $@ $(libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_OBJECTS): png.h pngconf.h \ pnglibconf.h pngpriv.h pngdebug.h pnginfo.h pngstruct.h pngprefix.h test: check-am # Extra checks check: scripts/symbols.chk # Don't distribute the generated script files dist-hook: cd '$(top_distdir)'; rm -f $(SCRIPT_CLEANFILES) # Make links between installed files with release-specific names and the generic # file names. If this install rule is run the generic names will be deleted and # recreated - this has obvious issues for systems with multiple installations. install-header-links: @set -ex; cd '$(DESTDIR)$(includedir)'; for f in $(HEADERS); do \ rm -f "$$f"; $(LN_S) "$(PNGLIB_BASENAME)/$$f" "$$f"; done uninstall-header-links: cd '$(DESTDIR)$(includedir)'; rm -f $(HEADERS) install-libpng-pc: @set -ex; cd '$(DESTDIR)$(pkgconfigdir)'; rm -f libpng.pc; \ $(LN_S) '$(PNGLIB_BASENAME).pc' libpng.pc uninstall-libpng-pc: rm -f '$(DESTDIR)$(pkgconfigdir)/libpng.pc' install-library-links: @set -x; cd '$(DESTDIR)$(libdir)';\ for ext in $(EXT_LIST); do\ rm -f "libpng.$$ext";\ if test -f "$(PNGLIB_BASENAME).$$ext"; then\ $(LN_S) "$(PNGLIB_BASENAME).$$ext" "libpng.$$ext" || exit 1;\ fi;\ done uninstall-library-links: @set -x; cd '$(DESTDIR)$(libdir)'; for ext in $(EXT_LIST); do\ rm -f "libpng.$$ext"; done install-libpng-config: @set -ex; cd '$(DESTDIR)$(bindir)'; rm -f libpng-config; \ $(LN_S) '$(PNGLIB_BASENAME)-config' libpng-config uninstall-libpng-config: rm -f '$(DESTDIR)$(bindir)/libpng-config' # If --enable-unversioned-links is specified the header and lib file links # will be automatically made on a 'make install': @DO_INSTALL_LINKS_TRUE@install-data-hook: install-header-links @DO_INSTALL_LINKS_TRUE@uninstall-hook: uninstall-header-links @DO_INSTALL_LINKS_TRUE@install-exec-hook: install-library-links @DO_INSTALL_LINKS_TRUE@uninstall-hook: uninstall-library-links # Likewise, --install-pc causes libpng.pc to be constructed: @DO_INSTALL_LIBPNG_PC_TRUE@install-data-hook: install-libpng-pc @DO_INSTALL_LIBPNG_PC_TRUE@uninstall-hook: uninstall-libpng-pc # And --install-config: @DO_INSTALL_LIBPNG_CONFIG_TRUE@install-exec-hook: install-libpng-config @DO_INSTALL_LIBPNG_CONFIG_TRUE@uninstall-hook: uninstall-libpng-config # The following addition ensures that 'make all' always builds the test programs # too. It used to, but some change either in libpng or configure stopped this # working. all-am: $(check_PROGRAMS) # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: libpng-1.6.43/README000066400000000000000000000223561456606525400137650ustar00rootroot00000000000000README for libpng version 1.6.43 ================================ See the note about version numbers near the top of `png.h`. See `INSTALL` for instructions on how to install libpng. Libpng comes in several distribution formats. Get `libpng-*.tar.gz` or `libpng-*.tar.xz` if you want UNIX-style line endings in the text files, or `lpng*.7z` or `lpng*.zip` if you want DOS-style line endings. For a detailed description on using libpng, read `libpng-manual.txt`. For examples of libpng in a program, see `example.c` and `pngtest.c`. For usage information and restrictions (what little they are) on libpng, see `png.h`. For a description on using zlib (the compression library used by libpng) and zlib's restrictions, see `zlib.h`. You should use zlib 1.0.4 or later to run this, but it _may_ work with versions as old as zlib 0.95. Even so, there are bugs in older zlib versions which can cause the output of invalid compression streams for some images. You should also note that zlib is a compression library that is useful for more things than just PNG files. You can use zlib as a drop-in replacement for `fread()` and `fwrite()`, if you are so inclined. zlib should be available at the same place that libpng is, or at https://zlib.net . You may also want a copy of the PNG specification. It is available as an RFC, a W3C Recommendation, and an ISO/IEC Standard. You can find these at http://www.libpng.org/pub/png/pngdocs.html . This code is currently being archived at https://libpng.sourceforge.io in the download area, and at http://libpng.download/src . This release, based in a large way on Glenn's, Guy's and Andreas' earlier work, was created and will be supported by myself and the PNG development group. Send comments, corrections and commendations to `png-mng-implement` at `lists.sourceforge.net`. (Subscription is required; visit https://lists.sourceforge.net/lists/listinfo/png-mng-implement to subscribe.) Send general questions about the PNG specification to `png-mng-misc` at `lists.sourceforge.net`. (Subscription is required; visit https://lists.sourceforge.net/lists/listinfo/png-mng-misc to subscribe.) Historical notes ---------------- The libpng library has been in extensive use and testing since mid-1995. Version 0.89, published a year later, was the first official release. By late 1997, it had finally gotten to the stage where there hadn't been significant changes to the API in some time, and people have a bad feeling about libraries with versions below 1.0. Version 1.0.0 was released in March 1998. Note that some of the changes to the `png_info` structure render this version of the library binary incompatible with libpng-0.89 or earlier versions if you are using a shared library. The type of the `filler` parameter for `png_set_filler()` has changed from `png_byte` to `png_uint_32`, which will affect shared-library applications that use this function. To avoid problems with changes to the internals of the `info_struct`, new APIs have been made available in 0.95 to avoid direct application access to `info_ptr`. These functions are the `png_set_` and `png_get_` functions. These functions should be used when accessing/storing the `info_struct` data, rather than manipulating it directly, to avoid such problems in the future. It is important to note that the APIs did not make current programs that access the info struct directly incompatible with the new library, through libpng-1.2.x. In libpng-1.4.x, which was meant to be a transitional release, members of the `png_struct` and the `info_struct` can still be accessed, but the compiler will issue a warning about deprecated usage. Since libpng-1.5.0, direct access to these structs is not allowed, and the definitions of the structs reside in private `pngstruct.h` and `pnginfo.h` header files that are not accessible to applications. It is strongly suggested that new programs use the new APIs (as shown in `example.c` and `pngtest.c`), and older programs be converted to the new format, to facilitate upgrades in the future. The additions since 0.89 include the ability to read from a PNG stream which has had some (or all) of the signature bytes read by the calling application. This also allows the reading of embedded PNG streams that do not have the PNG file signature. As well, it is now possible to set the library action on the detection of chunk CRC errors. It is possible to set different actions based on whether the CRC error occurred in a critical or an ancillary chunk. The additions since 0.90 include the ability to compile libpng as a Windows DLL, and new APIs for accessing data in the `info_struct`. Experimental functions included the ability to set weighting and cost factors for row filter selection, direct reads of integers from buffers on big-endian processors that support misaligned data access, faster methods of doing alpha composition, and more accurate 16-to-8 bit color conversion. Some of these experimental functions, such as the weighted filter heuristics, have since been removed. Files included in this distribution ----------------------------------- ANNOUNCE => Announcement of this version, with recent changes AUTHORS => List of contributing authors CHANGES => Description of changes between libpng versions INSTALL => Instructions to install libpng LICENSE => License to use and redistribute libpng README => This file TODO => Things not implemented in the current library TRADEMARK => Trademark information example.c => Example code for using libpng functions libpng.3 => Manual page for libpng (includes libpng-manual.txt) libpng-manual.txt => Description of libpng and its functions libpngpf.3 => Manual page for libpng's private functions (deprecated) png.5 => Manual page for the PNG format png.c => Basic interface functions common to library png.h => Library function and interface declarations (public) pngpriv.h => Library function and interface declarations (private) pngconf.h => System specific library configuration (public) pngstruct.h => png_struct declaration (private) pnginfo.h => png_info struct declaration (private) pngdebug.h => debugging macros (private) pngerror.c => Error/warning message I/O functions pngget.c => Functions for retrieving info from struct pngmem.c => Memory handling functions pngbar.png => PNG logo, 88x31 pngnow.png => PNG logo, 98x31 pngpread.c => Progressive reading functions pngread.c => Read data/helper high-level functions pngrio.c => Lowest-level data read I/O functions pngrtran.c => Read data transformation functions pngrutil.c => Read data utility functions pngset.c => Functions for storing data into the info_struct pngtest.c => Library test program pngtest.png => Library test sample image pngtrans.c => Common data transformation functions pngwio.c => Lowest-level write I/O functions pngwrite.c => High-level write functions pngwtran.c => Write data transformations pngwutil.c => Write utility functions arm/ => Optimized code for ARM Neon intel/ => Optimized code for INTEL SSE2 loongarch/ => Optimized code for LoongArch LSX mips/ => Optimized code for MIPS MSA and MIPS MMI powerpc/ => Optimized code for PowerPC VSX ci/ => Scripts for continuous integration contrib/ => External contributions arm-neon/ => Optimized code for the ARM-NEON platform mips-msa/ => Optimized code for the MIPS-MSA platform powerpc-vsx/ => Optimized code for the POWERPC-VSX platform examples/ => Examples of libpng usage gregbook/ => Source code for PNG reading and writing, from "PNG: The Definitive Guide" by Greg Roelofs, O'Reilly, 1999 libtests/ => Test programs oss-fuzz/ => Files used by the OSS-Fuzz project for fuzz-testing libpng pngexif/ => Program to inspect the EXIF information in PNG files pngminim/ => Minimal decoder, encoder, and progressive decoder programs demonstrating the use of pngusr.dfa pngminus/ => Simple pnm2png and png2pnm programs pngsuite/ => Test images testpngs/ => Test images tools/ => Various tools visupng/ => VisualPng, a Windows viewer for PNG images projects/ => Project files and workspaces for various IDEs owatcom/ => OpenWatcom project visualc71/ => Microsoft Visual C++ 7.1 workspace vstudio/ => Microsoft Visual Studio workspace scripts/ => Scripts and makefiles for building libpng (see scripts/README.txt for the complete list) tests/ => Test scripts Good luck, and happy coding! * Cosmin Truta (current maintainer, since 2018) * Glenn Randers-Pehrson (former maintainer, 1998-2018) * Andreas Eric Dilger (former maintainer, 1996-1997) * Guy Eric Schalnat (original author and former maintainer, 1995-1996) (formerly of Group 42, Inc.) libpng-1.6.43/TODO000066400000000000000000000020021456606525400135570ustar00rootroot00000000000000TODO - list of things to do for libpng: * Fix all defects (duh!) * Better C++ wrapper / full C++ implementation (?) * Fix the problems with C++ and 'extern "C"'. * cHRM transformation. * Palette creation. * "grayscale->palette" transformation and "palette->grayscale" detection. * Improved dithering. * Multi-lingual error and warning message support. * Complete sRGB transformation. (Currently it simply uses gamma=0.45455.) * Man pages for function calls. * Better documentation. * Better filter selection (e.g., counting huffman bits/precompression; filter inertia; filter costs). * Histogram creation. * Text conversion between different code pages (e.g., Latin-1 -> Mac). * Avoid building gamma tables whenever possible. * Greater precision in changing to linear gamma for compositing against background, and in doing rgb-to-gray transformations. * Investigate pre-incremented loop counters and other loop constructions. * Interpolated method of handling interlacing. * More validations for libpng transformations. libpng-1.6.43/TRADEMARK000066400000000000000000000005271456606525400143360ustar00rootroot00000000000000TRADEMARK ========= The name "libpng" has not been registered by the Copyright owners as a trademark in any jurisdiction. However, because libpng has been distributed and maintained world-wide, continually since 1995, the Copyright owners claim "common-law trademark protection" in any jurisdiction where common-law trademark is recognized. libpng-1.6.43/aclocal.m4000066400000000000000000001276351456606525400147530ustar00rootroot00000000000000# generated automatically by aclocal 1.16.5 -*- Autoconf -*- # Copyright (C) 1996-2021 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.72],, [m4_warning([this file was generated for autoconf 2.72. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) # Copyright (C) 2002-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.16' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.16.5], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.16.5])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # Figure out how to run the assembler. -*- Autoconf -*- # Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_AS # ---------- AC_DEFUN([AM_PROG_AS], [# By default we simply use the C compiler to build assembly code. AC_REQUIRE([AC_PROG_CC]) test "${CCAS+set}" = set || CCAS=$CC test "${CCASFLAGS+set}" = set || CCASFLAGS=$CFLAGS AC_ARG_VAR([CCAS], [assembler compiler command (defaults to CC)]) AC_ARG_VAR([CCASFLAGS], [assembler compiler flags (defaults to CFLAGS)]) _AM_IF_OPTION([no-dependencies],, [_AM_DEPENDENCIES([CCAS])])dnl ]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to # '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ([2.52])dnl m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], [$1], [CXX], [depcc="$CXX" am_compiler_list=], [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], [$1], [UPC], [depcc="$UPC" am_compiler_list=], [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE([dependency-tracking], [dnl AS_HELP_STRING( [--enable-dependency-tracking], [do not reject slow dependency extractors]) AS_HELP_STRING( [--disable-dependency-tracking], [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. # TODO: see whether this extra hack can be removed once we start # requiring Autoconf 2.70 or later. AS_CASE([$CONFIG_FILES], [*\'*], [eval set x "$CONFIG_FILES"], [*], [set x $CONFIG_FILES]) shift # Used to flag and report bootstrapping failures. am_rc=0 for am_mf do # Strip MF so we end up with the name of the file. am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile which includes # dependency-tracking related rules and includes. # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ || continue am_dirpart=`AS_DIRNAME(["$am_mf"])` am_filepart=`AS_BASENAME(["$am_mf"])` AM_RUN_LOG([cd "$am_dirpart" \ && sed -e '/# am--include-marker/d' "$am_filepart" \ | $MAKE -f - am--depfiles]) || am_rc=$? done if test $am_rc -ne 0; then AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments for automatic dependency tracking. If GNU make was not used, consider re-running the configure script with MAKE="gmake" (or whatever is necessary). You can also try re-running configure with the '--disable-dependency-tracking' option to at least be able to build the package (albeit without support for automatic dependency tracking).]) fi AS_UNSET([am_dirpart]) AS_UNSET([am_filepart]) AS_UNSET([am_mf]) AS_UNSET([am_rc]) rm -f conftest-deps.mk } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking is enabled. # This creates each '.Po' and '.Plo' makefile fragment that we'll need in # order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC]) [_AM_PROG_CC_C_O ]) # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.65])dnl m4_ifdef([_$0_ALREADY_INIT], [m4_fatal([$0 expanded multiple times ]m4_defn([_$0_ALREADY_INIT]))], [m4_define([_$0_ALREADY_INIT], m4_expansion_stack)])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], [$0: two- and three-arguments forms are deprecated.]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( m4_ifset([AC_PACKAGE_NAME], [ok]):m4_ifset([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) AM_MISSING_PROG([AUTOCONF], [autoconf]) AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) AM_MISSING_PROG([AUTOHEADER], [autoheader]) AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) # Variables for tags utilities; see am/tags.am if test -z "$CTAGS"; then CTAGS=ctags fi AC_SUBST([CTAGS]) if test -z "$ETAGS"; then ETAGS=etags fi AC_SUBST([ETAGS]) if test -z "$CSCOPE"; then CSCOPE=cscope fi AC_SUBST([CSCOPE]) AC_REQUIRE([AM_SILENT_RULES])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) fi fi dnl The trailing newline in this macro's definition is deliberate, for dnl backward compatibility and to allow trailing 'dnl'-style comments dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. ]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST([install_sh])]) # Copyright (C) 2003-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Add --enable-maintainer-mode option to configure. -*- Autoconf -*- # From Jim Meyering # Copyright (C) 1996-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAINTAINER_MODE([DEFAULT-MODE]) # ---------------------------------- # Control maintainer-specific portions of Makefiles. # Default is to disable them, unless 'enable' is passed literally. # For symmetry, 'disable' may be passed as well. Anyway, the user # can override the default with the --enable/--disable switch. AC_DEFUN([AM_MAINTAINER_MODE], [m4_case(m4_default([$1], [disable]), [enable], [m4_define([am_maintainer_other], [disable])], [disable], [m4_define([am_maintainer_other], [enable])], [m4_define([am_maintainer_other], [enable]) m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) dnl maintainer-mode's default is 'disable' unless 'enable' is passed AC_ARG_ENABLE([maintainer-mode], [AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode], am_maintainer_other[ make rules and dependencies not useful (and sometimes confusing) to the casual installer])], [USE_MAINTAINER_MODE=$enableval], [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) AC_MSG_RESULT([$USE_MAINTAINER_MODE]) AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) MAINT=$MAINTAINER_MODE_TRUE AC_SUBST([MAINT])dnl ] ) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAKE_INCLUDE() # ----------------- # Check whether make has an 'include' directive that can support all # the idioms we need for our automatic dependency tracking code. AC_DEFUN([AM_MAKE_INCLUDE], [AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive]) cat > confinc.mk << 'END' am__doit: @echo this is the am__doit target >confinc.out .PHONY: am__doit END am__include="#" am__quote= # BSD make does it like this. echo '.include "confinc.mk" # ignored' > confmf.BSD # Other make implementations (GNU, Solaris 10, AIX) do it like this. echo 'include confinc.mk # ignored' > confmf.GNU _am_result=no for s in GNU BSD; do AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out]) AS_CASE([$?:`cat confinc.out 2>/dev/null`], ['0:this is the am__doit target'], [AS_CASE([$s], [BSD], [am__include='.include' am__quote='"'], [am__include='include' am__quote=''])]) if test "$am__include" != "#"; then _am_result="yes ($s style)" break fi done rm -f confinc.* confmf.* AC_MSG_RESULT([${_am_result}]) AC_SUBST([am__include])]) AC_SUBST([am__quote])]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it is modern enough. # If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then MISSING="\${SHELL} '$am_aux_dir/missing'" fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) fi ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Copyright (C) 1999-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_CC_C_O # --------------- # Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC # to automatically call this. AC_DEFUN([_AM_PROG_CC_C_O], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl AC_LANG_PUSH([C])dnl AC_CACHE_CHECK( [whether $CC understands -c and -o together], [am_cv_prog_cc_c_o], [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i]) if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) # Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_RUN_LOG(COMMAND) # ------------------- # Run COMMAND, save the exit status in ac_status, and log it. # (This has been adapted from Autoconf's _AC_RUN_LOG macro.) AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD (exit $ac_status); }]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi if test "$[2]" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT([yes]) # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi AC_MSG_RESULT([done])]) rm -f conftest.file ]) # Copyright (C) 2009-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT # ("yes" being less verbose, "no" or empty being verbose). AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], [dnl AS_HELP_STRING( [--enable-silent-rules], [less verbose build output (undo: "make V=1")]) AS_HELP_STRING( [--disable-silent-rules], [verbose build output (undo: "make V=0")])dnl ]) case $enable_silent_rules in @%:@ ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} AC_CACHE_CHECK([whether $am_make supports nested variables], [am_cv_make_support_nested_variables], [if AS_ECHO([['TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) # Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar # AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar], [# The POSIX 1988 'ustar' format is defined with fixed-size fields. # There is notably a 21 bits limit for the UID and the GID. In fact, # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 # and bug#13588). am_max_uid=2097151 # 2^21 - 1 am_max_gid=$am_max_uid # The $UID and $GID variables are not portable, so we need to resort # to the POSIX-mandated id(1) utility. Errors in the 'id' calls # below are definitely unexpected, so allow the users to see them # (that is, avoid stderr redirection). am_uid=`id -u || echo unknown` am_gid=`id -g || echo unknown` AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) if test $am_uid -le $am_max_uid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) if test $am_gid -le $am_max_gid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi], [pax], [], [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Go ahead even if we have the value already cached. We do so because we # need to set the values for the 'am__tar' and 'am__untar' variables. _am_tools=${am_cv_prog_tar_$1-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([scripts/autoconf/libtool.m4]) m4_include([scripts/autoconf/ltoptions.m4]) m4_include([scripts/autoconf/ltsugar.m4]) m4_include([scripts/autoconf/ltversion.m4]) m4_include([scripts/autoconf/lt~obsolete.m4]) libpng-1.6.43/arm/000077500000000000000000000000001456606525400136545ustar00rootroot00000000000000libpng-1.6.43/arm/arm_init.c000066400000000000000000000116231456606525400156250ustar00rootroot00000000000000 /* arm_init.c - NEON optimised filter functions * * Copyright (c) 2018-2022 Cosmin Truta * Copyright (c) 2014,2016 Glenn Randers-Pehrson * Written by Mans Rullgard, 2011. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer * and license in png.h */ /* This module requires POSIX 1003.1 functions. */ #define _POSIX_SOURCE 1 #include "../pngpriv.h" #ifdef PNG_READ_SUPPORTED #if PNG_ARM_NEON_OPT > 0 #ifdef PNG_ARM_NEON_CHECK_SUPPORTED /* Do run-time checks */ /* WARNING: it is strongly recommended that you do not build libpng with * run-time checks for CPU features if at all possible. In the case of the ARM * NEON instructions there is no processor-specific way of detecting the * presence of the required support, therefore run-time detection is extremely * OS specific. * * You may set the macro PNG_ARM_NEON_FILE to the file name of file containing * a fragment of C source code which defines the png_have_neon function. There * are a number of implementations in contrib/arm-neon, but the only one that * has partial support is contrib/arm-neon/linux.c - a generic Linux * implementation which reads /proc/cpufino. */ #include /* for sig_atomic_t */ #ifndef PNG_ARM_NEON_FILE # if defined(__aarch64__) || defined(_M_ARM64) /* ARM Neon is expected to be unconditionally available on ARM64. */ # error "PNG_ARM_NEON_CHECK_SUPPORTED must not be defined on ARM64" # elif defined(__ARM_NEON__) || defined(__ARM_NEON) /* ARM Neon is expected to be available on the target CPU architecture. */ # error "PNG_ARM_NEON_CHECK_SUPPORTED must not be defined on this CPU arch" # elif defined(__linux__) # define PNG_ARM_NEON_FILE "contrib/arm-neon/linux.c" # else # error "No support for run-time ARM Neon checking; use compile-time options" # endif #endif static int png_have_neon(png_structp png_ptr); #ifdef PNG_ARM_NEON_FILE # include PNG_ARM_NEON_FILE #endif #endif /* PNG_ARM_NEON_CHECK_SUPPORTED */ #ifndef PNG_ALIGNED_MEMORY_SUPPORTED # error "ALIGNED_MEMORY is required; set: -DPNG_ALIGNED_MEMORY_SUPPORTED" #endif void png_init_filter_functions_neon(png_structp pp, unsigned int bpp) { /* The switch statement is compiled in for ARM_NEON_API, the call to * png_have_neon is compiled in for ARM_NEON_CHECK. If both are defined * the check is only performed if the API has not set the NEON option on * or off explicitly. In this case the check controls what happens. * * If the CHECK is not compiled in and the option is UNSET the behavior prior * to 1.6.7 was to use the NEON code - this was a bug caused by having the * wrong order of the 'ON' and 'default' cases. UNSET now defaults to OFF, * as documented in png.h */ png_debug(1, "in png_init_filter_functions_neon"); #ifdef PNG_ARM_NEON_API_SUPPORTED switch ((pp->options >> PNG_ARM_NEON) & 3) { case PNG_OPTION_UNSET: /* Allow the run-time check to execute if it has been enabled - * thus both API and CHECK can be turned on. If it isn't supported * this case will fall through to the 'default' below, which just * returns. */ #endif /* PNG_ARM_NEON_API_SUPPORTED */ #ifdef PNG_ARM_NEON_CHECK_SUPPORTED { static volatile sig_atomic_t no_neon = -1; /* not checked */ if (no_neon < 0) no_neon = !png_have_neon(pp); if (no_neon) return; } #ifdef PNG_ARM_NEON_API_SUPPORTED break; #endif #endif /* PNG_ARM_NEON_CHECK_SUPPORTED */ #ifdef PNG_ARM_NEON_API_SUPPORTED default: /* OFF or INVALID */ return; case PNG_OPTION_ON: /* Option turned on */ break; } #endif /* IMPORTANT: any new external functions used here must be declared using * PNG_INTERNAL_FUNCTION in ../pngpriv.h. This is required so that the * 'prefix' option to configure works: * * ./configure --with-libpng-prefix=foobar_ * * Verify you have got this right by running the above command, doing a build * and examining pngprefix.h; it must contain a #define for every external * function you add. (Notice that this happens automatically for the * initialization function.) */ pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up_neon; if (bpp == 3) { pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_neon; pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_neon; pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = png_read_filter_row_paeth3_neon; } else if (bpp == 4) { pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_neon; pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_neon; pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = png_read_filter_row_paeth4_neon; } } #endif /* PNG_ARM_NEON_OPT > 0 */ #endif /* READ */ libpng-1.6.43/arm/filter_neon.S000066400000000000000000000202401456606525400163020ustar00rootroot00000000000000 /* filter_neon.S - NEON optimised filter functions * * Copyright (c) 2018 Cosmin Truta * Copyright (c) 2014,2017 Glenn Randers-Pehrson * Written by Mans Rullgard, 2011. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer * and license in png.h */ /* This is required to get the symbol renames, which are #defines, and the * definitions (or not) of PNG_ARM_NEON_OPT and PNG_ARM_NEON_IMPLEMENTATION. */ #define PNG_VERSION_INFO_ONLY #include "../pngpriv.h" #if (defined(__linux__) || defined(__FreeBSD__)) && defined(__ELF__) .section .note.GNU-stack,"",%progbits /* mark stack as non-executable */ #endif #ifdef PNG_READ_SUPPORTED /* Assembler NEON support - only works for 32-bit ARM (i.e. it does not work for * ARM64). The code in arm/filter_neon_intrinsics.c supports ARM64, however it * only works if -mfpu=neon is specified on the GCC command line. See pngpriv.h * for the logic which sets PNG_USE_ARM_NEON_ASM: */ #if PNG_ARM_NEON_IMPLEMENTATION == 2 /* hand-coded assembler */ #if PNG_ARM_NEON_OPT > 0 #ifdef __ELF__ # define ELF #else # define ELF @ #endif .arch armv7-a .fpu neon .macro func name, export=0 .macro endfunc ELF .size \name, . - \name .endfunc .purgem endfunc .endm .text /* Explicitly specifying alignment here because some versions of * GAS don't align code correctly. This is harmless in correctly * written versions of GAS. */ .align 2 .if \export .global \name .endif ELF .type \name, STT_FUNC .func \name \name: .endm func png_read_filter_row_sub4_neon, export=1 ldr r3, [r0, #4] @ rowbytes vmov.i8 d3, #0 1: vld4.32 {d4[],d5[],d6[],d7[]}, [r1,:128] vadd.u8 d0, d3, d4 vadd.u8 d1, d0, d5 vadd.u8 d2, d1, d6 vadd.u8 d3, d2, d7 vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1,:128]! subs r3, r3, #16 bgt 1b bx lr endfunc func png_read_filter_row_sub3_neon, export=1 ldr r3, [r0, #4] @ rowbytes vmov.i8 d3, #0 mov r0, r1 mov r2, #3 mov r12, #12 vld1.8 {q11}, [r0], r12 1: vext.8 d5, d22, d23, #3 vadd.u8 d0, d3, d22 vext.8 d6, d22, d23, #6 vadd.u8 d1, d0, d5 vext.8 d7, d23, d23, #1 vld1.8 {q11}, [r0], r12 vst1.32 {d0[0]}, [r1,:32], r2 vadd.u8 d2, d1, d6 vst1.32 {d1[0]}, [r1], r2 vadd.u8 d3, d2, d7 vst1.32 {d2[0]}, [r1], r2 vst1.32 {d3[0]}, [r1], r2 subs r3, r3, #12 bgt 1b bx lr endfunc func png_read_filter_row_up_neon, export=1 ldr r3, [r0, #4] @ rowbytes 1: vld1.8 {q0}, [r1,:128] vld1.8 {q1}, [r2,:128]! vadd.u8 q0, q0, q1 vst1.8 {q0}, [r1,:128]! subs r3, r3, #16 bgt 1b bx lr endfunc func png_read_filter_row_avg4_neon, export=1 ldr r12, [r0, #4] @ rowbytes vmov.i8 d3, #0 1: vld4.32 {d4[],d5[],d6[],d7[]}, [r1,:128] vld4.32 {d16[],d17[],d18[],d19[]},[r2,:128]! vhadd.u8 d0, d3, d16 vadd.u8 d0, d0, d4 vhadd.u8 d1, d0, d17 vadd.u8 d1, d1, d5 vhadd.u8 d2, d1, d18 vadd.u8 d2, d2, d6 vhadd.u8 d3, d2, d19 vadd.u8 d3, d3, d7 vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1,:128]! subs r12, r12, #16 bgt 1b bx lr endfunc func png_read_filter_row_avg3_neon, export=1 push {r4,lr} ldr r12, [r0, #4] @ rowbytes vmov.i8 d3, #0 mov r0, r1 mov r4, #3 mov lr, #12 vld1.8 {q11}, [r0], lr 1: vld1.8 {q10}, [r2], lr vext.8 d5, d22, d23, #3 vhadd.u8 d0, d3, d20 vext.8 d17, d20, d21, #3 vadd.u8 d0, d0, d22 vext.8 d6, d22, d23, #6 vhadd.u8 d1, d0, d17 vext.8 d18, d20, d21, #6 vadd.u8 d1, d1, d5 vext.8 d7, d23, d23, #1 vld1.8 {q11}, [r0], lr vst1.32 {d0[0]}, [r1,:32], r4 vhadd.u8 d2, d1, d18 vst1.32 {d1[0]}, [r1], r4 vext.8 d19, d21, d21, #1 vadd.u8 d2, d2, d6 vhadd.u8 d3, d2, d19 vst1.32 {d2[0]}, [r1], r4 vadd.u8 d3, d3, d7 vst1.32 {d3[0]}, [r1], r4 subs r12, r12, #12 bgt 1b pop {r4,pc} endfunc .macro paeth rx, ra, rb, rc vaddl.u8 q12, \ra, \rb @ a + b vaddl.u8 q15, \rc, \rc @ 2*c vabdl.u8 q13, \rb, \rc @ pa vabdl.u8 q14, \ra, \rc @ pb vabd.u16 q15, q12, q15 @ pc vcle.u16 q12, q13, q14 @ pa <= pb vcle.u16 q13, q13, q15 @ pa <= pc vcle.u16 q14, q14, q15 @ pb <= pc vand q12, q12, q13 @ pa <= pb && pa <= pc vmovn.u16 d28, q14 vmovn.u16 \rx, q12 vbsl d28, \rb, \rc vbsl \rx, \ra, d28 .endm func png_read_filter_row_paeth4_neon, export=1 ldr r12, [r0, #4] @ rowbytes vmov.i8 d3, #0 vmov.i8 d20, #0 1: vld4.32 {d4[],d5[],d6[],d7[]}, [r1,:128] vld4.32 {d16[],d17[],d18[],d19[]},[r2,:128]! paeth d0, d3, d16, d20 vadd.u8 d0, d0, d4 paeth d1, d0, d17, d16 vadd.u8 d1, d1, d5 paeth d2, d1, d18, d17 vadd.u8 d2, d2, d6 paeth d3, d2, d19, d18 vmov d20, d19 vadd.u8 d3, d3, d7 vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1,:128]! subs r12, r12, #16 bgt 1b bx lr endfunc func png_read_filter_row_paeth3_neon, export=1 push {r4,lr} ldr r12, [r0, #4] @ rowbytes vmov.i8 d3, #0 vmov.i8 d4, #0 mov r0, r1 mov r4, #3 mov lr, #12 vld1.8 {q11}, [r0], lr 1: vld1.8 {q10}, [r2], lr paeth d0, d3, d20, d4 vext.8 d5, d22, d23, #3 vadd.u8 d0, d0, d22 vext.8 d17, d20, d21, #3 paeth d1, d0, d17, d20 vst1.32 {d0[0]}, [r1,:32], r4 vext.8 d6, d22, d23, #6 vadd.u8 d1, d1, d5 vext.8 d18, d20, d21, #6 paeth d2, d1, d18, d17 vext.8 d7, d23, d23, #1 vld1.8 {q11}, [r0], lr vst1.32 {d1[0]}, [r1], r4 vadd.u8 d2, d2, d6 vext.8 d19, d21, d21, #1 paeth d3, d2, d19, d18 vst1.32 {d2[0]}, [r1], r4 vmov d4, d19 vadd.u8 d3, d3, d7 vst1.32 {d3[0]}, [r1], r4 subs r12, r12, #12 bgt 1b pop {r4,pc} endfunc #endif /* PNG_ARM_NEON_OPT > 0 */ #endif /* PNG_ARM_NEON_IMPLEMENTATION == 2 (assembler) */ #endif /* READ */ libpng-1.6.43/arm/filter_neon_intrinsics.c000066400000000000000000000270751456606525400206040ustar00rootroot00000000000000 /* filter_neon_intrinsics.c - NEON optimised filter functions * * Copyright (c) 2018 Cosmin Truta * Copyright (c) 2014,2016 Glenn Randers-Pehrson * Written by James Yu , October 2013. * Based on filter_neon.S, written by Mans Rullgard, 2011. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer * and license in png.h */ #include "../pngpriv.h" #ifdef PNG_READ_SUPPORTED /* This code requires -mfpu=neon on the command line: */ #if PNG_ARM_NEON_IMPLEMENTATION == 1 /* intrinsics code from pngpriv.h */ #if defined(_MSC_VER) && !defined(__clang__) && defined(_M_ARM64) # include #else # include #endif /* libpng row pointers are not necessarily aligned to any particular boundary, * however this code will only work with appropriate alignment. arm/arm_init.c * checks for this (and will not compile unless it is done). This code uses * variants of png_aligncast to avoid compiler warnings. */ #define png_ptr(type,pointer) png_aligncast(type *,pointer) #define png_ptrc(type,pointer) png_aligncastconst(const type *,pointer) /* The following relies on a variable 'temp_pointer' being declared with type * 'type'. This is written this way just to hide the GCC strict aliasing * warning; note that the code is safe because there never is an alias between * the input and output pointers. * * When compiling with MSVC ARM64, the png_ldr macro can't be passed directly * to vst4_lane_u32, because of an internal compiler error inside MSVC. * To avoid this compiler bug, we use a temporary variable (vdest_val) to store * the result of png_ldr. */ #define png_ldr(type,pointer)\ (temp_pointer = png_ptr(type,pointer), *temp_pointer) #if PNG_ARM_NEON_OPT > 0 void png_read_filter_row_up_neon(png_row_infop row_info, png_bytep row, png_const_bytep prev_row) { png_bytep rp = row; png_bytep rp_stop = row + row_info->rowbytes; png_const_bytep pp = prev_row; png_debug(1, "in png_read_filter_row_up_neon"); for (; rp < rp_stop; rp += 16, pp += 16) { uint8x16_t qrp, qpp; qrp = vld1q_u8(rp); qpp = vld1q_u8(pp); qrp = vaddq_u8(qrp, qpp); vst1q_u8(rp, qrp); } } void png_read_filter_row_sub3_neon(png_row_infop row_info, png_bytep row, png_const_bytep prev_row) { png_bytep rp = row; png_bytep rp_stop = row + row_info->rowbytes; uint8x16_t vtmp = vld1q_u8(rp); uint8x8x2_t *vrpt = png_ptr(uint8x8x2_t, &vtmp); uint8x8x2_t vrp = *vrpt; uint8x8x4_t vdest; vdest.val[3] = vdup_n_u8(0); png_debug(1, "in png_read_filter_row_sub3_neon"); for (; rp < rp_stop;) { uint8x8_t vtmp1, vtmp2; uint32x2_t *temp_pointer; vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3); vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]); vtmp2 = vext_u8(vrp.val[0], vrp.val[1], 6); vdest.val[1] = vadd_u8(vdest.val[0], vtmp1); vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1); vdest.val[2] = vadd_u8(vdest.val[1], vtmp2); vdest.val[3] = vadd_u8(vdest.val[2], vtmp1); vtmp = vld1q_u8(rp + 12); vrpt = png_ptr(uint8x8x2_t, &vtmp); vrp = *vrpt; vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0); rp += 3; vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0); rp += 3; vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0); rp += 3; vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0); rp += 3; } PNG_UNUSED(prev_row) } void png_read_filter_row_sub4_neon(png_row_infop row_info, png_bytep row, png_const_bytep prev_row) { png_bytep rp = row; png_bytep rp_stop = row + row_info->rowbytes; uint8x8x4_t vdest; vdest.val[3] = vdup_n_u8(0); png_debug(1, "in png_read_filter_row_sub4_neon"); for (; rp < rp_stop; rp += 16) { uint32x2x4_t vtmp = vld4_u32(png_ptr(uint32_t,rp)); uint8x8x4_t *vrpt = png_ptr(uint8x8x4_t,&vtmp); uint8x8x4_t vrp = *vrpt; uint32x2x4_t *temp_pointer; uint32x2x4_t vdest_val; vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]); vdest.val[1] = vadd_u8(vdest.val[0], vrp.val[1]); vdest.val[2] = vadd_u8(vdest.val[1], vrp.val[2]); vdest.val[3] = vadd_u8(vdest.val[2], vrp.val[3]); vdest_val = png_ldr(uint32x2x4_t, &vdest); vst4_lane_u32(png_ptr(uint32_t,rp), vdest_val, 0); } PNG_UNUSED(prev_row) } void png_read_filter_row_avg3_neon(png_row_infop row_info, png_bytep row, png_const_bytep prev_row) { png_bytep rp = row; png_const_bytep pp = prev_row; png_bytep rp_stop = row + row_info->rowbytes; uint8x16_t vtmp; uint8x8x2_t *vrpt; uint8x8x2_t vrp; uint8x8x4_t vdest; vdest.val[3] = vdup_n_u8(0); vtmp = vld1q_u8(rp); vrpt = png_ptr(uint8x8x2_t,&vtmp); vrp = *vrpt; png_debug(1, "in png_read_filter_row_avg3_neon"); for (; rp < rp_stop; pp += 12) { uint8x8_t vtmp1, vtmp2, vtmp3; uint8x8x2_t *vppt; uint8x8x2_t vpp; uint32x2_t *temp_pointer; vtmp = vld1q_u8(pp); vppt = png_ptr(uint8x8x2_t,&vtmp); vpp = *vppt; vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3); vdest.val[0] = vhadd_u8(vdest.val[3], vpp.val[0]); vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]); vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 3); vtmp3 = vext_u8(vrp.val[0], vrp.val[1], 6); vdest.val[1] = vhadd_u8(vdest.val[0], vtmp2); vdest.val[1] = vadd_u8(vdest.val[1], vtmp1); vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 6); vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1); vtmp = vld1q_u8(rp + 12); vrpt = png_ptr(uint8x8x2_t,&vtmp); vrp = *vrpt; vdest.val[2] = vhadd_u8(vdest.val[1], vtmp2); vdest.val[2] = vadd_u8(vdest.val[2], vtmp3); vtmp2 = vext_u8(vpp.val[1], vpp.val[1], 1); vdest.val[3] = vhadd_u8(vdest.val[2], vtmp2); vdest.val[3] = vadd_u8(vdest.val[3], vtmp1); vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0); rp += 3; vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0); rp += 3; vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0); rp += 3; vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0); rp += 3; } } void png_read_filter_row_avg4_neon(png_row_infop row_info, png_bytep row, png_const_bytep prev_row) { png_bytep rp = row; png_bytep rp_stop = row + row_info->rowbytes; png_const_bytep pp = prev_row; uint8x8x4_t vdest; vdest.val[3] = vdup_n_u8(0); png_debug(1, "in png_read_filter_row_avg4_neon"); for (; rp < rp_stop; rp += 16, pp += 16) { uint32x2x4_t vtmp; uint8x8x4_t *vrpt, *vppt; uint8x8x4_t vrp, vpp; uint32x2x4_t *temp_pointer; uint32x2x4_t vdest_val; vtmp = vld4_u32(png_ptr(uint32_t,rp)); vrpt = png_ptr(uint8x8x4_t,&vtmp); vrp = *vrpt; vtmp = vld4_u32(png_ptrc(uint32_t,pp)); vppt = png_ptr(uint8x8x4_t,&vtmp); vpp = *vppt; vdest.val[0] = vhadd_u8(vdest.val[3], vpp.val[0]); vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]); vdest.val[1] = vhadd_u8(vdest.val[0], vpp.val[1]); vdest.val[1] = vadd_u8(vdest.val[1], vrp.val[1]); vdest.val[2] = vhadd_u8(vdest.val[1], vpp.val[2]); vdest.val[2] = vadd_u8(vdest.val[2], vrp.val[2]); vdest.val[3] = vhadd_u8(vdest.val[2], vpp.val[3]); vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]); vdest_val = png_ldr(uint32x2x4_t, &vdest); vst4_lane_u32(png_ptr(uint32_t,rp), vdest_val, 0); } } static uint8x8_t paeth(uint8x8_t a, uint8x8_t b, uint8x8_t c) { uint8x8_t d, e; uint16x8_t p1, pa, pb, pc; p1 = vaddl_u8(a, b); /* a + b */ pc = vaddl_u8(c, c); /* c * 2 */ pa = vabdl_u8(b, c); /* pa */ pb = vabdl_u8(a, c); /* pb */ pc = vabdq_u16(p1, pc); /* pc */ p1 = vcleq_u16(pa, pb); /* pa <= pb */ pa = vcleq_u16(pa, pc); /* pa <= pc */ pb = vcleq_u16(pb, pc); /* pb <= pc */ p1 = vandq_u16(p1, pa); /* pa <= pb && pa <= pc */ d = vmovn_u16(pb); e = vmovn_u16(p1); d = vbsl_u8(d, b, c); e = vbsl_u8(e, a, d); return e; } void png_read_filter_row_paeth3_neon(png_row_infop row_info, png_bytep row, png_const_bytep prev_row) { png_bytep rp = row; png_const_bytep pp = prev_row; png_bytep rp_stop = row + row_info->rowbytes; uint8x16_t vtmp; uint8x8x2_t *vrpt; uint8x8x2_t vrp; uint8x8_t vlast = vdup_n_u8(0); uint8x8x4_t vdest; vdest.val[3] = vdup_n_u8(0); vtmp = vld1q_u8(rp); vrpt = png_ptr(uint8x8x2_t,&vtmp); vrp = *vrpt; png_debug(1, "in png_read_filter_row_paeth3_neon"); for (; rp < rp_stop; pp += 12) { uint8x8x2_t *vppt; uint8x8x2_t vpp; uint8x8_t vtmp1, vtmp2, vtmp3; uint32x2_t *temp_pointer; vtmp = vld1q_u8(pp); vppt = png_ptr(uint8x8x2_t,&vtmp); vpp = *vppt; vdest.val[0] = paeth(vdest.val[3], vpp.val[0], vlast); vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]); vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3); vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 3); vdest.val[1] = paeth(vdest.val[0], vtmp2, vpp.val[0]); vdest.val[1] = vadd_u8(vdest.val[1], vtmp1); vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 6); vtmp3 = vext_u8(vpp.val[0], vpp.val[1], 6); vdest.val[2] = paeth(vdest.val[1], vtmp3, vtmp2); vdest.val[2] = vadd_u8(vdest.val[2], vtmp1); vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1); vtmp2 = vext_u8(vpp.val[1], vpp.val[1], 1); vtmp = vld1q_u8(rp + 12); vrpt = png_ptr(uint8x8x2_t,&vtmp); vrp = *vrpt; vdest.val[3] = paeth(vdest.val[2], vtmp2, vtmp3); vdest.val[3] = vadd_u8(vdest.val[3], vtmp1); vlast = vtmp2; vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0); rp += 3; vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0); rp += 3; vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0); rp += 3; vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0); rp += 3; } } void png_read_filter_row_paeth4_neon(png_row_infop row_info, png_bytep row, png_const_bytep prev_row) { png_bytep rp = row; png_bytep rp_stop = row + row_info->rowbytes; png_const_bytep pp = prev_row; uint8x8_t vlast = vdup_n_u8(0); uint8x8x4_t vdest; vdest.val[3] = vdup_n_u8(0); png_debug(1, "in png_read_filter_row_paeth4_neon"); for (; rp < rp_stop; rp += 16, pp += 16) { uint32x2x4_t vtmp; uint8x8x4_t *vrpt, *vppt; uint8x8x4_t vrp, vpp; uint32x2x4_t *temp_pointer; uint32x2x4_t vdest_val; vtmp = vld4_u32(png_ptr(uint32_t,rp)); vrpt = png_ptr(uint8x8x4_t,&vtmp); vrp = *vrpt; vtmp = vld4_u32(png_ptrc(uint32_t,pp)); vppt = png_ptr(uint8x8x4_t,&vtmp); vpp = *vppt; vdest.val[0] = paeth(vdest.val[3], vpp.val[0], vlast); vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]); vdest.val[1] = paeth(vdest.val[0], vpp.val[1], vpp.val[0]); vdest.val[1] = vadd_u8(vdest.val[1], vrp.val[1]); vdest.val[2] = paeth(vdest.val[1], vpp.val[2], vpp.val[1]); vdest.val[2] = vadd_u8(vdest.val[2], vrp.val[2]); vdest.val[3] = paeth(vdest.val[2], vpp.val[3], vpp.val[2]); vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]); vlast = vpp.val[3]; vdest_val = png_ldr(uint32x2x4_t, &vdest); vst4_lane_u32(png_ptr(uint32_t,rp), vdest_val, 0); } } #endif /* PNG_ARM_NEON_OPT > 0 */ #endif /* PNG_ARM_NEON_IMPLEMENTATION == 1 (intrinsics) */ #endif /* READ */ libpng-1.6.43/arm/palette_neon_intrinsics.c000066400000000000000000000111161456606525400207420ustar00rootroot00000000000000 /* palette_neon_intrinsics.c - NEON optimised palette expansion functions * * Copyright (c) 2018-2019 Cosmin Truta * Copyright (c) 2017-2018 Arm Holdings. All rights reserved. * Written by Richard Townsend , February 2017. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer * and license in png.h */ #include "../pngpriv.h" #if PNG_ARM_NEON_IMPLEMENTATION == 1 #if defined(_MSC_VER) && !defined(__clang__) && defined(_M_ARM64) # include #else # include #endif /* Build an RGBA8 palette from the separate RGB and alpha palettes. */ void png_riffle_palette_neon(png_structrp png_ptr) { png_const_colorp palette = png_ptr->palette; png_bytep riffled_palette = png_ptr->riffled_palette; png_const_bytep trans_alpha = png_ptr->trans_alpha; int num_trans = png_ptr->num_trans; int i; /* Initially black, opaque. */ uint8x16x4_t w = {{ vdupq_n_u8(0x00), vdupq_n_u8(0x00), vdupq_n_u8(0x00), vdupq_n_u8(0xff), }}; png_debug(1, "in png_riffle_palette_neon"); /* First, riffle the RGB colours into an RGBA8 palette. * The alpha component is set to opaque for now. */ for (i = 0; i < 256; i += 16) { uint8x16x3_t v = vld3q_u8((png_const_bytep)(palette + i)); w.val[0] = v.val[0]; w.val[1] = v.val[1]; w.val[2] = v.val[2]; vst4q_u8(riffled_palette + (i << 2), w); } /* Fix up the missing transparency values. */ for (i = 0; i < num_trans; i++) riffled_palette[(i << 2) + 3] = trans_alpha[i]; } /* Expands a palettized row into RGBA8. */ int png_do_expand_palette_rgba8_neon(png_structrp png_ptr, png_row_infop row_info, png_const_bytep row, png_bytepp ssp, png_bytepp ddp) { png_uint_32 row_width = row_info->width; const png_uint_32 *riffled_palette = (const png_uint_32 *)png_ptr->riffled_palette; const png_uint_32 pixels_per_chunk = 4; png_uint_32 i; png_debug(1, "in png_do_expand_palette_rgba8_neon"); PNG_UNUSED(row) if (row_width < pixels_per_chunk) return 0; /* This function originally gets the last byte of the output row. * The NEON part writes forward from a given position, so we have * to seek this back by 4 pixels x 4 bytes. */ *ddp = *ddp - ((pixels_per_chunk * sizeof(png_uint_32)) - 1); for (i = 0; i < row_width; i += pixels_per_chunk) { uint32x4_t cur; png_bytep sp = *ssp - i, dp = *ddp - (i << 2); cur = vld1q_dup_u32 (riffled_palette + *(sp - 3)); cur = vld1q_lane_u32(riffled_palette + *(sp - 2), cur, 1); cur = vld1q_lane_u32(riffled_palette + *(sp - 1), cur, 2); cur = vld1q_lane_u32(riffled_palette + *(sp - 0), cur, 3); vst1q_u32((void *)dp, cur); } if (i != row_width) { /* Remove the amount that wasn't processed. */ i -= pixels_per_chunk; } /* Decrement output pointers. */ *ssp = *ssp - i; *ddp = *ddp - (i << 2); return i; } /* Expands a palettized row into RGB8. */ int png_do_expand_palette_rgb8_neon(png_structrp png_ptr, png_row_infop row_info, png_const_bytep row, png_bytepp ssp, png_bytepp ddp) { png_uint_32 row_width = row_info->width; png_const_bytep palette = (png_const_bytep)png_ptr->palette; const png_uint_32 pixels_per_chunk = 8; png_uint_32 i; png_debug(1, "in png_do_expand_palette_rgb8_neon"); PNG_UNUSED(row) if (row_width <= pixels_per_chunk) return 0; /* Seeking this back by 8 pixels x 3 bytes. */ *ddp = *ddp - ((pixels_per_chunk * sizeof(png_color)) - 1); for (i = 0; i < row_width; i += pixels_per_chunk) { uint8x8x3_t cur; png_bytep sp = *ssp - i, dp = *ddp - ((i << 1) + i); cur = vld3_dup_u8(palette + sizeof(png_color) * (*(sp - 7))); cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 6)), cur, 1); cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 5)), cur, 2); cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 4)), cur, 3); cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 3)), cur, 4); cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 2)), cur, 5); cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 1)), cur, 6); cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 0)), cur, 7); vst3_u8((void *)dp, cur); } if (i != row_width) { /* Remove the amount that wasn't processed. */ i -= pixels_per_chunk; } /* Decrement output pointers. */ *ssp = *ssp - i; *ddp = *ddp - ((i << 1) + i); return i; } #endif /* PNG_ARM_NEON_IMPLEMENTATION */ libpng-1.6.43/autogen.sh000077500000000000000000000175351456606525400151110ustar00rootroot00000000000000#! /bin/sh # # Run 'autoreconf' to build 'configure', 'Makefile.in' and other configure # control files. # # The first time this is run on a GIT checkout the only files that exist are # configure.ac and Makefile.am; all of the autotools support scripts are # missing. They are instantiated with autoreconf --force --install. # # For regular ("tarball") distributions all the files should exist. We do not # want them to be updated *under any circumstances*. It should never be # necessary to run autogen.sh because ./configure --enable-maintainer-mode says # what to do if Makefile.am or configure.ac are changed. # # It is *probably* OK to update the files on a GIT checkout, because they have # come from the local tools, but leave that to the user who is assumed to know # whether it is ok or required. # # This script is intended to work without arguments, there are, however, hidden # arguments (a) for use while testing the script and (b) to fix up systems that # have been broken. If (b) is required the script prompts for the correct # options. For this reason the options are *NOT* documented in the help; this # is deliberate; UTSL. # clean= maintainer= while test $# -gt 0 do case "$1" in --maintainer) maintainer=1;; --clean) clean=1;; *) exec >&2 echo "$0: usage: ./autogen.sh" if test -d .git then echo " ./autogen.sh generates the configure script and" echo " Makefile.in, or refreshes them after changes to Makefile.am" echo " or configure.ac. You may prefer to just run autoreconf." elif test -z "$maintainer" then echo " DO NOT RUN THIS SCRIPT." echo " If you need to change Makefile.am or configure.ac then you" echo " also need to run ./configure --enable-maintainer-mode and" echo " use the appropriate autotools, *NOT* this script, to update" echo " everything, please check the documentation of autoreconf." echo " WARNING: libpng is intentionally generated with a known," echo " fixed, set of autotools. It is known *NOT* to work with" echo " the collection of autotools distributed on highly reputable" echo " operating systems." echo " Remember: autotools is GNU software, you are expected to" echo " pay for support." else echo " You have run autogen.sh with --maintainer enabled and you" echo " are not using a GIT distribution, then you have given an" echo " unrecognized argument. This is not good. --maintainer" echo " switches off any assumptions that you might not know what" echo " you are doing." fi exit 1;; esac shift done # # First check for a set of the autotools files; if absent then this is assumed # to be a GIT version and the local autotools must be used. If present this # is a tarball distribution and the script should not be used. If partially # present bad things are happening. # # The autotools generated files: libpng_autotools_files="Makefile.in aclocal.m4 config.guess config.h.in config.sub configure depcomp install-sh ltmain.sh missing\ test-driver" # # Files generated by versions of autoconf >2.68 or automake >1.13 (i.e. later # versions than those required by configure.ac): libpng_autotools_extra="compile config.h.in~" # # These are separate because 'maintainer-clean' does not remove them. libpng_libtool_files="scripts/autoconf/libtool.m4 scripts/autoconf/ltoptions.m4\ scripts/autoconf/ltsugar.m4 scripts/autoconf/ltversion.m4\ scripts/autoconf/lt~obsolete.m4" libpng_autotools_dirs="autom4te.cache" # not required # # The configure generated files: libpng_configure_files="Makefile config.h config.log config.status\ libpng-config libpng.pc libtool stamp-h1" libpng_configure_dirs=".deps" # # We must remove the configure generated files as well as the autotools # generated files if autotools are regenerated because otherwise if configure # has been run without "--enable-maintainer-mode" make can do a partial update # of Makefile. These functions do the two bits of cleaning. clean_autotools(){ rm -rf $libpng_autotools_files $libpng_libtool_files $libpng_autotools_dirs rm -rf $libpng_autotools_extra } clean_configure(){ rm -rf $libpng_configure_files $libpng_configure_dirs } # # Clean: remove everything (this is to help with testing) if test -n "$clean" then clean_configure if test -n "$maintainer" then clean_autotools fi exit 0 fi # # Validate the distribution. libpng_autotools_file_found= libpng_autotools_file_missing= for file in $libpng_autotools_files do if test -f "$file" then libpng_autotools_file_found=1 else libpng_autotools_file_missing=1 fi done # # Presence of one of these does not *invalidate* missing, but absence # invalidates found. for file in $libpng_libtool_files do if test ! -f "$file" then libpng_autotools_file_missing=1 fi done # # The cache directory doesn't matter - it will be regenerated and does not exist # anyway in a tarball. # # Either everything is missing or everything is there, the --maintainer option # just changes this so that the mode is set to generate all the files. mode= if test -z "$libpng_autotools_file_found" -o -n "$maintainer" then mode="autoreconf" else if test -n "$libpng_autotools_file_missing" then mode="broken" else mode="configure" fi fi # # So: case "$mode" in autoreconf) # Clean in case configure files exist clean_configure clean_autotools # Everything must be initialized, so use --force if autoreconf --warnings=all --force --install then missing= for file in $libpng_autotools_files do test -f "$file" || missing=1 done # ignore the cache directory test -z "$missing" || { exec >&2 echo "autoreconf was run, but did not produce all the expected" echo "files. It is likely that your autotools installation is" echo "not compatible with that expected by libpng." exit 1 } else exec >&2 echo "autoreconf failed: your version of autotools is incompatible" echo "with this libpng version. Please use a distributed archive" echo "(which includes the autotools generated files) and run configure" echo "instead." exit 1 fi;; configure) if test -d .git then exec >&2 echo "ERROR: running autoreconf on an initialized system" echo " This is not necessary; it is only necessary to remake the" echo " autotools generated files if Makefile.am or configure.ac" echo " change and make does the right thing with:" echo echo " ./configure --enable-maintainer-mode." echo echo " You can run autoreconf yourself if you don't like maintainer" echo " mode and you can also just run autoreconf -f -i to initialize" echo " everything in the first place; this script is only for" echo " compatibility with prior releases." exit 1 else exec >&2 echo "autogen.sh is intended only to generate 'configure' on systems" echo "that do not have it. You have a complete 'configure', if you" echo "need to change Makefile.am or configure.ac you also need to" echo "run configure with the --enable-maintainer-mode option." exit 1 fi;; broken) exec >&2 echo "Your system has a partial set of autotools generated files." echo "autogen.sh is unable to proceed. The full set of files is" echo "contained in the libpng 'tar' distribution archive and you do" echo "not need to run autogen.sh if you use it." exit 1;; esac libpng-1.6.43/ci/000077500000000000000000000000001456606525400134705ustar00rootroot00000000000000libpng-1.6.43/ci/.shellcheckrc000066400000000000000000000007571456606525400161340ustar00rootroot00000000000000# Disable the "expressions don't expand in single quotes, use double quotes" # advice. We need the regular expressions to remain uninterpolated. disable=SC2016 # Disable the "variable appears unused" warning caused by the use of getopts # with an obligatory (but unused) variable name in the main function. disable=SC2034 # Disable all the "quote to prevent globbing or word splitting" advice. # We need word splitting for well-known variables like MAKEFLAGS and CFLAGS. disable=SC2086,SC2206 libpng-1.6.43/ci/LICENSE_MIT.txt000066400000000000000000000020141456606525400160210ustar00rootroot00000000000000MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. libpng-1.6.43/ci/ci_lint.sh000077500000000000000000000074241456606525400154570ustar00rootroot00000000000000#!/usr/bin/env bash set -o errexit -o pipefail -o posix # Copyright (c) 2019-2024 Cosmin Truta. # # Use, modification and distribution are subject to the MIT License. # Please see the accompanying file LICENSE_MIT.txt # # SPDX-License-Identifier: MIT # shellcheck source=ci/lib/ci.lib.sh source "$(dirname "$0")/lib/ci.lib.sh" cd "$CI_TOPLEVEL_DIR" # Initialize the global constants CI_{...}{CHECK,CHECKER,LINT}. CI_SHELLCHECK="${CI_SHELLCHECK:-shellcheck}" CI_EDITORCONFIG_CHECKER="${CI_EDITORCONFIG_CHECKER:-editorconfig-checker}" CI_YAMLLINT="${CI_YAMLLINT:-yamllint}" # Initialize the global lint status. CI_LINT_STATUS=0 function ci_init_lint { ci_info "## START OF LINTING ##" local my_program # Complete the initialization of CI_SHELLCHECK. # Set it to the empty string if the shellcheck program is unavailable. my_program="$(command -v "$CI_SHELLCHECK")" || { ci_warn "program not found: '$CI_SHELLCHECK'" } CI_SHELLCHECK="$my_program" # Complete the initialization of CI_EDITORCONFIG_CHECKER. # Set it to the empty string if the editorconfig-checker program is unavailable. my_program="$(command -v "$CI_EDITORCONFIG_CHECKER")" || { ci_warn "program not found: '$CI_EDITORCONFIG_CHECKER'" } CI_EDITORCONFIG_CHECKER="$my_program" # Complete the initialization of CI_YAMLLINT. # Set it to the empty string if the yamllint program is unavailable. my_program="$(command -v "$CI_YAMLLINT")" || { ci_warn "program not found: '$CI_YAMLLINT'" } CI_YAMLLINT="$my_program" } function ci_finish_lint { ci_info "## END OF LINTING ##" if [[ $CI_LINT_STATUS -eq 0 ]] then ci_info "## SUCCESS ##" else ci_info "linting failed" fi return "$CI_LINT_STATUS" } function ci_lint_ci_scripts { [[ -x $CI_SHELLCHECK ]] || { ci_warn "## NOT LINTING: CI scripts ##" return 0 } ci_info "## LINTING: CI scripts ##" ci_spawn "$CI_SHELLCHECK" --version find ./ci -maxdepth 1 -name "*.sh" | { local my_file while IFS="" read -r my_file do ci_spawn "$CI_SHELLCHECK" -x "$my_file" || { # Linting failed. return 1 } done } } function ci_lint_text_files { [[ -x $CI_EDITORCONFIG_CHECKER ]] || { ci_warn "## NOT LINTING: text files ##" return 0 } ci_info "## LINTING: text files ##" ci_spawn "$CI_EDITORCONFIG_CHECKER" --version ci_spawn "$CI_EDITORCONFIG_CHECKER" || { # Linting failed. return 1 } } function ci_lint_yaml_files { [[ -x $CI_YAMLLINT ]] || { ci_warn "## NOT LINTING: YAML files ##" return 0 } ci_info "## LINTING: YAML files ##" ci_spawn "$CI_YAMLLINT" --version find . \( -iname "*.yml" -o -iname "*.yaml" \) -not -path "./out/*" | { local my_file while IFS="" read -r my_file do ci_spawn "$CI_YAMLLINT" --strict "$my_file" || { # Linting failed. return 1 } done } } function ci_lint { ci_init_lint ci_lint_ci_scripts || CI_LINT_STATUS=1 ci_lint_text_files || CI_LINT_STATUS=1 ci_lint_yaml_files || CI_LINT_STATUS=1 # TODO: ci_lint_png_files, etc. ci_finish_lint } function usage { echo "usage: $CI_SCRIPT_NAME []" echo "options: -?|-h|--help" exit "${@:-0}" } function main { local opt while getopts ":" opt do # This ain't a while-loop. It only pretends to be. [[ $1 == -[?h]* || $1 == --help || $1 == --help=* ]] && usage 0 ci_err "unknown option: '$1'" done shift $((OPTIND - 1)) [[ $# -eq 0 ]] || { echo >&2 "error: unexpected argument: '$1'" usage 2 } # And... go! ci_lint } main "$@" libpng-1.6.43/ci/ci_shellify.sh000077500000000000000000000057211456606525400163260ustar00rootroot00000000000000#!/usr/bin/env bash set -o errexit -o pipefail -o posix # Copyright (c) 2019-2024 Cosmin Truta. # # Use, modification and distribution are subject to the MIT License. # Please see the accompanying file LICENSE_MIT.txt # # SPDX-License-Identifier: MIT # shellcheck source=ci/lib/ci.lib.sh source "$(dirname "$0")/lib/ci.lib.sh" cd "$CI_TOPLEVEL_DIR" function ci_shellify_c { # Convert C preprocessor text, specifically originating # from png.h, to shell scripting text. # Select only the easy-to-parse definitions of PNG_LIBPNG_*. sed -n -e '/^\# *define * PNG_LIBPNG_[^ ]* * ["0-9A-Za-z_]/ p' | sed -e 's/^\# *define * PNG\([^ ]*\) * \([^ ]*\)/PNG\1=\2/' \ -e 's/=PNG\([0-9A-Za-z_]*\)/=\${PNG\1}/' \ -e 's/^\([^ ]*=[^ ]*\).*$/export \1;/' } function ci_shellify_autoconf { # Convert autoconf (M4) text, specifically originating # from configure.ac, to shell scripting text. # Select only the easy-to-parse definitions of PNGLIB_*. sed -n -e '/^ *PNGLIB_[^ ]*=[$"0-9A-Za-z_]/ p' | sed -e 's/^ *PNG\([0-9A-Za-z_]*\)=\([^# ]*\).*$/PNG\1=\2/' \ -e 's/^\([^ ]*=[^ ]*\).*$/export \1;/' } function ci_shellify_cmake { # Convert CMake lists text, specifically originating # from CMakeLists.txt, to shell scripting text. # Select only the easy-to-parse definitions of PNGLIB_*. sed -n -e '/^ *set *(PNGLIB_[^ ]* * [$"0-9A-Za-z_].*)/ p' | sed -e 's/^ *set *(PNG\([^ ]*\) * \([^() ]*\)).*$/PNG\1=\2/' \ -e 's/^\([^ ]*=[^ ]*\).*$/export \1;/' } function ci_shellify { local arg filename for arg in "$@" do test -f "$arg" || ci_err "no such file: '$arg'" filename="$(basename -- "$arg")" case "$filename" in ( *.[ch] ) [[ $filename == png.h ]] || { ci_err "unable to shellify: '$filename' (expecting: 'png.h')" } ci_shellify_c <"$arg" ;; ( config* | *.ac ) [[ $filename == configure.ac ]] || { ci_err "unable to shellify: '$filename' (expecting: 'configure.ac')" } ci_shellify_autoconf <"$arg" ;; ( *CMake* | *cmake* | *.txt ) [[ $filename == [Cc][Mm]ake[Ll]ists.txt ]] || { ci_err "unable to shellify: '$filename' (expecting: 'CMakeLists.txt')" } ci_shellify_cmake <"$arg" ;; ( * ) ci_err "unable to shellify: '$arg'" ;; esac done } function usage { echo "usage: $CI_SCRIPT_NAME [] ..." echo "options: -?|-h|--help" echo "files: png.h|configure.ac|CMakeLists.txt" exit "${@:-0}" } function main { local opt while getopts ":" opt do # This ain't a while-loop. It only pretends to be. [[ $1 == -[?h]* || $1 == --help || $1 == --help=* ]] && usage 0 ci_err "unknown option: '$1'" done shift $((OPTIND - 1)) [[ $# -eq 0 ]] && usage 2 # And... go! ci_shellify "$@" } main "$@" libpng-1.6.43/ci/ci_verify_cmake.sh000077500000000000000000000211571456606525400171540ustar00rootroot00000000000000#!/usr/bin/env bash set -o errexit -o pipefail -o posix # Copyright (c) 2019-2024 Cosmin Truta. # # Use, modification and distribution are subject to the MIT License. # Please see the accompanying file LICENSE_MIT.txt # # SPDX-License-Identifier: MIT # shellcheck source=ci/lib/ci.lib.sh source "$(dirname "$0")/lib/ci.lib.sh" cd "$CI_TOPLEVEL_DIR" CI_SRC_DIR="$CI_TOPLEVEL_DIR" CI_OUT_DIR="$CI_TOPLEVEL_DIR/out" CI_BUILD_DIR="$CI_OUT_DIR/ci_verify_cmake.$CI_TARGET_SYSTEM.$CI_TARGET_ARCH.build" CI_INSTALL_DIR="$CI_OUT_DIR/ci_verify_cmake.$CI_TARGET_SYSTEM.$CI_TARGET_ARCH.install" # Keep the following relative paths in sync with the absolute paths. # We use them for the benefit of native Windows tools that might be # otherwise confused by the path encoding used by Bash-on-Windows. CI_BUILD_TO_SRC_RELDIR="../.." CI_BUILD_TO_INSTALL_RELDIR="../ci_verify_cmake.$CI_TARGET_SYSTEM.$CI_TARGET_ARCH.install" function ci_init_build { # Ensure that the mandatory variables are initialized. CI_CMAKE="${CI_CMAKE:-cmake}" CI_CTEST="${CI_CTEST:-ctest}" CI_CMAKE_BUILD_TYPE="${CI_CMAKE_BUILD_TYPE:-Release}" if [[ $CI_CMAKE_GENERATOR == "Visual Studio"* ]] then # Clean up incidental mixtures of Windows and Bash-on-Windows # environment variables, to avoid confusing MSBuild. [[ $TEMP && ( $Temp || $temp ) ]] && unset TEMP [[ $TMP && ( $Tmp || $tmp ) ]] && unset TMP # Ensure that CI_CMAKE_GENERATOR_PLATFORM is initialized for this generator. [[ $CI_CMAKE_GENERATOR_PLATFORM ]] || { ci_err_internal "missing \$CI_CMAKE_GENERATOR_PLATFORM" } elif [[ -x $(command -v ninja) ]] then CI_CMAKE_GENERATOR="${CI_CMAKE_GENERATOR:-Ninja}" fi } function ci_trace_build { ci_info "## START OF CONFIGURATION ##" ci_info "build arch: $CI_BUILD_ARCH" ci_info "build system: $CI_BUILD_SYSTEM" [[ "$CI_TARGET_SYSTEM.$CI_TARGET_ARCH" != "$CI_BUILD_SYSTEM.$CI_BUILD_ARCH" ]] && { ci_info "target arch: $CI_TARGET_ARCH" ci_info "target system: $CI_TARGET_SYSTEM" } ci_info "source directory: $CI_SRC_DIR" ci_info "build directory: $CI_BUILD_DIR" ci_info "install directory: $CI_INSTALL_DIR" ci_info "environment option: \$CI_CMAKE: '$CI_CMAKE'" ci_info "environment option: \$CI_CMAKE_GENERATOR: '$CI_CMAKE_GENERATOR'" ci_info "environment option: \$CI_CMAKE_GENERATOR_PLATFORM: '$CI_CMAKE_GENERATOR_PLATFORM'" ci_info "environment option: \$CI_CMAKE_BUILD_TYPE: '$CI_CMAKE_BUILD_TYPE'" ci_info "environment option: \$CI_CMAKE_BUILD_FLAGS: '$CI_CMAKE_BUILD_FLAGS'" ci_info "environment option: \$CI_CMAKE_TOOLCHAIN_FILE: '$CI_CMAKE_TOOLCHAIN_FILE'" ci_info "environment option: \$CI_CMAKE_VARS: '$CI_CMAKE_VARS'" ci_info "environment option: \$CI_CTEST: '$CI_CTEST'" ci_info "environment option: \$CI_CTEST_FLAGS: '$CI_CTEST_FLAGS'" ci_info "environment option: \$CI_CC: '$CI_CC'" ci_info "environment option: \$CI_CC_FLAGS: '$CI_CC_FLAGS'" ci_info "environment option: \$CI_AR: '$CI_AR'" ci_info "environment option: \$CI_RANLIB: '$CI_RANLIB'" ci_info "environment option: \$CI_SANITIZERS: '$CI_SANITIZERS'" ci_info "environment option: \$CI_FORCE: '$CI_FORCE'" ci_info "environment option: \$CI_NO_TEST: '$CI_NO_TEST'" ci_info "environment option: \$CI_NO_INSTALL: '$CI_NO_INSTALL'" ci_info "environment option: \$CI_NO_CLEAN: '$CI_NO_CLEAN'" ci_info "executable: \$CI_CMAKE: $(command -V "$CI_CMAKE")" ci_info "executable: \$CI_CTEST: $(command -V "$CI_CTEST")" [[ $CI_CC ]] && { ci_info "executable: \$CI_CC: $(command -V "$CI_CC")" } [[ $CI_AR ]] && { ci_info "executable: \$CI_AR: $(command -V "$CI_AR")" } [[ $CI_RANLIB ]] && { ci_info "executable: \$CI_RANLIB: $(command -V "$CI_RANLIB")" } ci_info "## END OF CONFIGURATION ##" } function ci_cleanup_old_build { ci_info "## START OF PRE-BUILD CLEANUP ##" [[ ! -e $CI_BUILD_DIR && ! -e $CI_INSTALL_DIR ]] || { ci_spawn rm -fr "$CI_BUILD_DIR" ci_spawn rm -fr "$CI_INSTALL_DIR" } ci_info "## END OF PRE-BUILD CLEANUP ##" } function ci_build { ci_info "## START OF BUILD ##" # Adjust the CI environment variables, as needed. CI_CMAKE="$(command -v "$CI_CMAKE")" || ci_err "bad or missing \$CI_CMAKE" ci_spawn "$CI_CMAKE" --version CI_CTEST="$(command -v "$CI_CTEST")" || ci_err "bad or missing \$CI_CTEST" ci_spawn "$CI_CTEST" --version [[ $CI_CMAKE_GENERATOR == *"Ninja"* ]] && { CI_NINJA="$(command -v ninja)" || ci_err "bad or missing ninja, no pun intended" ci_spawn "$CI_NINJA" --version } [[ $CI_AR ]] && { # Use the full path of CI_AR to work around a mysterious CMake error. CI_AR="$(command -v "$CI_AR")" || ci_err "bad or missing \$CI_AR" } [[ $CI_RANLIB ]] && { # Use the full path of CI_RANLIB to work around a mysterious CMake error. CI_RANLIB="$(command -v "$CI_RANLIB")" || ci_err "bad or missing \$CI_RANLIB" } # Export the CMake environment variables. [[ $CI_CMAKE_GENERATOR ]] && { ci_spawn export CMAKE_GENERATOR="$CI_CMAKE_GENERATOR" } [[ $CI_CMAKE_GENERATOR_PLATFORM ]] && { ci_spawn export CMAKE_GENERATOR_PLATFORM="$CI_CMAKE_GENERATOR_PLATFORM" } # Initialize and populate the local arrays. local all_cmake_vars=() local all_cmake_build_flags=() local all_ctest_flags=() [[ $CI_CMAKE_TOOLCHAIN_FILE ]] && { all_cmake_vars+=("-DCMAKE_TOOLCHAIN_FILE=$CI_CMAKE_TOOLCHAIN_FILE") } [[ $CI_CC ]] && { all_cmake_vars+=("-DCMAKE_C_COMPILER=$CI_CC") } [[ $CI_CC_FLAGS || $CI_SANITIZERS ]] && { [[ $CI_SANITIZERS ]] && CI_CC_FLAGS+="${CI_CC_FLAGS:+" "}-fsanitize=$CI_SANITIZERS" all_cmake_vars+=("-DCMAKE_C_FLAGS=$CI_CC_FLAGS") } [[ $CI_AR ]] && { all_cmake_vars+=("-DCMAKE_AR=$CI_AR") } [[ $CI_RANLIB ]] && { all_cmake_vars+=("-DCMAKE_RANLIB=$CI_RANLIB") } all_cmake_vars+=("-DCMAKE_BUILD_TYPE=$CI_CMAKE_BUILD_TYPE") all_cmake_vars+=("-DCMAKE_VERBOSE_MAKEFILE=ON") all_cmake_vars+=($CI_CMAKE_VARS) all_cmake_build_flags+=($CI_CMAKE_BUILD_FLAGS) all_ctest_flags+=($CI_CTEST_FLAGS) # And... build! # Use $CI_BUILD_TO_SRC_RELDIR and $CI_BUILD_TO_INSTALL_RELDIR # instead of $CI_SRC_DIR and $CI_INSTALL_DIR from this point onwards. ci_spawn mkdir -p "$CI_BUILD_DIR" ci_spawn cd "$CI_BUILD_DIR" [[ $CI_BUILD_TO_SRC_RELDIR -ef $CI_SRC_DIR ]] || { ci_err_internal "bad or missing \$CI_BUILD_TO_SRC_RELDIR" } ci_spawn mkdir -p "$CI_INSTALL_DIR" [[ $CI_BUILD_TO_INSTALL_RELDIR -ef $CI_INSTALL_DIR ]] || { ci_err_internal "bad or missing \$CI_BUILD_TO_INSTALL_RELDIR" } # Spawn "cmake ...". ci_spawn "$CI_CMAKE" -DCMAKE_INSTALL_PREFIX="$CI_BUILD_TO_INSTALL_RELDIR" \ "${all_cmake_vars[@]}" \ "$CI_BUILD_TO_SRC_RELDIR" # Spawn "cmake --build ...". ci_spawn "$CI_CMAKE" --build . \ --config "$CI_CMAKE_BUILD_TYPE" \ "${all_cmake_build_flags[@]}" ci_expr $((CI_NO_TEST)) || { # Spawn "ctest" if testing is not disabled. ci_spawn "$CI_CTEST" --build-config "$CI_CMAKE_BUILD_TYPE" \ "${all_ctest_flags[@]}" } ci_expr $((CI_NO_INSTALL)) || { # Spawn "cmake --build ... --target install" if installation is not disabled. ci_spawn "$CI_CMAKE" --build . \ --config "$CI_CMAKE_BUILD_TYPE" \ --target install \ "${all_cmake_build_flags[@]}" } ci_expr $((CI_NO_CLEAN)) || { # Spawn "make --build ... --target clean" if cleaning is not disabled. ci_spawn "$CI_CMAKE" --build . \ --config "$CI_CMAKE_BUILD_TYPE" \ --target clean \ "${all_cmake_build_flags[@]}" } ci_info "## END OF BUILD ##" } function usage { echo "usage: $CI_SCRIPT_NAME []" echo "options: -?|-h|--help" exit "${@:-0}" } function main { local opt while getopts ":" opt do # This ain't a while-loop. It only pretends to be. [[ $1 == -[?h]* || $1 == --help || $1 == --help=* ]] && usage 0 ci_err "unknown option: '$1'" done shift $((OPTIND - 1)) # And... go! ci_init_build ci_trace_build [[ $# -eq 0 ]] || { echo >&2 "error: unexpected argument: '$1'" echo >&2 "note: this program accepts environment options only" usage 2 } ci_cleanup_old_build ci_build } main "$@" libpng-1.6.43/ci/ci_verify_configure.sh000077500000000000000000000147301456606525400200540ustar00rootroot00000000000000#!/usr/bin/env bash set -o errexit -o pipefail -o posix # Copyright (c) 2019-2024 Cosmin Truta. # # Use, modification and distribution are subject to the MIT License. # Please see the accompanying file LICENSE_MIT.txt # # SPDX-License-Identifier: MIT # shellcheck source=ci/lib/ci.lib.sh source "$(dirname "$0")/lib/ci.lib.sh" cd "$CI_TOPLEVEL_DIR" CI_SRC_DIR="$CI_TOPLEVEL_DIR" CI_OUT_DIR="$CI_TOPLEVEL_DIR/out" CI_BUILD_DIR="$CI_OUT_DIR/ci_verify_configure.$CI_TARGET_SYSTEM.$CI_TARGET_ARCH.build" CI_INSTALL_DIR="$CI_OUT_DIR/ci_verify_configure.$CI_TARGET_SYSTEM.$CI_TARGET_ARCH.install" function ci_init_build { # Ensure that the mandatory variables are initialized. CI_MAKE="${CI_MAKE:-make}" [[ "$CI_TARGET_SYSTEM.$CI_TARGET_ARCH" != "$CI_BUILD_SYSTEM.$CI_BUILD_ARCH" ]] || { # For native builds, set CI_CC to "cc" by default if the cc command is available. # The configure script defaults CC to "gcc", which is not always a good idea. [[ -x $(command -v cc) ]] && CI_CC="${CI_CC:-cc}" } # Ensure that the CI_ variables that cannot be customized reliably are not initialized. [[ ! $CI_CONFIGURE_VARS ]] || { ci_err "unsupported: \$CI_CONFIGURE_VARS='$CI_CONFIGURE_VARS'" } [[ ! $CI_MAKE_VARS ]] || { ci_err "unsupported: \$CI_MAKE_VARS='$CI_MAKE_VARS'" } } function ci_trace_build { ci_info "## START OF CONFIGURATION ##" ci_info "build arch: $CI_BUILD_ARCH" ci_info "build system: $CI_BUILD_SYSTEM" [[ "$CI_TARGET_SYSTEM.$CI_TARGET_ARCH" != "$CI_BUILD_SYSTEM.$CI_BUILD_ARCH" ]] && { ci_info "target arch: $CI_TARGET_ARCH" ci_info "target system: $CI_TARGET_SYSTEM" } ci_info "source directory: $CI_SRC_DIR" ci_info "build directory: $CI_BUILD_DIR" ci_info "install directory: $CI_INSTALL_DIR" ci_info "environment option: \$CI_CONFIGURE_FLAGS: '$CI_CONFIGURE_FLAGS'" ci_info "environment option: \$CI_MAKE: '$CI_MAKE'" ci_info "environment option: \$CI_MAKE_FLAGS: '$CI_MAKE_FLAGS'" ci_info "environment option: \$CI_CC: '$CI_CC'" ci_info "environment option: \$CI_CC_FLAGS: '$CI_CC_FLAGS'" ci_info "environment option: \$CI_CPP: '$CI_CPP'" ci_info "environment option: \$CI_CPP_FLAGS: '$CI_CPP_FLAGS'" ci_info "environment option: \$CI_AR: '$CI_AR'" ci_info "environment option: \$CI_RANLIB: '$CI_RANLIB'" ci_info "environment option: \$CI_LD: '$CI_LD'" ci_info "environment option: \$CI_LD_FLAGS: '$CI_LD_FLAGS'" ci_info "environment option: \$CI_SANITIZERS: '$CI_SANITIZERS'" ci_info "environment option: \$CI_FORCE: '$CI_FORCE'" ci_info "environment option: \$CI_NO_TEST: '$CI_NO_TEST'" ci_info "environment option: \$CI_NO_INSTALL: '$CI_NO_INSTALL'" ci_info "environment option: \$CI_NO_CLEAN: '$CI_NO_CLEAN'" ci_info "executable: \$CI_MAKE: $(command -V "$CI_MAKE")" [[ $CI_CC ]] && { ci_info "executable: \$CI_CC: $(command -V "$CI_CC")" } [[ $CI_CPP ]] && { ci_info "executable: \$CI_CPP: $(command -V "$CI_CPP")" } [[ $CI_AR ]] && { ci_info "executable: \$CI_AR: $(command -V "$CI_AR")" } [[ $CI_RANLIB ]] && { ci_info "executable: \$CI_RANLIB: $(command -V "$CI_RANLIB")" } [[ $CI_LD ]] && { ci_info "executable: \$CI_LD: $(command -V "$CI_LD")" } ci_info "## END OF CONFIGURATION ##" } function ci_cleanup_old_build { ci_info "## START OF PRE-BUILD CLEANUP ##" [[ ! -e $CI_BUILD_DIR && ! -e $CI_INSTALL_DIR ]] || { ci_spawn rm -fr "$CI_BUILD_DIR" ci_spawn rm -fr "$CI_INSTALL_DIR" } [[ ! -e "$CI_SRC_DIR/config.status" ]] || { ci_warn "unexpected build configuration file: '$CI_SRC_DIR/config.status'" if ci_expr $((CI_FORCE)) then # Delete the old config and (possibly) the old build. ci_info "note: forcing an in-tree build cleanup" if [[ -f $CI_SRC_DIR/Makefile ]] then ci_spawn make -C "$CI_SRC_DIR" distclean else ci_spawn rm -fr "$CI_SRC_DIR"/config.{log,status} fi else # Alert the user, but do not delete their files. ci_warn "the configure script might fail" ci_info "hint: consider using the option \$CI_FORCE=1" fi } ci_info "## END OF PRE-BUILD CLEANUP ##" } function ci_build { ci_info "## START OF BUILD ##" # Export the configure build environment. [[ $CI_CC ]] && ci_spawn export CC="$CI_CC" [[ $CI_CC_FLAGS ]] && ci_spawn export CFLAGS="$CI_CC_FLAGS" [[ $CI_CPP ]] && ci_spawn export CPP="$CI_CPP" [[ $CI_CPP_FLAGS ]] && ci_spawn export CPPFLAGS="$CI_CPP_FLAGS" [[ $CI_AR ]] && ci_spawn export AR="$CI_AR" [[ $CI_RANLIB ]] && ci_spawn export RANLIB="$CI_RANLIB" [[ $CI_LD ]] && ci_spawn export LD="$CI_LD" [[ $CI_LD_FLAGS ]] && ci_spawn export LDFLAGS="$CI_LD_FLAGS" [[ $CI_SANITIZERS ]] && { ci_spawn export CFLAGS="${CFLAGS:-"-O2"} -fsanitize=$CI_SANITIZERS" ci_spawn export LDFLAGS="${LDFLAGS}${LDFLAGS:+" "}-fsanitize=$CI_SANITIZERS" } # And... build! ci_spawn mkdir -p "$CI_BUILD_DIR" ci_spawn cd "$CI_BUILD_DIR" # Spawn "configure". ci_spawn "$CI_SRC_DIR/configure" --prefix="$CI_INSTALL_DIR" $CI_CONFIGURE_FLAGS # Spawn "make". ci_spawn "$CI_MAKE" $CI_MAKE_FLAGS ci_expr $((CI_NO_TEST)) || { # Spawn "make test" if testing is not disabled. ci_spawn "$CI_MAKE" $CI_MAKE_FLAGS test } ci_expr $((CI_NO_INSTALL)) || { # Spawn "make install" if installation is not disabled. ci_spawn "$CI_MAKE" $CI_MAKE_FLAGS install } ci_expr $((CI_NO_CLEAN)) || { # Spawn "make clean" and "make distclean" if cleaning is not disabled. ci_spawn "$CI_MAKE" $CI_MAKE_FLAGS clean ci_spawn "$CI_MAKE" $CI_MAKE_FLAGS distclean } ci_info "## END OF BUILD ##" } function usage { echo "usage: $CI_SCRIPT_NAME []" echo "options: -?|-h|--help" exit "${@:-0}" } function main { local opt while getopts ":" opt do # This ain't a while-loop. It only pretends to be. [[ $1 == -[?h]* || $1 == --help || $1 == --help=* ]] && usage 0 ci_err "unknown option: '$1'" done shift $((OPTIND - 1)) # And... go! ci_init_build ci_trace_build [[ $# -eq 0 ]] || { echo >&2 "error: unexpected argument: '$1'" echo >&2 "note: this program accepts environment options only" usage 2 } ci_cleanup_old_build ci_build } main "$@" libpng-1.6.43/ci/ci_verify_makefiles.sh000077500000000000000000000152301456606525400200270ustar00rootroot00000000000000#!/usr/bin/env bash set -o errexit -o pipefail -o posix # Copyright (c) 2019-2024 Cosmin Truta. # # Use, modification and distribution are subject to the MIT License. # Please see the accompanying file LICENSE_MIT.txt # # SPDX-License-Identifier: MIT # shellcheck source=ci/lib/ci.lib.sh source "$(dirname "$0")/lib/ci.lib.sh" cd "$CI_TOPLEVEL_DIR" CI_SRC_DIR="$CI_TOPLEVEL_DIR" function ci_init_build { # Ensure that the mandatory variables are initialized. CI_MAKE="${CI_MAKE:-make}" case "$CI_CC" in ( *clang* ) CI_MAKEFILES="${CI_MAKEFILES:-"scripts/makefile.clang"}" ;; ( *gcc* ) CI_MAKEFILES="${CI_MAKEFILES:-"scripts/makefile.gcc"}" ;; ( * ) CI_MAKEFILES="${CI_MAKEFILES:-"scripts/makefile.std"}" ;; esac } function ci_trace_build { ci_info "## START OF CONFIGURATION ##" ci_info "build arch: $CI_BUILD_ARCH" ci_info "build system: $CI_BUILD_SYSTEM" [[ "$CI_TARGET_SYSTEM.$CI_TARGET_ARCH" != "$CI_BUILD_SYSTEM.$CI_BUILD_ARCH" ]] && { ci_info "target arch: $CI_TARGET_ARCH" ci_info "target system: $CI_TARGET_SYSTEM" } ci_info "source directory: $CI_SRC_DIR" ci_info "environment option: \$CI_MAKEFILES: '$CI_MAKEFILES'" ci_info "environment option: \$CI_MAKE: '$CI_MAKE'" ci_info "environment option: \$CI_MAKE_FLAGS: '$CI_MAKE_FLAGS'" ci_info "environment option: \$CI_MAKE_VARS: '$CI_MAKE_VARS'" ci_info "environment option: \$CI_CC: '$CI_CC'" ci_info "environment option: \$CI_CC_FLAGS: '$CI_CC_FLAGS'" ci_info "environment option: \$CI_CPP: '$CI_CPP'" ci_info "environment option: \$CI_CPP_FLAGS: '$CI_CPP_FLAGS'" ci_info "environment option: \$CI_AR: '$CI_AR'" ci_info "environment option: \$CI_RANLIB: '$CI_RANLIB'" ci_info "environment option: \$CI_LD: '$CI_LD'" ci_info "environment option: \$CI_LD_FLAGS: '$CI_LD_FLAGS'" ci_info "environment option: \$CI_LIBS: '$CI_LIBS'" ci_info "environment option: \$CI_SANITIZERS: '$CI_SANITIZERS'" ci_info "environment option: \$CI_FORCE: '$CI_FORCE'" ci_info "environment option: \$CI_NO_TEST: '$CI_NO_TEST'" ci_info "environment option: \$CI_NO_CLEAN: '$CI_NO_CLEAN'" ci_info "executable: \$CI_MAKE: $(command -V "$CI_MAKE")" [[ $CI_CC ]] && { ci_info "executable: \$CI_CC: $(command -V "$CI_CC")" } [[ $CI_CPP ]] && { ci_info "executable: \$CI_CPP: $(command -V "$CI_CPP")" } [[ $CI_AR ]] && { ci_info "executable: \$CI_AR: $(command -V "$CI_AR")" } [[ $CI_RANLIB ]] && { ci_info "executable: \$CI_RANLIB: $(command -V "$CI_RANLIB")" } [[ $CI_LD ]] && { ci_info "executable: \$CI_LD: $(command -V "$CI_LD")" } ci_info "## END OF CONFIGURATION ##" } function ci_cleanup_old_build { # Any old makefile-based build will most likely leave a mess # of object files behind if interrupted, e.g., via Ctrl+C. # There may be other files behind, depending on what makefile # had been used. We cannot easily enumerate all of those. # Fortunately, for a clean makefiles-based build, it should be # sufficient to remove the old object files only. ci_info "## START OF PRE-BUILD CLEANUP ##" local find_args=(-maxdepth 1 \( -iname "*.o" -o -iname "*.obj" \)) [[ ! $(find "$CI_SRC_DIR" "${find_args[@]}" | head -n1) ]] || { ci_warn "unexpected build found in '$CI_SRC_DIR'" if ci_expr $((CI_FORCE)) then # Delete the old build. local my_file find "$CI_SRC_DIR" "${find_args[@]}" | while IFS="" read -r my_file do ci_spawn rm -fr "$my_file" done ci_info "## END OF PRE-BUILD CLEANUP ##" else # Alert the user, but do not delete their existing files, # and do not mess up their existing build. ci_info "hint: consider using the option \$CI_FORCE=1" ci_err "unable to continue" fi } } function ci_build { ci_info "## START OF BUILD ##" # Initialize and populate the local arrays. local all_make_flags=() local all_make_vars=() [[ $CI_MAKE_FLAGS ]] && { all_make_flags+=($CI_MAKE_FLAGS) } [[ $CI_CC ]] && { all_make_vars+=("CC=$CI_CC") } [[ $CI_CC_FLAGS || $CI_SANITIZERS ]] && { [[ $CI_SANITIZERS ]] && CI_CC_FLAGS="${CI_CC_FLAGS:-"-O2"} -fsanitize=$CI_SANITIZERS" all_make_vars+=("CFLAGS=$CI_CC_FLAGS") } [[ $CI_CPP ]] && { all_make_vars+=("CPP=$CI_CPP") } [[ $CI_CPP_FLAGS ]] && { all_make_vars+=("CPPFLAGS=$CI_CPP_FLAGS") } [[ $CI_AR ]] && { all_make_vars+=("AR=$CI_AR") } [[ $CI_RANLIB ]] && { all_make_vars+=("RANLIB=$CI_RANLIB") } [[ $CI_LD ]] && { all_make_vars+=("LD=$CI_LD") } [[ $CI_LD_FLAGS || $CI_SANITIZERS ]] && { [[ $CI_SANITIZERS ]] && CI_LD_FLAGS+="${CI_LD_FLAGS:+" "}-fsanitize=$CI_SANITIZERS" all_make_vars+=("LDFLAGS=$CI_LD_FLAGS") } [[ $CI_LIBS ]] && { all_make_vars+=("LIBS=$CI_LIBS") } all_make_vars+=($CI_MAKE_VARS) # And... build! local my_makefile for my_makefile in $CI_MAKEFILES do ci_info "using makefile: $my_makefile" # Spawn "make". ci_spawn "$CI_MAKE" -f "$my_makefile" \ "${all_make_flags[@]}" \ "${all_make_vars[@]}" ci_expr $((CI_NO_TEST)) || { # Spawn "make test" if testing is not disabled. ci_spawn "$CI_MAKE" -f "$my_makefile" \ "${all_make_flags[@]}" \ "${all_make_vars[@]}" \ test } ci_expr $((CI_NO_CLEAN)) || { # Spawn "make clean" if cleaning is not disabled. ci_spawn "$CI_MAKE" -f "$my_makefile" \ "${all_make_flags[@]}" \ "${all_make_vars[@]}" \ clean } done ci_info "## END OF BUILD ##" } function usage { echo "usage: $CI_SCRIPT_NAME []" echo "options: -?|-h|--help" exit "${@:-0}" } function main { local opt while getopts ":" opt do # This ain't a while-loop. It only pretends to be. [[ $1 == -[?h]* || $1 == --help || $1 == --help=* ]] && usage 0 ci_err "unknown option: '$1'" done shift $((OPTIND - 1)) # And... go! ci_init_build ci_trace_build [[ $# -eq 0 ]] || { echo >&2 "error: unexpected argument: '$1'" echo >&2 "note: this program accepts environment options only" usage 2 } ci_cleanup_old_build ci_build } main "$@" libpng-1.6.43/ci/ci_verify_version.sh000077500000000000000000000132271456606525400175600ustar00rootroot00000000000000#!/usr/bin/env bash set -o errexit -o pipefail -o posix # Copyright (c) 2019-2024 Cosmin Truta. # # Use, modification and distribution are subject to the MIT License. # Please see the accompanying file LICENSE_MIT.txt # # SPDX-License-Identifier: MIT # shellcheck source=ci/lib/ci.lib.sh source "$(dirname "$0")/lib/ci.lib.sh" cd "$CI_TOPLEVEL_DIR" function ci_init_shellify { [[ -f $CI_SCRIPT_DIR/ci_shellify.sh ]] || { ci_err_internal "missing script: '$CI_SCRIPT_DIR/ci_shellify.sh'" } } function ci_run_shellify { ci_info "shellifying:" "$@" local my_result "$BASH" "$CI_SCRIPT_DIR/ci_shellify.sh" "$@" echo "$my_result" | "$BASH" --posix || ci_err "bad shellify output" echo "$my_result" } function ci_verify_version { ci_info "## START OF VERIFICATION ##" local my_env_libpng_ver my_env_autoconf_ver my_env_cmake_ver my_expect ci_init_shellify my_env_libpng_ver="$(ci_run_shellify png.h)" echo "$my_env_libpng_ver" my_env_autoconf_ver="$(ci_run_shellify configure.ac)" echo "$my_env_autoconf_ver" my_env_cmake_ver="$(ci_run_shellify CMakeLists.txt)" echo "$my_env_cmake_ver" ci_info "## VERIFYING: png.h version definitions ##" eval "$my_env_libpng_ver" local my_expect="${PNG_LIBPNG_VER_MAJOR}.${PNG_LIBPNG_VER_MINOR}.${PNG_LIBPNG_VER_RELEASE}" if [[ "$PNG_LIBPNG_VER_STRING" == "$my_expect"* ]] then ci_info "matched: \$PNG_LIBPNG_VER_STRING == $my_expect*" else ci_err "mismatched: \$PNG_LIBPNG_VER_STRING != $my_expect*" fi my_expect=$((PNG_LIBPNG_VER_MAJOR*10000 + PNG_LIBPNG_VER_MINOR*100 + PNG_LIBPNG_VER_RELEASE)) if [[ "$PNG_LIBPNG_VER" == "$my_expect" ]] then ci_info "matched: \$PNG_LIBPNG_VER == $my_expect" else ci_err "mismatched: \$PNG_LIBPNG_VER != $my_expect" fi my_expect=$((PNG_LIBPNG_VER_MAJOR*10 + PNG_LIBPNG_VER_MINOR)) if [[ "$PNG_LIBPNG_VER_SHAREDLIB" == "$my_expect" ]] then ci_info "matched: \$PNG_LIBPNG_VER_SHAREDLIB == $my_expect" else ci_err "mismatched: \$PNG_LIBPNG_VER_SHAREDLIB != $my_expect" fi if [[ "$PNG_LIBPNG_VER_SONUM" == "$my_expect" ]] then ci_info "matched: \$PNG_LIBPNG_VER_SONUM == $my_expect" else ci_err "mismatched: \$PNG_LIBPNG_VER_SONUM != $my_expect" fi if [[ "$PNG_LIBPNG_VER_DLLNUM" == "$my_expect" ]] then ci_info "matched: \$PNG_LIBPNG_VER_DLLNUM == $my_expect" else ci_err "mismatched: \$PNG_LIBPNG_VER_DLLNUM != $my_expect" fi if [[ "$PNG_LIBPNG_VER_BUILD" == [01] ]] then ci_info "matched: \$PNG_LIBPNG_VER_BUILD == [01]" else ci_err "mismatched: \$PNG_LIBPNG_VER_BUILD != [01]" fi ci_info "## VERIFYING: png.h build definitions ##" my_expect="${PNG_LIBPNG_VER_MAJOR}.${PNG_LIBPNG_VER_MINOR}.${PNG_LIBPNG_VER_RELEASE}" if [[ "$PNG_LIBPNG_VER_STRING" == "$my_expect" ]] then if [[ $PNG_LIBPNG_VER_BUILD -eq 0 ]] then ci_info "matched: \$PNG_LIBPNG_VER_BUILD -eq 0" else ci_err "mismatched: \$PNG_LIBPNG_VER_BUILD -ne 0" fi if [[ $PNG_LIBPNG_BUILD_BASE_TYPE -eq $PNG_LIBPNG_BUILD_STABLE ]] then ci_info "matched: \$PNG_LIBPNG_BUILD_BASE_TYPE -eq \$PNG_LIBPNG_BUILD_BETA" else ci_err "mismatched: \$PNG_LIBPNG_BUILD_BASE_TYPE -ne \$PNG_LIBPNG_BUILD_BETA" fi elif [[ "$PNG_LIBPNG_VER_STRING" == "$my_expect".git ]] then if [[ $PNG_LIBPNG_VER_BUILD -ne 0 ]] then ci_info "matched: \$PNG_LIBPNG_VER_BUILD -ne 0" else ci_err "mismatched: \$PNG_LIBPNG_VER_BUILD -eq 0" fi if [[ $PNG_LIBPNG_BUILD_BASE_TYPE -eq $PNG_LIBPNG_BUILD_BETA ]] then ci_info "matched: \$PNG_LIBPNG_BUILD_BASE_TYPE -eq \$PNG_LIBPNG_BUILD_BETA" else ci_err "mismatched: \$PNG_LIBPNG_BUILD_BASE_TYPE -ne \$PNG_LIBPNG_BUILD_BETA" fi else ci_err "unexpected: \$PNG_LIBPNG_VER_STRING == '$PNG_LIBPNG_VER_STRING'" fi ci_info "## VERIFYING: png.h type definitions ##" my_expect="$(echo "png_libpng_version_${PNG_LIBPNG_VER_STRING}" | tr . _)" ci_spawn grep -w -e "$my_expect" png.h ci_info "## VERIFYING: configure.ac version definitions ##" eval "$my_env_autoconf_ver" if [[ "$PNGLIB_VERSION" == "$PNG_LIBPNG_VER_STRING" ]] then ci_info "matched: \$PNGLIB_VERSION == \$PNG_LIBPNG_VER_STRING" else ci_err "mismatched: \$PNGLIB_VERSION != \$PNG_LIBPNG_VER_STRING" fi ci_info "## VERIFYING: CMakeLists.txt version definitions ##" eval "$my_env_cmake_ver" if [[ "$PNGLIB_VERSION" == "$PNG_LIBPNG_VER_STRING" && "$PNGLIB_SUBREVISION" == 0 ]] then ci_info "matched: \$PNGLIB_VERSION == \$PNG_LIBPNG_VER_STRING" ci_info "matched: \$PNGLIB_SUBREVISION == 0" elif [[ "$PNGLIB_VERSION.$PNGLIB_SUBREVISION" == "$PNG_LIBPNG_VER_STRING" ]] then ci_info "matched: \$PNGLIB_VERSION.\$PNGLIB_SUBREVISION == \$PNG_LIBPNG_VER_STRING" else ci_err "mismatched: \$PNGLIB_VERSION != \$PNG_LIBPNG_VER_STRING" fi ci_info "## END OF VERIFICATION ##" ci_info "success!" } function usage { echo "usage: $CI_SCRIPT_NAME []" echo "options: -?|-h|--help" exit "${@:-0}" } function main { local opt while getopts ":" opt do # This ain't a while-loop. It only pretends to be. [[ $1 == -[?h]* || $1 == --help || $1 == --help=* ]] && usage 0 ci_err "unknown option: '$1'" done shift $((OPTIND - 1)) [[ $# -eq 0 ]] || { echo >&2 "error: unexpected argument: '$1'" usage 2 } # And... go! ci_verify_version } main "$@" libpng-1.6.43/ci/lib/000077500000000000000000000000001456606525400142365ustar00rootroot00000000000000libpng-1.6.43/ci/lib/ci.lib.sh000066400000000000000000000062201456606525400157320ustar00rootroot00000000000000# Copyright (c) 2019-2024 Cosmin Truta. # # Use, modification and distribution are subject to the MIT License. # Please see the accompanying file LICENSE_MIT.txt # # SPDX-License-Identifier: MIT test -f "$BASH_SOURCE" || { echo >&2 "warning: this module requires Bash version 3 or newer" } test "${#BASH_SOURCE[@]}" -gt 1 || { echo >&2 "warning: this module should be sourced from a Bash script" } # Reset the locale to avoid surprises from locale-dependent commands. export LC_ALL=C export LANG=C export LANGUAGE=C # Reset CDPATH to avoid surprises from the "cd" command. export CDPATH="" # Initialize the global constants CI_SCRIPT_{NAME,DIR} and CI_TOPLEVEL_DIR. CI_SCRIPT_NAME="$(basename -- "$0")" CI_SCRIPT_DIR="$(cd "$(dirname -- "$0")" && pwd)" CI_TOPLEVEL_DIR="$(cd "$(dirname -- "${BASH_SOURCE[0]}")/../.." && pwd)" # Initialize the global constants CI_BUILD_{...} for the host build platform. CI_BUILD_ARCH="${CI_BUILD_ARCH:-"$(uname -m | tr 'A-Z/\.-' 'a-z____')"}" CI_BUILD_SYSTEM="${CI_BUILD_SYSTEM:-"$(uname -s | tr 'A-Z/\.-' 'a-z____')"}" # Initialize the global constants CI_TARGET_{...} for the target platform. CI_TARGET_ARCH="${CI_TARGET_ARCH:-"$CI_BUILD_ARCH"}" CI_TARGET_SYSTEM="${CI_TARGET_SYSTEM:-"$CI_BUILD_SYSTEM"}" function ci_info { printf >&2 "%s: %s\\n" "$CI_SCRIPT_NAME" "$*" } function ci_warn { printf >&2 "%s: warning: %s\\n" "$CI_SCRIPT_NAME" "$*" } function ci_err { printf >&2 "%s: error: %s\\n" "$CI_SCRIPT_NAME" "$*" exit 2 } function ci_err_internal { printf >&2 "%s: internal error: %s\\n" "$CI_SCRIPT_NAME" "$*" printf >&2 "ABORTED\\n" # Exit with the conventional SIGABRT code. exit 134 } function ci_expr { if [[ ${*:-0} == [0-9] ]] then # This is the same as in the else-branch below, albeit much faster # for our intended use cases. return $((!$1)) else # The funny-looking compound command "... && return $? || return $?" # allows the execution to continue uninterrupted under "set -e". expr >/dev/null "$@" && return $? || return $? fi } function ci_spawn { printf >&2 "%s: executing:" "$CI_SCRIPT_NAME" printf >&2 " %q" "$@" printf >&2 "\\n" "$@" } # Ensure that the internal initialization is correct. [[ $CI_TOPLEVEL_DIR/ci/lib/ci.lib.sh -ef ${BASH_SOURCE[0]} ]] || { ci_err_internal "bad or missing \$CI_TOPLEVEL_DIR" } [[ $CI_SCRIPT_DIR/$CI_SCRIPT_NAME -ef $0 ]] || { ci_err_internal "bad or missing \$CI_SCRIPT_DIR/\$CI_SCRIPT_NAME" } [[ $CI_BUILD_ARCH && $CI_BUILD_SYSTEM ]] || { ci_err_internal "missing \$CI_BUILD_ARCH or \$CI_BUILD_SYSTEM" } [[ $CI_TARGET_ARCH && $CI_TARGET_SYSTEM ]] || { ci_err_internal "missing \$CI_TARGET_ARCH or \$CI_TARGET_SYSTEM" } # Ensure that the user initialization is correct. [[ ${CI_FORCE:-0} == [01] ]] || { ci_err "bad boolean option: \$CI_FORCE: '$CI_FORCE'" } [[ ${CI_NO_TEST:-0} == [01] ]] || { ci_err "bad boolean option: \$CI_NO_TEST: '$CI_NO_TEST'" } [[ ${CI_NO_INSTALL:-0} == [01] ]] || { ci_err "bad boolean option: \$CI_NO_INSTALL: '$CI_NO_INSTALL'" } [[ ${CI_NO_CLEAN:-0} == [01] ]] || { ci_err "bad boolean option: \$CI_NO_CLEAN: '$CI_NO_CLEAN'" } libpng-1.6.43/compile000077500000000000000000000163501456606525400144600ustar00rootroot00000000000000#! /bin/sh # Wrapper for compilers which do not understand '-c -o'. scriptversion=2018-03-07.03; # UTC # Copyright (C) 1999-2021 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . nl=' ' # We need space, tab and new line, in precisely that order. Quoting is # there to prevent tools from complaining about whitespace usage. IFS=" "" $nl" file_conv= # func_file_conv build_file lazy # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. If the determined conversion # type is listed in (the comma separated) LAZY, no conversion will # take place. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN* | MSYS*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv/,$2, in *,$file_conv,*) ;; mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin/* | msys/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_cl_dashL linkdir # Make cl look for libraries in LINKDIR func_cl_dashL () { func_file_conv "$1" if test -z "$lib_path"; then lib_path=$file else lib_path="$lib_path;$file" fi linker_opts="$linker_opts -LIBPATH:$file" } # func_cl_dashl library # Do a library search-path lookup for cl func_cl_dashl () { lib=$1 found=no save_IFS=$IFS IFS=';' for dir in $lib_path $LIB do IFS=$save_IFS if $shared && test -f "$dir/$lib.dll.lib"; then found=yes lib=$dir/$lib.dll.lib break fi if test -f "$dir/$lib.lib"; then found=yes lib=$dir/$lib.lib break fi if test -f "$dir/lib$lib.a"; then found=yes lib=$dir/lib$lib.a break fi done IFS=$save_IFS if test "$found" != yes; then lib=$lib.lib fi } # func_cl_wrapper cl arg... # Adjust compile command to suit cl func_cl_wrapper () { # Assume a capable shell lib_path= shared=: linker_opts= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. eat=1 case $2 in *.o | *.[oO][bB][jJ]) func_file_conv "$2" set x "$@" -Fo"$file" shift ;; *) func_file_conv "$2" set x "$@" -Fe"$file" shift ;; esac ;; -I) eat=1 func_file_conv "$2" mingw set x "$@" -I"$file" shift ;; -I*) func_file_conv "${1#-I}" mingw set x "$@" -I"$file" shift ;; -l) eat=1 func_cl_dashl "$2" set x "$@" "$lib" shift ;; -l*) func_cl_dashl "${1#-l}" set x "$@" "$lib" shift ;; -L) eat=1 func_cl_dashL "$2" ;; -L*) func_cl_dashL "${1#-L}" ;; -static) shared=false ;; -Wl,*) arg=${1#-Wl,} save_ifs="$IFS"; IFS=',' for flag in $arg; do IFS="$save_ifs" linker_opts="$linker_opts $flag" done IFS="$save_ifs" ;; -Xlinker) eat=1 linker_opts="$linker_opts $2" ;; -*) set x "$@" "$1" shift ;; *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) func_file_conv "$1" set x "$@" -Tp"$file" shift ;; *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) func_file_conv "$1" mingw set x "$@" "$file" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -n "$linker_opts"; then linker_opts="-link$linker_opts" fi exec "$@" $linker_opts exit 1 } eat= case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] Wrapper for compilers which do not understand '-c -o'. Remove '-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the right script to run: please start by reading the file 'INSTALL'. Report bugs to . EOF exit $? ;; -v | --v*) echo "compile $scriptversion" exit $? ;; cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \ icl | *[/\\]icl | icl.exe | *[/\\]icl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac ofile= cfile= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. # So we strip '-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) ofile=$2 ;; *) set x "$@" -o "$2" shift ;; esac ;; *.c) cfile=$1 set x "$@" "$1" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -z "$ofile" || test -z "$cfile"; then # If no '-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no # '.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi # Name of file we expect compiler to create. cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. # Note: use '[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d while true; do if mkdir "$lockdir" >/dev/null 2>&1; then break fi sleep 1 done # FIXME: race condition here if user kills between mkdir and trap. trap "rmdir '$lockdir'; exit 1" 1 2 15 # Run the compile. "$@" ret=$? if test -f "$cofile"; then test "$cofile" = "$ofile" || mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" fi rmdir "$lockdir" exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: libpng-1.6.43/config.guess000077500000000000000000001426761456606525400154350ustar00rootroot00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2023 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale timestamp='2023-08-22' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: # https://git.savannah.gnu.org/cgit/config.git/plain/config.guess # # Please send patches to . # The "shellcheck disable" line above the timestamp inhibits complaints # about features and limitations of the classic Bourne shell that were # superseded or lifted in POSIX. However, this script identifies a wide # variety of pre-POSIX systems that do not have POSIX shells at all, and # even some reasonably current systems (Solaris 10 as case-in-point) still # have a pre-POSIX /bin/sh. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system '$me' is run on. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2023 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try '$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi # Just in case it came from the environment. GUESS= # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, 'CC_FOR_BUILD' used to be named 'HOST_CC'. We still # use 'HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. tmp= # shellcheck disable=SC2172 trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 set_cc_for_build() { # prevent multiple calls if $tmp is already set test "$tmp" && return 0 : "${TMPDIR=/tmp}" # shellcheck disable=SC2039,SC3028 { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } dummy=$tmp/dummy case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in ,,) echo "int x;" > "$dummy.c" for driver in cc gcc c89 c99 ; do if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then CC_FOR_BUILD=$driver break fi done if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac } # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if test -f /.attbin/uname ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case $UNAME_SYSTEM in Linux|GNU|GNU/*) LIBC=unknown set_cc_for_build cat <<-EOF > "$dummy.c" #if defined(__ANDROID__) LIBC=android #else #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #elif defined(__GLIBC__) LIBC=gnu #else #include /* First heuristic to detect musl libc. */ #ifdef __DEFINED_va_list LIBC=musl #endif #endif #endif EOF cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` eval "$cc_set_libc" # Second heuristic to detect musl libc. if [ "$LIBC" = unknown ] && command -v ldd >/dev/null && ldd --version 2>&1 | grep -q ^musl; then LIBC=musl fi # If the system lacks a compiler, then just pick glibc. # We could probably try harder. if [ "$LIBC" = unknown ]; then LIBC=gnu fi ;; esac # Note: order is significant - the case branches are not exclusive. case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ /sbin/sysctl -n hw.machine_arch 2>/dev/null || \ /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \ echo unknown)` case $UNAME_MACHINE_ARCH in aarch64eb) machine=aarch64_be-unknown ;; armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` machine=${arch}${endian}-unknown ;; *) machine=$UNAME_MACHINE_ARCH-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently (or will in the future) and ABI. case $UNAME_MACHINE_ARCH in earm*) os=netbsdelf ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # Determine ABI tags. case $UNAME_MACHINE_ARCH in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case $UNAME_VERSION in Debian*) release='-gnu' ;; *) release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. GUESS=$machine-${os}${release}${abi-} ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE ;; *:SecBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE ;; *:LibertyBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE ;; *:MidnightBSD:*:*) GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE ;; *:ekkoBSD:*:*) GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE ;; *:SolidBSD:*:*) GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE ;; *:OS108:*:*) GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE ;; macppc:MirBSD:*:*) GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE ;; *:MirBSD:*:*) GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE ;; *:Sortix:*:*) GUESS=$UNAME_MACHINE-unknown-sortix ;; *:Twizzler:*:*) GUESS=$UNAME_MACHINE-unknown-twizzler ;; *:Redox:*:*) GUESS=$UNAME_MACHINE-unknown-redox ;; mips:OSF1:*.*) GUESS=mips-dec-osf1 ;; alpha:OSF1:*:*) # Reset EXIT trap before exiting to avoid spurious non-zero exit code. trap '' 0 case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case $ALPHA_CPU_TYPE in "EV4 (21064)") UNAME_MACHINE=alpha ;; "EV4.5 (21064)") UNAME_MACHINE=alpha ;; "LCA4 (21066/21068)") UNAME_MACHINE=alpha ;; "EV5 (21164)") UNAME_MACHINE=alphaev5 ;; "EV5.6 (21164A)") UNAME_MACHINE=alphaev56 ;; "EV5.6 (21164PC)") UNAME_MACHINE=alphapca56 ;; "EV5.7 (21164PC)") UNAME_MACHINE=alphapca57 ;; "EV6 (21264)") UNAME_MACHINE=alphaev6 ;; "EV6.7 (21264A)") UNAME_MACHINE=alphaev67 ;; "EV6.8CB (21264C)") UNAME_MACHINE=alphaev68 ;; "EV6.8AL (21264B)") UNAME_MACHINE=alphaev68 ;; "EV6.8CX (21264D)") UNAME_MACHINE=alphaev68 ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE=alphaev69 ;; "EV7 (21364)") UNAME_MACHINE=alphaev7 ;; "EV7.9 (21364A)") UNAME_MACHINE=alphaev79 ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` GUESS=$UNAME_MACHINE-dec-osf$OSF_REL ;; Amiga*:UNIX_System_V:4.0:*) GUESS=m68k-unknown-sysv4 ;; *:[Aa]miga[Oo][Ss]:*:*) GUESS=$UNAME_MACHINE-unknown-amigaos ;; *:[Mm]orph[Oo][Ss]:*:*) GUESS=$UNAME_MACHINE-unknown-morphos ;; *:OS/390:*:*) GUESS=i370-ibm-openedition ;; *:z/VM:*:*) GUESS=s390-ibm-zvmoe ;; *:OS400:*:*) GUESS=powerpc-ibm-os400 ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) GUESS=arm-acorn-riscix$UNAME_RELEASE ;; arm*:riscos:*:*|arm*:RISCOS:*:*) GUESS=arm-unknown-riscos ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) GUESS=hppa1.1-hitachi-hiuxmpp ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. case `(/bin/universe) 2>/dev/null` in att) GUESS=pyramid-pyramid-sysv3 ;; *) GUESS=pyramid-pyramid-bsd ;; esac ;; NILE*:*:*:dcosx) GUESS=pyramid-pyramid-svr4 ;; DRS?6000:unix:4.0:6*) GUESS=sparc-icl-nx6 ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) GUESS=sparc-icl-nx7 ;; esac ;; s390x:SunOS:*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL ;; sun4H:SunOS:5.*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=sparc-hal-solaris2$SUN_REL ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=sparc-sun-solaris2$SUN_REL ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) GUESS=i386-pc-auroraux$UNAME_RELEASE ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) set_cc_for_build SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -m64 -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH=x86_64 fi fi SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=$SUN_ARCH-pc-solaris2$SUN_REL ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=sparc-sun-solaris3$SUN_REL ;; sun4*:SunOS:*:*) case `/usr/bin/arch -k` in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like '4.1.3-JL'. SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'` GUESS=sparc-sun-sunos$SUN_REL ;; sun3*:SunOS:*:*) GUESS=m68k-sun-sunos$UNAME_RELEASE ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 case `/bin/arch` in sun3) GUESS=m68k-sun-sunos$UNAME_RELEASE ;; sun4) GUESS=sparc-sun-sunos$UNAME_RELEASE ;; esac ;; aushp:SunOS:*:*) GUESS=sparc-auspex-sunos$UNAME_RELEASE ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) GUESS=m68k-atari-mint$UNAME_RELEASE ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) GUESS=m68k-atari-mint$UNAME_RELEASE ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) GUESS=m68k-atari-mint$UNAME_RELEASE ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) GUESS=m68k-milan-mint$UNAME_RELEASE ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) GUESS=m68k-hades-mint$UNAME_RELEASE ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) GUESS=m68k-unknown-mint$UNAME_RELEASE ;; m68k:machten:*:*) GUESS=m68k-apple-machten$UNAME_RELEASE ;; powerpc:machten:*:*) GUESS=powerpc-apple-machten$UNAME_RELEASE ;; RISC*:Mach:*:*) GUESS=mips-dec-mach_bsd4.3 ;; RISC*:ULTRIX:*:*) GUESS=mips-dec-ultrix$UNAME_RELEASE ;; VAX*:ULTRIX*:*:*) GUESS=vax-dec-ultrix$UNAME_RELEASE ;; 2020:CLIX:*:* | 2430:CLIX:*:*) GUESS=clipper-intergraph-clix$UNAME_RELEASE ;; mips:*:*:UMIPS | mips:*:*:RISCos) set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`"$dummy" "$dummyarg"` && { echo "$SYSTEM_NAME"; exit; } GUESS=mips-mips-riscos$UNAME_RELEASE ;; Motorola:PowerMAX_OS:*:*) GUESS=powerpc-motorola-powermax ;; Motorola:*:4.3:PL8-*) GUESS=powerpc-harris-powermax ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) GUESS=powerpc-harris-powermax ;; Night_Hawk:Power_UNIX:*:*) GUESS=powerpc-harris-powerunix ;; m88k:CX/UX:7*:*) GUESS=m88k-harris-cxux7 ;; m88k:*:4*:R4*) GUESS=m88k-motorola-sysv4 ;; m88k:*:3*:R3*) GUESS=m88k-motorola-sysv3 ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110 then if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \ test "$TARGET_BINARY_INTERFACE"x = x then GUESS=m88k-dg-dgux$UNAME_RELEASE else GUESS=m88k-dg-dguxbcs$UNAME_RELEASE fi else GUESS=i586-dg-dgux$UNAME_RELEASE fi ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) GUESS=m88k-dolphin-sysv3 ;; M88*:*:R3*:*) # Delta 88k system running SVR3 GUESS=m88k-motorola-sysv3 ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) GUESS=m88k-tektronix-sysv3 ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) GUESS=m68k-tektronix-bsd ;; *:IRIX*:*:*) IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'` GUESS=mips-sgi-irix$IRIX_REL ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. GUESS=romp-ibm-aix # uname -m gives an 8 hex-code CPU id ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) GUESS=i386-ibm-aix ;; ia64:AIX:*:*) if test -x /usr/bin/oslevel ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=$UNAME_VERSION.$UNAME_RELEASE fi GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` then GUESS=$SYSTEM_NAME else GUESS=rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then GUESS=rs6000-ibm-aix3.2.4 else GUESS=rs6000-ibm-aix3.2 fi ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if test -x /usr/bin/lslpp ; then IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \ awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else IBM_REV=$UNAME_VERSION.$UNAME_RELEASE fi GUESS=$IBM_ARCH-ibm-aix$IBM_REV ;; *:AIX:*:*) GUESS=rs6000-ibm-aix ;; ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) GUESS=romp-ibm-bsd4.4 ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and GUESS=romp-ibm-bsd$UNAME_RELEASE # 4.3 with uname added to ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) GUESS=rs6000-bull-bosx ;; DPX/2?00:B.O.S.:*:*) GUESS=m68k-bull-sysv3 ;; 9000/[34]??:4.3bsd:1.*:*) GUESS=m68k-hp-bsd ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) GUESS=m68k-hp-bsd4.4 ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` case $UNAME_MACHINE in 9000/31?) HP_ARCH=m68000 ;; 9000/[34]??) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if test -x /usr/bin/getconf; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case $sc_cpu_version in 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case $sc_kernel_bits in 32) HP_ARCH=hppa2.0n ;; 64) HP_ARCH=hppa2.0w ;; '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi if test "$HP_ARCH" = ""; then set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if test "$HP_ARCH" = hppa2.0w then set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH=hppa2.0w else HP_ARCH=hppa64 fi fi GUESS=$HP_ARCH-hp-hpux$HPUX_REV ;; ia64:HP-UX:*:*) HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` GUESS=ia64-hp-hpux$HPUX_REV ;; 3050*:HI-UX:*:*) set_cc_for_build sed 's/^ //' << EOF > "$dummy.c" #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } GUESS=unknown-hitachi-hiuxwe2 ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) GUESS=hppa1.1-hp-bsd ;; 9000/8??:4.3bsd:*:*) GUESS=hppa1.0-hp-bsd ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) GUESS=hppa1.0-hp-mpeix ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) GUESS=hppa1.1-hp-osf ;; hp8??:OSF1:*:*) GUESS=hppa1.0-hp-osf ;; i*86:OSF1:*:*) if test -x /usr/sbin/sysversion ; then GUESS=$UNAME_MACHINE-unknown-osf1mk else GUESS=$UNAME_MACHINE-unknown-osf1 fi ;; parisc*:Lites*:*:*) GUESS=hppa1.1-hp-lites ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) GUESS=c1-convex-bsd ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) GUESS=c34-convex-bsd ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) GUESS=c38-convex-bsd ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) GUESS=c4-convex-bsd ;; CRAY*Y-MP:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=ymp-cray-unicos$CRAY_REL ;; CRAY*[A-Z]90:*:*:*) echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=t90-cray-unicos$CRAY_REL ;; CRAY*T3E:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=alphaev5-cray-unicosmk$CRAY_REL ;; CRAY*SV1:*:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=sv1-cray-unicos$CRAY_REL ;; *:UNICOS/mp:*:*) CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` GUESS=craynv-cray-unicosmp$CRAY_REL ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE ;; sparc*:BSD/OS:*:*) GUESS=sparc-unknown-bsdi$UNAME_RELEASE ;; *:BSD/OS:*:*) GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE ;; arm:FreeBSD:*:*) UNAME_PROCESSOR=`uname -p` set_cc_for_build if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi else FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf fi ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`uname -p` case $UNAME_PROCESSOR in amd64) UNAME_PROCESSOR=x86_64 ;; i386) UNAME_PROCESSOR=i586 ;; esac FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL ;; i*:CYGWIN*:*) GUESS=$UNAME_MACHINE-pc-cygwin ;; *:MINGW64*:*) GUESS=$UNAME_MACHINE-pc-mingw64 ;; *:MINGW*:*) GUESS=$UNAME_MACHINE-pc-mingw32 ;; *:MSYS*:*) GUESS=$UNAME_MACHINE-pc-msys ;; i*:PW*:*) GUESS=$UNAME_MACHINE-pc-pw32 ;; *:SerenityOS:*:*) GUESS=$UNAME_MACHINE-pc-serenity ;; *:Interix*:*) case $UNAME_MACHINE in x86) GUESS=i586-pc-interix$UNAME_RELEASE ;; authenticamd | genuineintel | EM64T) GUESS=x86_64-unknown-interix$UNAME_RELEASE ;; IA64) GUESS=ia64-unknown-interix$UNAME_RELEASE ;; esac ;; i*:UWIN*:*) GUESS=$UNAME_MACHINE-pc-uwin ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) GUESS=x86_64-pc-cygwin ;; prep*:SunOS:5.*:*) SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` GUESS=powerpcle-unknown-solaris2$SUN_REL ;; *:GNU:*:*) # the GNU system GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'` GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'` GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL ;; *:GNU/*:*:*) # other systems with GNU libc and userland GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"` GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC ;; x86_64:[Mm]anagarm:*:*|i?86:[Mm]anagarm:*:*) GUESS="$UNAME_MACHINE-pc-managarm-mlibc" ;; *:[Mm]anagarm:*:*) GUESS="$UNAME_MACHINE-unknown-managarm-mlibc" ;; *:Minix:*:*) GUESS=$UNAME_MACHINE-unknown-minix ;; aarch64:Linux:*:*) set_cc_for_build CPU=$UNAME_MACHINE LIBCABI=$LIBC if test "$CC_FOR_BUILD" != no_compiler_found; then ABI=64 sed 's/^ //' << EOF > "$dummy.c" #ifdef __ARM_EABI__ #ifdef __ARM_PCS_VFP ABI=eabihf #else ABI=eabi #endif #endif EOF cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'` eval "$cc_set_abi" case $ABI in eabi | eabihf) CPU=armv8l; LIBCABI=$LIBC$ABI ;; esac fi GUESS=$CPU-unknown-linux-$LIBCABI ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC=gnulibc1 ; fi GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; arm*:Linux:*:*) set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then GUESS=$UNAME_MACHINE-unknown-linux-$LIBC else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi else GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf fi fi ;; avr32*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; cris:Linux:*:*) GUESS=$UNAME_MACHINE-axis-linux-$LIBC ;; crisv32:Linux:*:*) GUESS=$UNAME_MACHINE-axis-linux-$LIBC ;; e2k:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; frv:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; hexagon:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; i*86:Linux:*:*) GUESS=$UNAME_MACHINE-pc-linux-$LIBC ;; ia64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; k1om:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; kvx:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; kvx:cos:*:*) GUESS=$UNAME_MACHINE-unknown-cos ;; kvx:mbr:*:*) GUESS=$UNAME_MACHINE-unknown-mbr ;; loongarch32:Linux:*:* | loongarch64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; m32r*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; m68*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; mips:Linux:*:* | mips64:Linux:*:*) set_cc_for_build IS_GLIBC=0 test x"${LIBC}" = xgnu && IS_GLIBC=1 sed 's/^ //' << EOF > "$dummy.c" #undef CPU #undef mips #undef mipsel #undef mips64 #undef mips64el #if ${IS_GLIBC} && defined(_ABI64) LIBCABI=gnuabi64 #else #if ${IS_GLIBC} && defined(_ABIN32) LIBCABI=gnuabin32 #else LIBCABI=${LIBC} #endif #endif #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 CPU=mipsisa64r6 #else #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 CPU=mipsisa32r6 #else #if defined(__mips64) CPU=mips64 #else CPU=mips #endif #endif #endif #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) MIPS_ENDIAN=el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) MIPS_ENDIAN= #else MIPS_ENDIAN= #endif #endif EOF cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'` eval "$cc_set_vars" test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } ;; mips64el:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; openrisc*:Linux:*:*) GUESS=or1k-unknown-linux-$LIBC ;; or32:Linux:*:* | or1k*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; padre:Linux:*:*) GUESS=sparc-unknown-linux-$LIBC ;; parisc64:Linux:*:* | hppa64:Linux:*:*) GUESS=hppa64-unknown-linux-$LIBC ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;; PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;; *) GUESS=hppa-unknown-linux-$LIBC ;; esac ;; ppc64:Linux:*:*) GUESS=powerpc64-unknown-linux-$LIBC ;; ppc:Linux:*:*) GUESS=powerpc-unknown-linux-$LIBC ;; ppc64le:Linux:*:*) GUESS=powerpc64le-unknown-linux-$LIBC ;; ppcle:Linux:*:*) GUESS=powerpcle-unknown-linux-$LIBC ;; riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; s390:Linux:*:* | s390x:Linux:*:*) GUESS=$UNAME_MACHINE-ibm-linux-$LIBC ;; sh64*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; sh*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; sparc:Linux:*:* | sparc64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; tile*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; vax:Linux:*:*) GUESS=$UNAME_MACHINE-dec-linux-$LIBC ;; x86_64:Linux:*:*) set_cc_for_build CPU=$UNAME_MACHINE LIBCABI=$LIBC if test "$CC_FOR_BUILD" != no_compiler_found; then ABI=64 sed 's/^ //' << EOF > "$dummy.c" #ifdef __i386__ ABI=x86 #else #ifdef __ILP32__ ABI=x32 #endif #endif EOF cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'` eval "$cc_set_abi" case $ABI in x86) CPU=i686 ;; x32) LIBCABI=${LIBC}x32 ;; esac fi GUESS=$CPU-pc-linux-$LIBCABI ;; xtensa*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. GUESS=i386-sequent-sysv4 ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION ;; i*86:OS/2:*:*) # If we were able to find 'uname', then EMX Unix compatibility # is probably installed. GUESS=$UNAME_MACHINE-pc-os2-emx ;; i*86:XTS-300:*:STOP) GUESS=$UNAME_MACHINE-unknown-stop ;; i*86:atheos:*:*) GUESS=$UNAME_MACHINE-unknown-atheos ;; i*86:syllable:*:*) GUESS=$UNAME_MACHINE-pc-syllable ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) GUESS=i386-unknown-lynxos$UNAME_RELEASE ;; i*86:*DOS:*:*) GUESS=$UNAME_MACHINE-pc-msdosdjgpp ;; i*86:*:4.*:*) UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL else GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL fi ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL else GUESS=$UNAME_MACHINE-pc-sysv32 fi ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. GUESS=i586-pc-msdosdjgpp ;; Intel:Mach:3*:*) GUESS=i386-pc-mach3 ;; paragon:*:*:*) GUESS=i860-intel-osf1 ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then GUESS=i860-stardent-sysv$UNAME_RELEASE # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. GUESS=i860-unknown-sysv$UNAME_RELEASE # Unknown i860-SVR4 fi ;; mini*:CTIX:SYS*5:*) # "miniframe" GUESS=m68010-convergent-sysv ;; mc68k:UNIX:SYSTEM5:3.51m) GUESS=m68k-convergent-sysv ;; M680?0:D-NIX:5.3:*) GUESS=m68k-diab-dnix ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) GUESS=m68k-unknown-lynxos$UNAME_RELEASE ;; mc68030:UNIX_System_V:4.*:*) GUESS=m68k-atari-sysv4 ;; TSUNAMI:LynxOS:2.*:*) GUESS=sparc-unknown-lynxos$UNAME_RELEASE ;; rs6000:LynxOS:2.*:*) GUESS=rs6000-unknown-lynxos$UNAME_RELEASE ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) GUESS=powerpc-unknown-lynxos$UNAME_RELEASE ;; SM[BE]S:UNIX_SV:*:*) GUESS=mips-dde-sysv$UNAME_RELEASE ;; RM*:ReliantUNIX-*:*:*) GUESS=mips-sni-sysv4 ;; RM*:SINIX-*:*:*) GUESS=mips-sni-sysv4 ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` GUESS=$UNAME_MACHINE-sni-sysv4 else GUESS=ns32k-sni-sysv fi ;; PENTIUM:*:4.0*:*) # Unisys 'ClearPath HMP IX 4000' SVR4/MP effort # says GUESS=i586-unisys-sysv4 ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm GUESS=hppa1.1-stratus-sysv4 ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. GUESS=i860-stratus-sysv4 ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. GUESS=$UNAME_MACHINE-stratus-vos ;; *:VOS:*:*) # From Paul.Green@stratus.com. GUESS=hppa1.1-stratus-vos ;; mc68*:A/UX:*:*) GUESS=m68k-apple-aux$UNAME_RELEASE ;; news*:NEWS-OS:6*:*) GUESS=mips-sony-newsos6 ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if test -d /usr/nec; then GUESS=mips-nec-sysv$UNAME_RELEASE else GUESS=mips-unknown-sysv$UNAME_RELEASE fi ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. GUESS=powerpc-be-beos ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. GUESS=powerpc-apple-beos ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. GUESS=i586-pc-beos ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. GUESS=i586-pc-haiku ;; ppc:Haiku:*:*) # Haiku running on Apple PowerPC GUESS=powerpc-apple-haiku ;; *:Haiku:*:*) # Haiku modern gcc (not bound by BeOS compat) GUESS=$UNAME_MACHINE-unknown-haiku ;; SX-4:SUPER-UX:*:*) GUESS=sx4-nec-superux$UNAME_RELEASE ;; SX-5:SUPER-UX:*:*) GUESS=sx5-nec-superux$UNAME_RELEASE ;; SX-6:SUPER-UX:*:*) GUESS=sx6-nec-superux$UNAME_RELEASE ;; SX-7:SUPER-UX:*:*) GUESS=sx7-nec-superux$UNAME_RELEASE ;; SX-8:SUPER-UX:*:*) GUESS=sx8-nec-superux$UNAME_RELEASE ;; SX-8R:SUPER-UX:*:*) GUESS=sx8r-nec-superux$UNAME_RELEASE ;; SX-ACE:SUPER-UX:*:*) GUESS=sxace-nec-superux$UNAME_RELEASE ;; Power*:Rhapsody:*:*) GUESS=powerpc-apple-rhapsody$UNAME_RELEASE ;; *:Rhapsody:*:*) GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE ;; arm64:Darwin:*:*) GUESS=aarch64-apple-darwin$UNAME_RELEASE ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` case $UNAME_PROCESSOR in unknown) UNAME_PROCESSOR=powerpc ;; esac if command -v xcode-select > /dev/null 2> /dev/null && \ ! xcode-select --print-path > /dev/null 2> /dev/null ; then # Avoid executing cc if there is no toolchain installed as # cc will be a stub that puts up a graphical alert # prompting the user to install developer tools. CC_FOR_BUILD=no_compiler_found else set_cc_for_build fi if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_PPC >/dev/null then UNAME_PROCESSOR=powerpc fi elif test "$UNAME_PROCESSOR" = i386 ; then # uname -m returns i386 or x86_64 UNAME_PROCESSOR=$UNAME_MACHINE fi GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE ;; *:QNX:*:4*) GUESS=i386-pc-qnx ;; NEO-*:NONSTOP_KERNEL:*:*) GUESS=neo-tandem-nsk$UNAME_RELEASE ;; NSE-*:NONSTOP_KERNEL:*:*) GUESS=nse-tandem-nsk$UNAME_RELEASE ;; NSR-*:NONSTOP_KERNEL:*:*) GUESS=nsr-tandem-nsk$UNAME_RELEASE ;; NSV-*:NONSTOP_KERNEL:*:*) GUESS=nsv-tandem-nsk$UNAME_RELEASE ;; NSX-*:NONSTOP_KERNEL:*:*) GUESS=nsx-tandem-nsk$UNAME_RELEASE ;; *:NonStop-UX:*:*) GUESS=mips-compaq-nonstopux ;; BS2000:POSIX*:*:*) GUESS=bs2000-siemens-sysv ;; DS/*:UNIX_System_V:*:*) GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "${cputype-}" = 386; then UNAME_MACHINE=i386 elif test "x${cputype-}" != x; then UNAME_MACHINE=$cputype fi GUESS=$UNAME_MACHINE-unknown-plan9 ;; *:TOPS-10:*:*) GUESS=pdp10-unknown-tops10 ;; *:TENEX:*:*) GUESS=pdp10-unknown-tenex ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) GUESS=pdp10-dec-tops20 ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) GUESS=pdp10-xkl-tops20 ;; *:TOPS-20:*:*) GUESS=pdp10-unknown-tops20 ;; *:ITS:*:*) GUESS=pdp10-unknown-its ;; SEI:*:*:SEIUX) GUESS=mips-sei-seiux$UNAME_RELEASE ;; *:DragonFly:*:*) DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case $UNAME_MACHINE in A*) GUESS=alpha-dec-vms ;; I*) GUESS=ia64-dec-vms ;; V*) GUESS=vax-dec-vms ;; esac ;; *:XENIX:*:SysV) GUESS=i386-pc-xenix ;; i*86:skyos:*:*) SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'` GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL ;; i*86:rdos:*:*) GUESS=$UNAME_MACHINE-pc-rdos ;; i*86:Fiwix:*:*) GUESS=$UNAME_MACHINE-pc-fiwix ;; *:AROS:*:*) GUESS=$UNAME_MACHINE-unknown-aros ;; x86_64:VMkernel:*:*) GUESS=$UNAME_MACHINE-unknown-esx ;; amd64:Isilon\ OneFS:*:*) GUESS=x86_64-unknown-onefs ;; *:Unleashed:*:*) GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE ;; esac # Do we have a guess based on uname results? if test "x$GUESS" != x; then echo "$GUESS" exit fi # No uname command or uname output not recognized. set_cc_for_build cat > "$dummy.c" < #include #endif #if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) #if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) #include #if defined(_SIZE_T_) || defined(SIGLOST) #include #endif #endif #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) #if !defined (ultrix) #include #if defined (BSD) #if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); #else #if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); #else printf ("vax-dec-bsd\n"); exit (0); #endif #endif #else printf ("vax-dec-bsd\n"); exit (0); #endif #else #if defined(_SIZE_T_) || defined(SIGLOST) struct utsname un; uname (&un); printf ("vax-dec-ultrix%s\n", un.release); exit (0); #else printf ("vax-dec-ultrix\n"); exit (0); #endif #endif #endif #if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) #if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) #if defined(_SIZE_T_) || defined(SIGLOST) struct utsname *un; uname (&un); printf ("mips-dec-ultrix%s\n", un.release); exit (0); #else printf ("mips-dec-ultrix\n"); exit (0); #endif #endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } echo "$0: unable to guess system type" >&2 case $UNAME_MACHINE:$UNAME_SYSTEM in mips:Linux | mips64:Linux) # If we got here on MIPS GNU/Linux, output extra information. cat >&2 <&2 <&2 </dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = "$UNAME_MACHINE" UNAME_RELEASE = "$UNAME_RELEASE" UNAME_SYSTEM = "$UNAME_SYSTEM" UNAME_VERSION = "$UNAME_VERSION" EOF fi exit 1 # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: libpng-1.6.43/config.h.in000066400000000000000000000074471456606525400151340ustar00rootroot00000000000000/* config.h.in. Generated from configure.ac by autoheader. */ /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you have the 'feenableexcept' function. */ #undef HAVE_FEENABLEEXCEPT /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the 'm' library (-lm). */ #undef HAVE_LIBM /* Define to 1 if you have the 'z' library (-lz). */ #undef HAVE_LIBZ /* Define to 1 if you have the 'pow' function. */ #undef HAVE_POW /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDIO_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to the sub-directory where libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Turn on ARM Neon optimizations at run-time */ #undef PNG_ARM_NEON_API_SUPPORTED /* Check for ARM Neon support at run-time */ #undef PNG_ARM_NEON_CHECK_SUPPORTED /* Enable ARM Neon optimizations */ #undef PNG_ARM_NEON_OPT /* Enable Intel SSE optimizations */ #undef PNG_INTEL_SSE_OPT /* Enable LOONGARCH LSX optimizations */ #undef PNG_LOONGARCH_LSX_OPT /* Turn on MIPS MMI optimizations at run-time */ #undef PNG_MIPS_MMI_API_SUPPORTED /* Check for MIPS MMI support at run-time */ #undef PNG_MIPS_MMI_CHECK_SUPPORTED /* Enable MIPS MMI optimizations */ #undef PNG_MIPS_MMI_OPT /* Turn on MIPS MSA optimizations at run-time */ #undef PNG_MIPS_MSA_API_SUPPORTED /* Check for MIPS MSA support at run-time */ #undef PNG_MIPS_MSA_CHECK_SUPPORTED /* Enable MIPS MSA optimizations */ #undef PNG_MIPS_MSA_OPT /* Turn on POWERPC VSX optimizations at run-time */ #undef PNG_POWERPC_VSX_API_SUPPORTED /* Check for POWERPC VSX support at run-time */ #undef PNG_POWERPC_VSX_CHECK_SUPPORTED /* Enable POWERPC VSX optimizations */ #undef PNG_POWERPC_VSX_OPT /* Define to 1 if all of the C89 standard headers exist (not just the ones required in a freestanding environment). This macro is provided for backward compatibility; new code need not use it. */ #undef STDC_HEADERS /* Define to 1 if your declares 'struct tm'. */ #undef TM_IN_SYS_TIME /* Version number of package */ #undef VERSION /* Define to the equivalent of the C99 'restrict' keyword, or to nothing if this is not supported. Do not define if restrict is supported only directly. */ #undef restrict /* Work around a bug in older versions of Sun C++, which did not #define __restrict__ or support _Restrict or __restrict__ even though the corresponding Sun C compiler ended up with "#define restrict _Restrict" or "#define restrict __restrict__" in the previous line. This workaround can be removed once we assume Oracle Developer Studio 12.5 (2016) or later. */ #if defined __SUNPRO_CC && !defined __RESTRICT && !defined __restrict__ # define _Restrict # define __restrict__ #endif libpng-1.6.43/config.sub000077500000000000000000001072021456606525400150620ustar00rootroot00000000000000#! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2023 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale timestamp='2023-09-19' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # https://git.savannah.gnu.org/cgit/config.git/plain/config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. # The "shellcheck disable" line above the timestamp inhibits complaints # about features and limitations of the classic Bourne shell that were # superseded or lifted in POSIX. However, this script identifies a wide # variety of pre-POSIX systems that do not have POSIX shells at all, and # even some reasonably current systems (Solaris 10 as case-in-point) still # have a pre-POSIX /bin/sh. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright 1992-2023 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try '$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; *local*) # First pass through any local machine types. echo "$1" exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Split fields of configuration type # shellcheck disable=SC2162 saved_IFS=$IFS IFS="-" read field1 field2 field3 field4 <&2 exit 1 ;; *-*-*-*) basic_machine=$field1-$field2 basic_os=$field3-$field4 ;; *-*-*) # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two # parts maybe_os=$field2-$field3 case $maybe_os in nto-qnx* | linux-* | uclinux-uclibc* \ | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ | storm-chaos* | os2-emx* | rtmk-nova* | managarm-* \ | windows-* ) basic_machine=$field1 basic_os=$maybe_os ;; android-linux) basic_machine=$field1-unknown basic_os=linux-android ;; *) basic_machine=$field1-$field2 basic_os=$field3 ;; esac ;; *-*) # A lone config we happen to match not fitting any pattern case $field1-$field2 in decstation-3100) basic_machine=mips-dec basic_os= ;; *-*) # Second component is usually, but not always the OS case $field2 in # Prevent following clause from handling this valid os sun*os*) basic_machine=$field1 basic_os=$field2 ;; zephyr*) basic_machine=$field1-unknown basic_os=$field2 ;; # Manufacturers dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \ | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \ | unicom* | ibm* | next | hp | isi* | apollo | altos* \ | convergent* | ncr* | news | 32* | 3600* | 3100* \ | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \ | ultra | tti* | harris | dolphin | highlevel | gould \ | cbm | ns | masscomp | apple | axis | knuth | cray \ | microblaze* | sim | cisco \ | oki | wec | wrs | winbond) basic_machine=$field1-$field2 basic_os= ;; *) basic_machine=$field1 basic_os=$field2 ;; esac ;; esac ;; *) # Convert single-component short-hands not valid as part of # multi-component configurations. case $field1 in 386bsd) basic_machine=i386-pc basic_os=bsd ;; a29khif) basic_machine=a29k-amd basic_os=udi ;; adobe68k) basic_machine=m68010-adobe basic_os=scout ;; alliant) basic_machine=fx80-alliant basic_os= ;; altos | altos3068) basic_machine=m68k-altos basic_os= ;; am29k) basic_machine=a29k-none basic_os=bsd ;; amdahl) basic_machine=580-amdahl basic_os=sysv ;; amiga) basic_machine=m68k-unknown basic_os= ;; amigaos | amigados) basic_machine=m68k-unknown basic_os=amigaos ;; amigaunix | amix) basic_machine=m68k-unknown basic_os=sysv4 ;; apollo68) basic_machine=m68k-apollo basic_os=sysv ;; apollo68bsd) basic_machine=m68k-apollo basic_os=bsd ;; aros) basic_machine=i386-pc basic_os=aros ;; aux) basic_machine=m68k-apple basic_os=aux ;; balance) basic_machine=ns32k-sequent basic_os=dynix ;; blackfin) basic_machine=bfin-unknown basic_os=linux ;; cegcc) basic_machine=arm-unknown basic_os=cegcc ;; convex-c1) basic_machine=c1-convex basic_os=bsd ;; convex-c2) basic_machine=c2-convex basic_os=bsd ;; convex-c32) basic_machine=c32-convex basic_os=bsd ;; convex-c34) basic_machine=c34-convex basic_os=bsd ;; convex-c38) basic_machine=c38-convex basic_os=bsd ;; cray) basic_machine=j90-cray basic_os=unicos ;; crds | unos) basic_machine=m68k-crds basic_os= ;; da30) basic_machine=m68k-da30 basic_os= ;; decstation | pmax | pmin | dec3100 | decstatn) basic_machine=mips-dec basic_os= ;; delta88) basic_machine=m88k-motorola basic_os=sysv3 ;; dicos) basic_machine=i686-pc basic_os=dicos ;; djgpp) basic_machine=i586-pc basic_os=msdosdjgpp ;; ebmon29k) basic_machine=a29k-amd basic_os=ebmon ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson basic_os=ose ;; gmicro) basic_machine=tron-gmicro basic_os=sysv ;; go32) basic_machine=i386-pc basic_os=go32 ;; h8300hms) basic_machine=h8300-hitachi basic_os=hms ;; h8300xray) basic_machine=h8300-hitachi basic_os=xray ;; h8500hms) basic_machine=h8500-hitachi basic_os=hms ;; harris) basic_machine=m88k-harris basic_os=sysv3 ;; hp300 | hp300hpux) basic_machine=m68k-hp basic_os=hpux ;; hp300bsd) basic_machine=m68k-hp basic_os=bsd ;; hppaosf) basic_machine=hppa1.1-hp basic_os=osf ;; hppro) basic_machine=hppa1.1-hp basic_os=proelf ;; i386mach) basic_machine=i386-mach basic_os=mach ;; isi68 | isi) basic_machine=m68k-isi basic_os=sysv ;; m68knommu) basic_machine=m68k-unknown basic_os=linux ;; magnum | m3230) basic_machine=mips-mips basic_os=sysv ;; merlin) basic_machine=ns32k-utek basic_os=sysv ;; mingw64) basic_machine=x86_64-pc basic_os=mingw64 ;; mingw32) basic_machine=i686-pc basic_os=mingw32 ;; mingw32ce) basic_machine=arm-unknown basic_os=mingw32ce ;; monitor) basic_machine=m68k-rom68k basic_os=coff ;; morphos) basic_machine=powerpc-unknown basic_os=morphos ;; moxiebox) basic_machine=moxie-unknown basic_os=moxiebox ;; msdos) basic_machine=i386-pc basic_os=msdos ;; msys) basic_machine=i686-pc basic_os=msys ;; mvs) basic_machine=i370-ibm basic_os=mvs ;; nacl) basic_machine=le32-unknown basic_os=nacl ;; ncr3000) basic_machine=i486-ncr basic_os=sysv4 ;; netbsd386) basic_machine=i386-pc basic_os=netbsd ;; netwinder) basic_machine=armv4l-rebel basic_os=linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony basic_os=newsos ;; news1000) basic_machine=m68030-sony basic_os=newsos ;; necv70) basic_machine=v70-nec basic_os=sysv ;; nh3000) basic_machine=m68k-harris basic_os=cxux ;; nh[45]000) basic_machine=m88k-harris basic_os=cxux ;; nindy960) basic_machine=i960-intel basic_os=nindy ;; mon960) basic_machine=i960-intel basic_os=mon960 ;; nonstopux) basic_machine=mips-compaq basic_os=nonstopux ;; os400) basic_machine=powerpc-ibm basic_os=os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson basic_os=ose ;; os68k) basic_machine=m68k-none basic_os=os68k ;; paragon) basic_machine=i860-intel basic_os=osf ;; parisc) basic_machine=hppa-unknown basic_os=linux ;; psp) basic_machine=mipsallegrexel-sony basic_os=psp ;; pw32) basic_machine=i586-unknown basic_os=pw32 ;; rdos | rdos64) basic_machine=x86_64-pc basic_os=rdos ;; rdos32) basic_machine=i386-pc basic_os=rdos ;; rom68k) basic_machine=m68k-rom68k basic_os=coff ;; sa29200) basic_machine=a29k-amd basic_os=udi ;; sei) basic_machine=mips-sei basic_os=seiux ;; sequent) basic_machine=i386-sequent basic_os= ;; sps7) basic_machine=m68k-bull basic_os=sysv2 ;; st2000) basic_machine=m68k-tandem basic_os= ;; stratus) basic_machine=i860-stratus basic_os=sysv4 ;; sun2) basic_machine=m68000-sun basic_os= ;; sun2os3) basic_machine=m68000-sun basic_os=sunos3 ;; sun2os4) basic_machine=m68000-sun basic_os=sunos4 ;; sun3) basic_machine=m68k-sun basic_os= ;; sun3os3) basic_machine=m68k-sun basic_os=sunos3 ;; sun3os4) basic_machine=m68k-sun basic_os=sunos4 ;; sun4) basic_machine=sparc-sun basic_os= ;; sun4os3) basic_machine=sparc-sun basic_os=sunos3 ;; sun4os4) basic_machine=sparc-sun basic_os=sunos4 ;; sun4sol2) basic_machine=sparc-sun basic_os=solaris2 ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun basic_os= ;; sv1) basic_machine=sv1-cray basic_os=unicos ;; symmetry) basic_machine=i386-sequent basic_os=dynix ;; t3e) basic_machine=alphaev5-cray basic_os=unicos ;; t90) basic_machine=t90-cray basic_os=unicos ;; toad1) basic_machine=pdp10-xkl basic_os=tops20 ;; tpf) basic_machine=s390x-ibm basic_os=tpf ;; udi29k) basic_machine=a29k-amd basic_os=udi ;; ultra3) basic_machine=a29k-nyu basic_os=sym1 ;; v810 | necv810) basic_machine=v810-nec basic_os=none ;; vaxv) basic_machine=vax-dec basic_os=sysv ;; vms) basic_machine=vax-dec basic_os=vms ;; vsta) basic_machine=i386-pc basic_os=vsta ;; vxworks960) basic_machine=i960-wrs basic_os=vxworks ;; vxworks68) basic_machine=m68k-wrs basic_os=vxworks ;; vxworks29k) basic_machine=a29k-wrs basic_os=vxworks ;; xbox) basic_machine=i686-pc basic_os=mingw32 ;; ymp) basic_machine=ymp-cray basic_os=unicos ;; *) basic_machine=$1 basic_os= ;; esac ;; esac # Decode 1-component or ad-hoc basic machines case $basic_machine in # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) cpu=hppa1.1 vendor=winbond ;; op50n) cpu=hppa1.1 vendor=oki ;; op60c) cpu=hppa1.1 vendor=oki ;; ibm*) cpu=i370 vendor=ibm ;; orion105) cpu=clipper vendor=highlevel ;; mac | mpw | mac-mpw) cpu=m68k vendor=apple ;; pmac | pmac-mpw) cpu=powerpc vendor=apple ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) cpu=m68000 vendor=att ;; 3b*) cpu=we32k vendor=att ;; bluegene*) cpu=powerpc vendor=ibm basic_os=cnk ;; decsystem10* | dec10*) cpu=pdp10 vendor=dec basic_os=tops10 ;; decsystem20* | dec20*) cpu=pdp10 vendor=dec basic_os=tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) cpu=m68k vendor=motorola ;; dpx2*) cpu=m68k vendor=bull basic_os=sysv3 ;; encore | umax | mmax) cpu=ns32k vendor=encore ;; elxsi) cpu=elxsi vendor=elxsi basic_os=${basic_os:-bsd} ;; fx2800) cpu=i860 vendor=alliant ;; genix) cpu=ns32k vendor=ns ;; h3050r* | hiux*) cpu=hppa1.1 vendor=hitachi basic_os=hiuxwe2 ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) cpu=m68000 vendor=hp ;; hp9k3[2-9][0-9]) cpu=m68k vendor=hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) cpu=hppa1.1 vendor=hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp cpu=hppa1.1 vendor=hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp cpu=hppa1.1 vendor=hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) cpu=hppa1.1 vendor=hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) cpu=hppa1.0 vendor=hp ;; i*86v32) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=sysv32 ;; i*86v4*) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=sysv4 ;; i*86v) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=sysv ;; i*86sol2) cpu=`echo "$1" | sed -e 's/86.*/86/'` vendor=pc basic_os=solaris2 ;; j90 | j90-cray) cpu=j90 vendor=cray basic_os=${basic_os:-unicos} ;; iris | iris4d) cpu=mips vendor=sgi case $basic_os in irix*) ;; *) basic_os=irix4 ;; esac ;; miniframe) cpu=m68000 vendor=convergent ;; *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) cpu=m68k vendor=atari basic_os=mint ;; news-3600 | risc-news) cpu=mips vendor=sony basic_os=newsos ;; next | m*-next) cpu=m68k vendor=next case $basic_os in openstep*) ;; nextstep*) ;; ns2*) basic_os=nextstep2 ;; *) basic_os=nextstep3 ;; esac ;; np1) cpu=np1 vendor=gould ;; op50n-* | op60c-*) cpu=hppa1.1 vendor=oki basic_os=proelf ;; pa-hitachi) cpu=hppa1.1 vendor=hitachi basic_os=hiuxwe2 ;; pbd) cpu=sparc vendor=tti ;; pbb) cpu=m68k vendor=tti ;; pc532) cpu=ns32k vendor=pc532 ;; pn) cpu=pn vendor=gould ;; power) cpu=power vendor=ibm ;; ps2) cpu=i386 vendor=ibm ;; rm[46]00) cpu=mips vendor=siemens ;; rtpc | rtpc-*) cpu=romp vendor=ibm ;; sde) cpu=mipsisa32 vendor=sde basic_os=${basic_os:-elf} ;; simso-wrs) cpu=sparclite vendor=wrs basic_os=vxworks ;; tower | tower-32) cpu=m68k vendor=ncr ;; vpp*|vx|vx-*) cpu=f301 vendor=fujitsu ;; w65) cpu=w65 vendor=wdc ;; w89k-*) cpu=hppa1.1 vendor=winbond basic_os=proelf ;; none) cpu=none vendor=none ;; leon|leon[3-9]) cpu=sparc vendor=$basic_machine ;; leon-*|leon[3-9]-*) cpu=sparc vendor=`echo "$basic_machine" | sed 's/-.*//'` ;; *-*) # shellcheck disable=SC2162 saved_IFS=$IFS IFS="-" read cpu vendor <&2 exit 1 ;; esac ;; esac # Here we canonicalize certain aliases for manufacturers. case $vendor in digital*) vendor=dec ;; commodore*) vendor=cbm ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if test x"$basic_os" != x then # First recognize some ad-hoc cases, or perhaps split kernel-os, or else just # set os. obj= case $basic_os in gnu/linux*) kernel=linux os=`echo "$basic_os" | sed -e 's|gnu/linux|gnu|'` ;; os2-emx) kernel=os2 os=`echo "$basic_os" | sed -e 's|os2-emx|emx|'` ;; nto-qnx*) kernel=nto os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'` ;; *-*) # shellcheck disable=SC2162 saved_IFS=$IFS IFS="-" read kernel os <&2 fi ;; *) echo "Invalid configuration '$1': OS '$os' not recognized" 1>&2 exit 1 ;; esac case $obj in aout* | coff* | elf* | pe*) ;; '') # empty is fine ;; *) echo "Invalid configuration '$1': Machine code format '$obj' not recognized" 1>&2 exit 1 ;; esac # Here we handle the constraint that a (synthetic) cpu and os are # valid only in combination with each other and nowhere else. case $cpu-$os in # The "javascript-unknown-ghcjs" triple is used by GHC; we # accept it here in order to tolerate that, but reject any # variations. javascript-ghcjs) ;; javascript-* | *-ghcjs) echo "Invalid configuration '$1': cpu '$cpu' is not valid with os '$os$obj'" 1>&2 exit 1 ;; esac # As a final step for OS-related things, validate the OS-kernel combination # (given a valid OS), if there is a kernel. case $kernel-$os-$obj in linux-gnu*- | linux-dietlibc*- | linux-android*- | linux-newlib*- \ | linux-musl*- | linux-relibc*- | linux-uclibc*- | linux-mlibc*- ) ;; uclinux-uclibc*- ) ;; managarm-mlibc*- | managarm-kernel*- ) ;; windows*-msvc*-) ;; -dietlibc*- | -newlib*- | -musl*- | -relibc*- | -uclibc*- | -mlibc*- ) # These are just libc implementations, not actual OSes, and thus # require a kernel. echo "Invalid configuration '$1': libc '$os' needs explicit kernel." 1>&2 exit 1 ;; -kernel*- ) echo "Invalid configuration '$1': '$os' needs explicit kernel." 1>&2 exit 1 ;; *-kernel*- ) echo "Invalid configuration '$1': '$kernel' does not support '$os'." 1>&2 exit 1 ;; *-msvc*- ) echo "Invalid configuration '$1': '$os' needs 'windows'." 1>&2 exit 1 ;; kfreebsd*-gnu*- | kopensolaris*-gnu*-) ;; vxworks-simlinux- | vxworks-simwindows- | vxworks-spe-) ;; nto-qnx*-) ;; os2-emx-) ;; *-eabi*- | *-gnueabi*-) ;; none--*) # None (no kernel, i.e. freestanding / bare metal), # can be paired with an machine code file format ;; -*-) # Blank kernel with real OS is always fine. ;; --*) # Blank kernel and OS with real machine code file format is always fine. ;; *-*-*) echo "Invalid configuration '$1': Kernel '$kernel' not known to work with OS '$os'." 1>&2 exit 1 ;; esac # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. case $vendor in unknown) case $cpu-$os in *-riscix*) vendor=acorn ;; *-sunos*) vendor=sun ;; *-cnk* | *-aix*) vendor=ibm ;; *-beos*) vendor=be ;; *-hpux*) vendor=hp ;; *-mpeix*) vendor=hp ;; *-hiux*) vendor=hitachi ;; *-unos*) vendor=crds ;; *-dgux*) vendor=dg ;; *-luna*) vendor=omron ;; *-genix*) vendor=ns ;; *-clix*) vendor=intergraph ;; *-mvs* | *-opened*) vendor=ibm ;; *-os400*) vendor=ibm ;; s390-* | s390x-*) vendor=ibm ;; *-ptx*) vendor=sequent ;; *-tpf*) vendor=ibm ;; *-vxsim* | *-vxworks* | *-windiss*) vendor=wrs ;; *-aux*) vendor=apple ;; *-hms*) vendor=hitachi ;; *-mpw* | *-macos*) vendor=apple ;; *-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*) vendor=atari ;; *-vos*) vendor=stratus ;; esac ;; esac echo "$cpu-$vendor${kernel:+-$kernel}${os:+-$os}${obj:+-$obj}" exit # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: libpng-1.6.43/configure000077500000000000000000017442451456606525400150250ustar00rootroot00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.72 for libpng 1.6.43. # # Report bugs to . # # # Copyright (C) 1992-1996, 1998-2017, 2020-2023 Free Software Foundation, # Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case e in #( e) case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac ;; esac fi # Reset variables that may have inherited troublesome values from # the environment. # IFS needs to be set, to space, tab, and newline, in precisely that order. # (If _AS_PATH_WALK were called with IFS unset, it would have the # side effect of setting IFS to empty, thus disabling word splitting.) # Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl IFS=" "" $as_nl" PS1='$ ' PS2='> ' PS4='+ ' # Ensure predictable behavior from utilities with locale-dependent output. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # We cannot yet rely on "unset" to work, but we need these variables # to be unset--not just set to an empty or harmless value--now, to # avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct # also avoids known problems related to "unset" and subshell syntax # in other old shells (e.g. bash 2.01 and pdksh 5.2.14). for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH do eval test \${$as_var+y} \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done # Ensure that fds 0, 1, and 2 are open. if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. if ${PATH_SEPARATOR+false} :; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac test -r "$as_dir$0" && as_myself=$as_dir$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as 'sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed 'exec'. printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case e in #( e) case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ) then : else case e in #( e) exitcode=1; echo positional parameters were not saved. ;; esac fi test x\$exitcode = x0 || exit 1 blah=\$(echo \$(echo blah)) test x\"\$blah\" = xblah || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1 test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" if (eval "$as_required") 2>/dev/null then : as_have_required=yes else case e in #( e) as_have_required=no ;; esac fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null then : else case e in #( e) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null then : CONFIG_SHELL=$as_shell as_have_required=yes if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null then : break 2 fi fi done;; esac as_found=false done IFS=$as_save_IFS if $as_found then : else case e in #( e) if { test -f "$SHELL" || test -f "$SHELL.exe"; } && as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null then : CONFIG_SHELL=$SHELL as_have_required=yes fi ;; esac fi if test "x$CONFIG_SHELL" != x then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed 'exec'. printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno then : printf "%s\n" "$0: This script requires a shell more modern than all" printf "%s\n" "$0: the shells that I found on your system." if test ${ZSH_VERSION+y} ; then printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should" printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later." else printf "%s\n" "$0: Please tell bug-autoconf@gnu.org and $0: png-mng-implement@lists.sourceforge.net about your $0: system, including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi ;; esac fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null then : eval 'as_fn_append () { eval $1+=\$2 }' else case e in #( e) as_fn_append () { eval $1=\$$1\$2 } ;; esac fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null then : eval 'as_fn_arith () { as_val=$(( $* )) }' else case e in #( e) as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } ;; esac fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi printf "%s\n" "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' t clear :clear s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } # Determine whether it's possible to make 'echo' print without a newline. # These variables are no longer used directly by Autoconf, but are AC_SUBSTed # for compatibility with existing Makefiles. ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac # For backward compatibility with old third-party macros, we provide # the shell variables $as_echo and $as_echo_n. New code should use # AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. as_echo='printf %s\n' as_echo_n='printf %s' rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both 'ln -s file dir' and 'ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; 'ln -s' creates a wrapper executable. # In both cases, we have to default to 'cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_sed_cpp="y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" as_tr_cpp="eval sed '$as_sed_cpp'" # deprecated # Sed expression to map a string onto a valid variable name. as_sed_sh="y%*+%pp%;s%[^_$as_cr_alnum]%_%g" as_tr_sh="eval sed '$as_sed_sh'" # deprecated SHELL=${CONFIG_SHELL-/bin/sh} test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='libpng' PACKAGE_TARNAME='libpng' PACKAGE_VERSION='1.6.43' PACKAGE_STRING='libpng 1.6.43' PACKAGE_BUGREPORT='png-mng-implement@lists.sourceforge.net' PACKAGE_URL='' ac_unique_file="pngget.c" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_STDIO_H # include #endif #ifdef HAVE_STDLIB_H # include #endif #ifdef HAVE_STRING_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_header_c_list= ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS PNG_LOONGARCH_LSX_FALSE PNG_LOONGARCH_LSX_TRUE PNG_POWERPC_VSX_FALSE PNG_POWERPC_VSX_TRUE PNG_INTEL_SSE_FALSE PNG_INTEL_SSE_TRUE PNG_MIPS_MMI_FALSE PNG_MIPS_MMI_TRUE PNG_MIPS_MSA_FALSE PNG_MIPS_MSA_TRUE PNG_ARM_NEON_FALSE PNG_ARM_NEON_TRUE DO_INSTALL_LIBPNG_CONFIG_FALSE DO_INSTALL_LIBPNG_CONFIG_TRUE DO_INSTALL_LIBPNG_PC_FALSE DO_INSTALL_LIBPNG_PC_TRUE DO_INSTALL_LINKS_FALSE DO_INSTALL_LINKS_TRUE DO_PNG_PREFIX_FALSE DO_PNG_PREFIX_TRUE PNG_PREFIX binconfigs pkgconfigdir PNGLIB_RELEASE PNGLIB_MINOR PNGLIB_MAJOR PNGLIB_VERSION SYMBOL_PREFIX HAVE_LD_VERSION_SCRIPT_FALSE HAVE_LD_VERSION_SCRIPT_TRUE HAVE_SOLARIS_LD_FALSE HAVE_SOLARIS_LD_TRUE HAVE_CLOCK_GETTIME_FALSE HAVE_CLOCK_GETTIME_TRUE PNG_COPTS ENABLE_TOOLS_FALSE ENABLE_TOOLS_TRUE ENABLE_TESTS_FALSE ENABLE_TESTS_TRUE DFNCPP LT_SYS_LIBRARY_PATH OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL MANIFEST_TOOL RANLIB ac_ct_AR AR FILECMD NM ac_ct_DUMPBIN DUMPBIN LIBTOOL OBJDUMP DLLTOOL AS LN_S CPP LD FGREP EGREP GREP SED host_os host_vendor host_cpu host build_os build_vendor build_cpu build am__fastdepCCAS_FALSE am__fastdepCCAS_TRUE CCASDEPMODE CCASFLAGS CCAS am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC MAINT MAINTAINER_MODE_FALSE MAINTAINER_MODE_TRUE AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V AM_V CSCOPE ETAGS CTAGS am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir runstatedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL am__quote' ac_subst_files='' ac_user_opts=' enable_option_checking enable_silent_rules enable_maintainer_mode enable_dependency_tracking with_gnu_ld enable_shared enable_static with_pic enable_fast_install with_aix_soname with_sysroot enable_libtool_lock enable_tests enable_tools enable_werror with_zlib_prefix with_pkgconfigdir with_binconfigs with_libpng_prefix enable_unversioned_links enable_unversioned_libpng_pc enable_unversioned_libpng_config enable_hardware_optimizations enable_arm_neon enable_mips_msa enable_mips_mmi enable_intel_sse enable_powerpc_vsx enable_loongarch_lsx ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CCAS CCASFLAGS CPP LT_SYS_LIBRARY_PATH AWK PNG_COPTS' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: '$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: '$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -runstatedir | --runstatedir | --runstatedi | --runstated \ | --runstate | --runstat | --runsta | --runst | --runs \ | --run | --ru | --r) ac_prev=runstatedir ;; -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ | --run=* | --ru=* | --r=*) runstatedir=$ac_optarg ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: '$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: '$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: '$ac_option' Try '$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: '$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: '$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but 'cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF 'configure' configures libpng 1.6.43 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print 'checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for '--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or '..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, 'make install' will install all the files in '$ac_default_prefix/bin', '$ac_default_prefix/lib' etc. You can specify an installation prefix other than '$ac_default_prefix' using '--prefix', for instance '--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/libpng] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of libpng 1.6.43:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-silent-rules less verbose build output (undo: "make V=1") --disable-silent-rules verbose build output (undo: "make V=0") --enable-maintainer-mode enable make rules and dependencies not useful (and sometimes confusing) to the casual installer --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build --enable-shared[=PKGS] build shared libraries [default=yes] --enable-static[=PKGS] build static libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) --disable-tests do not build the test programs (default is to build) --disable-tools do not build the auxiliary tools (default is to build) --enable-werror[=OPT] Pass -Werror or the given argument to the compiler if it is supported --enable-unversioned-links Installed libpng header files are placed in a versioned subdirectory and installed libpng library (including DLL) files are versioned. If this option is enabled unversioned links will be created pointing to the corresponding installed files. If you use libpng.pc or libpng-config for all builds you do not need these links, but if you compile programs directly they will typically #include and link with -lpng; in that case you need the links. The links can be installed manually using 'make install-header-links' and 'make install-library-links' and can be removed using the corresponding uninstall- targets. If you do enable this option every libpng 'make install' will recreate the links to point to the just installed version of libpng. The default is to create the links; use --disable-unversioned-links to change this --enable-unversioned-libpng-pc Install the configuration file 'libpng.pc' as a link to the versioned version. This is done by default - use --disable-unversioned-libpng-pc to change this. --enable-unversioned-libpng-config Install the configuration file 'libpng-config' as a link to the versioned version. This is done by default - use --disable-unversioned-libpng-config to change this. --enable-hardware-optimizations Enable hardware optimizations: =no/off, yes/on. --enable-arm-neon Enable ARM NEON optimizations: =no/off, check, api, yes/on. no/off: disable the optimizations; check: use internal checking code (deprecated and poorly supported); api: disable by default, enable by a call to png_set_option; yes/on: turn on unconditionally. If not specified: determined by the compiler. --enable-mips-msa Enable MIPS MSA optimizations: =no/off, check, api, yes/on. no/off: disable the optimizations; check: use internal checking code (deprecated and poorly supported); api: disable by default, enable by a call to png_set_option; yes/on: turn on unconditionally. If not specified: determined by the compiler. --enable-mips-mmi Enable MIPS MMI optimizations: =no/off, check, api, yes/on. no/off: disable the optimizations; check: use internal checking code (deprecated and poorly supported); api: disable by default, enable by a call to png_set_option; yes/on: turn on unconditionally. If not specified: determined by the compiler. --enable-intel-sse Enable Intel SSE optimizations: =no/off, yes/on. no/off: disable the optimizations; yes/on: enable the optimizations. If not specified: determined by the compiler. --enable-powerpc-vsx Enable POWERPC VSX optimizations: =no/off, check, api, yes/on. no/off: disable the optimizations; check: use internal checking code; api: disable by default, enable by a call to png_set_option; yes/on: turn on unconditionally. If not specified: determined by the compiler. --enable-loongarch-lsx Enable LOONGARCH LSX optimizations: =no/off, yes/on: no/off: disable the optimizations; yes/on: turn on unconditionally. If not specified: determined by the compiler. Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use both] --with-aix-soname=aix|svr4|both shared library versioning (aka "SONAME") variant to provide on AIX, [default=aix]. --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified). --with-zlib-prefix prefix that may have been used in installed zlib --with-pkgconfigdir Use the specified pkgconfig dir (default is libdir/pkgconfig) --with-binconfigs Generate shell libpng-config scripts as well as pkg-config data [default=yes] --with-libpng-prefix prefix libpng exported function (API) names with the given value Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CCAS assembler compiler command (defaults to CC) CCASFLAGS assembler compiler flags (defaults to CFLAGS) CPP C preprocessor LT_SYS_LIBRARY_PATH User-defined run-time library search path. AWK AWK language processor PNG_COPTS additional flags for the C compiler, to be used for options that would cause configure itself to fail Use these variables to override the choices made by 'configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for configure.gnu first; this name is used for a wrapper for # Metaconfig's "Configure" on case-insensitive file systems. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF libpng configure 1.6.43 generated by GNU Autoconf 2.72 Copyright (C) 2023 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest.beam if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext then : ac_retval=0 else case e in #( e) printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 ;; esac fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err } then : ac_retval=0 else case e in #( e) printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 ;; esac fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext } then : ac_retval=0 else case e in #( e) printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 ;; esac fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else case e in #( e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO" then : eval "$3=yes" else case e in #( e) eval "$3=no" ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; esac fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else case e in #( e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (void); below. */ #include #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (void); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main (void) { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : eval "$3=yes" else case e in #( e) eval "$3=no" ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext ;; esac fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func ac_configure_args_raw= for ac_arg do case $ac_arg in *\'*) ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append ac_configure_args_raw " '$ac_arg'" done case $ac_configure_args_raw in *$as_nl*) ac_safe_unquote= ;; *) ac_unsafe_z='|&;<>()$`\\"*?[ '' ' # This string ends in space, tab. ac_unsafe_a="$ac_unsafe_z#~" ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g" ac_configure_args_raw=` printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;; esac cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by libpng $as_me 1.6.43, which was generated by GNU Autoconf 2.72. Invocation command line was $ $0$ac_configure_args_raw _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac printf "%s\n" "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Sanitize IFS. IFS=" "" $as_nl" # Save into config.log some information that might help in debugging. { echo printf "%s\n" "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo printf "%s\n" "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then printf "%s\n" "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then printf "%s\n" "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && printf "%s\n" "$as_me: caught signal $ac_signal" printf "%s\n" "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h printf "%s\n" "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. if test -n "$CONFIG_SITE"; then ac_site_files="$CONFIG_SITE" elif test "x$prefix" != xNONE; then ac_site_files="$prefix/share/config.site $prefix/etc/config.site" else ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi for ac_site_file in $ac_site_files do case $ac_site_file in #( */*) : ;; #( *) : ac_site_file=./$ac_site_file ;; esac if test -f "$ac_site_file" && test -r "$ac_site_file"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See 'config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 printf "%s\n" "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 printf "%s\n" "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Test code for whether the C compiler supports C89 (global declarations) ac_c_conftest_c89_globals=' /* Does the compiler advertise C89 conformance? Do not test the value of __STDC__, because some compilers set it to 0 while being otherwise adequately conformant. */ #if !defined __STDC__ # error "Compiler does not advertise C89 conformance" #endif #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7 src/conf.sh. */ struct buf { int x; }; struct buf * (*rcsopen) (struct buf *, struct stat *, int); static char *e (char **p, int i) { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* C89 style stringification. */ #define noexpand_stringify(a) #a const char *stringified = noexpand_stringify(arbitrary+token=sequence); /* C89 style token pasting. Exercises some of the corner cases that e.g. old MSVC gets wrong, but not very hard. */ #define noexpand_concat(a,b) a##b #define expand_concat(a,b) noexpand_concat(a,b) extern int vA; extern int vbee; #define aye A #define bee B int *pvA = &expand_concat(v,aye); int *pvbee = &noexpand_concat(v,bee); /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not \xHH hex character constants. These do not provoke an error unfortunately, instead are silently treated as an "x". The following induces an error, until -std is added to get proper ANSI mode. Curiously \x00 != x always comes out true, for an array size at least. It is necessary to write \x00 == 0 to get something that is true only with -std. */ int osf4_cc_array ['\''\x00'\'' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) '\''x'\'' int xlc6_cc_array[FOO(a) == '\''x'\'' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, int *(*)(struct buf *, struct stat *, int), int, int);' # Test code for whether the C compiler supports C89 (body of main). ac_c_conftest_c89_main=' ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]); ' # Test code for whether the C compiler supports C99 (global declarations) ac_c_conftest_c99_globals=' /* Does the compiler advertise C99 conformance? */ #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L # error "Compiler does not advertise C99 conformance" #endif // See if C++-style comments work. #include extern int puts (const char *); extern int printf (const char *, ...); extern int dprintf (int, const char *, ...); extern void *malloc (size_t); extern void free (void *); // Check varargs macros. These examples are taken from C99 6.10.3.5. // dprintf is used instead of fprintf to avoid needing to declare // FILE and stderr. #define debug(...) dprintf (2, __VA_ARGS__) #define showlist(...) puts (#__VA_ARGS__) #define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) static void test_varargs_macros (void) { int x = 1234; int y = 5678; debug ("Flag"); debug ("X = %d\n", x); showlist (The first, second, and third items.); report (x>y, "x is %d but y is %d", x, y); } // Check long long types. #define BIG64 18446744073709551615ull #define BIG32 4294967295ul #define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) #if !BIG_OK #error "your preprocessor is broken" #endif #if BIG_OK #else #error "your preprocessor is broken" #endif static long long int bignum = -9223372036854775807LL; static unsigned long long int ubignum = BIG64; struct incomplete_array { int datasize; double data[]; }; struct named_init { int number; const wchar_t *name; double average; }; typedef const char *ccp; static inline int test_restrict (ccp restrict text) { // Iterate through items via the restricted pointer. // Also check for declarations in for loops. for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i) continue; return 0; } // Check varargs and va_copy. static bool test_varargs (const char *format, ...) { va_list args; va_start (args, format); va_list args_copy; va_copy (args_copy, args); const char *str = ""; int number = 0; float fnumber = 0; while (*format) { switch (*format++) { case '\''s'\'': // string str = va_arg (args_copy, const char *); break; case '\''d'\'': // int number = va_arg (args_copy, int); break; case '\''f'\'': // float fnumber = va_arg (args_copy, double); break; default: break; } } va_end (args_copy); va_end (args); return *str && number && fnumber; } ' # Test code for whether the C compiler supports C99 (body of main). ac_c_conftest_c99_main=' // Check bool. _Bool success = false; success |= (argc != 0); // Check restrict. if (test_restrict ("String literal") == 0) success = true; char *restrict newvar = "Another string"; // Check varargs. success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234); test_varargs_macros (); // Check flexible array members. struct incomplete_array *ia = malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); ia->datasize = 10; for (int i = 0; i < ia->datasize; ++i) ia->data[i] = i * 1.234; // Work around memory leak warnings. free (ia); // Check named initializers. struct named_init ni = { .number = 34, .name = L"Test wide string", .average = 543.34343, }; ni.number = 58; int dynamic_array[ni.number]; dynamic_array[0] = argv[0][0]; dynamic_array[ni.number - 1] = 543; // work around unused variable warnings ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\'' || dynamic_array[ni.number - 1] != 543); ' # Test code for whether the C compiler supports C11 (global declarations) ac_c_conftest_c11_globals=' /* Does the compiler advertise C11 conformance? */ #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L # error "Compiler does not advertise C11 conformance" #endif // Check _Alignas. char _Alignas (double) aligned_as_double; char _Alignas (0) no_special_alignment; extern char aligned_as_int; char _Alignas (0) _Alignas (int) aligned_as_int; // Check _Alignof. enum { int_alignment = _Alignof (int), int_array_alignment = _Alignof (int[100]), char_alignment = _Alignof (char) }; _Static_assert (0 < -_Alignof (int), "_Alignof is signed"); // Check _Noreturn. int _Noreturn does_not_return (void) { for (;;) continue; } // Check _Static_assert. struct test_static_assert { int x; _Static_assert (sizeof (int) <= sizeof (long int), "_Static_assert does not work in struct"); long int y; }; // Check UTF-8 literals. #define u8 syntax error! char const utf8_literal[] = u8"happens to be ASCII" "another string"; // Check duplicate typedefs. typedef long *long_ptr; typedef long int *long_ptr; typedef long_ptr long_ptr; // Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1. struct anonymous { union { struct { int i; int j; }; struct { int k; long int l; } w; }; int m; } v1; ' # Test code for whether the C compiler supports C11 (body of main). ac_c_conftest_c11_main=' _Static_assert ((offsetof (struct anonymous, i) == offsetof (struct anonymous, w.k)), "Anonymous union alignment botch"); v1.i = 2; v1.w.k = 5; ok |= v1.i != 5; ' # Test code for whether the C compiler supports C11 (complete). ac_c_conftest_c11_program="${ac_c_conftest_c89_globals} ${ac_c_conftest_c99_globals} ${ac_c_conftest_c11_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} ${ac_c_conftest_c99_main} ${ac_c_conftest_c11_main} return ok; } " # Test code for whether the C compiler supports C99 (complete). ac_c_conftest_c99_program="${ac_c_conftest_c89_globals} ${ac_c_conftest_c99_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} ${ac_c_conftest_c99_main} return ok; } " # Test code for whether the C compiler supports C89 (complete). ac_c_conftest_c89_program="${ac_c_conftest_c89_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} return ok; } " as_fn_append ac_header_c_list " stdio.h stdio_h HAVE_STDIO_H" as_fn_append ac_header_c_list " stdlib.h stdlib_h HAVE_STDLIB_H" as_fn_append ac_header_c_list " string.h string_h HAVE_STRING_H" as_fn_append ac_header_c_list " inttypes.h inttypes_h HAVE_INTTYPES_H" as_fn_append ac_header_c_list " stdint.h stdint_h HAVE_STDINT_H" as_fn_append ac_header_c_list " strings.h strings_h HAVE_STRINGS_H" as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H" as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H" as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H" # Auxiliary files required by this configure script. ac_aux_files="ltmain.sh config.guess config.sub compile missing install-sh" # Locations in which to look for auxiliary files. ac_aux_dir_candidates="${srcdir}${PATH_SEPARATOR}${srcdir}/..${PATH_SEPARATOR}${srcdir}/../.." # Search for a directory containing all of the required auxiliary files, # $ac_aux_files, from the $PATH-style list $ac_aux_dir_candidates. # If we don't find one directory that contains all the files we need, # we report the set of missing files from the *first* directory in # $ac_aux_dir_candidates and give up. ac_missing_aux_files="" ac_first_candidate=: printf "%s\n" "$as_me:${as_lineno-$LINENO}: looking for aux files: $ac_aux_files" >&5 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in $ac_aux_dir_candidates do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac as_found=: printf "%s\n" "$as_me:${as_lineno-$LINENO}: trying $as_dir" >&5 ac_aux_dir_found=yes ac_install_sh= for ac_aux in $ac_aux_files do # As a special case, if "install-sh" is required, that requirement # can be satisfied by any of "install-sh", "install.sh", or "shtool", # and $ac_install_sh is set appropriately for whichever one is found. if test x"$ac_aux" = x"install-sh" then if test -f "${as_dir}install-sh"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install-sh found" >&5 ac_install_sh="${as_dir}install-sh -c" elif test -f "${as_dir}install.sh"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install.sh found" >&5 ac_install_sh="${as_dir}install.sh -c" elif test -f "${as_dir}shtool"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}shtool found" >&5 ac_install_sh="${as_dir}shtool install -c" else ac_aux_dir_found=no if $ac_first_candidate; then ac_missing_aux_files="${ac_missing_aux_files} install-sh" else break fi fi else if test -f "${as_dir}${ac_aux}"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}${ac_aux} found" >&5 else ac_aux_dir_found=no if $ac_first_candidate; then ac_missing_aux_files="${ac_missing_aux_files} ${ac_aux}" else break fi fi fi done if test "$ac_aux_dir_found" = yes; then ac_aux_dir="$as_dir" break fi ac_first_candidate=false as_found=false done IFS=$as_save_IFS if $as_found then : else case e in #( e) as_fn_error $? "cannot find required auxiliary files:$ac_missing_aux_files" "$LINENO" 5 ;; esac fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. if test -f "${ac_aux_dir}config.guess"; then ac_config_guess="$SHELL ${ac_aux_dir}config.guess" fi if test -f "${ac_aux_dir}config.sub"; then ac_config_sub="$SHELL ${ac_aux_dir}config.sub" fi if test -f "$ac_aux_dir/configure"; then ac_configure="$SHELL ${ac_aux_dir}configure" fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: '$ac_var' was set to '$ac_old_val' in the previous run" >&5 printf "%s\n" "$as_me: error: '$ac_var' was set to '$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: '$ac_var' was not set in the previous run" >&5 printf "%s\n" "$as_me: error: '$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: '$ac_var' has changed since the previous run:" >&5 printf "%s\n" "$as_me: error: '$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in '$ac_var' since the previous run:" >&5 printf "%s\n" "$as_me: warning: ignoring whitespace changes in '$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: '$ac_old_val'" >&5 printf "%s\n" "$as_me: former value: '$ac_old_val'" >&2;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: '$ac_new_val'" >&5 printf "%s\n" "$as_me: current value: '$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run '${MAKE-make} distclean' and/or 'rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # libpng does not follow GNU file name conventions (hence 'foreign') # color-tests requires automake 1.11 or later # silent-rules requires automake 1.11 or later # dist-xz requires automake 1.11 or later # 1.12.2 fixes a security issue in 1.11.2 and 1.12.1 # 1.13 is required for parallel tests am__api_version='1.16' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 printf %s "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if test ${ac_cv_path_install+y} then : printf %s "(cached) " >&6 else case e in #( e) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac # Account for fact that we put trailing slashes in our PATH walk. case $as_dir in #(( ./ | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir/" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir ;; esac fi if test ${ac_cv_path_install+y}; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 printf "%s\n" "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 printf %s "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi if test "$2" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi rm -f conftest.file test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was 's,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`printf "%s\n" "$program_transform_name" | sed "$ac_script"` # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` if test x"${MISSING+set}" != xset; then MISSING="\${SHELL} '$am_aux_dir/missing'" fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 printf "%s\n" "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_STRIP+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 printf "%s\n" "$STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_STRIP+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 printf "%s\n" "$ac_ct_STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a race-free mkdir -p" >&5 printf %s "checking for a race-free mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if test ${ac_cv_path_mkdir+y} then : printf %s "(cached) " >&6 else case e in #( e) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext" || continue case `"$as_dir$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir ('*'coreutils) '* | \ *'BusyBox '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS ;; esac fi test -d ./--version && rmdir ./--version if test ${ac_cv_path_mkdir+y}; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use plain mkdir -p, # in the hope it doesn't have the bugs of ancient mkdir. MKDIR_P='mkdir -p' fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 printf "%s\n" "$MKDIR_P" >&6; } for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_AWK+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 printf "%s\n" "$AWK" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$AWK" && break done { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 printf %s "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`printf "%s\n" "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval test \${ac_cv_prog_make_${ac_make}_set+y} then : printf %s "(cached) " >&6 else case e in #( e) cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make ;; esac fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } SET_MAKE= else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null # Check whether --enable-silent-rules was given. if test ${enable_silent_rules+y} then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=1;; esac am_make=${MAKE-make} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 printf %s "checking whether $am_make supports nested variables... " >&6; } if test ${am_cv_make_support_nested_variables+y} then : printf %s "(cached) " >&6 else case e in #( e) if printf "%s\n" 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 printf "%s\n" "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='libpng' VERSION='1.6.43' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h printf "%s\n" "#define VERSION \"$VERSION\"" >>confdefs.h # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # mkdir_p='$(MKDIR_P)' # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar pax cpio none' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' # Variables for tags utilities; see am/tags.am if test -z "$CTAGS"; then CTAGS=ctags fi if test -z "$ETAGS"; then ETAGS=etags fi if test -z "$CSCOPE"; then CSCOPE=cscope fi # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 fi fi # The following line causes --disable-maintainer-mode to be the default to # configure. This is necessary because libpng distributions cannot rely on the # time stamps of the autotools generated files being correct { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 printf %s "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } # Check whether --enable-maintainer-mode was given. if test ${enable_maintainer_mode+y} then : enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval else case e in #( e) USE_MAINTAINER_MODE=no ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 printf "%s\n" "$USE_MAINTAINER_MODE" >&6; } if test $USE_MAINTAINER_MODE = yes; then MAINTAINER_MODE_TRUE= MAINTAINER_MODE_FALSE='#' else MAINTAINER_MODE_TRUE='#' MAINTAINER_MODE_FALSE= fi MAINT=$MAINTAINER_MODE_TRUE PNGLIB_VERSION=1.6.43 PNGLIB_MAJOR=1 PNGLIB_MINOR=6 PNGLIB_RELEASE=43 ac_config_headers="$ac_config_headers config.h" # Check for basic programs. ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@" fi fi fi ;; esac fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args. set dummy ${ac_tool_prefix}clang; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}clang" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "clang", so it can be a program name with args. set dummy clang; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="clang" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi fi test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See 'config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion -version; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 printf %s "checking whether the C compiler works... " >&6; } ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : # Autoconf-2.13 could set the ac_cv_exeext variable to 'no'. # So ignore a value of 'no', otherwise this would lead to 'EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test ${ac_cv_exeext+y} && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an '-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else case e in #( e) ac_file='' ;; esac fi if test -z "$ac_file" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See 'config.log' for more details" "$LINENO" 5; } else case e in #( e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 printf %s "checking for C compiler default output file name... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 printf "%s\n" "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 printf %s "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : # If both 'conftest.exe' and 'conftest' are 'present' (well, observable) # catch 'conftest.exe'. For instance with Cygwin, 'ls conftest' will # work properly (i.e., refer to 'conftest.exe'), while it won't with # 'rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else case e in #( e) { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See 'config.log' for more details" "$LINENO" 5; } ;; esac fi rm -f conftest conftest$ac_cv_exeext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 printf "%s\n" "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { FILE *f = fopen ("conftest.out", "w"); if (!f) return 1; return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 printf %s "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error 77 "cannot run C compiled programs. If you meant to cross compile, use '--host'. See 'config.log' for more details" "$LINENO" 5; } fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 printf "%s\n" "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext \ conftest.o conftest.obj conftest.out ac_clean_files=$ac_clean_files_save { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 printf %s "checking for suffix of object files... " >&6; } if test ${ac_cv_objext+y} then : printf %s "(cached) " >&6 else case e in #( e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else case e in #( e) printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See 'config.log' for more details" "$LINENO" 5; } ;; esac fi rm -f conftest.$ac_cv_objext conftest.$ac_ext ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 printf "%s\n" "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5 printf %s "checking whether the compiler supports GNU C... " >&6; } if test ${ac_cv_c_compiler_gnu+y} then : printf %s "(cached) " >&6 else case e in #( e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_compiler_gnu=yes else case e in #( e) ac_compiler_gnu=no ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; } ac_compiler_gnu=$ac_cv_c_compiler_gnu if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+y} ac_save_CFLAGS=$CFLAGS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 printf %s "checking whether $CC accepts -g... " >&6; } if test ${ac_cv_prog_cc_g+y} then : printf %s "(cached) " >&6 else case e in #( e) ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_g=yes else case e in #( e) CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : else case e in #( e) ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 printf "%s\n" "$ac_cv_prog_cc_g" >&6; } if test $ac_test_CFLAGS; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi ac_prog_cc_stdc=no if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5 printf %s "checking for $CC option to enable C11 features... " >&6; } if test ${ac_cv_prog_cc_c11+y} then : printf %s "(cached) " >&6 else case e in #( e) ac_cv_prog_cc_c11=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c11_program _ACEOF for ac_arg in '' -std=gnu11 do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c11=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c11" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC ;; esac fi if test "x$ac_cv_prog_cc_c11" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else case e in #( e) if test "x$ac_cv_prog_cc_c11" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else case e in #( e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5 printf "%s\n" "$ac_cv_prog_cc_c11" >&6; } CC="$CC $ac_cv_prog_cc_c11" ;; esac fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11 ac_prog_cc_stdc=c11 ;; esac fi fi if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5 printf %s "checking for $CC option to enable C99 features... " >&6; } if test ${ac_cv_prog_cc_c99+y} then : printf %s "(cached) " >&6 else case e in #( e) ac_cv_prog_cc_c99=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c99_program _ACEOF for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99= do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c99=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c99" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC ;; esac fi if test "x$ac_cv_prog_cc_c99" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else case e in #( e) if test "x$ac_cv_prog_cc_c99" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else case e in #( e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 printf "%s\n" "$ac_cv_prog_cc_c99" >&6; } CC="$CC $ac_cv_prog_cc_c99" ;; esac fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 ac_prog_cc_stdc=c99 ;; esac fi fi if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5 printf %s "checking for $CC option to enable C89 features... " >&6; } if test ${ac_cv_prog_cc_c89+y} then : printf %s "(cached) " >&6 else case e in #( e) ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c89_program _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC ;; esac fi if test "x$ac_cv_prog_cc_c89" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else case e in #( e) if test "x$ac_cv_prog_cc_c89" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else case e in #( e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 printf "%s\n" "$ac_cv_prog_cc_c89" >&6; } CC="$CC $ac_cv_prog_cc_c89" ;; esac fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 ac_prog_cc_stdc=c89 ;; esac fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 printf %s "checking whether $CC understands -c and -o together... " >&6; } if test ${am_cv_prog_cc_c_o+y} then : printf %s "(cached) " >&6 else case e in #( e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 printf "%s\n" "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5 printf %s "checking whether ${MAKE-make} supports the include directive... " >&6; } cat > confinc.mk << 'END' am__doit: @echo this is the am__doit target >confinc.out .PHONY: am__doit END am__include="#" am__quote= # BSD make does it like this. echo '.include "confinc.mk" # ignored' > confmf.BSD # Other make implementations (GNU, Solaris 10, AIX) do it like this. echo 'include confinc.mk # ignored' > confmf.GNU _am_result=no for s in GNU BSD; do { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5 (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } case $?:`cat confinc.out 2>/dev/null` in #( '0:this is the am__doit target') : case $s in #( BSD) : am__include='.include' am__quote='"' ;; #( *) : am__include='include' am__quote='' ;; esac ;; #( *) : ;; esac if test "$am__include" != "#"; then _am_result="yes ($s style)" break fi done rm -f confinc.* confmf.* { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5 printf "%s\n" "${_am_result}" >&6; } # Check whether --enable-dependency-tracking was given. if test ${enable_dependency_tracking+y} then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi depcc="$CC" am_compiler_list= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 printf %s "checking dependency style of $depcc... " >&6; } if test ${am_cv_CC_dependencies_compiler_type+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 printf "%s\n" "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi # By default we simply use the C compiler to build assembly code. test "${CCAS+set}" = set || CCAS=$CC test "${CCASFLAGS+set}" = set || CCASFLAGS=$CFLAGS depcc="$CCAS" am_compiler_list= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 printf %s "checking dependency style of $depcc... " >&6; } if test ${am_cv_CCAS_dependencies_compiler_type+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CCAS_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CCAS_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CCAS_dependencies_compiler_type=none fi ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_CCAS_dependencies_compiler_type" >&5 printf "%s\n" "$am_cv_CCAS_dependencies_compiler_type" >&6; } CCASDEPMODE=depmode=$am_cv_CCAS_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CCAS_dependencies_compiler_type" = gcc3; then am__fastdepCCAS_TRUE= am__fastdepCCAS_FALSE='#' else am__fastdepCCAS_TRUE='#' am__fastdepCCAS_FALSE= fi # Make sure we can run config.sub. $SHELL "${ac_aux_dir}config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL ${ac_aux_dir}config.sub" "$LINENO" 5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 printf %s "checking build system type... " >&6; } if test ${ac_cv_build+y} then : printf %s "(cached) " >&6 else case e in #( e) ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "${ac_aux_dir}config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "${ac_aux_dir}config.sub" $ac_build_alias` || as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $ac_build_alias failed" "$LINENO" 5 ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 printf "%s\n" "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 printf %s "checking host system type... " >&6; } if test ${ac_cv_host+y} then : printf %s "(cached) " >&6 else case e in #( e) if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "${ac_aux_dir}config.sub" $host_alias` || as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $host_alias failed" "$LINENO" 5 fi ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 printf "%s\n" "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 printf %s "checking for a sed that does not truncate output... " >&6; } if test ${ac_cv_path_SED+y} then : printf %s "(cached) " >&6 else case e in #( e) ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in sed gsed do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in #( *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; #( *) ac_count=0 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 printf "%s\n" "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 printf %s "checking for grep that handles long lines and -e... " >&6; } if test ${ac_cv_path_GREP+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in grep ggrep do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in #( *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; #( *) ac_count=0 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 printf "%s\n" "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 printf %s "checking for egrep... " >&6; } if test ${ac_cv_path_EGREP+y} then : printf %s "(cached) " >&6 else case e in #( e) if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in egrep do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in #( *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; #( *) ac_count=0 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 printf "%s\n" "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" EGREP_TRADITIONAL=$EGREP ac_cv_path_EGREP_TRADITIONAL=$EGREP { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 printf %s "checking for fgrep... " >&6; } if test ${ac_cv_path_FGREP+y} then : printf %s "(cached) " >&6 else case e in #( e) if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 then ac_cv_path_FGREP="$GREP -F" else if test -z "$FGREP"; then ac_path_FGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in fgrep do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_FGREP" || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in #( *GNU*) ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; #( *) ac_count=0 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" 'FGREP' >> "conftest.nl" "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_FGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_FGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_FGREP"; then as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_FGREP=$FGREP fi fi ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 printf "%s\n" "$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" test -z "$GREP" && GREP=grep ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 printf %s "checking how to print strings... " >&6; } # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "" } case $ECHO in printf*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: printf" >&5 printf "%s\n" "printf" >&6; } ;; print*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 printf "%s\n" "print -r" >&6; } ;; *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: cat" >&5 printf "%s\n" "cat" >&6; } ;; esac # Check whether --with-gnu-ld was given. if test ${with_gnu_ld+y} then : withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes else case e in #( e) with_gnu_ld=no ;; esac fi ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 printf %s "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 printf %s "checking for GNU ld... " >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 printf %s "checking for non-GNU ld... " >&6; } fi if test ${lt_cv_path_LD+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 printf "%s\n" "$LD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 printf %s "checking if the linker ($LD) is GNU ld... " >&6; } if test ${lt_cv_prog_gnu_ld+y} then : printf %s "(cached) " >&6 else case e in #( e) # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 printf "%s\n" "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 printf %s "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test ${ac_cv_prog_CPP+y} then : printf %s "(cached) " >&6 else case e in #( e) # Double quotes because $CC needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" cpp /lib/cpp do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO" then : else case e in #( e) # Broken: fails on valid input. continue ;; esac fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO" then : # Broken: success on invalid input. continue else case e in #( e) # Passes both tests. ac_preproc_ok=: break ;; esac fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of 'break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok then : break fi done ac_cv_prog_CPP=$CPP ;; esac fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 printf "%s\n" "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO" then : else case e in #( e) # Broken: fails on valid input. continue ;; esac fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO" then : # Broken: success on invalid input. continue else case e in #( e) # Passes both tests. ac_preproc_ok=: break ;; esac fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of 'break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok then : else case e in #( e) { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See 'config.log' for more details" "$LINENO" 5; } ;; esac fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_AWK+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 printf "%s\n" "$AWK" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$AWK" && break done { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 printf %s "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 printf "%s\n" "no, using $LN_S" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 printf %s "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`printf "%s\n" "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval test \${ac_cv_prog_make_${ac_make}_set+y} then : printf %s "(cached) " >&6 else case e in #( e) cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make ;; esac fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } SET_MAKE= else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi case `pwd` in *\ * | *\ *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 printf "%s\n" "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac macro_version='2.4.7' macro_revision='2.4.7' ltmain=$ac_aux_dir/ltmain.sh # Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\(["`$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 printf %s "checking for BSD- or MS-compatible name lister (nm)... " >&6; } if test ${lt_cv_path_NM+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM=$NM else lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. tmp_nm=$ac_dir/$lt_tmp_nm if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty case $build_os in mingw*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac case `"$tmp_nm" -B $lt_bad_file 2>&1 | $SED '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | $SED '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 printf "%s\n" "$lt_cv_path_NM" >&6; } if test no != "$lt_cv_path_NM"; then NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else if test -n "$ac_tool_prefix"; then for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_DUMPBIN+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$DUMPBIN"; then ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi DUMPBIN=$ac_cv_prog_DUMPBIN if test -n "$DUMPBIN"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 printf "%s\n" "$DUMPBIN" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$DUMPBIN" && break done fi if test -z "$DUMPBIN"; then ac_ct_DUMPBIN=$DUMPBIN for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_DUMPBIN+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$ac_ct_DUMPBIN"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN if test -n "$ac_ct_DUMPBIN"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 printf "%s\n" "$ac_ct_DUMPBIN" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_DUMPBIN" && break done if test "x$ac_ct_DUMPBIN" = x; then DUMPBIN=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DUMPBIN=$ac_ct_DUMPBIN fi fi case `$DUMPBIN -symbols -headers /dev/null 2>&1 | $SED '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: ;; esac fi if test : != "$DUMPBIN"; then NM=$DUMPBIN fi fi test -z "$NM" && NM=nm { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 printf %s "checking the name lister ($NM) interface... " >&6; } if test ${lt_cv_nm_interface+y} then : printf %s "(cached) " >&6 else case e in #( e) lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest* ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 printf "%s\n" "$lt_cv_nm_interface" >&6; } # find the maximum length of command line arguments { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 printf %s "checking the maximum length of command line arguments... " >&6; } if test ${lt_cv_sys_max_cmd_len+y} then : printf %s "(cached) " >&6 else case e in #( e) i=0 teststring=ABCD case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; bitrig* | darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | $SED 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac ;; esac fi if test -n "$lt_cv_sys_max_cmd_len"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 printf "%s\n" "$lt_cv_sys_max_cmd_len" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5 printf "%s\n" "none" >&6; } fi max_cmd_len=$lt_cv_sys_max_cmd_len : ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 printf %s "checking how to convert $build file names to $host format... " >&6; } if test ${lt_cv_to_host_file_cmd+y} then : printf %s "(cached) " >&6 else case e in #( e) case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac ;; esac fi to_host_file_cmd=$lt_cv_to_host_file_cmd { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 printf "%s\n" "$lt_cv_to_host_file_cmd" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 printf %s "checking how to convert $build file names to toolchain format... " >&6; } if test ${lt_cv_to_tool_file_cmd+y} then : printf %s "(cached) " >&6 else case e in #( e) #assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac ;; esac fi to_tool_file_cmd=$lt_cv_to_tool_file_cmd { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 printf "%s\n" "$lt_cv_to_tool_file_cmd" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 printf %s "checking for $LD option to reload object files... " >&6; } if test ${lt_cv_ld_reload_flag+y} then : printf %s "(cached) " >&6 else case e in #( e) lt_cv_ld_reload_flag='-r' ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 printf "%s\n" "$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in cygwin* | mingw* | pw32* | cegcc*) if test yes != "$GCC"; then reload_cmds=false fi ;; darwin*) if test yes = "$GCC"; then reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi ;; esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}file", so it can be a program name with args. set dummy ${ac_tool_prefix}file; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_FILECMD+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$FILECMD"; then ac_cv_prog_FILECMD="$FILECMD" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_FILECMD="${ac_tool_prefix}file" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi FILECMD=$ac_cv_prog_FILECMD if test -n "$FILECMD"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $FILECMD" >&5 printf "%s\n" "$FILECMD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_FILECMD"; then ac_ct_FILECMD=$FILECMD # Extract the first word of "file", so it can be a program name with args. set dummy file; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_FILECMD+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$ac_ct_FILECMD"; then ac_cv_prog_ac_ct_FILECMD="$ac_ct_FILECMD" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_FILECMD="file" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi ac_ct_FILECMD=$ac_cv_prog_ac_ct_FILECMD if test -n "$ac_ct_FILECMD"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_FILECMD" >&5 printf "%s\n" "$ac_ct_FILECMD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_FILECMD" = x; then FILECMD=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac FILECMD=$ac_ct_FILECMD fi else FILECMD="$ac_cv_prog_FILECMD" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_OBJDUMP+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 printf "%s\n" "$OBJDUMP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_OBJDUMP+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 printf "%s\n" "$ac_ct_OBJDUMP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi test -z "$OBJDUMP" && OBJDUMP=objdump { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 printf %s "checking how to recognize dependent libraries... " >&6; } if test ${lt_cv_deplibs_check_method+y} then : printf %s "(cached) " >&6 else case e in #( e) lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # that responds to the $file_magic_cmd with a given extended regex. # If you have 'file' or equivalent on your system and you're not sure # whether 'pass_all' will *always* work, you probably want this one. case $host_os in aix[4-9]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='$FILECMD -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly* | midnightbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=$FILECMD case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[3-9]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd* | bitrig*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; os2*) lt_cv_deplibs_check_method=pass_all ;; esac ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 printf "%s\n" "$lt_cv_deplibs_check_method" >&6; } file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_DLLTOOL+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 printf "%s\n" "$DLLTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_DLLTOOL+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 printf "%s\n" "$ac_ct_DLLTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi test -z "$DLLTOOL" && DLLTOOL=dlltool { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 printf %s "checking how to associate runtime and link libraries... " >&6; } if test ${lt_cv_sharedlib_from_linklib_cmd+y} then : printf %s "(cached) " >&6 else case e in #( e) lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh; # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 printf "%s\n" "$lt_cv_sharedlib_from_linklib_cmd" >&6; } sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO if test -n "$ac_tool_prefix"; then for ac_prog in ar do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_AR+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi AR=$ac_cv_prog_AR if test -n "$AR"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 printf "%s\n" "$AR" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_AR+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 printf "%s\n" "$ac_ct_AR" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} # Use ARFLAGS variable as AR's operation code to sync the variable naming with # Automake. If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have # higher priority because thats what people were doing historically (setting # ARFLAGS for automake and AR_FLAGS for libtool). FIXME: Make the AR_FLAGS # variable obsoleted/removed. test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr} lt_ar_flags=$AR_FLAGS # Make AR_FLAGS overridable by 'make ARFLAGS='. Don't try to run-time override # by AR_FLAGS because that was never working and AR_FLAGS is about to die. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 printf %s "checking for archiver @FILE support... " >&6; } if test ${lt_cv_ar_at_file+y} then : printf %s "(cached) " >&6 else case e in #( e) lt_cv_ar_at_file=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 printf "%s\n" "$lt_cv_ar_at_file" >&6; } if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_STRIP+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 printf "%s\n" "$STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_STRIP+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 printf "%s\n" "$ac_ct_STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi test -z "$STRIP" && STRIP=: if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_RANLIB+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 printf "%s\n" "$RANLIB" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_RANLIB+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 printf "%s\n" "$ac_ct_RANLIB" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi test -z "$RANLIB" && RANLIB=: # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in bitrig* | openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Check for command to grab the raw symbol name followed by C symbol from nm. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 printf %s "checking command to parse $NM output from $compiler object... " >&6; } if test ${lt_cv_sys_global_symbol_pipe+y} then : printf %s "(cached) " >&6 else case e in #( e) # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[BCDT]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) if test ia64 = "$host_cpu"; then symcode='[ABCDEGRST]' fi ;; irix* | nonstopux*) symcode='[BCDEGRST]' ;; osf*) symcode='[BCDEGQRST]' ;; solaris*) symcode='[BDRT]' ;; sco3.2v5*) symcode='[DT]' ;; sysv4.2uw2*) symcode='[DT]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[ABDT]' ;; sysv4) symcode='[DFNSTU]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[ABCDGIRSTW]' ;; esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. lt_cv_sys_global_symbol_to_import="$SED -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" lt_c_name_lib_hook="\ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" else # Disable hooks by default. lt_cv_sys_global_symbol_to_import= lt_cdecl_hook= lt_c_name_hook= lt_c_name_lib_hook= fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="$SED -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="$SED -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="$SED -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++ or ICC, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ " /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ " /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ " {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ " s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else lt_cv_sys_global_symbol_pipe="$SED -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | $SED '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= fi done ;; esac fi if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: failed" >&5 printf "%s\n" "failed" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ok" >&5 printf "%s\n" "ok" >&6; } fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then nm_file_list_spec='@' fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 printf %s "checking for sysroot... " >&6; } # Check whether --with-sysroot was given. if test ${with_sysroot+y} then : withval=$with_sysroot; else case e in #( e) with_sysroot=no ;; esac fi lt_sysroot= case $with_sysroot in #( yes) if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | $SED -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 printf "%s\n" "$with_sysroot" >&6; } as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 printf "%s\n" "${lt_sysroot:-no}" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5 printf %s "checking for a working dd... " >&6; } if test ${ac_cv_path_lt_DD+y} then : printf %s "(cached) " >&6 else case e in #( e) printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i : ${lt_DD:=$DD} if test -z "$lt_DD"; then ac_path_lt_DD_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in dd do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_lt_DD="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_lt_DD" || continue if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: fi $ac_path_lt_DD_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_lt_DD"; then : fi else ac_cv_path_lt_DD=$lt_DD fi rm -f conftest.i conftest2.i conftest.out ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 printf "%s\n" "$ac_cv_path_lt_DD" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5 printf %s "checking how to truncate binary pipes... " >&6; } if test ${lt_cv_truncate_bin+y} then : printf %s "(cached) " >&6 else case e in #( e) printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i lt_cv_truncate_bin= if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" fi rm -f conftest.i conftest2.i conftest.out test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 printf "%s\n" "$lt_cv_truncate_bin" >&6; } # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in $*""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } # Check whether --enable-libtool-lock was given. if test ${enable_libtool_lock+y} then : enableval=$enable_libtool_lock; fi test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out what ABI is being produced by ac_compile, and set mode # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `$FILECMD conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; *ELF-64*) HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test yes = "$lt_cv_prog_gnu_ld"; then case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; mips64*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then emul=elf case `$FILECMD conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; *64-bit*) emul="${emul}64" ;; esac case `$FILECMD conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; *LSB*) emul="${emul}ltsmip" ;; esac case `$FILECMD conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; esac LD="${LD-ld} -m $emul" fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. Note that the listed cases only cover the # situations where additional linker options are needed (such as when # doing 32-bit compilation for a host where ld defaults to 64-bit, or # vice versa); the common cases where no linker options are needed do # not appear in the list. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `$FILECMD conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `$FILECMD conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*linux*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*linux*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 printf %s "checking whether the C compiler needs -belf... " >&6; } if test ${lt_cv_cc_needs_belf+y} then : printf %s "(cached) " >&6 else case e in #( e) ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_cv_cc_needs_belf=yes else case e in #( e) lt_cv_cc_needs_belf=no ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 printf "%s\n" "$lt_cv_cc_needs_belf" >&6; } if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `$FILECMD conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD=${LD-ld}_sol2 fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks=$enable_libtool_lock if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. set dummy ${ac_tool_prefix}mt; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_MANIFEST_TOOL+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$MANIFEST_TOOL"; then ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL if test -n "$MANIFEST_TOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 printf "%s\n" "$MANIFEST_TOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_MANIFEST_TOOL"; then ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL # Extract the first word of "mt", so it can be a program name with args. set dummy mt; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_MANIFEST_TOOL+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$ac_ct_MANIFEST_TOOL"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL if test -n "$ac_ct_MANIFEST_TOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 printf "%s\n" "$ac_ct_MANIFEST_TOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_MANIFEST_TOOL" = x; then MANIFEST_TOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL fi else MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" fi test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 printf %s "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } if test ${lt_cv_path_mainfest_tool+y} then : printf %s "(cached) " >&6 else case e in #( e) lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&5 if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest* ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 printf "%s\n" "$lt_cv_path_mainfest_tool" >&6; } if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi case $host_os in rhapsody* | darwin*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_DSYMUTIL+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$DSYMUTIL"; then ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi DSYMUTIL=$ac_cv_prog_DSYMUTIL if test -n "$DSYMUTIL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 printf "%s\n" "$DSYMUTIL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_DSYMUTIL"; then ac_ct_DSYMUTIL=$DSYMUTIL # Extract the first word of "dsymutil", so it can be a program name with args. set dummy dsymutil; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_DSYMUTIL+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$ac_ct_DSYMUTIL"; then ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL if test -n "$ac_ct_DSYMUTIL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 printf "%s\n" "$ac_ct_DSYMUTIL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_DSYMUTIL" = x; then DSYMUTIL=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DSYMUTIL=$ac_ct_DSYMUTIL fi else DSYMUTIL="$ac_cv_prog_DSYMUTIL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. set dummy ${ac_tool_prefix}nmedit; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_NMEDIT+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$NMEDIT"; then ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi NMEDIT=$ac_cv_prog_NMEDIT if test -n "$NMEDIT"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 printf "%s\n" "$NMEDIT" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_NMEDIT"; then ac_ct_NMEDIT=$NMEDIT # Extract the first word of "nmedit", so it can be a program name with args. set dummy nmedit; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_NMEDIT+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$ac_ct_NMEDIT"; then ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_NMEDIT="nmedit" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT if test -n "$ac_ct_NMEDIT"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 printf "%s\n" "$ac_ct_NMEDIT" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_NMEDIT" = x; then NMEDIT=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac NMEDIT=$ac_ct_NMEDIT fi else NMEDIT="$ac_cv_prog_NMEDIT" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. set dummy ${ac_tool_prefix}lipo; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_LIPO+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$LIPO"; then ac_cv_prog_LIPO="$LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi LIPO=$ac_cv_prog_LIPO if test -n "$LIPO"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 printf "%s\n" "$LIPO" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_LIPO"; then ac_ct_LIPO=$LIPO # Extract the first word of "lipo", so it can be a program name with args. set dummy lipo; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_LIPO+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$ac_ct_LIPO"; then ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_LIPO="lipo" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO if test -n "$ac_ct_LIPO"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 printf "%s\n" "$ac_ct_LIPO" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_LIPO" = x; then LIPO=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac LIPO=$ac_ct_LIPO fi else LIPO="$ac_cv_prog_LIPO" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. set dummy ${ac_tool_prefix}otool; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_OTOOL+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$OTOOL"; then ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi OTOOL=$ac_cv_prog_OTOOL if test -n "$OTOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 printf "%s\n" "$OTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL"; then ac_ct_OTOOL=$OTOOL # Extract the first word of "otool", so it can be a program name with args. set dummy otool; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_OTOOL+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$ac_ct_OTOOL"; then ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL="otool" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL if test -n "$ac_ct_OTOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 printf "%s\n" "$ac_ct_OTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_OTOOL" = x; then OTOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL=$ac_ct_OTOOL fi else OTOOL="$ac_cv_prog_OTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. set dummy ${ac_tool_prefix}otool64; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_OTOOL64+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$OTOOL64"; then ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi OTOOL64=$ac_cv_prog_OTOOL64 if test -n "$OTOOL64"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 printf "%s\n" "$OTOOL64" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL64"; then ac_ct_OTOOL64=$OTOOL64 # Extract the first word of "otool64", so it can be a program name with args. set dummy otool64; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_OTOOL64+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$ac_ct_OTOOL64"; then ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL64="otool64" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 if test -n "$ac_ct_OTOOL64"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 printf "%s\n" "$ac_ct_OTOOL64" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_OTOOL64" = x; then OTOOL64=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL64=$ac_ct_OTOOL64 fi else OTOOL64="$ac_cv_prog_OTOOL64" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 printf %s "checking for -single_module linker flag... " >&6; } if test ${lt_cv_apple_cc_single_mod+y} then : printf %s "(cached) " >&6 else case e in #( e) lt_cv_apple_cc_single_mod=no if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&5 $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&5 # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 fi rm -rf libconftest.dylib* rm -f conftest.* fi ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 printf "%s\n" "$lt_cv_apple_cc_single_mod" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 printf %s "checking for -exported_symbols_list linker flag... " >&6; } if test ${lt_cv_ld_exported_symbols_list+y} then : printf %s "(cached) " >&6 else case e in #( e) lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_cv_ld_exported_symbols_list=yes else case e in #( e) lt_cv_ld_exported_symbols_list=no ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 printf "%s\n" "$lt_cv_ld_exported_symbols_list" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 printf %s "checking for -force_load linker flag... " >&6; } if test ${lt_cv_ld_force_load+y} then : printf %s "(cached) " >&6 else case e in #( e) lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 echo "$AR $AR_FLAGS libconftest.a conftest.o" >&5 $AR $AR_FLAGS libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&5 elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&5 fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 printf "%s\n" "$lt_cv_ld_force_load" >&6; } case $host_os in rhapsody* | darwin1.[012]) _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; darwin*) case $MACOSX_DEPLOYMENT_TARGET,$host in 10.[012],*|,*powerpc*-darwin[5-8]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; *) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi if test yes = "$lt_cv_ld_exported_symbols_list"; then _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac # func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x$2 in x) ;; *:) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" ;; x:*) eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" ;; *::*) eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" ;; *) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" ;; esac } ac_header= ac_cache= for ac_item in $ac_header_c_list do if test $ac_cache; then ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default" if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then printf "%s\n" "#define $ac_item 1" >> confdefs.h fi ac_header= ac_cache= elif test $ac_header; then ac_cache=$ac_item else ac_header=$ac_item fi done if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes then : printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default " if test "x$ac_cv_header_dlfcn_h" = xyes then : printf "%s\n" "#define HAVE_DLFCN_H 1" >>confdefs.h fi # Set options enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. set dummy ${ac_tool_prefix}as; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_AS+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$AS"; then ac_cv_prog_AS="$AS" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_AS="${ac_tool_prefix}as" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi AS=$ac_cv_prog_AS if test -n "$AS"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AS" >&5 printf "%s\n" "$AS" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_AS"; then ac_ct_AS=$AS # Extract the first word of "as", so it can be a program name with args. set dummy as; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_AS+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$ac_ct_AS"; then ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AS="as" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi ac_ct_AS=$ac_cv_prog_ac_ct_AS if test -n "$ac_ct_AS"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5 printf "%s\n" "$ac_ct_AS" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_AS" = x; then AS="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AS=$ac_ct_AS fi else AS="$ac_cv_prog_AS" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_DLLTOOL+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 printf "%s\n" "$DLLTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_DLLTOOL+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 printf "%s\n" "$ac_ct_DLLTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_OBJDUMP+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 printf "%s\n" "$OBJDUMP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_OBJDUMP+y} then : printf %s "(cached) " >&6 else case e in #( e) if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi ;; esac fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 printf "%s\n" "$ac_ct_OBJDUMP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi ;; esac test -z "$AS" && AS=as test -z "$DLLTOOL" && DLLTOOL=dlltool test -z "$OBJDUMP" && OBJDUMP=objdump enable_dlopen=no # Check whether --enable-shared was given. if test ${enable_shared+y} then : enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS=$lt_save_ifs ;; esac else case e in #( e) enable_shared=yes ;; esac fi # Check whether --enable-static was given. if test ${enable_static+y} then : enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS=$lt_save_ifs ;; esac else case e in #( e) enable_static=yes ;; esac fi # Check whether --with-pic was given. if test ${with_pic+y} then : withval=$with_pic; lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS=$lt_save_ifs ;; esac else case e in #( e) pic_mode=default ;; esac fi # Check whether --enable-fast-install was given. if test ${enable_fast_install+y} then : enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS=$lt_save_ifs ;; esac else case e in #( e) enable_fast_install=yes ;; esac fi shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[5-9]*,yes) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 printf %s "checking which variant of shared library versioning to provide... " >&6; } # Check whether --with-aix-soname was given. if test ${with_aix_soname+y} then : withval=$with_aix_soname; case $withval in aix|svr4|both) ;; *) as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 ;; esac lt_cv_with_aix_soname=$with_aix_soname else case e in #( e) if test ${lt_cv_with_aix_soname+y} then : printf %s "(cached) " >&6 else case e in #( e) lt_cv_with_aix_soname=aix ;; esac fi with_aix_soname=$lt_cv_with_aix_soname ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 printf "%s\n" "$with_aix_soname" >&6; } if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, # the AIX toolchain works better with OBJECT_MODE set (default 32). if test 64 = "${OBJECT_MODE-32}"; then shared_archive_member_spec=shr_64 else shared_archive_member_spec=shr fi fi ;; *) with_aix_soname=aix ;; esac # This can be used to rebuild libtool when needed LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' test -z "$LN_S" && LN_S="ln -s" if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 printf %s "checking for objdir... " >&6; } if test ${lt_cv_objdir+y} then : printf %s "(cached) " >&6 else case e in #( e) rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 printf "%s\n" "$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir printf "%s\n" "#define LT_OBJDIR \"$lt_cv_objdir/\"" >>confdefs.h case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a '.a' archive for static linking (except MSVC and # ICC, which need '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld old_CC=$CC old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o func_cc_basename $compiler cc_basename=$func_cc_basename_result # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 printf %s "checking for ${ac_tool_prefix}file... " >&6; } if test ${lt_cv_path_MAGIC_CMD+y} then : printf %s "(cached) " >&6 else case e in #( e) case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/${ac_tool_prefix}file"; then lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac ;; esac fi MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 printf "%s\n" "$MAGIC_CMD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for file" >&5 printf %s "checking for file... " >&6; } if test ${lt_cv_path_MAGIC_CMD+y} then : printf %s "(cached) " >&6 else case e in #( e) case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/file"; then lt_cv_path_MAGIC_CMD=$ac_dir/"file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac ;; esac fi MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 printf "%s\n" "$MAGIC_CMD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi else MAGIC_CMD=: fi fi fi ;; esac # Use C for the default configuration in the libtool script lt_save_CC=$CC ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o objext=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= if test yes = "$GCC"; then case $cc_basename in nvcc*) lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; *) lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 printf %s "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } if test ${lt_cv_prog_compiler_rtti_exceptions+y} then : printf %s "(cached) " >&6 else case e in #( e) lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $RM conftest* ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 printf "%s\n" "$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl= lt_prog_compiler_pic= lt_prog_compiler_static= if test yes = "$GCC"; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi lt_prog_compiler_pic='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) lt_prog_compiler_pic='-fPIC' ;; esac ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic=-Kconform_pic fi ;; *) lt_prog_compiler_pic='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 lt_prog_compiler_wl='-Xlinker ' if test -n "$lt_prog_compiler_pic"; then lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl='-Wl,' if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' case $cc_basename in nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; esac ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static='$wl-static' ;; esac ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64, which still supported -KPIC. ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # Lahey Fortran 8.1. lf95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='--shared' lt_prog_compiler_static='--static' ;; nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; tcc*) # Fabrice Bellard et al's Tiny C Compiler lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-qpic' lt_prog_compiler_static='-qstaticlink' ;; *) case `$CC -V 2>&1 | $SED 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='' ;; *Sun\ F* | *Sun*Fortran*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; *Intel*\ [CF]*Compiler*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; *Portland\ Group*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; esac ;; esac ;; newsos6) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static='-non_shared' ;; rdos*) lt_prog_compiler_static='-non_shared' ;; solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) lt_prog_compiler_wl='-Qoption ld ';; *) lt_prog_compiler_wl='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl='-Qoption ld ' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; unicos*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_can_build_shared=no ;; uts4*) lt_prog_compiler_pic='-pic' lt_prog_compiler_static='-Bstatic' ;; *) lt_prog_compiler_can_build_shared=no ;; esac fi case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; *) lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 printf %s "checking for $compiler option to produce PIC... " >&6; } if test ${lt_cv_prog_compiler_pic+y} then : printf %s "(cached) " >&6 else case e in #( e) lt_cv_prog_compiler_pic=$lt_prog_compiler_pic ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 printf "%s\n" "$lt_cv_prog_compiler_pic" >&6; } lt_prog_compiler_pic=$lt_cv_prog_compiler_pic # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 printf %s "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } if test ${lt_cv_prog_compiler_pic_works+y} then : printf %s "(cached) " >&6 else case e in #( e) lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works=yes fi fi $RM conftest* ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 printf "%s\n" "$lt_cv_prog_compiler_pic_works" >&6; } if test yes = "$lt_cv_prog_compiler_pic_works"; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; esac else lt_prog_compiler_pic= lt_prog_compiler_can_build_shared=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 printf %s "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if test ${lt_cv_prog_compiler_static_works+y} then : printf %s "(cached) " >&6 else case e in #( e) lt_cv_prog_compiler_static_works=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works=yes fi else lt_cv_prog_compiler_static_works=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 printf "%s\n" "$lt_cv_prog_compiler_static_works" >&6; } if test yes = "$lt_cv_prog_compiler_static_works"; then : else lt_prog_compiler_static= fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if test ${lt_cv_prog_compiler_c_o+y} then : printf %s "(cached) " >&6 else case e in #( e) lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 printf "%s\n" "$lt_cv_prog_compiler_c_o" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if test ${lt_cv_prog_compiler_c_o+y} then : printf %s "(cached) " >&6 else case e in #( e) lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 printf "%s\n" "$lt_cv_prog_compiler_c_o" >&6; } hard_links=nottested if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 printf %s "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 printf "%s\n" "$hard_links" >&6; } if test no = "$hard_links"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 printf "%s\n" "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 printf %s "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } runpath_var= allow_undefined_flag= always_export_symbols=no archive_cmds= archive_expsym_cmds= compiler_needs_object=no enable_shared_with_static_runtimes=no export_dynamic_flag_spec= export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' hardcode_automatic=no hardcode_direct=no hardcode_direct_absolute=no hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_minus_L=no hardcode_shlibpath_var=unsupported inherit_rpath=no link_all_deplibs=unknown module_cmds= module_expsym_cmds= old_archive_from_new_cmds= old_archive_from_expsyms_cmds= thread_safe_flag_spec= whole_archive_flag_spec= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ' (' and ')$', so one must not match beginning or # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', # as well as any symbol that contains 'd'. exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++ or Intel C++ Compiler. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC) with_gnu_ld=yes ;; openbsd* | bitrig*) with_gnu_ld=no ;; esac ld_shlibs=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; *\ \(GNU\ Binutils\)\ [3-9]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' export_dynamic_flag_spec='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test ia64 != "$host_cpu"; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' export_dynamic_flag_spec='$wl--export-all-symbols' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; haiku*) archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' link_all_deplibs=yes ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported shrext_cmds=.dll archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes file_list_spec='@' ;; interix[3-9]*) hardcode_direct=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='$wl-rpath,$libdir' export_dynamic_flag_spec='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 whole_archive_flag_spec= tmp_sharedflag='--shared' ;; nagfor*) # NAGFOR 5.3 tmp_sharedflag='-Wl,-shared' ;; xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes ;; esac case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C 5.9 whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in tcc*) export_dynamic_flag_spec='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else ld_shlibs=no fi ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac ;; sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct=yes hardcode_shlibpath_var=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac if test no = "$ld_shlibs"; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= whole_archive_flag_spec= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag=unsupported always_export_symbols=yes archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds='' hardcode_direct=yes hardcode_direct_absolute=yes hardcode_libdir_separator=':' link_all_deplibs=yes file_list_spec='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # traditional, no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. hardcode_direct=no hardcode_direct_absolute=no ;; esac if test yes = "$GCC"; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag="$shared_flag "'$wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi export_dynamic_flag_spec='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if test ${lt_cv_aix_libpath_+y} then : printf %s "(cached) " >&6 else case e in #( e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=/usr/lib:/lib fi ;; esac fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if test ${lt_cv_aix_libpath_+y} then : printf %s "(cached) " >&6 else case e in #( e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=/usr/lib:/lib fi ;; esac fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag=' $wl-bernotok' allow_undefined_flag=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' fi archive_cmds_need_lc=yes archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; bsdi[45]*) export_dynamic_flag_spec=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++ or Intel C++ Compiler. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl* | icl*) # Native MSVC or ICC hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported always_export_symbols=yes file_list_spec='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' enable_shared_with_static_runtimes=yes exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib old_postinstall_cmds='chmod 644 $oldlib' postlink_cmds='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC and ICC wrapper hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_from_new_cmds='true' # FIXME: Should let the user specify the lib program. old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' enable_shared_with_static_runtimes=yes ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported if test yes = "$lt_cv_ld_force_load"; then whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec='' fi link_all_deplibs=yes allow_undefined_flag=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" archive_expsym_cmds="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" module_expsym_cmds="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" else ld_shlibs=no fi ;; dgux*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly* | midnightbsd*) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test yes = "$GCC"; then archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes export_dynamic_flag_spec='$wl-E' ;; hpux10*) if test yes,no = "$GCC,$with_gnu_ld"; then archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 printf %s "checking if $CC understands -b... " >&6; } if test ${lt_cv_prog_compiler__b+y} then : printf %s "(cached) " >&6 else case e in #( e) lt_cv_prog_compiler__b=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -b" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler__b=yes fi else lt_cv_prog_compiler__b=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 printf "%s\n" "$lt_cv_prog_compiler__b" >&6; } if test yes = "$lt_cv_prog_compiler__b"; then archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi ;; esac fi if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no hardcode_shlibpath_var=no ;; *) hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test yes = "$GCC"; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 printf %s "checking whether the $host_os linker accepts -exported_symbol... " >&6; } if test ${lt_cv_irix_exported_symbol+y} then : printf %s "(cached) " >&6 else case e in #( e) save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo (void) { return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_cv_irix_exported_symbol=yes else case e in #( e) lt_cv_irix_exported_symbol=no ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 printf "%s\n" "$lt_cv_irix_exported_symbol" >&6; } if test yes = "$lt_cv_irix_exported_symbol"; then archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: inherit_rpath=yes link_all_deplibs=yes ;; linux*) case $cc_basename in tcc*) # Fabrice Bellard et al's Tiny C Compiler ld_shlibs=yes archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; *nto* | *qnx*) ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no hardcode_direct_absolute=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec='$wl-rpath,$libdir' export_dynamic_flag_spec='$wl-E' else archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='$wl-rpath,$libdir' fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported shrext_cmds=.dll archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes file_list_spec='@' ;; osf3*) if test yes = "$GCC"; then allow_undefined_flag=' $wl-expect_unresolved $wl\*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test yes = "$GCC"; then allow_undefined_flag=' $wl-expect_unresolved $wl\*' archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi archive_cmds_need_lc='no' hardcode_libdir_separator=: ;; solaris*) no_undefined_flag=' -z defs' if test yes = "$GCC"; then wlarc='$wl' archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='$wl' archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi hardcode_libdir_flag_spec='-R$libdir' hardcode_shlibpath_var=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test yes = "$GCC"; then whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else whole_archive_flag_spec='-z allextract$convenience -z defaultextract' fi ;; esac link_all_deplibs=yes ;; sunos4*) if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; sysv4) case $host_vendor in sni) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds='$CC -r -o $output$reload_objs' hardcode_direct=no ;; motorola) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var=no ;; sysv4.3*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no export_dynamic_flag_spec='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag='$wl-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag='$wl-z,text' allow_undefined_flag='$wl-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='$wl-R,$libdir' hardcode_libdir_separator=':' link_all_deplibs=yes export_dynamic_flag_spec='$wl-Bexport' runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; *) ld_shlibs=no ;; esac if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) export_dynamic_flag_spec='$wl-Blargedynsym' ;; esac fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 printf "%s\n" "$ld_shlibs" >&6; } test no = "$ld_shlibs" && can_build_shared=no with_gnu_ld=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc" in x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes if test yes,yes = "$GCC,$enable_shared"; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 printf %s "checking whether -lc should be explicitly linked in... " >&6; } if test ${lt_cv_archive_cmds_need_lc+y} then : printf %s "(cached) " >&6 else case e in #( e) $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc=no else lt_cv_archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 printf "%s\n" "$lt_cv_archive_cmds_need_lc" >&6; } archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ;; esac fi ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 printf %s "checking dynamic linker characteristics... " >&6; } if test yes = "$GCC"; then case $host_os in darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` # ...but if some path component already ends with the multilib dir we assume # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). case "$lt_multi_os_dir; $lt_search_path_spec " in "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) lt_multi_os_dir= ;; esac for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" elif test -n "$lt_multi_os_dir"; then test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS = " "; FS = "/|\n";} { lt_foo = ""; lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[lt_foo]++; } if (lt_freq[lt_foo] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's|/\([A-Za-z]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a(lib.so.V)' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | $SED -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | $SED -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl* | *,icl*) # Native MSVC or ICC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC and ICC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly* | midnightbsd*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. hardcode_libdir_flag_spec='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if test ${lt_cv_shlibpath_overrides_runpath+y} then : printf %s "(cached) " >&6 else case e in #( e) lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir ;; esac fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 printf "%s\n" "$dynamic_linker" >&6; } test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 printf %s "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || test yes = "$hardcode_automatic"; then # We can hardcode non-existent directories. if test no != "$hardcode_direct" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && test no != "$hardcode_minus_L"; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 printf "%s\n" "$hardcode_action" >&6; } if test relink = "$hardcode_action" || test yes = "$inherit_rpath"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 printf %s "checking for dlopen in -ldl... " >&6; } if test ${ac_cv_lib_dl_dlopen+y} then : printf %s "(cached) " >&6 else case e in #( e) ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. The 'extern "C"' is for builds by C++ compilers; although this is not generally supported in C code supporting it here has little cost and some practical benefit (sr 110532). */ #ifdef __cplusplus extern "C" #endif char dlopen (void); int main (void) { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dl_dlopen=yes else case e in #( e) ac_cv_lib_dl_dlopen=no ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 printf "%s\n" "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl else case e in #( e) lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; esac fi ;; tpf*) # Don't try to run any link tests for TPF. We know it's impossible # because TPF is a cross-compiler, and we know how we open DSOs. lt_cv_dlopen=dlopen lt_cv_dlopen_libs= lt_cv_dlopen_self=no ;; *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" if test "x$ac_cv_func_shl_load" = xyes then : lt_cv_dlopen=shl_load else case e in #( e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 printf %s "checking for shl_load in -ldld... " >&6; } if test ${ac_cv_lib_dld_shl_load+y} then : printf %s "(cached) " >&6 else case e in #( e) ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. The 'extern "C"' is for builds by C++ compilers; although this is not generally supported in C code supporting it here has little cost and some practical benefit (sr 110532). */ #ifdef __cplusplus extern "C" #endif char shl_load (void); int main (void) { return shl_load (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dld_shl_load=yes else case e in #( e) ac_cv_lib_dld_shl_load=no ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 printf "%s\n" "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = xyes then : lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld else case e in #( e) ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes then : lt_cv_dlopen=dlopen else case e in #( e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 printf %s "checking for dlopen in -ldl... " >&6; } if test ${ac_cv_lib_dl_dlopen+y} then : printf %s "(cached) " >&6 else case e in #( e) ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. The 'extern "C"' is for builds by C++ compilers; although this is not generally supported in C code supporting it here has little cost and some practical benefit (sr 110532). */ #ifdef __cplusplus extern "C" #endif char dlopen (void); int main (void) { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dl_dlopen=yes else case e in #( e) ac_cv_lib_dl_dlopen=no ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 printf "%s\n" "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl else case e in #( e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 printf %s "checking for dlopen in -lsvld... " >&6; } if test ${ac_cv_lib_svld_dlopen+y} then : printf %s "(cached) " >&6 else case e in #( e) ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. The 'extern "C"' is for builds by C++ compilers; although this is not generally supported in C code supporting it here has little cost and some practical benefit (sr 110532). */ #ifdef __cplusplus extern "C" #endif char dlopen (void); int main (void) { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_svld_dlopen=yes else case e in #( e) ac_cv_lib_svld_dlopen=no ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 printf "%s\n" "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = xyes then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld else case e in #( e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 printf %s "checking for dld_link in -ldld... " >&6; } if test ${ac_cv_lib_dld_dld_link+y} then : printf %s "(cached) " >&6 else case e in #( e) ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. The 'extern "C"' is for builds by C++ compilers; although this is not generally supported in C code supporting it here has little cost and some practical benefit (sr 110532). */ #ifdef __cplusplus extern "C" #endif char dld_link (void); int main (void) { return dld_link (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dld_dld_link=yes else case e in #( e) ac_cv_lib_dld_dld_link=no ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 printf "%s\n" "$ac_cv_lib_dld_dld_link" >&6; } if test "x$ac_cv_lib_dld_dld_link" = xyes then : lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld fi ;; esac fi ;; esac fi ;; esac fi ;; esac fi ;; esac fi ;; esac if test no = "$lt_cv_dlopen"; then enable_dlopen=no else enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS=$CPPFLAGS test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 printf %s "checking whether a program can dlopen itself... " >&6; } if test ${lt_cv_dlopen_self+y} then : printf %s "(cached) " >&6 else case e in #( e) if test yes = "$cross_compiling"; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed lt_cv_dlopen_self=no fi fi rm -fr conftest* ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 printf "%s\n" "$lt_cv_dlopen_self" >&6; } if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 printf %s "checking whether a statically linked program can dlopen itself... " >&6; } if test ${lt_cv_dlopen_self_static+y} then : printf %s "(cached) " >&6 else case e in #( e) if test yes = "$cross_compiling"; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed lt_cv_dlopen_self_static=no fi fi rm -fr conftest* ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 printf "%s\n" "$lt_cv_dlopen_self_static" >&6; } fi CPPFLAGS=$save_CPPFLAGS LDFLAGS=$save_LDFLAGS LIBS=$save_LIBS ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi striplib= old_striplib= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 printf %s "checking whether stripping libraries is possible... " >&6; } if test -z "$STRIP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } else if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then old_striplib="$STRIP --strip-debug" striplib="$STRIP --strip-unneeded" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else case $host_os in darwin*) # FIXME - insert some real tests, host_os isn't really good enough striplib="$STRIP -x" old_striplib="$STRIP -S" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } ;; freebsd*) if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then old_striplib="$STRIP --strip-debug" striplib="$STRIP --strip-unneeded" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi ;; *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } ;; esac fi fi # Report what library types will actually be built { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 printf %s "checking if libtool supports shared libraries... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 printf "%s\n" "$can_build_shared" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 printf %s "checking whether to build shared libraries... " >&6; } test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[4-9]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 printf "%s\n" "$enable_shared" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 printf %s "checking whether to build static libraries... " >&6; } # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 printf "%s\n" "$enable_static" >&6; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CC=$lt_save_CC ac_config_commands="$ac_config_commands libtool" # Only expand once: # Some awk implementations crash when confronted with pnglibconf.dfa. # Run a test now, to make sure this doesn't happen. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if awk ($AWK) works" >&5 printf %s "checking if awk ($AWK) works... " >&6; } if ${AWK} -f ${srcdir}/scripts/options.awk out="/dev/null" version=search\ ${srcdir}/pngconf.h ${srcdir}/scripts/pnglibconf.dfa\ ${srcdir}/pngusr.dfa 1>&2 then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error 1 "no See 'config.log' for more details" "$LINENO" 5; } fi # This is a remnant of the old cc -E validation, where it may have been # necessary to use a different preprocessor for .dfn files DFNCPP="$CPP" # Check whether --enable-tests was given. if test ${enable_tests+y} then : enableval=$enable_tests; enable_tests="$enableval" else case e in #( e) enable_tests=yes ;; esac fi if test "$enable_tests" != "no"; then ENABLE_TESTS_TRUE= ENABLE_TESTS_FALSE='#' else ENABLE_TESTS_TRUE='#' ENABLE_TESTS_FALSE= fi # Check whether --enable-tools was given. if test ${enable_tools+y} then : enableval=$enable_tools; enable_tools="$enableval" else case e in #( e) enable_tools=yes ;; esac fi if test "$enable_tools" != "no"; then ENABLE_TOOLS_TRUE= ENABLE_TOOLS_FALSE='#' else ENABLE_TOOLS_TRUE='#' ENABLE_TOOLS_FALSE= fi # -Werror cannot be passed to GCC in CFLAGS because configure will fail # (it checks the compiler with a program that generates a warning). # Add the following option to deal with this: # Check whether --enable-werror was given. if test ${enable_werror+y} then : enableval=$enable_werror; test "$enable_werror" = "yes" && enable_werror="-Werror" if test "$enable_werror" != "no"; then sav_CFLAGS="$CFLAGS" CFLAGS="$enable_werror $CFLAGS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the compiler allows $enable_werror" >&5 printf %s "checking if the compiler allows $enable_werror... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main(int argc, char **argv){ return argv[argc-1][0]; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } PNG_COPTS="$PNG_COPTS $enable_werror" else case e in #( e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext CFLAGS="$sav_CFLAGS" fi fi # For GCC 5 the default mode for C is -std=gnu11 instead of -std=gnu89. # In pngpriv.h we request just the POSIX 1003.1 and C89 APIs by defining # _POSIX_SOURCE to 1. This is incompatible with the new default mode, so # we test for that and force the "-std=c89" compiler option: { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we need to force back C standard to C89" >&5 printf %s "checking if we need to force back C standard to C89... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _POSIX_SOURCE 1 #include int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } else case e in #( e) if test "x$GCC" != "xyes"; then as_fn_error $? "Forcing back to C89 is required but the flags are only known for GCC" "$LINENO" 5 fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } CFLAGS="$CFLAGS -std=c89" ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext # Checks for structures and compiler characteristics. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5 printf %s "checking whether struct tm is in sys/time.h or time.h... " >&6; } if test ${ac_cv_struct_tm+y} then : printf %s "(cached) " >&6 else case e in #( e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main (void) { struct tm tm; int *p = &tm.tm_sec; return !p; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_struct_tm=time.h else case e in #( e) ac_cv_struct_tm=sys/time.h ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tm" >&5 printf "%s\n" "$ac_cv_struct_tm" >&6; } if test $ac_cv_struct_tm = sys/time.h; then printf "%s\n" "#define TM_IN_SYS_TIME 1" >>confdefs.h fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C/C++ restrict keyword" >&5 printf %s "checking for C/C++ restrict keyword... " >&6; } if test ${ac_cv_c_restrict+y} then : printf %s "(cached) " >&6 else case e in #( e) ac_cv_c_restrict=no # Put '__restrict__' first, to avoid problems with glibc and non-GCC; see: # https://lists.gnu.org/archive/html/bug-autoconf/2016-02/msg00006.html # Put 'restrict' last, because C++ lacks it. for ac_kw in __restrict__ __restrict _Restrict restrict; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ typedef int *int_ptr; int foo (int_ptr $ac_kw ip) { return ip[0]; } int bar (int [$ac_kw]); /* Catch GCC bug 14050. */ int bar (int ip[$ac_kw]) { return ip[0]; } int main (void) { int s[1]; int *$ac_kw t = s; t[0] = 0; return foo (t) + bar (t); ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_c_restrict=$ac_kw fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext test "$ac_cv_c_restrict" != no && break done ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_restrict" >&5 printf "%s\n" "$ac_cv_c_restrict" >&6; } case $ac_cv_c_restrict in restrict) ;; no) printf "%s\n" "#define restrict /**/" >>confdefs.h ;; *) printf "%s\n" "#define restrict $ac_cv_c_restrict" >>confdefs.h ;; esac # Checks for library functions. for ac_func in pow do : ac_fn_c_check_func "$LINENO" "pow" "ac_cv_func_pow" if test "x$ac_cv_func_pow" = xyes then : printf "%s\n" "#define HAVE_POW 1" >>confdefs.h else case e in #( e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pow in -lm" >&5 printf %s "checking for pow in -lm... " >&6; } if test ${ac_cv_lib_m_pow+y} then : printf %s "(cached) " >&6 else case e in #( e) ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. The 'extern "C"' is for builds by C++ compilers; although this is not generally supported in C code supporting it here has little cost and some practical benefit (sr 110532). */ #ifdef __cplusplus extern "C" #endif char pow (void); int main (void) { return pow (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_m_pow=yes else case e in #( e) ac_cv_lib_m_pow=no ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_pow" >&5 printf "%s\n" "$ac_cv_lib_m_pow" >&6; } if test "x$ac_cv_lib_m_pow" = xyes then : printf "%s\n" "#define HAVE_LIBM 1" >>confdefs.h LIBS="-lm $LIBS" else case e in #( e) as_fn_error $? "cannot find pow" "$LINENO" 5 ;; esac fi ;; esac fi done # Some later POSIX 1003.1 functions are required for test programs, failure # here is soft (the corresponding test program is not built). ac_fn_c_check_func "$LINENO" "clock_gettime" "ac_cv_func_clock_gettime" if test "x$ac_cv_func_clock_gettime" = xyes then : else case e in #( e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: not building timepng" >&5 printf "%s\n" "$as_me: WARNING: not building timepng" >&2;} ;; esac fi if test "$ac_cv_func_clock_gettime" = "yes"; then HAVE_CLOCK_GETTIME_TRUE= HAVE_CLOCK_GETTIME_FALSE='#' else HAVE_CLOCK_GETTIME_TRUE='#' HAVE_CLOCK_GETTIME_FALSE= fi # Check whether --with-zlib-prefix was given. if test ${with_zlib_prefix+y} then : withval=$with_zlib_prefix; ZPREFIX=${withval} else case e in #( e) ZPREFIX='z_' ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for zlibVersion in -lz" >&5 printf %s "checking for zlibVersion in -lz... " >&6; } if test ${ac_cv_lib_z_zlibVersion+y} then : printf %s "(cached) " >&6 else case e in #( e) ac_check_lib_save_LIBS=$LIBS LIBS="-lz $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. The 'extern "C"' is for builds by C++ compilers; although this is not generally supported in C code supporting it here has little cost and some practical benefit (sr 110532). */ #ifdef __cplusplus extern "C" #endif char zlibVersion (void); int main (void) { return zlibVersion (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_z_zlibVersion=yes else case e in #( e) ac_cv_lib_z_zlibVersion=no ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_zlibVersion" >&5 printf "%s\n" "$ac_cv_lib_z_zlibVersion" >&6; } if test "x$ac_cv_lib_z_zlibVersion" = xyes then : printf "%s\n" "#define HAVE_LIBZ 1" >>confdefs.h LIBS="-lz $LIBS" else case e in #( e) as_ac_Lib=`printf "%s\n" "ac_cv_lib_z_${ZPREFIX}zlibVersion" | sed "$as_sed_sh"` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ${ZPREFIX}zlibVersion in -lz" >&5 printf %s "checking for ${ZPREFIX}zlibVersion in -lz... " >&6; } if eval test \${$as_ac_Lib+y} then : printf %s "(cached) " >&6 else case e in #( e) ac_check_lib_save_LIBS=$LIBS LIBS="-lz $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. The 'extern "C"' is for builds by C++ compilers; although this is not generally supported in C code supporting it here has little cost and some practical benefit (sr 110532). */ #ifdef __cplusplus extern "C" #endif char ${ZPREFIX}zlibVersion (void); int main (void) { return ${ZPREFIX}zlibVersion (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : eval "$as_ac_Lib=yes" else case e in #( e) eval "$as_ac_Lib=no" ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS ;; esac fi eval ac_res=\$$as_ac_Lib { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes" then : printf "%s\n" "#define HAVE_LIBZ 1" >>confdefs.h LIBS="-lz $LIBS" else case e in #( e) as_fn_error $? "zlib not installed" "$LINENO" 5 ;; esac fi ;; esac fi # The following is for pngvalid, to ensure it catches FP errors even on # platforms that don't enable FP exceptions, the function appears in the math # library (typically), it's not an error if it is not found. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for feenableexcept in -lm" >&5 printf %s "checking for feenableexcept in -lm... " >&6; } if test ${ac_cv_lib_m_feenableexcept+y} then : printf %s "(cached) " >&6 else case e in #( e) ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. The 'extern "C"' is for builds by C++ compilers; although this is not generally supported in C code supporting it here has little cost and some practical benefit (sr 110532). */ #ifdef __cplusplus extern "C" #endif char feenableexcept (void); int main (void) { return feenableexcept (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_m_feenableexcept=yes else case e in #( e) ac_cv_lib_m_feenableexcept=no ;; esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_feenableexcept" >&5 printf "%s\n" "$ac_cv_lib_m_feenableexcept" >&6; } if test "x$ac_cv_lib_m_feenableexcept" = xyes then : printf "%s\n" "#define HAVE_LIBM 1" >>confdefs.h LIBS="-lm $LIBS" fi ac_fn_c_check_func "$LINENO" "feenableexcept" "ac_cv_func_feenableexcept" if test "x$ac_cv_func_feenableexcept" = xyes then : printf "%s\n" "#define HAVE_FEENABLEEXCEPT 1" >>confdefs.h fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if using Solaris linker" >&5 printf %s "checking if using Solaris linker... " >&6; } SLD=`$LD --version 2>&1 | grep Solaris` if test "$SLD"; then have_solaris_ld=yes { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else have_solaris_ld=no { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "$have_solaris_ld" = "yes"; then HAVE_SOLARIS_LD_TRUE= HAVE_SOLARIS_LD_FALSE='#' else HAVE_SOLARIS_LD_TRUE='#' HAVE_SOLARIS_LD_FALSE= fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if libraries can be versioned" >&5 printf %s "checking if libraries can be versioned... " >&6; } # Special case for PE/COFF platforms: ld reports # support for version-script, but doesn't actually # DO anything with it. case $host in *cygwin* | *mingw32* | *interix* ) have_ld_version_script=no { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } ;; * ) if test "$have_solaris_ld" = "yes"; then GLD=`$LD --help < /dev/null 2>&1 | grep 'M mapfile'` else GLD=`$LD --help < /dev/null 2>/dev/null | grep version-script` fi if test "$GLD"; then have_ld_version_script=yes { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else have_ld_version_script=no { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: *** You have not enabled versioned symbols." >&5 printf "%s\n" "$as_me: WARNING: *** You have not enabled versioned symbols." >&2;} fi ;; esac if test "$have_ld_version_script" = "yes"; then HAVE_LD_VERSION_SCRIPT_TRUE= HAVE_LD_VERSION_SCRIPT_FALSE='#' else HAVE_LD_VERSION_SCRIPT_TRUE='#' HAVE_LD_VERSION_SCRIPT_FALSE= fi if test "$have_ld_version_script" = "yes"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for symbol prefix" >&5 printf %s "checking for symbol prefix... " >&6; } SYMBOL_PREFIX=`echo "PREFIX=__USER_LABEL_PREFIX__" \ | ${CPP:-${CC:-gcc} -E} - 2>&1 \ | ${EGREP:-grep} "^PREFIX=" \ | ${SED:-sed} -e "s:^PREFIX=::" -e "s:__USER_LABEL_PREFIX__::"` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $SYMBOL_PREFIX" >&5 printf "%s\n" "$SYMBOL_PREFIX" >&6; } fi # Substitutions for .in files # Additional arguments (and substitutions) # Allow the pkg-config directory to be set # Check whether --with-pkgconfigdir was given. if test ${with_pkgconfigdir+y} then : withval=$with_pkgconfigdir; pkgconfigdir=${withval} else case e in #( e) pkgconfigdir='${libdir}/pkgconfig' ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: pkgconfig directory is ${pkgconfigdir}" >&5 printf "%s\n" "$as_me: pkgconfig directory is ${pkgconfigdir}" >&6;} # Make the *-config binary config scripts optional # Check whether --with-binconfigs was given. if test ${with_binconfigs+y} then : withval=$with_binconfigs; if test "${withval}" = no; then binconfigs= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: libpng-config scripts will not be built" >&5 printf "%s\n" "$as_me: libpng-config scripts will not be built" >&6;} else binconfigs='${binconfigs}' fi else case e in #( e) binconfigs='${binconfigs}' ;; esac fi # Support for prefixes to the API function names; this will generate defines # at the start of the build to rename exported library functions # Check whether --with-libpng-prefix was given. if test ${with_libpng_prefix+y} then : withval=$with_libpng_prefix; if test "${withval:-no}" != "no"; then PNG_PREFIX=${withval} fi fi if test "${with_libpng_prefix:-no}" != "no"; then DO_PNG_PREFIX_TRUE= DO_PNG_PREFIX_FALSE='#' else DO_PNG_PREFIX_TRUE='#' DO_PNG_PREFIX_FALSE= fi # Control over what links are made for installed files. Versioned files are # always installed, when the following options are turned on corresponding # unversioned links are also created (normally as symbolic links): # Check whether --enable-unversioned-links was given. if test ${enable_unversioned_links+y} then : enableval=$enable_unversioned_links; fi # The AM_CONDITIONAL test is written so that the default is enabled; # --disable-unversioned-links must be given to turn the option off. if test "$enable_unversioned_links" != "no"; then DO_INSTALL_LINKS_TRUE= DO_INSTALL_LINKS_FALSE='#' else DO_INSTALL_LINKS_TRUE='#' DO_INSTALL_LINKS_FALSE= fi # Check whether --enable-unversioned-libpng-pc was given. if test ${enable_unversioned_libpng_pc+y} then : enableval=$enable_unversioned_libpng_pc; fi if test "$enable_unversioned_libpng_pc" != "no"; then DO_INSTALL_LIBPNG_PC_TRUE= DO_INSTALL_LIBPNG_PC_FALSE='#' else DO_INSTALL_LIBPNG_PC_TRUE='#' DO_INSTALL_LIBPNG_PC_FALSE= fi # Check whether --enable-unversioned-libpng-config was given. if test ${enable_unversioned_libpng_config+y} then : enableval=$enable_unversioned_libpng_config; fi if test "$enable_unversioned_libpng_config" != "no"; then DO_INSTALL_LIBPNG_CONFIG_TRUE= DO_INSTALL_LIBPNG_CONFIG_FALSE='#' else DO_INSTALL_LIBPNG_CONFIG_TRUE='#' DO_INSTALL_LIBPNG_CONFIG_FALSE= fi # HOST-SPECIFIC OPTIONS # ===================== # # DEFAULT # ======= # # Check whether --enable-hardware-optimizations was given. if test ${enable_hardware_optimizations+y} then : enableval=$enable_hardware_optimizations; case "$enableval" in no|off) # disable hardware optimization on all systems: enable_arm_neon=no printf "%s\n" "#define PNG_ARM_NEON_OPT 0" >>confdefs.h enable_mips_msa=no printf "%s\n" "#define PNG_MIPS_MSA_OPT 0" >>confdefs.h enable_mips_mmi=no printf "%s\n" "#define PNG_MIPS_MMI_OPT 0" >>confdefs.h enable_powerpc_vsx=no printf "%s\n" "#define PNG_POWERPC_VSX_OPT 0" >>confdefs.h enable_intel_sse=no printf "%s\n" "#define PNG_INTEL_SSE_OPT 0" >>confdefs.h enable_loongarch_lsx=no printf "%s\n" "#define PNG_LOONGARCH_LSX_OPT 0" >>confdefs.h ;; *) # allow enabling hardware optimization on any system: case "$host_cpu" in arm*|aarch64*) enable_arm_neon=yes printf "%s\n" "#define PNG_ARM_NEON_OPT 2" >>confdefs.h ;; mipsel*|mips64el*) enable_mips_mmi=yes enable_mips_msa=yes printf "%s\n" "#define PNG_MIPS_MMI_OPT 1" >>confdefs.h printf "%s\n" "#define PNG_MIPS_MSA_OPT 2" >>confdefs.h ;; i?86|x86_64) enable_intel_sse=yes printf "%s\n" "#define PNG_INTEL_SSE_OPT 1" >>confdefs.h ;; powerpc*|ppc64*) enable_powerpc_vsx=yes printf "%s\n" "#define PNG_POWERPC_VSX_OPT 2" >>confdefs.h ;; loongarch*) enable_loongarch_lsx=yes printf "%s\n" "#define PNG_LOONGARCH_LSX_OPT 1" >>confdefs.h ;; esac ;; esac fi # ARM NEON # ======== # Check whether --enable-arm-neon was given. if test ${enable_arm_neon+y} then : enableval=$enable_arm_neon; case "$enableval" in no|off) # disable the default enabling on __ARM_NEON__ systems: printf "%s\n" "#define PNG_ARM_NEON_OPT 0" >>confdefs.h # Prevent inclusion of the assembler files below: enable_arm_neon=no ;; check) printf "%s\n" "#define PNG_ARM_NEON_CHECK_SUPPORTED /**/" >>confdefs.h ;; api) printf "%s\n" "#define PNG_ARM_NEON_API_SUPPORTED /**/" >>confdefs.h ;; yes|on) printf "%s\n" "#define PNG_ARM_NEON_OPT 2" >>confdefs.h { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: --enable-arm-neon: please specify 'check' or 'api'; if you want the optimizations unconditionally, pass '-mfpu=neon' to the compiler." >&5 printf "%s\n" "$as_me: WARNING: --enable-arm-neon: please specify 'check' or 'api'; if you want the optimizations unconditionally, pass '-mfpu=neon' to the compiler." >&2;};; *) as_fn_error $? "--enable-arm-neon=${enable_arm_neon}: invalid argument" "$LINENO" 5 esac fi # Add ARM-specific files to all builds where $host_cpu is arm ('arm*') or # where ARM optimizations were explicitly requested. (This allows a fallback # if a future host CPU does not match 'arm*'.) if test "$enable_arm_neon" != 'no' && case "$host_cpu" in arm*|aarch64*) : ;; *) test "$enable_arm_neon" != '' ;; esac; then PNG_ARM_NEON_TRUE= PNG_ARM_NEON_FALSE='#' else PNG_ARM_NEON_TRUE='#' PNG_ARM_NEON_FALSE= fi # MIPS MSA # ======== # Check whether --enable-mips-msa was given. if test ${enable_mips_msa+y} then : enableval=$enable_mips_msa; case "$enableval" in no|off) # disable the default enabling on __mips_msa systems: printf "%s\n" "#define PNG_MIPS_MSA_OPT 0" >>confdefs.h # Prevent inclusion of the assembler files below: enable_mips_msa=no ;; check) printf "%s\n" "#define PNG_MIPS_MSA_CHECK_SUPPORTED /**/" >>confdefs.h ;; api) printf "%s\n" "#define PNG_MIPS_MSA_API_SUPPORTED /**/" >>confdefs.h ;; yes|on) printf "%s\n" "#define PNG_MIPS_MSA_OPT 2" >>confdefs.h { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: --enable-mips-msa: please specify 'check' or 'api'; if you want the optimizations unconditionally, pass '-mmsa -mfp64' to the compiler." >&5 printf "%s\n" "$as_me: WARNING: --enable-mips-msa: please specify 'check' or 'api'; if you want the optimizations unconditionally, pass '-mmsa -mfp64' to the compiler." >&2;};; *) as_fn_error $? "--enable-mips-msa=${enable_mips_msa}: invalid argument" "$LINENO" 5 esac fi # Add MIPS-specific files to all builds where $host_cpu is mips ('mips*') or # where MIPS optimizations were explicitly requested. (This allows a fallback # if a future host CPU does not match 'mips*'.) if test "$enable_mips_msa" != 'no' && case "$host_cpu" in mipsel*|mips64el*) : ;; esac; then PNG_MIPS_MSA_TRUE= PNG_MIPS_MSA_FALSE='#' else PNG_MIPS_MSA_TRUE='#' PNG_MIPS_MSA_FALSE= fi # MIPS MMI # ======== # Check whether --enable-mips-mmi was given. if test ${enable_mips_mmi+y} then : enableval=$enable_mips_mmi; case "$enableval" in no|off) # disable the default enabling on __mips_mmi systems: printf "%s\n" "#define PNG_MIPS_MMI_OPT 0" >>confdefs.h # Prevent inclusion of the assembler files below: enable_mips_mmi=no;; check) printf "%s\n" "#define PNG_MIPS_MMI_CHECK_SUPPORTED /**/" >>confdefs.h ;; api) printf "%s\n" "#define PNG_MIPS_MMI_API_SUPPORTED /**/" >>confdefs.h ;; yes|on) printf "%s\n" "#define PNG_MIPS_MMI_OPT 1" >>confdefs.h { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: --enable-mips-mmi: please specify 'check' or 'api'; if you want the optimizations unconditionally pass '-mloongson-mmi -march=loongson3a' to the compiler." >&5 printf "%s\n" "$as_me: WARNING: --enable-mips-mmi: please specify 'check' or 'api'; if you want the optimizations unconditionally pass '-mloongson-mmi -march=loongson3a' to the compiler." >&2;};; *) as_fn_error $? "--enable-mips-mmi=${enable_mips_mmi}: invalid argument" "$LINENO" 5 esac fi # Add MIPS specific files to all builds where the host_cpu is mips ('mips*') or # where MIPS optimizations were explicitly requested. (This allows a fallback # if a future host CPU does not match 'mips*'.) if test "$enable_mips_mmi" != 'no' && case "$host_cpu" in mipsel*|mips64el*) : ;; esac; then PNG_MIPS_MMI_TRUE= PNG_MIPS_MMI_FALSE='#' else PNG_MIPS_MMI_TRUE='#' PNG_MIPS_MMI_FALSE= fi # INTEL SSE # ========= # Check whether --enable-intel-sse was given. if test ${enable_intel_sse+y} then : enableval=$enable_intel_sse; case "$enableval" in no|off) # disable the default enabling: printf "%s\n" "#define PNG_INTEL_SSE_OPT 0" >>confdefs.h # Prevent inclusion of the assembler files below: enable_intel_sse=no ;; yes|on) printf "%s\n" "#define PNG_INTEL_SSE_OPT 1" >>confdefs.h ;; *) as_fn_error $? "--enable-intel-sse=${enable_intel_sse}: invalid argument" "$LINENO" 5 esac fi # Add Intel-specific files to all builds where $host_cpu is Intel ('x86*') or # where Intel optimizations were explicitly requested. (This allows a fallback # if a future host CPU does not match 'x86*'.) if test "$enable_intel_sse" != 'no' && case "$host_cpu" in i?86|x86_64) : ;; *) test "$enable_intel_sse" != '' ;; esac; then PNG_INTEL_SSE_TRUE= PNG_INTEL_SSE_FALSE='#' else PNG_INTEL_SSE_TRUE='#' PNG_INTEL_SSE_FALSE= fi # POWERPC VSX # =========== # Check whether --enable-powerpc-vsx was given. if test ${enable_powerpc_vsx+y} then : enableval=$enable_powerpc_vsx; case "$enableval" in no|off) # disable the default enabling on __ppc64__ systems: printf "%s\n" "#define PNG_POWERPC_VSX_OPT 0" >>confdefs.h # Prevent inclusion of the platform-specific files below: enable_powerpc_vsx=no ;; check) printf "%s\n" "#define PNG_POWERPC_VSX_CHECK_SUPPORTED /**/" >>confdefs.h { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: --enable-powerpc-vsx: please see contrib/powerpc/README for the list of supported systems." >&5 printf "%s\n" "$as_me: WARNING: --enable-powerpc-vsx: please see contrib/powerpc/README for the list of supported systems." >&2;};; api) printf "%s\n" "#define PNG_POWERPC_VSX_API_SUPPORTED /**/" >>confdefs.h ;; yes|on) printf "%s\n" "#define PNG_POWERPC_VSX_OPT 2" >>confdefs.h { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: --enable-powerpc-vsx: please specify 'check' or 'api'; if you want the optimizations unconditionally, pass '-maltivec -mvsx' or '-mcpu=power8' to the compiler." >&5 printf "%s\n" "$as_me: WARNING: --enable-powerpc-vsx: please specify 'check' or 'api'; if you want the optimizations unconditionally, pass '-maltivec -mvsx' or '-mcpu=power8' to the compiler." >&2;};; *) as_fn_error $? "--enable-powerpc-vsx=${enable_powerpc_vsx}: invalid argument" "$LINENO" 5 esac fi # Add PowerPC-specific files to all builds where $host_cpu is powerpc # ('powerpc*') or where PowerPC optimizations were explicitly requested. # (This allows a fallback if a future host CPU does not match 'powerpc*'.) if test "$enable_powerpc_vsx" != 'no' && case "$host_cpu" in powerpc*|ppc64*) : ;; esac; then PNG_POWERPC_VSX_TRUE= PNG_POWERPC_VSX_FALSE='#' else PNG_POWERPC_VSX_TRUE='#' PNG_POWERPC_VSX_FALSE= fi # LOONGARCH LSX # ============= # Check whether --enable-loongarch-lsx was given. if test ${enable_loongarch_lsx+y} then : enableval=$enable_loongarch_lsx; case "$enableval" in no|off) # disable the default enabling on __loongarch_simd systems: printf "%s\n" "#define PNG_LOONGARCH_LSX_OPT 0" >>confdefs.h # Prevent inclusion of the assembler files below: enable_loongarch_lsx=no;; yes|on) printf "%s\n" "#define PNG_LOONGARCH_LSX_OPT 1" >>confdefs.h ;; *) as_fn_error $? "--enable-loongarch-lsx=${enable_loongarch_lsx}: invalid argument" "$LINENO" 5 esac fi if test "$enable_loongarch_lsx" != "no" && case "$host_cpu" in loongarch*) : ;; *) test "$enable_loongarch_lsx" != '' ;; esac then compiler_support_loongarch_lsx=no { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to use LoongArch LSX intrinsics" >&5 printf %s "checking whether to use LoongArch LSX intrinsics... " >&6; } save_CFLAGS="$CFLAGS" LSX_CFLAGS="${LSX_CFLAGS:-"-mlsx"}" CFLAGS="$CFLAGS $LSX_CFLAGS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main(){ __m128i a, b, c; a = __lsx_vadd_w(b, c); return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : compiler_support_loongarch_lsx=yes fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext CFLAGS="$save_CFLAGS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $compiler_support_loongarch_lsx" >&5 printf "%s\n" "$compiler_support_loongarch_lsx" >&6; } if test "$compiler_support_loongarch_lsx" = "yes"; then printf "%s\n" "#define PNG_LOONGARCH_LSX_OPT 1" >>confdefs.h else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Compiler does not support loongarch LSX." >&5 printf "%s\n" "$as_me: WARNING: Compiler does not support loongarch LSX." >&2;} fi fi # Add LoongArch specific files to all builds where the host_cpu is loongarch # ('loongarch*') or where LoongArch optimizations were explicitly requested. # (This allows a fallback if a future host CPU does not match 'loongarch*'.) if test "$enable_loongarch_lsx" != "no" && test "$compiler_support_loongarch_lsx" = "yes" && case "$host_cpu" in loongarch*) : ;; *) test "$enable_loongarch_lsx" != '' ;; esac; then PNG_LOONGARCH_LSX_TRUE= PNG_LOONGARCH_LSX_FALSE='#' else PNG_LOONGARCH_LSX_TRUE='#' PNG_LOONGARCH_LSX_FALSE= fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Extra options for compiler: $PNG_COPTS" >&5 printf "%s\n" "$as_me: Extra options for compiler: $PNG_COPTS" >&6;} # Config files, substituting as above ac_config_files="$ac_config_files Makefile libpng.pc:libpng.pc.in" ac_config_files="$ac_config_files libpng-config:libpng-config.in" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # 'ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* 'ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # 'set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # 'set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 printf "%s\n" "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 printf %s "checking that generated files are newer than configure... " >&6; } if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: done" >&5 printf "%s\n" "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCCAS_TRUE}" && test -z "${am__fastdepCCAS_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCCAS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${ENABLE_TESTS_TRUE}" && test -z "${ENABLE_TESTS_FALSE}"; then as_fn_error $? "conditional \"ENABLE_TESTS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${ENABLE_TOOLS_TRUE}" && test -z "${ENABLE_TOOLS_FALSE}"; then as_fn_error $? "conditional \"ENABLE_TOOLS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_CLOCK_GETTIME_TRUE}" && test -z "${HAVE_CLOCK_GETTIME_FALSE}"; then as_fn_error $? "conditional \"HAVE_CLOCK_GETTIME\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_SOLARIS_LD_TRUE}" && test -z "${HAVE_SOLARIS_LD_FALSE}"; then as_fn_error $? "conditional \"HAVE_SOLARIS_LD\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_LD_VERSION_SCRIPT_TRUE}" && test -z "${HAVE_LD_VERSION_SCRIPT_FALSE}"; then as_fn_error $? "conditional \"HAVE_LD_VERSION_SCRIPT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${DO_PNG_PREFIX_TRUE}" && test -z "${DO_PNG_PREFIX_FALSE}"; then as_fn_error $? "conditional \"DO_PNG_PREFIX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${DO_INSTALL_LINKS_TRUE}" && test -z "${DO_INSTALL_LINKS_FALSE}"; then as_fn_error $? "conditional \"DO_INSTALL_LINKS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${DO_INSTALL_LIBPNG_PC_TRUE}" && test -z "${DO_INSTALL_LIBPNG_PC_FALSE}"; then as_fn_error $? "conditional \"DO_INSTALL_LIBPNG_PC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${DO_INSTALL_LIBPNG_CONFIG_TRUE}" && test -z "${DO_INSTALL_LIBPNG_CONFIG_FALSE}"; then as_fn_error $? "conditional \"DO_INSTALL_LIBPNG_CONFIG\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${PNG_ARM_NEON_TRUE}" && test -z "${PNG_ARM_NEON_FALSE}"; then as_fn_error $? "conditional \"PNG_ARM_NEON\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${PNG_MIPS_MSA_TRUE}" && test -z "${PNG_MIPS_MSA_FALSE}"; then as_fn_error $? "conditional \"PNG_MIPS_MSA\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${PNG_MIPS_MMI_TRUE}" && test -z "${PNG_MIPS_MMI_FALSE}"; then as_fn_error $? "conditional \"PNG_MIPS_MMI\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${PNG_INTEL_SSE_TRUE}" && test -z "${PNG_INTEL_SSE_FALSE}"; then as_fn_error $? "conditional \"PNG_INTEL_SSE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${PNG_POWERPC_VSX_TRUE}" && test -z "${PNG_POWERPC_VSX_FALSE}"; then as_fn_error $? "conditional \"PNG_POWERPC_VSX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${PNG_LOONGARCH_LSX_TRUE}" && test -z "${PNG_LOONGARCH_LSX_FALSE}"; then as_fn_error $? "conditional \"PNG_LOONGARCH_LSX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case e in #( e) case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac ;; esac fi # Reset variables that may have inherited troublesome values from # the environment. # IFS needs to be set, to space, tab, and newline, in precisely that order. # (If _AS_PATH_WALK were called with IFS unset, it would have the # side effect of setting IFS to empty, thus disabling word splitting.) # Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl IFS=" "" $as_nl" PS1='$ ' PS2='> ' PS4='+ ' # Ensure predictable behavior from utilities with locale-dependent output. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # We cannot yet rely on "unset" to work, but we need these variables # to be unset--not just set to an empty or harmless value--now, to # avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct # also avoids known problems related to "unset" and subshell syntax # in other old shells (e.g. bash 2.01 and pdksh 5.2.14). for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH do eval test \${$as_var+y} \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done # Ensure that fds 0, 1, and 2 are open. if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. if ${PATH_SEPARATOR+false} :; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac test -r "$as_dir$0" && as_myself=$as_dir$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as 'sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi printf "%s\n" "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null then : eval 'as_fn_append () { eval $1+=\$2 }' else case e in #( e) as_fn_append () { eval $1=\$$1\$2 } ;; esac fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null then : eval 'as_fn_arith () { as_val=$(( $* )) }' else case e in #( e) as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } ;; esac fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # Determine whether it's possible to make 'echo' print without a newline. # These variables are no longer used directly by Autoconf, but are AC_SUBSTed # for compatibility with existing Makefiles. ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac # For backward compatibility with old third-party macros, we provide # the shell variables $as_echo and $as_echo_n. New code should use # AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. as_echo='printf %s\n' as_echo_n='printf %s' rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both 'ln -s file dir' and 'ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; 'ln -s' creates a wrapper executable. # In both cases, we have to default to 'cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_sed_cpp="y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" as_tr_cpp="eval sed '$as_sed_cpp'" # deprecated # Sed expression to map a string onto a valid variable name. as_sed_sh="y%*+%pp%;s%[^_$as_cr_alnum]%_%g" as_tr_sh="eval sed '$as_sed_sh'" # deprecated exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by libpng $as_me 1.6.43, which was generated by GNU Autoconf 2.72. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ '$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to ." _ACEOF ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"` ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"` cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ libpng config.status 1.6.43 configured by $0, generated by GNU Autoconf 2.72, with options \\"\$ac_cs_config\\" Copyright (C) 2023 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) printf "%s\n" "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) printf "%s\n" "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: '$1' Try '$0 --help' for more information.";; --help | --hel | -h ) printf "%s\n" "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: '$1' Try '$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \printf "%s\n" "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX printf "%s\n" "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`' DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`' PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' FILECMD='`$ECHO "$FILECMD" | $SED "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' lt_ar_flags='`$ECHO "$lt_ar_flags" | $SED "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`' objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`' configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`' hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } # Quote evaled strings. for var in SED \ GREP \ EGREP \ FGREP \ SHELL \ ECHO \ LD \ AS \ DLLTOOL \ OBJDUMP \ PATH_SEPARATOR \ NM \ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ FILECMD \ deplibs_check_method \ file_magic_cmd \ file_magic_glob \ want_nocaseglob \ sharedlib_from_linklib_cmd \ AR \ archiver_list_spec \ STRIP \ RANLIB \ CC \ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_import \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ lt_cv_nm_interface \ nm_file_list_spec \ lt_cv_truncate_bin \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_pic \ lt_prog_compiler_wl \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ MANIFEST_TOOL \ DSYMUTIL \ NMEDIT \ LIPO \ OTOOL \ OTOOL64 \ shrext_cmds \ export_dynamic_flag_spec \ whole_archive_flag_spec \ compiler_needs_object \ with_gnu_ld \ allow_undefined_flag \ no_undefined_flag \ hardcode_libdir_flag_spec \ hardcode_libdir_separator \ exclude_expsyms \ include_expsyms \ file_list_spec \ variables_saved_for_relink \ libname_spec \ library_names_spec \ soname_spec \ install_override_mode \ finish_eval \ old_striplib \ striplib; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in reload_cmds \ old_postinstall_cmds \ old_postuninstall_cmds \ old_archive_cmds \ extract_expsyms_cmds \ old_archive_from_new_cmds \ old_archive_from_expsyms_cmds \ archive_cmds \ archive_expsym_cmds \ module_cmds \ module_expsym_cmds \ export_symbols_cmds \ prelink_cmds \ postlink_cmds \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ configure_time_dlsearch_path \ configure_time_lt_sys_library_path; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done ac_aux_dir='$ac_aux_dir' # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi PACKAGE='$PACKAGE' VERSION='$VERSION' RM='$RM' ofile='$ofile' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "libpng.pc") CONFIG_FILES="$CONFIG_FILES libpng.pc:libpng.pc.in" ;; "libpng-config") CONFIG_FILES="$CONFIG_FILES libpng-config:libpng-config.in" ;; *) as_fn_error $? "invalid argument: '$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test ${CONFIG_FILES+y} || CONFIG_FILES=$config_files test ${CONFIG_HEADERS+y} || CONFIG_HEADERS=$config_headers test ${CONFIG_COMMANDS+y} || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to '$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with './config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with './config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script 'defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag '$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain ':'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: '$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is 'configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 printf "%s\n" "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`printf "%s\n" "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 printf "%s\n" "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when '$srcdir' = '.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable 'datarootdir' which seems to be undefined. Please make sure it is defined" >&5 printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable 'datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { printf "%s\n" "/* $configure_input */" >&1 \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 printf "%s\n" "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else printf "%s\n" "/* $configure_input */" >&1 \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 printf "%s\n" "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. # TODO: see whether this extra hack can be removed once we start # requiring Autoconf 2.70 or later. case $CONFIG_FILES in #( *\'*) : eval set x "$CONFIG_FILES" ;; #( *) : set x $CONFIG_FILES ;; #( *) : ;; esac shift # Used to flag and report bootstrapping failures. am_rc=0 for am_mf do # Strip MF so we end up with the name of the file. am_mf=`printf "%s\n" "$am_mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile which includes # dependency-tracking related rules and includes. # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ || continue am_dirpart=`$as_dirname -- "$am_mf" || $as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$am_mf" : 'X\(//\)[^/]' \| \ X"$am_mf" : 'X\(//\)$' \| \ X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$am_mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` am_filepart=`$as_basename -- "$am_mf" || $as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \ X"$am_mf" : 'X\(//\)$' \| \ X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X/"$am_mf" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` { echo "$as_me:$LINENO: cd "$am_dirpart" \ && sed -e '/# am--include-marker/d' "$am_filepart" \ | $MAKE -f - am--depfiles" >&5 (cd "$am_dirpart" \ && sed -e '/# am--include-marker/d' "$am_filepart" \ | $MAKE -f - am--depfiles) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } || am_rc=$? done if test $am_rc -ne 0; then { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "Something went wrong bootstrapping makefile fragments for automatic dependency tracking. If GNU make was not used, consider re-running the configure script with MAKE=\"gmake\" (or whatever is necessary). You can also try re-running configure with the '--disable-dependency-tracking' option to at least be able to build the package (albeit without support for automatic dependency tracking). See 'config.log' for more details" "$LINENO" 5; } fi { am_dirpart=; unset am_dirpart;} { am_filepart=; unset am_filepart;} { am_mf=; unset am_mf;} { am_rc=; unset am_rc;} rm -f conftest-deps.mk } ;; "libtool":C) # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. # Written by Gordon Matzigkeit, 1996 # Copyright (C) 2014 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program or library that is built # using GNU Libtool, you may include this file under the same # distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # The names of the tagged configurations supported by this script. available_tags='' # Configured defaults for sys_lib_dlsearch_path munging. : \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} # ### BEGIN LIBTOOL CONFIG # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="\$SED -e 1s/^X//" # A grep program that handles long lines. GREP=$lt_GREP # An ERE matcher. EGREP=$lt_EGREP # A literal string matcher. FGREP=$lt_FGREP # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that protects backslashes. ECHO=$lt_ECHO # Which release of libtool.m4 was used? macro_version=$macro_version macro_revision=$macro_revision # Assembler program. AS=$lt_AS # DLL creation program. DLLTOOL=$lt_DLLTOOL # Object dumper program. OBJDUMP=$lt_OBJDUMP # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # What type of objects to build. pic_mode=$pic_mode # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # Shared archive member basename,for filename based shared library versioning on AIX. shared_archive_member_spec=$shared_archive_member_spec # The PATH separator for the build system. PATH_SEPARATOR=$lt_PATH_SEPARATOR # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # A BSD- or MS-compatible name lister. NM=$lt_NM # Whether we need soft or hard links. LN_S=$lt_LN_S # What is the maximum length of a command? max_cmd_len=$max_cmd_len # Object file suffix (normally "o"). objext=$ac_objext # Executable file suffix (normally ""). exeext=$exeext # whether the shell understands "unset". lt_unset=$lt_unset # turn spaces into newlines. SP2NL=$lt_lt_SP2NL # turn newlines into spaces. NL2SP=$lt_lt_NL2SP # convert \$build file names to \$host format. to_host_file_cmd=$lt_cv_to_host_file_cmd # convert \$build files to toolchain format. to_tool_file_cmd=$lt_cv_to_tool_file_cmd # A file(cmd) program that detects file types. FILECMD=$lt_FILECMD # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method = "file_magic". file_magic_cmd=$lt_file_magic_cmd # How to find potential files when deplibs_check_method = "file_magic". file_magic_glob=$lt_file_magic_glob # Find potential files using nocaseglob when deplibs_check_method = "file_magic". want_nocaseglob=$lt_want_nocaseglob # Command to associate shared and link libraries. sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd # The archiver. AR=$lt_AR # Flags to create an archive (by configure). lt_ar_flags=$lt_ar_flags # Flags to create an archive. AR_FLAGS=\${ARFLAGS-"\$lt_ar_flags"} # How to feed a file listing to the archiver. archiver_list_spec=$lt_archiver_list_spec # A symbol stripping program. STRIP=$lt_STRIP # Commands used to install an old-style archive. RANLIB=$lt_RANLIB old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Whether to use a lock for old archive extraction. lock_old_archive_extraction=$lock_old_archive_extraction # A C compiler. LTCC=$lt_CC # LTCC compiler flags. LTCFLAGS=$lt_CFLAGS # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration. global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm into a list of symbols to manually relocate. global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import # Transform the output of nm in a C name address pair. global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix # The name lister interface. nm_interface=$lt_lt_cv_nm_interface # Specify filename containing input files for \$NM. nm_file_list_spec=$lt_nm_file_list_spec # The root where to search for dependent libraries,and where our libraries should be installed. lt_sysroot=$lt_sysroot # Command to truncate a binary pipe. lt_truncate_bin=$lt_lt_cv_truncate_bin # The name of the directory that contains temporary libtool files. objdir=$objdir # Used to examine libraries when file_magic_cmd begins with "file". MAGIC_CMD=$MAGIC_CMD # Must we lock files when doing compilation? need_locks=$lt_need_locks # Manifest tool. MANIFEST_TOOL=$lt_MANIFEST_TOOL # Tool to manipulate archived DWARF debug symbol files on Mac OS X. DSYMUTIL=$lt_DSYMUTIL # Tool to change global to local symbols on Mac OS X. NMEDIT=$lt_NMEDIT # Tool to manipulate fat objects and archives on Mac OS X. LIPO=$lt_LIPO # ldd/readelf like tool for Mach-O binaries on Mac OS X. OTOOL=$lt_OTOOL # ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. OTOOL64=$lt_OTOOL64 # Old archive suffix (normally "a"). libext=$libext # Shared library suffix (normally ".so"). shrext_cmds=$lt_shrext_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Variables whose values should be saved in libtool wrapper scripts and # restored at link time. variables_saved_for_relink=$lt_variables_saved_for_relink # Do we need the "lib" prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Library versioning type. version_type=$version_type # Shared library runtime path variable. runpath_var=$runpath_var # Shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Permission mode override for installation of shared libraries. install_override_mode=$lt_install_override_mode # Command to use after installation of a shared archive. postinstall_cmds=$lt_postinstall_cmds # Command to use after uninstallation of a shared archive. postuninstall_cmds=$lt_postuninstall_cmds # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # As "finish_cmds", except a single script fragment to be evaled but # not shown. finish_eval=$lt_finish_eval # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Compile-time system search path for libraries. sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Detected run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path # Explicit LT_SYS_LIBRARY_PATH set during ./configure time. configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # The linker used to build libraries. LD=$lt_LD # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds # A language specific compiler. CC=$lt_compiler # Is the compiler the GNU compiler? with_gcc=$GCC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds archive_expsym_cmds=$lt_archive_expsym_cmds # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds module_expsym_cmds=$lt_module_expsym_cmds # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \$shlibpath_var if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms # Symbols that must always be exported. include_expsyms=$lt_include_expsyms # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds # Specify filename containing input files. file_list_spec=$lt_file_list_spec # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # ### END LIBTOOL CONFIG _LT_EOF cat <<'_LT_EOF' >> "$cfgfile" # ### BEGIN FUNCTIONS SHARED WITH CONFIGURE # func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x$2 in x) ;; *:) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" ;; x:*) eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" ;; *::*) eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" ;; *) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" ;; esac } # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in $*""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } # ### END FUNCTIONS SHARED WITH CONFIGURE _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac ltmain=$ac_aux_dir/ltmain.sh # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? $SED '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ;; "libpng-config":F) chmod +x libpng-config ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi libpng-1.6.43/configure.ac000066400000000000000000000577051456606525400154010ustar00rootroot00000000000000# configure.ac # Copyright (c) 2018-2024 Cosmin Truta # Copyright (c) 2004-2016 Glenn Randers-Pehrson # This code is released under the libpng license. # For conditions of distribution and use, see the disclaimer # and license in png.h dnl Process this file with autoconf to produce a configure script. dnl dnl Minor upgrades (compatible ABI): increment the package version dnl (third field in two places below) and set the PNGLIB_RELEASE dnl variable. dnl dnl Major upgrades (incompatible ABI): increment the package major dnl version (second field, or first if desired), set the minor dnl to 0, set PNGLIB_MAJOR below *and* follow the instructions in dnl Makefile.am to upgrade the package name. dnl This is here to prevent earlier autoconf from being used, it dnl should not be necessary to regenerate configure if the time dnl stamps are correct AC_PREREQ([2.68]) dnl Version number stuff here: AC_INIT([libpng],[1.6.43],[png-mng-implement@lists.sourceforge.net]) AC_CONFIG_MACRO_DIR([scripts/autoconf]) # libpng does not follow GNU file name conventions (hence 'foreign') # color-tests requires automake 1.11 or later # silent-rules requires automake 1.11 or later # dist-xz requires automake 1.11 or later # 1.12.2 fixes a security issue in 1.11.2 and 1.12.1 # 1.13 is required for parallel tests AM_INIT_AUTOMAKE([1.13 foreign dist-xz color-tests silent-rules subdir-objects]) # The following line causes --disable-maintainer-mode to be the default to # configure. This is necessary because libpng distributions cannot rely on the # time stamps of the autotools generated files being correct AM_MAINTAINER_MODE dnl configure.ac and Makefile.am expect automake 1.11.2 or a compatible later dnl version; aclocal.m4 will generate a failure if you use a prior version of dnl automake, so the following is not necessary (and is not defined anyway): dnl AM_PREREQ([1.11.2]) dnl stop configure from automagically running automake PNGLIB_VERSION=1.6.43 PNGLIB_MAJOR=1 PNGLIB_MINOR=6 PNGLIB_RELEASE=43 dnl End of version number stuff AC_CONFIG_SRCDIR([pngget.c]) AC_CONFIG_HEADERS([config.h]) # Check for basic programs. AC_LANG([C]) AC_PROG_CC AM_PROG_AS LT_PATH_LD AC_PROG_CPP AC_PROG_AWK AC_PROG_INSTALL AC_PROG_LN_S AC_PROG_MAKE_SET dnl libtool/libtoolize; version 2.4.2 is the tested version. This or any dnl compatible later version may be used LT_INIT([win32-dll]) LT_PREREQ([2.4.2]) dnl Declare the AWK variable. AC_ARG_VAR(AWK, [AWK language processor]) # Some awk implementations crash when confronted with pnglibconf.dfa. # Run a test now, to make sure this doesn't happen. AC_MSG_CHECKING([if awk ($AWK) works]) if ${AWK} -f ${srcdir}/scripts/options.awk out="/dev/null" version=search\ ${srcdir}/pngconf.h ${srcdir}/scripts/pnglibconf.dfa\ ${srcdir}/pngusr.dfa 1>&2 then AC_MSG_RESULT([yes]) else AC_MSG_FAILURE([no], 1) fi # This is a remnant of the old cc -E validation, where it may have been # necessary to use a different preprocessor for .dfn files DFNCPP="$CPP" AC_SUBST(DFNCPP) AC_ARG_ENABLE([tests], AS_HELP_STRING([--disable-tests], [do not build the test programs (default is to build)]), [enable_tests="$enableval"], [enable_tests=yes]) AM_CONDITIONAL([ENABLE_TESTS], [test "$enable_tests" != "no"]) AC_ARG_ENABLE([tools], AS_HELP_STRING([--disable-tools], [do not build the auxiliary tools (default is to build)]), [enable_tools="$enableval"], [enable_tools=yes]) AM_CONDITIONAL([ENABLE_TOOLS], [test "$enable_tools" != "no"]) # -Werror cannot be passed to GCC in CFLAGS because configure will fail # (it checks the compiler with a program that generates a warning). # Add the following option to deal with this: AC_ARG_VAR(PNG_COPTS, [additional flags for the C compiler, to be used for options that would] [cause configure itself to fail]) AC_ARG_ENABLE(werror, AS_HELP_STRING([[[--enable-werror[=OPT]]]], [Pass -Werror or the given argument to the compiler if it is supported]), [test "$enable_werror" = "yes" && enable_werror="-Werror" if test "$enable_werror" != "no"; then sav_CFLAGS="$CFLAGS" CFLAGS="$enable_werror $CFLAGS" AC_MSG_CHECKING([if the compiler allows $enable_werror]) AC_COMPILE_IFELSE( [AC_LANG_SOURCE([ [int main(int argc, char **argv){] [return argv[argc-1][0];] [}]])], AC_MSG_RESULT(yes) PNG_COPTS="$PNG_COPTS $enable_werror", AC_MSG_RESULT(no)) CFLAGS="$sav_CFLAGS" fi],) # For GCC 5 the default mode for C is -std=gnu11 instead of -std=gnu89. # In pngpriv.h we request just the POSIX 1003.1 and C89 APIs by defining # _POSIX_SOURCE to 1. This is incompatible with the new default mode, so # we test for that and force the "-std=c89" compiler option: AC_MSG_CHECKING([if we need to force back C standard to C89]) AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([ [#define _POSIX_SOURCE 1] [#include ] ])], AC_MSG_RESULT(no),[ if test "x$GCC" != "xyes"; then AC_MSG_ERROR( [Forcing back to C89 is required but the flags are only known for GCC]) fi AC_MSG_RESULT(yes) CFLAGS="$CFLAGS -std=c89" ]) # Checks for structures and compiler characteristics. AC_STRUCT_TM AC_C_RESTRICT # Checks for library functions. AC_CHECK_FUNCS([pow], , [AC_CHECK_LIB([m], [pow], , [AC_MSG_ERROR([cannot find pow])])]) # Some later POSIX 1003.1 functions are required for test programs, failure # here is soft (the corresponding test program is not built). AC_CHECK_FUNC([clock_gettime], , [AC_MSG_WARN([not building timepng])]) AM_CONDITIONAL([HAVE_CLOCK_GETTIME], [test "$ac_cv_func_clock_gettime" = "yes"]) AC_ARG_WITH(zlib-prefix, AS_HELP_STRING([[[--with-zlib-prefix]]], [prefix that may have been used in installed zlib]), [ZPREFIX=${withval}], [ZPREFIX='z_']) AC_CHECK_LIB([z], [zlibVersion], , [AC_CHECK_LIB([z], [${ZPREFIX}zlibVersion], , [AC_MSG_ERROR([zlib not installed])])]) # The following is for pngvalid, to ensure it catches FP errors even on # platforms that don't enable FP exceptions, the function appears in the math # library (typically), it's not an error if it is not found. AC_CHECK_LIB([m], [feenableexcept]) AC_CHECK_FUNCS([feenableexcept]) AC_MSG_CHECKING([if using Solaris linker]) SLD=`$LD --version 2>&1 | grep Solaris` if test "$SLD"; then have_solaris_ld=yes AC_MSG_RESULT(yes) else have_solaris_ld=no AC_MSG_RESULT(no) fi AM_CONDITIONAL(HAVE_SOLARIS_LD, test "$have_solaris_ld" = "yes") AC_MSG_CHECKING([if libraries can be versioned]) # Special case for PE/COFF platforms: ld reports # support for version-script, but doesn't actually # DO anything with it. case $host in *cygwin* | *mingw32* | *interix* ) have_ld_version_script=no AC_MSG_RESULT(no) ;; * ) if test "$have_solaris_ld" = "yes"; then GLD=`$LD --help < /dev/null 2>&1 | grep 'M mapfile'` else GLD=`$LD --help < /dev/null 2>/dev/null | grep version-script` fi if test "$GLD"; then have_ld_version_script=yes AC_MSG_RESULT(yes) else have_ld_version_script=no AC_MSG_RESULT(no) AC_MSG_WARN(*** You have not enabled versioned symbols.) fi ;; esac AM_CONDITIONAL(HAVE_LD_VERSION_SCRIPT, test "$have_ld_version_script" = "yes") if test "$have_ld_version_script" = "yes"; then AC_MSG_CHECKING([for symbol prefix]) SYMBOL_PREFIX=`echo "PREFIX=__USER_LABEL_PREFIX__" \ | ${CPP:-${CC:-gcc} -E} - 2>&1 \ | ${EGREP:-grep} "^PREFIX=" \ | ${SED:-sed} -e "s:^PREFIX=::" -e "s:__USER_LABEL_PREFIX__::"` AC_SUBST(SYMBOL_PREFIX) AC_MSG_RESULT($SYMBOL_PREFIX) fi # Substitutions for .in files AC_SUBST(PNGLIB_VERSION) AC_SUBST(PNGLIB_MAJOR) AC_SUBST(PNGLIB_MINOR) AC_SUBST(PNGLIB_RELEASE) # Additional arguments (and substitutions) # Allow the pkg-config directory to be set AC_ARG_WITH(pkgconfigdir, AS_HELP_STRING([[[--with-pkgconfigdir]]], [Use the specified pkgconfig dir (default is libdir/pkgconfig)]), [pkgconfigdir=${withval}], [pkgconfigdir='${libdir}/pkgconfig']) AC_SUBST([pkgconfigdir]) AC_MSG_NOTICE([[pkgconfig directory is ${pkgconfigdir}]]) # Make the *-config binary config scripts optional AC_ARG_WITH(binconfigs, AS_HELP_STRING([[[--with-binconfigs]]], [Generate shell libpng-config scripts as well as pkg-config data] [@<:@default=yes@:>@]), [if test "${withval}" = no; then binconfigs= AC_MSG_NOTICE([[libpng-config scripts will not be built]]) else binconfigs='${binconfigs}' fi], [binconfigs='${binconfigs}']) AC_SUBST([binconfigs]) # Support for prefixes to the API function names; this will generate defines # at the start of the build to rename exported library functions AC_ARG_WITH(libpng-prefix, AS_HELP_STRING([[[--with-libpng-prefix]]], [prefix libpng exported function (API) names with the given value]), [if test "${withval:-no}" != "no"; then AC_SUBST([PNG_PREFIX], [${withval}]) fi]) AM_CONDITIONAL([DO_PNG_PREFIX], [test "${with_libpng_prefix:-no}" != "no"]) # Control over what links are made for installed files. Versioned files are # always installed, when the following options are turned on corresponding # unversioned links are also created (normally as symbolic links): AC_ARG_ENABLE([unversioned-links], AS_HELP_STRING([[[--enable-unversioned-links]]], [Installed libpng header files are placed in a versioned subdirectory] [and installed libpng library (including DLL) files are versioned.] [If this option is enabled unversioned links will be created pointing to] [the corresponding installed files. If you use libpng.pc or] [libpng-config for all builds you do not need these links, but if you] [compile programs directly they will typically #include and] [link with -lpng; in that case you need the links.] [The links can be installed manually using 'make install-header-links'] [and 'make install-library-links' and can be removed using the] [corresponding uninstall- targets. If you do enable this option every] [libpng 'make install' will recreate the links to point to the just] [installed version of libpng. The default is to create the links;] [use --disable-unversioned-links to change this])) # The AM_CONDITIONAL test is written so that the default is enabled; # --disable-unversioned-links must be given to turn the option off. AM_CONDITIONAL([DO_INSTALL_LINKS],[test "$enable_unversioned_links" != "no"]) AC_ARG_ENABLE([unversioned-libpng-pc], AS_HELP_STRING([[[--enable-unversioned-libpng-pc]]], [Install the configuration file 'libpng.pc' as a link to the versioned] [version. This is done by default - use --disable-unversioned-libpng-pc] [to change this.])) AM_CONDITIONAL([DO_INSTALL_LIBPNG_PC], [test "$enable_unversioned_libpng_pc" != "no"]) AC_ARG_ENABLE([unversioned-libpng-config], AS_HELP_STRING([[[--enable-unversioned-libpng-config]]], [Install the configuration file 'libpng-config' as a link to the] [versioned version. This is done by default - use] [--disable-unversioned-libpng-config to change this.])) AM_CONDITIONAL([DO_INSTALL_LIBPNG_CONFIG], [test "$enable_unversioned_libpng_config" != "no"]) # HOST-SPECIFIC OPTIONS # ===================== # # DEFAULT # ======= # AC_ARG_ENABLE([hardware-optimizations], AS_HELP_STRING([[[--enable-hardware-optimizations]]], [Enable hardware optimizations: =no/off, yes/on.]), [case "$enableval" in no|off) # disable hardware optimization on all systems: enable_arm_neon=no AC_DEFINE([PNG_ARM_NEON_OPT], [0], [Disable ARM_NEON optimizations]) enable_mips_msa=no AC_DEFINE([PNG_MIPS_MSA_OPT], [0], [Disable MIPS_MSA optimizations]) enable_mips_mmi=no AC_DEFINE([PNG_MIPS_MMI_OPT], [0], [Disable MIPS_MMI optimizations]) enable_powerpc_vsx=no AC_DEFINE([PNG_POWERPC_VSX_OPT], [0], [Disable POWERPC VSX optimizations]) enable_intel_sse=no AC_DEFINE([PNG_INTEL_SSE_OPT], [0], [Disable INTEL_SSE optimizations]) enable_loongarch_lsx=no AC_DEFINE([PNG_LOONGARCH_LSX_OPT], [0], [Disable LOONGARCH_LSX optimizations]) ;; *) # allow enabling hardware optimization on any system: case "$host_cpu" in arm*|aarch64*) enable_arm_neon=yes AC_DEFINE([PNG_ARM_NEON_OPT], [2], [Enable ARM_NEON optimizations]) ;; mipsel*|mips64el*) enable_mips_mmi=yes enable_mips_msa=yes AC_DEFINE([PNG_MIPS_MMI_OPT], [1], [Enable MIPS_MMI optimizations]) AC_DEFINE([PNG_MIPS_MSA_OPT], [2], [Enable MIPS_MSA optimizations]) ;; i?86|x86_64) enable_intel_sse=yes AC_DEFINE([PNG_INTEL_SSE_OPT], [1], [Enable Intel SSE optimizations]) ;; powerpc*|ppc64*) enable_powerpc_vsx=yes AC_DEFINE([PNG_POWERPC_VSX_OPT], [2], [Enable POWERPC VSX optimizations]) ;; loongarch*) enable_loongarch_lsx=yes AC_DEFINE([PNG_LOONGARCH_LSX_OPT], [1], [Enable LOONGARCH_LSX optimizations]) ;; esac ;; esac]) # ARM NEON # ======== AC_ARG_ENABLE([arm-neon], AS_HELP_STRING([[[--enable-arm-neon]]], [Enable ARM NEON optimizations: =no/off, check, api, yes/on.] [no/off: disable the optimizations;] [check: use internal checking code (deprecated and poorly supported);] [api: disable by default, enable by a call to png_set_option;] [yes/on: turn on unconditionally.] [If not specified: determined by the compiler.]), [case "$enableval" in no|off) # disable the default enabling on __ARM_NEON__ systems: AC_DEFINE([PNG_ARM_NEON_OPT], [0], [Disable ARM Neon optimizations]) # Prevent inclusion of the assembler files below: enable_arm_neon=no ;; check) AC_DEFINE([PNG_ARM_NEON_CHECK_SUPPORTED], [], [Check for ARM Neon support at run-time]);; api) AC_DEFINE([PNG_ARM_NEON_API_SUPPORTED], [], [Turn on ARM Neon optimizations at run-time]);; yes|on) AC_DEFINE([PNG_ARM_NEON_OPT], [2], [Enable ARM Neon optimizations]) AC_MSG_WARN([--enable-arm-neon: please specify 'check' or 'api';] [if you want the optimizations unconditionally,] [pass '-mfpu=neon' to the compiler.]);; *) AC_MSG_ERROR([--enable-arm-neon=${enable_arm_neon}:] [invalid argument]) esac]) # Add ARM-specific files to all builds where $host_cpu is arm ('arm*') or # where ARM optimizations were explicitly requested. (This allows a fallback # if a future host CPU does not match 'arm*'.) AM_CONDITIONAL([PNG_ARM_NEON], [test "$enable_arm_neon" != 'no' && case "$host_cpu" in arm*|aarch64*) : ;; *) test "$enable_arm_neon" != '' ;; esac]) # MIPS MSA # ======== AC_ARG_ENABLE([mips-msa], AS_HELP_STRING([[[--enable-mips-msa]]], [Enable MIPS MSA optimizations: =no/off, check, api, yes/on.] [no/off: disable the optimizations;] [check: use internal checking code (deprecated and poorly supported);] [api: disable by default, enable by a call to png_set_option;] [yes/on: turn on unconditionally.] [If not specified: determined by the compiler.]), [case "$enableval" in no|off) # disable the default enabling on __mips_msa systems: AC_DEFINE([PNG_MIPS_MSA_OPT], [0], [Disable MIPS MSA optimizations]) # Prevent inclusion of the assembler files below: enable_mips_msa=no ;; check) AC_DEFINE([PNG_MIPS_MSA_CHECK_SUPPORTED], [], [Check for MIPS MSA support at run-time]);; api) AC_DEFINE([PNG_MIPS_MSA_API_SUPPORTED], [], [Turn on MIPS MSA optimizations at run-time]);; yes|on) AC_DEFINE([PNG_MIPS_MSA_OPT], [2], [Enable MIPS MSA optimizations]) AC_MSG_WARN([--enable-mips-msa: please specify 'check' or 'api';] [if you want the optimizations unconditionally,] [pass '-mmsa -mfp64' to the compiler.]);; *) AC_MSG_ERROR([--enable-mips-msa=${enable_mips_msa}:] [invalid argument]) esac]) # Add MIPS-specific files to all builds where $host_cpu is mips ('mips*') or # where MIPS optimizations were explicitly requested. (This allows a fallback # if a future host CPU does not match 'mips*'.) AM_CONDITIONAL([PNG_MIPS_MSA], [test "$enable_mips_msa" != 'no' && case "$host_cpu" in mipsel*|mips64el*) : ;; esac]) # MIPS MMI # ======== AC_ARG_ENABLE([mips-mmi], AS_HELP_STRING([[[--enable-mips-mmi]]], [Enable MIPS MMI optimizations: =no/off, check, api, yes/on.] [no/off: disable the optimizations;] [check: use internal checking code (deprecated and poorly supported);] [api: disable by default, enable by a call to png_set_option;] [yes/on: turn on unconditionally.] [If not specified: determined by the compiler.]), [case "$enableval" in no|off) # disable the default enabling on __mips_mmi systems: AC_DEFINE([PNG_MIPS_MMI_OPT], [0], [Disable MIPS MMI optimizations]) # Prevent inclusion of the assembler files below: enable_mips_mmi=no;; check) AC_DEFINE([PNG_MIPS_MMI_CHECK_SUPPORTED], [], [Check for MIPS MMI support at run-time]);; api) AC_DEFINE([PNG_MIPS_MMI_API_SUPPORTED], [], [Turn on MIPS MMI optimizations at run-time]);; yes|on) AC_DEFINE([PNG_MIPS_MMI_OPT], [1], [Enable MIPS MMI optimizations]) AC_MSG_WARN([--enable-mips-mmi: please specify 'check' or 'api';] [if you want the optimizations unconditionally] [pass '-mloongson-mmi -march=loongson3a' to the compiler.]);; *) AC_MSG_ERROR([--enable-mips-mmi=${enable_mips_mmi}:] [invalid argument]) esac]) # Add MIPS specific files to all builds where the host_cpu is mips ('mips*') or # where MIPS optimizations were explicitly requested. (This allows a fallback # if a future host CPU does not match 'mips*'.) AM_CONDITIONAL([PNG_MIPS_MMI], [test "$enable_mips_mmi" != 'no' && case "$host_cpu" in mipsel*|mips64el*) : ;; esac]) # INTEL SSE # ========= AC_ARG_ENABLE([intel-sse], AS_HELP_STRING([[[--enable-intel-sse]]], [Enable Intel SSE optimizations: =no/off, yes/on.] [no/off: disable the optimizations;] [yes/on: enable the optimizations.] [If not specified: determined by the compiler.]), [case "$enableval" in no|off) # disable the default enabling: AC_DEFINE([PNG_INTEL_SSE_OPT], [0], [Disable Intel SSE optimizations]) # Prevent inclusion of the assembler files below: enable_intel_sse=no ;; yes|on) AC_DEFINE([PNG_INTEL_SSE_OPT], [1], [Enable Intel SSE optimizations]);; *) AC_MSG_ERROR([--enable-intel-sse=${enable_intel_sse}:] [invalid argument]) esac]) # Add Intel-specific files to all builds where $host_cpu is Intel ('x86*') or # where Intel optimizations were explicitly requested. (This allows a fallback # if a future host CPU does not match 'x86*'.) AM_CONDITIONAL([PNG_INTEL_SSE], [test "$enable_intel_sse" != 'no' && case "$host_cpu" in i?86|x86_64) : ;; *) test "$enable_intel_sse" != '' ;; esac]) # POWERPC VSX # =========== AC_ARG_ENABLE([powerpc-vsx], AS_HELP_STRING([[[--enable-powerpc-vsx]]], [Enable POWERPC VSX optimizations: =no/off, check, api, yes/on.] [no/off: disable the optimizations;] [check: use internal checking code;] [api: disable by default, enable by a call to png_set_option;] [yes/on: turn on unconditionally.] [If not specified: determined by the compiler.]), [case "$enableval" in no|off) # disable the default enabling on __ppc64__ systems: AC_DEFINE([PNG_POWERPC_VSX_OPT], [0], [Disable POWERPC VSX optimizations]) # Prevent inclusion of the platform-specific files below: enable_powerpc_vsx=no ;; check) AC_DEFINE([PNG_POWERPC_VSX_CHECK_SUPPORTED], [], [Check for POWERPC VSX support at run-time]) AC_MSG_WARN([--enable-powerpc-vsx: please see contrib/powerpc/README] [for the list of supported systems.]);; api) AC_DEFINE([PNG_POWERPC_VSX_API_SUPPORTED], [], [Turn on POWERPC VSX optimizations at run-time]);; yes|on) AC_DEFINE([PNG_POWERPC_VSX_OPT], [2], [Enable POWERPC VSX optimizations]) AC_MSG_WARN([--enable-powerpc-vsx: please specify 'check' or 'api';] [if you want the optimizations unconditionally,] [pass '-maltivec -mvsx' or '-mcpu=power8' to the compiler.]);; *) AC_MSG_ERROR([--enable-powerpc-vsx=${enable_powerpc_vsx}:] [invalid argument]) esac]) # Add PowerPC-specific files to all builds where $host_cpu is powerpc # ('powerpc*') or where PowerPC optimizations were explicitly requested. # (This allows a fallback if a future host CPU does not match 'powerpc*'.) AM_CONDITIONAL([PNG_POWERPC_VSX], [test "$enable_powerpc_vsx" != 'no' && case "$host_cpu" in powerpc*|ppc64*) : ;; esac]) # LOONGARCH LSX # ============= AC_ARG_ENABLE([loongarch-lsx], AS_HELP_STRING([[[--enable-loongarch-lsx]]], [Enable LOONGARCH LSX optimizations: =no/off, yes/on:] [no/off: disable the optimizations;] [yes/on: turn on unconditionally.] [If not specified: determined by the compiler.]), [case "$enableval" in no|off) # disable the default enabling on __loongarch_simd systems: AC_DEFINE([PNG_LOONGARCH_LSX_OPT], [0], [Disable LOONGARCH LSX optimizations]) # Prevent inclusion of the assembler files below: enable_loongarch_lsx=no;; yes|on) AC_DEFINE([PNG_LOONGARCH_LSX_OPT], [1], [Enable LOONGARCH LSX optimizations]) ;; *) AC_MSG_ERROR([--enable-loongarch-lsx=${enable_loongarch_lsx}:] [invalid argument]) esac]) if test "$enable_loongarch_lsx" != "no" && case "$host_cpu" in loongarch*) : ;; *) test "$enable_loongarch_lsx" != '' ;; esac then compiler_support_loongarch_lsx=no AC_MSG_CHECKING(whether to use LoongArch LSX intrinsics) save_CFLAGS="$CFLAGS" LSX_CFLAGS="${LSX_CFLAGS:-"-mlsx"}" CFLAGS="$CFLAGS $LSX_CFLAGS" AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ #include int main(){ __m128i a, b, c; a = __lsx_vadd_w(b, c); return 0; }]])],compiler_support_loongarch_lsx=yes) CFLAGS="$save_CFLAGS" AC_MSG_RESULT($compiler_support_loongarch_lsx) if test "$compiler_support_loongarch_lsx" = "yes"; then AC_DEFINE([PNG_LOONGARCH_LSX_OPT], [1], [Enable LOONGARCH LSX optimizations]) else AC_MSG_WARN([Compiler does not support loongarch LSX.]) fi fi # Add LoongArch specific files to all builds where the host_cpu is loongarch # ('loongarch*') or where LoongArch optimizations were explicitly requested. # (This allows a fallback if a future host CPU does not match 'loongarch*'.) AM_CONDITIONAL([PNG_LOONGARCH_LSX], [test "$enable_loongarch_lsx" != "no" && test "$compiler_support_loongarch_lsx" = "yes" && case "$host_cpu" in loongarch*) : ;; *) test "$enable_loongarch_lsx" != '' ;; esac]) AC_MSG_NOTICE([[Extra options for compiler: $PNG_COPTS]]) # Config files, substituting as above AC_CONFIG_FILES([Makefile libpng.pc:libpng.pc.in]) AC_CONFIG_FILES([libpng-config:libpng-config.in], [chmod +x libpng-config]) AC_OUTPUT libpng-1.6.43/contrib/000077500000000000000000000000001456606525400145355ustar00rootroot00000000000000libpng-1.6.43/contrib/.editorconfig000066400000000000000000000001421456606525400172070ustar00rootroot00000000000000# https://editorconfig.org root = false [*.[ch]] max_doc_length = unset max_line_length = unset libpng-1.6.43/contrib/README.txt000066400000000000000000000004231456606525400162320ustar00rootroot00000000000000 This "contrib" directory contains contributions which are not necessarily under the libpng license, although all are open source. They are not part of libpng proper and are not used for building the library, although some are used for testing the library via "make check". libpng-1.6.43/contrib/arm-neon/000077500000000000000000000000001456606525400162515ustar00rootroot00000000000000libpng-1.6.43/contrib/arm-neon/README000066400000000000000000000065751456606525400171460ustar00rootroot00000000000000OPERATING SYSTEM SPECIFIC ARM NEON DETECTION -------------------------------------------- Detection of the ability to execute ARM NEON on an ARM processor requires operating system support. (The information is not available in user mode.) HOW TO USE THIS --------------- This directory contains C code fragments that can be included in arm/arm_init.c by setting the macro PNG_ARM_NEON_FILE to the file name in "" or <> at build time. This setting is not recorded in pnglibconf.h and can be changed simply by rebuilding arm/arm_init.o with the required macro definition. For any of this code to be used the ARM NEON code must be enabled and run time checks must be supported. I.e.: #if PNG_ARM_NEON_OPT > 0 #ifdef PNG_ARM_NEON_CHECK_SUPPORTED This is done in a 'configure' build by passing configure the argument: --enable-arm-neon=check Apart from the basic Linux implementation in contrib/arm-neon/linux.c this code is unsupported. That means that it is not even compiled on a regular basis and may be broken in any given minor release. FILE FORMAT ----------- Each file documents its testing status as of the last time it was tested (which may have been a long time ago): STATUS: one of: SUPPORTED: This indicates that the file is included in the regularly performed test builds and bugs are fixed when discovered. COMPILED: This indicates that the code did compile at least once. See the more detailed description for the extent to which the result was successful. TESTED: This means the code was fully compiled into the libpng test programs and these were run at least once. BUG REPORTS: an email address to which to send reports of problems The file is a fragment of C code. It should not define any 'extern' symbols; everything should be static. It must define the function: static int png_have_neon(png_structp png_ptr); That function must return 1 if ARM NEON instructions are supported, 0 if not. It must not execute png_error unless it detects a bug. A png_error will prevent the reading of the PNG and in the future, writing too. BUG REPORTS ----------- If you mail a bug report for any file that is not SUPPORTED there may only be limited response. Consider fixing it and sending a patch to fix the problem - this is more likely to result in action. CONTRIBUTIONS ------------- You may send contributions of new implementations to png-mng-implement@sourceforge.net. Please write code in strict C90 C where possible. Obviously OS dependencies are to be expected. If you submit code you must have the authors permission and it must have a license that is acceptable to the current maintainer; in particular that license must permit modification and redistribution. Please try to make the contribution a single file and give the file a clear and unambiguous name that identifies the target OS. If multiple files really are required put them all in a sub-directory. You must also be prepared to handle bug reports from users of the code, either by joining the png-mng-implement mailing list or by providing an email for the "BUG REPORTS" entry or both. Please make sure that the header of the file contains the STATUS and BUG REPORTS fields as above. Please list the OS requirements as precisely as possible. Ideally you should also list the environment in which the code has been tested and certainly list any environments where you suspect it might not work. libpng-1.6.43/contrib/arm-neon/android-ndk.c000066400000000000000000000024371456606525400206150ustar00rootroot00000000000000/* contrib/arm-neon/android-ndk.c * * Copyright (c) 2014 Glenn Randers-Pehrson * Written by John Bowler, 2014. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer * and license in png.h * * SEE contrib/arm-neon/README before reporting bugs * * STATUS: COMPILED, UNTESTED * BUG REPORTS: png-mng-implement@sourceforge.net * * png_have_neon implemented for the Android NDK, see: * * Documentation: * http://www.kandroid.org/ndk/docs/CPU-ARM-NEON.html * https://code.google.com/p/android/issues/detail?id=49065 * * NOTE: this requires that libpng is built against the Android NDK and linked * with an implementation of the Android ARM 'cpu-features' library. The code * has been compiled only, not linked: no version of the library has been found, * only the header files exist in the NDK. */ #include static int png_have_neon(png_structp png_ptr) { /* This is a whole lot easier than the linux code, however it is probably * implemented as below, therefore it is better to cache the result (these * function calls may be slow!) */ PNG_UNUSED(png_ptr) return android_getCpuFamily() == ANDROID_CPU_FAMILY_ARM && (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0; } libpng-1.6.43/contrib/arm-neon/linux-auxv.c000066400000000000000000000062161456606525400205420ustar00rootroot00000000000000/* contrib/arm-neon/linux-auxv.c * * Copyright (c) 2014 Glenn Randers-Pehrson * Written by Mans Rullgard, 2011. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer * and license in png.h * * SEE contrib/arm-neon/README before reporting bugs * * STATUS: COMPILED, TESTED * BUG REPORTS: png-mng-implement@sourceforge.net * * png_have_neon implemented for Linux versions which allow access to * /proc/self/auxv. This is probably faster, cleaner and safer than the code to * read /proc/cpuinfo in contrib/arm-neon/linux, however it is yet another piece * of potentially untested code and has more complex dependencies than the code * to read cpuinfo. * * This generic __linux__ implementation requires reading /proc/self/auxv and * looking at each element for one that records NEON capabilities. */ #include /* for POSIX 1003.1 */ #include /* for EINTR */ #include #include #include #include #include /* A read call may be interrupted, in which case it returns -1 and sets errno to * EINTR if nothing was done, otherwise (if something was done) a partial read * may result. */ static size_t safe_read(png_structp png_ptr, int fd, void *buffer_in, size_t nbytes) { size_t ntotal = 0; char *buffer = png_voidcast(char*, buffer_in); while (nbytes > 0) { unsigned int nread; int iread; /* Passing nread > INT_MAX to read is implementation defined in POSIX * 1003.1, therefore despite the unsigned argument portable code must * limit the value to INT_MAX! */ if (nbytes > INT_MAX) nread = INT_MAX; else nread = (unsigned int)/*SAFE*/nbytes; iread = read(fd, buffer, nread); if (iread == -1) { /* This is the devil in the details, a read can terminate early with 0 * bytes read because of EINTR, yet it still returns -1 otherwise end * of file cannot be distinguished. */ if (errno != EINTR) { png_warning(png_ptr, "/proc read failed"); return 0; /* I.e., a permanent failure */ } } else if (iread < 0) { /* Not a valid 'read' result: */ png_warning(png_ptr, "OS /proc read bug"); return 0; } else if (iread > 0) { /* Continue reading until a permanent failure, or EOF */ buffer += iread; nbytes -= (unsigned int)/*SAFE*/iread; ntotal += (unsigned int)/*SAFE*/iread; } else return ntotal; } return ntotal; /* nbytes == 0 */ } static int png_have_neon(png_structp png_ptr) { int fd = open("/proc/self/auxv", O_RDONLY); Elf32_auxv_t aux; /* Failsafe: failure to open means no NEON */ if (fd == -1) { png_warning(png_ptr, "/proc/self/auxv open failed"); return 0; } while (safe_read(png_ptr, fd, &aux, sizeof aux) == sizeof aux) { if (aux.a_type == AT_HWCAP && (aux.a_un.a_val & HWCAP_NEON) != 0) { close(fd); return 1; } } close(fd); return 0; } libpng-1.6.43/contrib/arm-neon/linux.c000066400000000000000000000105361456606525400175610ustar00rootroot00000000000000/* contrib/arm-neon/linux.c * * Copyright (c) 2014, 2017 Glenn Randers-Pehrson * Written by John Bowler, 2014, 2017. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer * and license in png.h * * SEE contrib/arm-neon/README before reporting bugs * * STATUS: SUPPORTED * BUG REPORTS: png-mng-implement@sourceforge.net * * png_have_neon implemented for Linux by reading the widely available * pseudo-file /proc/cpuinfo. * * This code is strict ANSI-C and is probably moderately portable; it does * however use and it assumes that /proc/cpuinfo is never localized. */ #include static int png_have_neon(png_structp png_ptr) { FILE *f = fopen("/proc/cpuinfo", "rb"); if (f != NULL) { /* This is a simple state machine which reads the input byte-by-byte until * it gets a match on the 'neon' feature or reaches the end of the stream. */ static const char ch_feature[] = { 70, 69, 65, 84, 85, 82, 69, 83 }; static const char ch_neon[] = { 78, 69, 79, 78 }; enum { StartLine, Feature, Colon, StartTag, Neon, HaveNeon, SkipTag, SkipLine } state; int counter; for (state=StartLine, counter=0;;) { int ch = fgetc(f); if (ch == EOF) { /* EOF means error or end-of-file, return false; neon at EOF is * assumed to be a mistake. */ fclose(f); return 0; } switch (state) { case StartLine: /* Match spaces at the start of line */ if (ch <= 32) /* skip control characters and space */ break; counter=0; state = Feature; /* FALLTHROUGH */ case Feature: /* Match 'FEATURE', ASCII case insensitive. */ if ((ch & ~0x20) == ch_feature[counter]) { if (++counter == (sizeof ch_feature)) state = Colon; break; } /* did not match 'feature' */ state = SkipLine; /* FALLTHROUGH */ case SkipLine: skipLine: /* Skip everything until we see linefeed or carriage return */ if (ch != 10 && ch != 13) break; state = StartLine; break; case Colon: /* Match any number of space or tab followed by ':' */ if (ch == 32 || ch == 9) break; if (ch == 58) /* i.e. ':' */ { state = StartTag; break; } /* Either a bad line format or a 'feature' prefix followed by * other characters. */ state = SkipLine; goto skipLine; case StartTag: /* Skip space characters before a tag */ if (ch == 32 || ch == 9) break; state = Neon; counter = 0; /* FALLTHROUGH */ case Neon: /* Look for 'neon' tag */ if ((ch & ~0x20) == ch_neon[counter]) { if (++counter == (sizeof ch_neon)) state = HaveNeon; break; } state = SkipTag; /* FALLTHROUGH */ case SkipTag: /* Skip non-space characters */ if (ch == 10 || ch == 13) state = StartLine; else if (ch == 32 || ch == 9) state = StartTag; break; case HaveNeon: /* Have seen a 'neon' prefix, but there must be a space or new * line character to terminate it. */ if (ch == 10 || ch == 13 || ch == 32 || ch == 9) { fclose(f); return 1; } state = SkipTag; break; default: png_error(png_ptr, "png_have_neon: internal error (bug)"); } } } #ifdef PNG_WARNINGS_SUPPORTED else png_warning(png_ptr, "/proc/cpuinfo open failed"); #endif return 0; } libpng-1.6.43/contrib/conftest/000077500000000000000000000000001456606525400163625ustar00rootroot00000000000000libpng-1.6.43/contrib/conftest/README000066400000000000000000000035321456606525400172450ustar00rootroot00000000000000This directory contains test configuration files, currently always '.dfa' files intended to be used in the build by setting the make macro DFA_XTRA to the name of the file. These files are used in release validation of the 'configure' builds of libpng by building 'make check', or 'make all-am' for cross-builds, with each .dfa file. The files in this directory may change between minor releases, however contributions describing specific builds of libpng are welcomed. There is no guarantee that libpng will continue to build with such configurations; support for given configurations can be, and has been, dropped between successive minor releases. However if a .dfa file describing a configuration is not in this directory it is very unlikely that it will be tested before a minor release! You can use these .dfa files as the basis of new configurations. Files in this directory should not have any use restrictions or restrictive licenses. This directory is not included in the .zip and .7z distributions, which do not contain 'configure' scripts. DOCUMENTATION ============= Examples: ${srcdir}/pngusr.dfa ${srcdir}/contrib/pngminim/*/pngusr.dfa Documentation of the options: ${srcdir}/scripts/pnglibconf.dfa Documentation of the file format: ${srcdir}/scripts/options.awk FILE NAMING =========== File names in this directory may NOT contain any of the five characters: - , + * ? Neither may they contain any space character. While other characters may be used it is strongly suggested that file names be limited to lower case Latiin alphabetic characters (a-z), digits (0-9) and, if necessary the underscore (_) character. File names should be about 8 characters long (excluding the .dfa extension). Submitted .dfa files should have names between 7 and 16 characters long, shorter names (6 characters or less) are reserved for standard tests. libpng-1.6.43/contrib/conftest/basic.dfa000066400000000000000000000062741456606525400201300ustar00rootroot00000000000000# basic.dfa # Build time configuration of libpng # # Author: John Bowler # Copyright: (c) John Bowler, 2024 # Usage rights: # To the extent possible under law, the author has waived all copyright and # related or neighboring rights to this work. This work is published from: # United States. # # Build libpng with basic read and write support. This enables the lowest # level libpng read and write APIs - the "row-by-row" ones. # # Support is enabled only for those transformations that are observed to be # required by widely used apps or are in the v3 specification. # everything = off # The sequential read code is enabled here; the progressive code can be used # instead but there is no point enabling both. option READ on option SEQUENTIAL_READ on option EASY_ACCESS on option SET_USER_LIMITS on option INFO_IMAGE on option READ_16BIT on # Errors: these can be disabled but then there won't be any error messages # just failures and the error messages are really needed for apps: option WARNINGS on option ERROR_TEXT on option BENIGN_READ_ERRORS on # Required for many display programs such as web browsers: option PROGRESSIVE_READ on # Switch on the write code - this makes a minimalist encoder but with # interlace support turned on; otherwise png_read_png..png_write_png will # fail on an interlaced image. option WRITE on option WRITE_INTERLACING on option WRITE_16BIT on # Usages of the 'fixed' APIs are relatively rare but they do occur # one or the other for both the API and the internal math. #Fixed point: option FIXED_POINT on #Floating point: option FLOATING_POINT on option FLOATING_ARITHMETIC on # Basic error handling, IO and user memory support. The latter allows the # application program to provide its own implementations of 'malloc' and 'free'. option SETJMP on option STDIO on option USER_MEM on # Gamma handling: this needs to be on for the gamma handling option READ_GAMMA on # The supported chunks chunk bKGD on chunk cHRM on chunk eXIf on chunk gAMA on chunk iCCP on chunk iTXt on chunk pHYs on chunk sBIT on chunk sRGB on chunk tEXt on chunk tIME on chunk tRNS on chunk zTXt on # These don't seem to be used anywhere: # chunk pCAL # chunk sCAL # chunk sPLT # The rest of this is app dependent: none of these options are required for # read/write of the full range of PNG files and the normal chunk handling on # read. option WRITE_CUSTOMIZE_ZTXT_COMPRESSION on option WRITE_CUSTOMIZE_COMPRESSION on option READ_EXPAND on option READ_FILLER on option READ_GRAY_TO_RGB on option READ_INVERT on option READ_PACK on option READ_RGB_TO_GRAY on option READ_SCALE_16_TO_8 on option READ_SHIFT on option READ_STRIP_16_TO_8 on option READ_STRIP_ALPHA on option READ_SWAP on option CONVERT_tIME on # optipng option IO_STATE on option STORE_UNKNOWN_CHUNKS on option HANDLE_AS_UNKNOWN on # pngcrush option READ_USER_TRANSFORM on option WRITE_FLUSH on # pnmtopng chunk hIST on # cairo option WRITE_PACKSWAP on option WRITE_USER_TRANSFORM on # graphicsmagick option READ_USER_CHUNKS on # Qt5.15 qtgui (gentoo package split) Qt6.6 qtbase option READ_BGR on option WRITE_BGR on option READ_SWAP_ALPHA on option WRITE_SWAP_ALPHA on chunk oFFs on # ghostscript-gpl option WRITE_INVERT_ALPHA on option WRITE_INVERT on libpng-1.6.43/contrib/conftest/pngcp.dfa000066400000000000000000000036451456606525400201550ustar00rootroot00000000000000# pngcp.dfa # Build time configuration of libpng # # Author: John Bowler # Copyright: (c) John Bowler, 2016 # Usage rights: # To the extent possible under law, the author has waived all copyright and # related or neighboring rights to this work. This work is published from: # United States. # # Build libpng with support for pngcp. This means just png_read_png, # png_write_png and small number of configuration settings. # everything = off # This option is specific to this configuration; it adds a #define to the # generated pnglibconf.h which turns on the (not portable) timing option for # pngcp. Note that any option is automatically preceded by PNG_; there is no # way round this and this is deliberate. option PNGCP_TIMING # Because of the everything off above the option must also be turned on. This # may not be done in one step because it is safer and avoids mis-spelled options # in user .dfa files to error out if an unrecognized option is turned on. option PNGCP_TIMING on # Options to turn on png_read_png and png_write_png: option INFO_IMAGE on option SEQUENTIAL_READ on option EASY_ACCESS on option WRITE on option WRITE_16BIT on option WRITE_FILTER on # pngcp needs this to preserve unknown chunks, switching all these on means that # pngcp can work without explicit known chunk reading support option UNKNOWN_CHUNKS on option SET_UNKNOWN_CHUNKS on option HANDLE_AS_UNKNOWN on option SAVE_UNKNOWN_CHUNKS on option WRITE_UNKNOWN_CHUNKS on # pngcp needs this to handle palette files with invalid indices: option CHECK_FOR_INVALID_INDEX on option GET_PALETTE_MAX on # Pre-libpng 1.7 pngcp has to stash text chunks manually, post 1.7 without this # text chunks should be handled as unknown ok. option TEXT on # this is used to turn off limits: option USER_LIMITS on option SET_USER_LIMITS on # these are just required for specific customizations option WRITE_CUSTOMIZE_ZTXT_COMPRESSION on option WRITE_CUSTOMIZE_COMPRESSION on libpng-1.6.43/contrib/conftest/read.dfa000066400000000000000000000040461456606525400177550ustar00rootroot00000000000000# read.dfa # Build time configuration of libpng # # Author: John Bowler # Copyright: (c) John Bowler, 2013 # Usage rights: # To the extent possible under law, the author has waived all copyright and # related or neighboring rights to this work. This work is published from: # United States. # # Build libpng with basic read support. This enables the lowest level libpng # read API - the one where the calling code has to use a loop to read each row. # At present this is the API used by most programs. # # Support is enabled only for those chunks and transformations that are # typically required - others can be added easily. # everything = off # The sequential read code is enabled here; the progressive code can be used # instead but there is no point enabling both. option SEQUENTIAL_READ on # Likewise it is pointless enabling both fixed and floating point APIs. Choose # one or the other for both the API and the internal math. #Fixed point: #option FIXED_POINT on #option FLOATING_ARITHMETIC off #Floating point: option FLOATING_POINT on option FLOATING_ARITHMETIC on # Basic error handling, IO and user memory support. The latter allows the # application program to provide its own implementations of 'malloc' and 'free'. option SETJMP on option STDIO on option USER_MEM on # To read the full set of PNG images correctly interlace, transparency and # 16-bit support is required. The application can implement interlace itself, # but very few do and it's no longer possible to disable it when READ is # enabled. option READ_tRNS on option READ_16BIT on # Everything else is application dependent. This file assumes the app handles # all the native PNG bit layouts, so it doesn't need any of layout change # transforms, but needs libpng to perform gamma correction. It doesn't do any # colorspace stuff and ignores the 'significant bit' information. # # If your app always expands the image to a limited set of bit layouts you # probably want to consider using the simplified API instead of the low level # one - see png.h and s_read.dfa. option READ_GAMMA on libpng-1.6.43/contrib/conftest/s_read.dfa000066400000000000000000000025171456606525400203000ustar00rootroot00000000000000# s_read.dfa # Build time configuration of libpng # # Author: John Bowler # Copyright: (c) John Bowler, 2013 # Usage rights: # To the extent possible under law, the author has waived all copyright and # related or neighboring rights to this work. This work is published from: # United States. # # Build libpng with simplified read support (only). This builds a minimal # libpng able to read all PNG formats and convert them into a small number of # well understood memory formats. # everything = off option SIMPLIFIED_READ on # It isn't necessary to chose fixed or floating point for the APIs because the # simplified API doesn't need fixed or floating point numbers. It is necessary # to chose an internal math implementation. The default (because of 'everything # = off') is fixed point - turn the floating point implementation on if you have # hardware floating point or prefer your software floating point implementation. option FLOATING_ARITHMETIC on # This is not strictly necessary, but without it the message strings in the API # will not be filled in option ERROR_TEXT on # Switching these options on enables the 'AFIRST' and 'BGR' formats - you don't # need this if you don't use them, they just allow the in-memory layout to be # changed to match common hardware formats. option SIMPLIFIED_READ_AFIRST on option SIMPLIFIED_READ_BGR on libpng-1.6.43/contrib/conftest/s_write.dfa000066400000000000000000000023141456606525400205120ustar00rootroot00000000000000# s_write.dfa # Build time configuration of libpng # # Author: John Bowler # Copyright: (c) John Bowler, 2013 # Usage rights: # To the extent possible under law, the author has waived all copyright and # related or neighboring rights to this work. This work is published from: # United States. # # Build libpng with (just) simplified write support # everything = off option SIMPLIFIED_WRITE on # It isn't necessary to chose fixed or floating point for the APIs because the # simplified API doesn't need fixed or floating point numbers. It is necessary # to chose an internal math implementation. The default (because of 'everything # = off') is fixed point - turn the floating point implementation on if you have # hardware floating point or prefer your software floating point implementation. option FLOATING_ARITHMETIC on # This is not strictly necessary, but without it the message strings in the API # will not be filled in option ERROR_TEXT on # Switching these options on enables the 'AFIRST' and 'BGR' formats - you don't # need this if you don't use them, they just allow the in-memory layout to be # changed to match common hardware formats. option SIMPLIFIED_WRITE_AFIRST on option SIMPLIFIED_WRITE_BGR on libpng-1.6.43/contrib/conftest/simple.dfa000066400000000000000000000024571456606525400203370ustar00rootroot00000000000000# simple.dfa # Build time configuration of libpng # # Author: John Bowler # Copyright: (c) John Bowler, 2013 # Usage rights: # To the extent possible under law, the author has waived all copyright and # related or neighboring rights to this work. This work is published from: # United States. # # Build libpng with just the simplified APIs (read and write). # everything = off option SIMPLIFIED_WRITE on option SIMPLIFIED_READ on # It isn't necessary to chose fixed or floating point for the APIs because the # simplified API doesn't need fixed or floating point numbers. It is necessary # to chose an internal math implementation. The default (because of 'everything # = off') is fixed point - turn the floating point implementation on if you have # hardware floating point or prefer your software floating point implementation. option FLOATING_ARITHMETIC on # This is not strictly necessary, but without it the message strings in the API # will not be filled in option ERROR_TEXT on # Switching these options on enables the 'AFIRST' and 'BGR' formats - you don't # need this if you don't use them, they just allow the in-memory layout to be # changed to match common hardware formats. option SIMPLIFIED_READ_AFIRST on option SIMPLIFIED_READ_BGR on option SIMPLIFIED_WRITE_AFIRST on option SIMPLIFIED_WRITE_BGR on libpng-1.6.43/contrib/conftest/write.dfa000066400000000000000000000027461456606525400202010ustar00rootroot00000000000000# write.dfa # Build time configuration of libpng # # Author: John Bowler # Copyright: (c) John Bowler, 2013 # Usage rights: # To the extent possible under law, the author has waived all copyright and # related or neighboring rights to this work. This work is published from: # United States. # # Build libpng with no read support and minimal write support. # everything = off # Switch on the write code - this makes a minimalist encoder option WRITE on # Choose fixed or floating point APIs and arithmetic. The choices are # independent but normally they will match. It is typically better to use the # floating point if you have floating point hardware. If you don't know, or # (perhaps) to make libpng smaller used fixed point throughout. #Fixed point: #option FIXED_POINT on #option FLOATING_ARITHMETIC off #Floating point: option FLOATING_POINT on option FLOATING_ARITHMETIC on # Basic error handling, IO and user memory support. The latter allows the # application program to provide its own implementations of 'malloc' and 'free'. option SETJMP on option STDIO on option USER_MEM on # Everything else is optional. Unlike the read code in libpng the write code # does not need to deal with arbitrary formats, so only add support for things # you really do write! For example you might only write sRGB images, sometimes # with transparency and never write 16 bit images, so: option WRITE_sRGB on option WRITE_tRNS on #option WRITE_16BIT off (this is the default with 'everything = off') libpng-1.6.43/contrib/examples/000077500000000000000000000000001456606525400163535ustar00rootroot00000000000000libpng-1.6.43/contrib/examples/README.txt000066400000000000000000000017011456606525400200500ustar00rootroot00000000000000 This directory (contrib/examples) contains examples of libpng usage. NO COPYRIGHT RIGHTS ARE CLAIMED TO ANY OF THE FILES IN THIS DIRECTORY. To the extent possible under law, the authors have waived all copyright and related or neighboring rights to this work. This work is published from: United States. The files may be used freely in any way. The intention is that appropriate parts of the files be used in other libpng-using programs without any need for the authors of the using code to seek copyright or license from the original authors. The source code and comments in this directory are the original work of the people named below. No other person or organization has made contributions to the work in this directory. ORIGINAL AUTHORS The following people have contributed to the code in this directory. None of the people below claim any rights with regard to the contents of this directory. John Bowler libpng-1.6.43/contrib/examples/iccfrompng.c000066400000000000000000000111061456606525400206450ustar00rootroot00000000000000/*- iccfrompng * * COPYRIGHT: Written by John Cunningham Bowler, 2011. * To the extent possible under law, the author has waived all copyright and * related or neighboring rights to this work. This work is published from: * United States. * * Extract any icc profiles found in the given PNG files. This is a simple * example of a program that extracts information from the header of a PNG file * without processing the image. Notice that some header information may occur * after the image data. Textual data and comments are an example; the approach * in this file won't work reliably for such data because it only looks for the * information in the section of the file that precedes the image data. * * Compile and link against libpng and zlib, plus anything else required on the * system you use. * * To use supply a list of PNG files containing iCCP chunks, the chunks will be * extracted to a similarly named file with the extension replaced by 'icc', * which will be overwritten without warning. */ #include #include #include #include #include #if defined(PNG_READ_SUPPORTED) && defined(PNG_STDIO_SUPPORTED) && \ defined (PNG_iCCP_SUPPORTED) static int verbose = 1; static png_byte no_profile[] = "no profile"; static png_bytep extract(FILE *fp, png_uint_32 *proflen) { png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,0,0,0); png_infop info_ptr = NULL; png_bytep result = NULL; /* Initialize for error or no profile: */ *proflen = 0; if (png_ptr == NULL) { fprintf(stderr, "iccfrompng: version library mismatch?\n"); return 0; } if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return 0; } png_init_io(png_ptr, fp); info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) png_error(png_ptr, "OOM allocating info structure"); png_read_info(png_ptr, info_ptr); { png_charp name; int compression_type; png_bytep profile; if (png_get_iCCP(png_ptr, info_ptr, &name, &compression_type, &profile, proflen) & PNG_INFO_iCCP) { result = malloc(*proflen); if (result != NULL) memcpy(result, profile, *proflen); else png_error(png_ptr, "OOM allocating profile buffer"); } else result = no_profile; } png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return result; } static int extract_one_file(const char *filename) { int result = 0; FILE *fp = fopen(filename, "rb"); if (fp != NULL) { png_uint_32 proflen = 0; png_bytep profile = extract(fp, &proflen); if (profile != NULL && profile != no_profile) { size_t len; char *output; { const char *ep = strrchr(filename, '.'); if (ep != NULL) len = ep-filename; else len = strlen(filename); } output = malloc(len + 5); if (output != NULL) { FILE *of; memcpy(output, filename, len); strcpy(output+len, ".icc"); of = fopen(output, "wb"); if (of != NULL) { if (fwrite(profile, proflen, 1, of) == 1 && fflush(of) == 0 && fclose(of) == 0) { if (verbose) printf("%s -> %s\n", filename, output); /* Success return */ result = 1; } else { fprintf(stderr, "%s: error writing profile\n", output); if (remove(output)) fprintf(stderr, "%s: could not remove file\n", output); } } else fprintf(stderr, "%s: failed to open output file\n", output); free(output); } else fprintf(stderr, "%s: OOM allocating string!\n", filename); free(profile); } else if (verbose && profile == no_profile) printf("%s has no profile\n", filename); } else fprintf(stderr, "%s: could not open file\n", filename); return result; } int main(int argc, char **argv) { int i; int extracted = 0; for (i=1; i #include #include /* required for error handling */ /* Normally use here to get the installed libpng, but this is done to * ensure the code picks up the local libpng implementation: */ #include "../../png.h" #if defined(PNG_READ_SUPPORTED) && defined(PNG_SEQUENTIAL_READ_SUPPORTED) /* Return component 'c' of pixel 'x' from the given row. */ static unsigned int component(png_const_bytep row, png_uint_32 x, unsigned int c, unsigned int bit_depth, unsigned int channels) { /* PNG images can be up to 2^31 pixels wide, but this means they can be up to * 2^37 bits wide (for a 64-bit pixel - the largest possible) and hence 2^34 * bytes wide. Since the row fitted into memory, however, the following must * work: */ png_uint_32 bit_offset_hi = bit_depth * ((x >> 6) * channels); png_uint_32 bit_offset_lo = bit_depth * ((x & 0x3f) * channels + c); row = (png_const_bytep)(((const png_byte (*)[8])row) + bit_offset_hi); row += bit_offset_lo >> 3; bit_offset_lo &= 0x07; /* PNG pixels are packed into bytes to put the first pixel in the highest * bits of the byte and into two bytes for 16-bit values with the high 8 bits * first, so: */ switch (bit_depth) { case 1: return (row[0] >> (7-bit_offset_lo)) & 0x01; case 2: return (row[0] >> (6-bit_offset_lo)) & 0x03; case 4: return (row[0] >> (4-bit_offset_lo)) & 0x0f; case 8: return row[0]; case 16: return (row[0] << 8) + row[1]; default: /* This should never happen; it indicates a bug in this program or in * libpng itself: */ fprintf(stderr, "pngpixel: invalid bit depth %u\n", bit_depth); exit(1); } } /* Print a pixel from a row returned by libpng; determine the row format, find * the pixel, and print the relevant information to stdout. */ static void print_pixel(png_structp png_ptr, png_infop info_ptr, png_const_bytep row, png_uint_32 x) { unsigned int bit_depth = png_get_bit_depth(png_ptr, info_ptr); switch (png_get_color_type(png_ptr, info_ptr)) { case PNG_COLOR_TYPE_GRAY: printf("GRAY %u\n", component(row, x, 0, bit_depth, 1)); return; /* The palette case is slightly more difficult - the palette and, if * present, the tRNS ('transparency', though the values are really * opacity) data must be read to give the full picture: */ case PNG_COLOR_TYPE_PALETTE: { int index = component(row, x, 0, bit_depth, 1); png_colorp palette = NULL; int num_palette = 0; if ((png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette) & PNG_INFO_PLTE) && num_palette > 0 && palette != NULL) { png_bytep trans_alpha = NULL; int num_trans = 0; if ((png_get_tRNS(png_ptr, info_ptr, &trans_alpha, &num_trans, NULL) & PNG_INFO_tRNS) && num_trans > 0 && trans_alpha != NULL) printf("INDEXED %u = %d %d %d %d\n", index, palette[index].red, palette[index].green, palette[index].blue, index < num_trans ? trans_alpha[index] : 255); else /* no transparency */ printf("INDEXED %u = %d %d %d\n", index, palette[index].red, palette[index].green, palette[index].blue); } else printf("INDEXED %u = invalid index\n", index); } return; case PNG_COLOR_TYPE_RGB: printf("RGB %u %u %u\n", component(row, x, 0, bit_depth, 3), component(row, x, 1, bit_depth, 3), component(row, x, 2, bit_depth, 3)); return; case PNG_COLOR_TYPE_GRAY_ALPHA: printf("GRAY+ALPHA %u %u\n", component(row, x, 0, bit_depth, 2), component(row, x, 1, bit_depth, 2)); return; case PNG_COLOR_TYPE_RGB_ALPHA: printf("RGBA %u %u %u %u\n", component(row, x, 0, bit_depth, 4), component(row, x, 1, bit_depth, 4), component(row, x, 2, bit_depth, 4), component(row, x, 3, bit_depth, 4)); return; default: png_error(png_ptr, "pngpixel: invalid color type"); } } int main(int argc, const char **argv) { /* This program uses the default, based, libpng error handling * mechanism, therefore any local variable that exists before the call to * setjmp and is changed after the call to setjmp returns successfully must * be declared with 'volatile' to ensure that their values don't get * destroyed by longjmp: */ volatile int result = 1/*fail*/; if (argc == 4) { long x = atol(argv[1]); long y = atol(argv[2]); FILE *f = fopen(argv[3], "rb"); volatile png_bytep row = NULL; if (f != NULL) { /* libpng requires a callback function for handling errors; this * callback must not return. The default callback function uses a * stored style jmp_buf which is held in a png_struct and * writes error messages to stderr. Creating the png_struct is a * little tricky; just copy the following code. */ png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_ptr != NULL) { png_infop info_ptr = png_create_info_struct(png_ptr); if (info_ptr != NULL) { /* Declare stack variables to hold pointers to locally allocated * data. */ /* Initialize the error control buffer: */ if (setjmp(png_jmpbuf(png_ptr)) == 0) { png_uint_32 width, height; int bit_depth, color_type, interlace_method, compression_method, filter_method; png_bytep row_tmp; /* Now associate the recently opened (FILE*) with the default * libpng initialization functions. Sometimes libpng is * compiled without stdio support (it can be difficult to do * in some environments); in that case you will have to write * your own read callback to read data from the (FILE*). */ png_init_io(png_ptr, f); /* And read the first part of the PNG file - the header and * all the information up to the first pixel. */ png_read_info(png_ptr, info_ptr); /* This fills in enough information to tell us the width of * each row in bytes, allocate the appropriate amount of * space. In this case png_malloc is used - it will not * return if memory isn't available. */ row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); /* To avoid the overhead of using a volatile auto copy row_tmp * to a local here - just use row for the png_free below. */ row_tmp = row; /* All the information we need is in the header is returned by * png_get_IHDR, if this fails we can now use 'png_error' to * signal the error and return control to the setjmp above. */ if (png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_method, &compression_method, &filter_method)) { int passes, pass; /* png_set_interlace_handling returns the number of * passes required as well as turning on libpng's * handling, but since we do it ourselves this is * necessary: */ switch (interlace_method) { case PNG_INTERLACE_NONE: passes = 1; break; case PNG_INTERLACE_ADAM7: passes = PNG_INTERLACE_ADAM7_PASSES; break; default: png_error(png_ptr, "pngpixel: unknown interlace"); } /* Now read the pixels, pass-by-pass, row-by-row: */ png_start_read_image(png_ptr); for (pass=0; pass #include #include #include /* Normally use here to get the installed libpng, but this is done to * ensure the code picks up the local libpng implementation: */ #include "../../png.h" #if defined(PNG_SIMPLIFIED_READ_SUPPORTED) && \ defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) int main(int argc, const char **argv) { int result = 1; if (argc == 3) { png_image image; /* Only the image structure version number needs to be set. */ memset(&image, 0, sizeof image); image.version = PNG_IMAGE_VERSION; if (png_image_begin_read_from_file(&image, argv[1])) { png_bytep buffer; /* Change this to try different formats! If you set a colormap format * then you must also supply a colormap below. */ image.format = PNG_FORMAT_RGBA; buffer = malloc(PNG_IMAGE_SIZE(image)); if (buffer != NULL) { if (png_image_finish_read(&image, NULL/*background*/, buffer, 0/*row_stride*/, NULL/*colormap for PNG_FORMAT_FLAG_COLORMAP */)) { if (png_image_write_to_file(&image, argv[2], 0/*convert_to_8bit*/, buffer, 0/*row_stride*/, NULL/*colormap*/)) result = 0; else fprintf(stderr, "pngtopng: write %s: %s\n", argv[2], image.message); } else fprintf(stderr, "pngtopng: read %s: %s\n", argv[1], image.message); free(buffer); } else { fprintf(stderr, "pngtopng: out of memory: %lu bytes\n", (unsigned long)PNG_IMAGE_SIZE(image)); /* This is the only place where a 'free' is required; libpng does * the cleanup on error and success, but in this case we couldn't * complete the read because of running out of memory and so libpng * has not got to the point where it can do cleanup. */ png_image_free(&image); } } else /* Failed to read the first argument: */ fprintf(stderr, "pngtopng: %s: %s\n", argv[1], image.message); } else /* Wrong number of arguments */ fprintf(stderr, "pngtopng: usage: pngtopng input-file output-file\n"); return result; } #endif /* READ && WRITE */ libpng-1.6.43/contrib/examples/simpleover.c000066400000000000000000000500311456606525400207030ustar00rootroot00000000000000/*- simpleover * * COPYRIGHT: Written by John Cunningham Bowler, 2015. * To the extent possible under law, the author has waived all copyright and * related or neighboring rights to this work. This work is published from: * United States. * * Read several PNG files, which should have an alpha channel or transparency * information, and composite them together to produce one or more 16-bit linear * RGBA intermediates. This involves doing the correct 'over' composition to * combine the alpha channels and corresponding data. * * Finally read an output (background) PNG using the 24-bit RGB format (the * PNG will be composited on green (#00ff00) by default if it has an alpha * channel), and apply the intermediate image generated above to specified * locations in the image. * * The command line has the general format: * * simpleover [output.png] * {--sprite=width,height,name {[--at=x,y] {sprite.png}}} * {--add=name {x,y}} * * The --sprite and --add options may occur multiple times. They are executed * in order. --add may refer to any sprite already read. * * This code is intended to show how to composite multiple images together * correctly. Apart from the libpng Simplified API the only work done in here * is to combine multiple input PNG images into a single sprite; this involves * a Porter-Duff 'over' operation and the input PNG images may, as a result, * be regarded as being layered one on top of the other with the first (leftmost * on the command line) being at the bottom and the last on the top. */ #include #include #include #include #include /* Normally use here to get the installed libpng, but this is done to * ensure the code picks up the local libpng implementation, so long as this * file is linked against a sufficiently recent libpng (1.6+) it is ok to * change this to : */ #include "../../png.h" #ifdef PNG_SIMPLIFIED_READ_SUPPORTED #define sprite_name_chars 15 struct sprite { FILE *file; png_uint_16p buffer; unsigned int width; unsigned int height; char name[sprite_name_chars+1]; }; #if 0 /* div by 65535 test program */ #include #include int main(void) { double err = 0; unsigned int xerr = 0; unsigned int r = 32769; { unsigned int x = 0; do { unsigned int t = x + (x >> 16) /*+ (x >> 31)*/ + r; double v = x, errtest; if (t < x) { fprintf(stderr, "overflow: %u+%u -> %u\n", x, r, t); return 1; } v /= 65535; errtest = v; t >>= 16; errtest -= t; if (errtest > err) { err = errtest; xerr = x; if (errtest >= .5) { fprintf(stderr, "error: %u/65535 = %f, not %u, error %f\n", x, v, t, errtest); return 0; } } } while (++x <= 65535U*65535U); } printf("error %f @ %u\n", err, xerr); return 0; } #endif /* div by 65535 test program */ static void sprite_op(const struct sprite *sprite, int x_offset, int y_offset, png_imagep image, const png_uint_16 *buffer) { /* This is where the Porter-Duff 'Over' operator is evaluated; change this * code to change the operator (this could be parameterized). Any other * image processing operation could be used here. */ /* Check for an x or y offset that pushes any part of the image beyond the * right or bottom of the sprite: */ if ((y_offset < 0 || (unsigned)/*SAFE*/y_offset < sprite->height) && (x_offset < 0 || (unsigned)/*SAFE*/x_offset < sprite->width)) { unsigned int y = 0; if (y_offset < 0) y = -y_offset; /* Skip to first visible row */ do { unsigned int x = 0; if (x_offset < 0) x = -x_offset; do { /* In and out are RGBA values, so: */ const png_uint_16 *in_pixel = buffer + (y * image->width + x)*4; png_uint_32 in_alpha = in_pixel[3]; /* This is the optimized Porter-Duff 'Over' operation, when the * input alpha is 0 the output is not changed. */ if (in_alpha > 0) { png_uint_16 *out_pixel = sprite->buffer + ((y+y_offset) * sprite->width + (x+x_offset))*4; /* This is the weight to apply to the output: */ in_alpha = 65535-in_alpha; if (in_alpha > 0) { /* The input must be composed onto the output. This means * multiplying the current output pixel value by the inverse * of the input alpha (1-alpha). A division is required but * it is by the constant 65535. Approximate this as: * * (x + (x >> 16) + 32769) >> 16; * * This is exact (and does not overflow) for all values of * x in the range 0..65535*65535. (Note that the calculation * produces the closest integer; the maximum error is <0.5). */ png_uint_32 tmp; # define compose(c)\ tmp = out_pixel[c] * in_alpha;\ tmp = (tmp + (tmp >> 16) + 32769) >> 16;\ out_pixel[c] = tmp + in_pixel[c] /* The following is very vectorizable... */ compose(0); compose(1); compose(2); compose(3); } else out_pixel[0] = in_pixel[0], out_pixel[1] = in_pixel[1], out_pixel[2] = in_pixel[2], out_pixel[3] = in_pixel[3]; } } while (++x < image->width); } while (++y < image->height); } } static int create_sprite(struct sprite *sprite, int *argc, const char ***argv) { /* Read the arguments and create this sprite. The sprite buffer has already * been allocated. This reads the input PNGs one by one in linear format, * composes them onto the sprite buffer (the code in the function above) * then saves the result, converting it on the fly to PNG RGBA 8-bit format. */ while (*argc > 0) { char tombstone; int x = 0, y = 0; if ((*argv)[0][0] == '-' && (*argv)[0][1] == '-') { /* The only supported option is --at. */ if (sscanf((*argv)[0], "--at=%d,%d%c", &x, &y, &tombstone) != 2) break; /* success; caller will parse this option */ ++*argv, --*argc; } else { /* The argument has to be a file name */ png_image image; image.version = PNG_IMAGE_VERSION; image.opaque = NULL; if (png_image_begin_read_from_file(&image, (*argv)[0])) { png_uint_16p buffer; image.format = PNG_FORMAT_LINEAR_RGB_ALPHA; buffer = malloc(PNG_IMAGE_SIZE(image)); if (buffer != NULL) { if (png_image_finish_read(&image, NULL/*background*/, buffer, 0/*row_stride*/, NULL/*colormap for PNG_FORMAT_FLAG_COLORMAP*/)) { /* This is the place where the Porter-Duff 'Over' operator * needs to be done by this code. In fact, any image * processing required can be done here; the data is in * the correct format (linear, 16-bit) and source and * destination are in memory. */ sprite_op(sprite, x, y, &image, buffer); free(buffer); ++*argv, --*argc; /* And continue to the next argument */ continue; } else { free(buffer); fprintf(stderr, "simpleover: read %s: %s\n", (*argv)[0], image.message); } } else { fprintf(stderr, "simpleover: out of memory: %lu bytes\n", (unsigned long)PNG_IMAGE_SIZE(image)); /* png_image_free must be called if we abort the Simplified API * read because of a problem detected in this code. If problems * are detected in the Simplified API it cleans up itself. */ png_image_free(&image); } } else { /* Failed to read the first argument: */ fprintf(stderr, "simpleover: %s: %s\n", (*argv)[0], image.message); } return 0; /* failure */ } } /* All the sprite operations have completed successfully. Save the RGBA * buffer as a PNG using the simplified write API. */ sprite->file = tmpfile(); if (sprite->file != NULL) { png_image save; memset(&save, 0, sizeof save); save.version = PNG_IMAGE_VERSION; save.opaque = NULL; save.width = sprite->width; save.height = sprite->height; save.format = PNG_FORMAT_LINEAR_RGB_ALPHA; save.flags = PNG_IMAGE_FLAG_FAST; save.colormap_entries = 0; if (png_image_write_to_stdio(&save, sprite->file, 1/*convert_to_8_bit*/, sprite->buffer, 0/*row_stride*/, NULL/*colormap*/)) { /* Success; the buffer is no longer needed: */ free(sprite->buffer); sprite->buffer = NULL; return 1; /* ok */ } else fprintf(stderr, "simpleover: write sprite %s: %s\n", sprite->name, save.message); } else fprintf(stderr, "simpleover: sprite %s: could not allocate tmpfile: %s\n", sprite->name, strerror(errno)); return 0; /* fail */ } static int add_sprite(png_imagep output, png_bytep out_buf, struct sprite *sprite, int *argc, const char ***argv) { /* Given a --add argument naming this sprite, perform the operations listed * in the following arguments. The arguments are expected to have the form * (x,y), which is just an offset at which to add the sprite to the * output. */ while (*argc > 0) { char tombstone; int x, y; if ((*argv)[0][0] == '-' && (*argv)[0][1] == '-') return 1; /* success */ if (sscanf((*argv)[0], "%d,%d%c", &x, &y, &tombstone) == 2) { /* Now add the new image into the sprite data, but only if it * will fit. */ if (x < 0 || y < 0 || (unsigned)/*SAFE*/x >= output->width || (unsigned)/*SAFE*/y >= output->height || sprite->width > output->width-x || sprite->height > output->height-y) { fprintf(stderr, "simpleover: sprite %s @ (%d,%d) outside image\n", sprite->name, x, y); /* Could just skip this, but for the moment it is an error */ return 0; /* error */ } else { /* Since we know the sprite fits we can just read it into the * output using the simplified API. */ png_image in; in.version = PNG_IMAGE_VERSION; rewind(sprite->file); if (png_image_begin_read_from_stdio(&in, sprite->file)) { in.format = PNG_FORMAT_RGB; /* force compose */ if (png_image_finish_read(&in, NULL/*background*/, out_buf + (y*output->width + x)*3/*RGB*/, output->width*3/*row_stride*/, NULL/*colormap for PNG_FORMAT_FLAG_COLORMAP*/)) { ++*argv, --*argc; continue; } } /* The read failed: */ fprintf(stderr, "simpleover: add sprite %s: %s\n", sprite->name, in.message); return 0; /* error */ } } else { fprintf(stderr, "simpleover: --add='%s': invalid position %s\n", sprite->name, (*argv)[0]); return 0; /* error */ } } return 1; /* ok */ } static int simpleover_process(png_imagep output, png_bytep out_buf, int argc, const char **argv) { int result = 1; /* success */ # define csprites 10/*limit*/ # define str(a) #a int nsprites = 0; struct sprite sprites[csprites]; while (argc > 0) { result = 0; /* fail */ if (strncmp(argv[0], "--sprite=", 9) == 0) { char tombstone; if (nsprites < csprites) { int n; sprites[nsprites].width = sprites[nsprites].height = 0; sprites[nsprites].name[0] = 0; n = sscanf(argv[0], "--sprite=%u,%u,%" str(sprite_name_chars) "s%c", &sprites[nsprites].width, &sprites[nsprites].height, sprites[nsprites].name, &tombstone); if ((n == 2 || n == 3) && sprites[nsprites].width > 0 && sprites[nsprites].height > 0) { size_t buf_size, tmp; /* Default a name if not given. */ if (sprites[nsprites].name[0] == 0) sprintf(sprites[nsprites].name, "sprite-%d", nsprites+1); /* Allocate a buffer for the sprite and calculate the buffer * size: */ buf_size = sizeof (png_uint_16 [4]); buf_size *= sprites[nsprites].width; buf_size *= sprites[nsprites].height; /* This can overflow a (size_t); check for this: */ tmp = buf_size; tmp /= sprites[nsprites].width; tmp /= sprites[nsprites].height; if (tmp == sizeof (png_uint_16 [4])) { sprites[nsprites].buffer = malloc(buf_size); /* This buffer must be initialized to transparent: */ memset(sprites[nsprites].buffer, 0, buf_size); if (sprites[nsprites].buffer != NULL) { sprites[nsprites].file = NULL; ++argv, --argc; if (create_sprite(sprites+nsprites++, &argc, &argv)) { result = 1; /* still ok */ continue; } break; /* error */ } } /* Overflow, or OOM */ fprintf(stderr, "simpleover: %s: sprite too large\n", argv[0]); break; } else { fprintf(stderr, "simpleover: %s: invalid sprite (%u,%u)\n", argv[0], sprites[nsprites].width, sprites[nsprites].height); break; } } else { fprintf(stderr, "simpleover: %s: too many sprites\n", argv[0]); break; } } else if (strncmp(argv[0], "--add=", 6) == 0) { const char *name = argv[0]+6; int isprite = nsprites; ++argv, --argc; while (--isprite >= 0) { if (strcmp(sprites[isprite].name, name) == 0) { if (!add_sprite(output, out_buf, sprites+isprite, &argc, &argv)) goto out; /* error in add_sprite */ break; } } if (isprite < 0) /* sprite not found */ { fprintf(stderr, "simpleover: --add='%s': sprite not found\n", name); break; } } else { fprintf(stderr, "simpleover: %s: unrecognized operation\n", argv[0]); break; } result = 1; /* ok */ } /* Clean up the cache of sprites: */ out: while (--nsprites >= 0) { if (sprites[nsprites].buffer != NULL) free(sprites[nsprites].buffer); if (sprites[nsprites].file != NULL) (void)fclose(sprites[nsprites].file); } return result; } int main(int argc, const char **argv) { int result = 1; /* default to fail */ if (argc >= 2) { int argi = 2; const char *output = NULL; png_image image; if (argc > 2 && argv[2][0] != '-'/*an operation*/) { output = argv[2]; argi = 3; } image.version = PNG_IMAGE_VERSION; image.opaque = NULL; if (png_image_begin_read_from_file(&image, argv[1])) { png_bytep buffer; image.format = PNG_FORMAT_RGB; /* 24-bit RGB */ buffer = malloc(PNG_IMAGE_SIZE(image)); if (buffer != NULL) { png_color background = {0, 0xff, 0}; /* fully saturated green */ if (png_image_finish_read(&image, &background, buffer, 0/*row_stride*/, NULL/*colormap for PNG_FORMAT_FLAG_COLORMAP */)) { /* At this point png_image_finish_read has cleaned up the * allocated data in png_image, and only the buffer needs to be * freed. * * Perform the remaining operations: */ if (simpleover_process(&image, buffer, argc-argi, argv+argi)) { /* Write the output: */ if ((output != NULL && png_image_write_to_file(&image, output, 0/*convert_to_8bit*/, buffer, 0/*row_stride*/, NULL/*colormap*/)) || (output == NULL && png_image_write_to_stdio(&image, stdout, 0/*convert_to_8bit*/, buffer, 0/*row_stride*/, NULL/*colormap*/))) result = 0; else fprintf(stderr, "simpleover: write %s: %s\n", output == NULL ? "stdout" : output, image.message); } /* else simpleover_process writes an error message */ } else fprintf(stderr, "simpleover: read %s: %s\n", argv[1], image.message); free(buffer); } else { fprintf(stderr, "simpleover: out of memory: %lu bytes\n", (unsigned long)PNG_IMAGE_SIZE(image)); /* This is the only place where a 'free' is required; libpng does * the cleanup on error and success, but in this case we couldn't * complete the read because of running out of memory. */ png_image_free(&image); } } else { /* Failed to read the first argument: */ fprintf(stderr, "simpleover: %s: %s\n", argv[1], image.message); } } else { /* Usage message */ fprintf(stderr, "simpleover: usage: simpleover background.png [output.png]\n" " Output 'background.png' as a 24-bit RGB PNG file in 'output.png'\n" " or, if not given, stdout. 'background.png' will be composited\n" " on fully saturated green.\n" "\n" " Optionally, before output, process additional PNG files:\n" "\n" " --sprite=width,height,name {[--at=x,y] {sprite.png}}\n" " Produce a transparent sprite of size (width,height) and with\n" " name 'name'.\n" " For each sprite.png composite it using a Porter-Duff 'Over'\n" " operation at offset (x,y) in the sprite (defaulting to (0,0)).\n" " Input PNGs will be truncated to the area of the sprite.\n" "\n" " --add='name' {x,y}\n" " Optionally, before output, composite a sprite, 'name', which\n" " must have been previously produced using --sprite, at each\n" " offset (x,y) in the output image. Each sprite must fit\n" " completely within the output image.\n" "\n" " PNG files are processed in the order they occur on the command\n" " line and thus the first PNG processed appears as the bottommost\n" " in the output image.\n"); } return result; } #endif /* SIMPLIFIED_READ */ libpng-1.6.43/contrib/gregbook/000077500000000000000000000000001456606525400163345ustar00rootroot00000000000000libpng-1.6.43/contrib/gregbook/COPYING000066400000000000000000000432611456606525400173750ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. libpng-1.6.43/contrib/gregbook/LICENSE000066400000000000000000000045051456606525400173450ustar00rootroot00000000000000 --------------------------------------------------------------------------- Copyright (c) 1998-2008 Greg Roelofs. All rights reserved. This software is provided "as is," without warranty of any kind, express or implied. In no event shall the author or contributors be held liable for any damages arising in any way from the use of this software. The contents of this file are DUAL-LICENSED. You may modify and/or redistribute this software according to the terms of one of the following two licenses (at your option): LICENSE 1 ("BSD-like with advertising clause"): Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. Redistributions of source code must retain the above copyright notice, disclaimer, and this list of conditions. 2. Redistributions in binary form must reproduce the above copyright notice, disclaimer, and this list of conditions in the documenta- tion and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgment: This product includes software developed by Greg Roelofs and contributors for the book, "PNG: The Definitive Guide," published by O'Reilly and Associates. LICENSE 2 (GNU GPL v2 or later): This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --------------------------------------------------------------------------- libpng-1.6.43/contrib/gregbook/Makefile.mingw32000066400000000000000000000075441456606525400212730ustar00rootroot00000000000000# Sample makefile for rpng-win / rpng2-win / wpng using mingw32-gcc and make. # Greg Roelofs # Last modified: 2 June 2007 # # The programs built by this makefile are described in the book, # "PNG: The Definitive Guide," by Greg Roelofs (O'Reilly and # Associates, 1999). Go buy a copy, eh? Well, OK, it's not # generally for sale anymore, but it's the thought that counts, # right? (Hint: http://www.libpng.org/pub/png/book/ ) # # Invoke this makefile from a DOS-prompt window via: # # make -f Makefile.mingw32 # # This makefile assumes libpng and zlib have already been built or downloaded # and are in subdirectories at the same level as the current subdirectory # (as indicated by the PNGDIR and ZDIR macros below). It makes no assumptions # at all about the mingw32 installation tree (W32DIR). Edit as appropriate. # # Note that the names of the dynamic and static libpng and zlib libraries # used below may change in later releases of the libraries. This makefile # builds both statically and dynamically linked executables by default. # (You need only one set, but for testing it can be handy to have both.) # macros -------------------------------------------------------------------- #PNGDIR = ../..# for libpng-x.y.z/contrib/gregbook builds PNGDIR = ../libpng-win32 PNGINC = -I$(PNGDIR) PNGLIBd = $(PNGDIR)/libpng.dll.a # dynamically linked PNGLIBs = $(PNGDIR)/libpng.a # statically linked, local libpng #ZDIR = ../../../zlib-win32# for libpng-x.y.z/contrib/gregbook builds ZDIR = ../zlib-win32 ZINC = -I$(ZDIR) ZLIBd = $(ZDIR)/libzdll.a ZLIBs = $(ZDIR)/libz.a # change this to be the path where mingw32 installs its stuff: W32DIR = #W32DIR = /usr/local/cross-tools/i386-mingw32msvc W32INC = -I$(W32DIR)/include W32LIB = $(W32DIR)/lib/libuser32.a $(W32DIR)/lib/libgdi32.a CC = gcc #CC = i386-mingw32msvc-gcc # e.g., Linux -> Win32 cross-compilation LD = $(CC) RM = rm -f CPPFLAGS = $(INCS) CFLAGS = -O -Wall $(MINGW_CCFLAGS) # [note that -Wall is a gcc-specific compilation flag ("most warnings on")] # [-ansi, -pedantic and -W can also be used] LDFLAGS = $(MINGW_LDFLAGS) O = .o E = .exe INCS = $(PNGINC) $(ZINC) $(W32INC) RLIBSd = $(PNGLIBd) $(ZLIBd) $(W32LIB) -lm RLIBSs = $(PNGLIBs) $(ZLIBs) $(W32LIB) -lm WLIBSd = $(PNGLIBd) $(ZLIBd) WLIBSs = $(PNGLIBs) $(ZLIBs) RPNG = rpng-win RPNG2 = rpng2-win WPNG = wpng ROBJSd = $(RPNG)$(O) readpng.pic$(O) ROBJS2d = $(RPNG2)$(O) readpng2.pic$(O) WOBJSd = $(WPNG)$(O) writepng.pic$(O) RPNGs = $(RPNG)-static RPNG2s = $(RPNG2)-static WPNGs = $(WPNG)-static ROBJSs = $(RPNG)$(O) readpng$(O) ROBJS2s = $(RPNG2)$(O) readpng2$(O) WOBJSs = $(WPNG)$(O) writepng$(O) STATIC_EXES = $(RPNGs)$(E) $(RPNG2s)$(E) $(WPNGs)$(E) DYNAMIC_EXES = $(RPNG)$(E) $(RPNG2)$(E) $(WPNG)$(E) EXES = $(STATIC_EXES) $(DYNAMIC_EXES) # implicit make rules ------------------------------------------------------- .c$(O): $(CC) -c $(CPPFLAGS) $(CFLAGS) $< %.pic$(O): %.c $(CC) -c $(CPPFLAGS) $(CFLAGS) -DPNG_BUILD_DLL -o $@ $< # dependencies -------------------------------------------------------------- all: $(EXES) $(RPNGs)$(E): $(ROBJSs) $(LD) $(LDFLAGS) -o $@ $(ROBJSs) $(RLIBSs) $(RPNG)$(E): $(ROBJSd) $(LD) $(LDFLAGS) -o $@ $(ROBJSd) $(RLIBSd) $(RPNG2s)$(E): $(ROBJS2s) $(LD) $(LDFLAGS) -o $@ $(ROBJS2s) $(RLIBSs) $(RPNG2)$(E): $(ROBJS2d) $(LD) $(LDFLAGS) -o $@ $(ROBJS2d) $(RLIBSd) $(WPNGs)$(E): $(WOBJSs) $(LD) $(LDFLAGS) -o $@ $(WOBJSs) $(WLIBSs) $(WPNG)$(E): $(WOBJSd) $(LD) $(LDFLAGS) -o $@ $(WOBJSd) $(WLIBSd) $(RPNG)$(O): $(RPNG).c readpng.h $(RPNG2)$(O): $(RPNG2).c readpng2.h $(WPNG)$(O): $(WPNG).c writepng.h readpng$(O) readpng.pic$(O): readpng.c readpng.h readpng2$(O) readpng2.pic$(O): readpng2.c readpng2.h writepng$(O) writepng.pic$(O): writepng.c writepng.h # maintenance --------------------------------------------------------------- clean: $(RM) $(EXES) $(RM) $(ROBJSs) $(ROBJS2s) $(WOBJSs) $(RM) $(ROBJSd) $(ROBJS2d) $(WOBJSd) libpng-1.6.43/contrib/gregbook/Makefile.sgi000066400000000000000000000056561456606525400205710ustar00rootroot00000000000000# Sample makefile for rpng-x / rpng2-x / wpng for SGI using cc and make. # Greg Roelofs # Last modified: 7 March 2002 # # The programs built by this makefile are described in the book, # "PNG: The Definitive Guide," by Greg Roelofs (O'Reilly and # Associates, 1999). Go buy a copy, eh? Buy some for friends # and family, too. (Not that this is a blatant plug or anything.) # # Invoke this makefile from a shell prompt in the usual way; for example: # # make -f Makefile.sgi # # This makefile assumes libpng and zlib have already been built or downloaded # and are both installed in /usr/local/{include,lib} (as indicated by the # PNG* and Z* macros below). Edit as appropriate--choose only ONE each of # the PNGINC, PNGLIB, ZINC and ZLIB lines. # # This makefile builds dynamically linked executables (against libpng and zlib, # that is), but that can be changed by uncommenting the appropriate PNGLIB and # ZLIB lines. # macros -------------------------------------------------------------------- PNGINC = -I/usr/local/include/libpng16 PNGLIB = -L/usr/local/lib -lpng16 # dynamically linked against libpng #PNGLIB = /usr/local/lib/libpng16.a # statically linked against libpng # or: #PNGINC = -I../.. #PNGLIB = -L../.. -lpng #PNGLIB = ../../libpng.a ZINC = -I/usr/local/include ZLIB = -L/usr/local/lib -lz # dynamically linked against zlib #ZLIB = /usr/local/lib/libz.a # statically linked against zlib #ZINC = -I../zlib #ZLIB = -L../zlib -lz #ZLIB = ../../../zlib/libz.a XINC = -I/usr/include/X11 # old-style, stock X distributions XLIB = -L/usr/lib/X11 -lX11 #XINC = -I/usr/openwin/include # Sun workstations (OpenWindows) #XLIB = -L/usr/openwin/lib -lX11 #XINC = -I/usr/X11R6/include # new X distributions (XFree86, etc.) #XLIB = -L/usr/X11R6/lib -lX11 INCS = $(PNGINC) $(ZINC) $(XINC) RLIBS = $(PNGLIB) $(ZLIB) $(XLIB) -lm WLIBS = $(PNGLIB) $(ZLIB) CC = cc LD = cc RM = rm -f # ABI must be the same as that used to build libpng. ABI = CPPFLAGS = CFLAGS = $(ABI) -O -fullwarn $(INCS) LDFLAGS = $(ABI) O = .o E = RPNG = rpng-x RPNG2 = rpng2-x WPNG = wpng ROBJS = $(RPNG)$(O) readpng$(O) ROBJS2 = $(RPNG2)$(O) readpng2$(O) WOBJS = $(WPNG)$(O) writepng$(O) EXES = $(RPNG)$(E) $(RPNG2)$(E) $(WPNG)$(E) # implicit make rules ------------------------------------------------------- .c$(O): $(CC) -c $(CPPFLAGS) $(CFLAGS) $< # dependencies -------------------------------------------------------------- all: $(EXES) $(RPNG)$(E): $(ROBJS) $(LD) $(LDFLAGS) -o $@ $(ROBJS) $(RLIBS) $(RPNG2)$(E): $(ROBJS2) $(LD) $(LDFLAGS) -o $@ $(ROBJS2) $(RLIBS) $(WPNG)$(E): $(WOBJS) $(LD) $(LDFLAGS) -o $@ $(WOBJS) $(WLIBS) $(RPNG)$(O): $(RPNG).c readpng.h $(RPNG2)$(O): $(RPNG2).c readpng2.h $(WPNG)$(O): $(WPNG).c writepng.h readpng$(O): readpng.c readpng.h readpng2$(O): readpng2.c readpng2.h writepng$(O): writepng.c writepng.h # maintenance --------------------------------------------------------------- clean: $(RM) $(EXES) $(ROBJS) $(ROBJS2) $(WOBJS) libpng-1.6.43/contrib/gregbook/Makefile.unx000066400000000000000000000077751456606525400206250ustar00rootroot00000000000000# Sample makefile for rpng-x / rpng2-x / wpng using gcc and make. # Greg Roelofs # Last modified: 2 June 2007 # # The programs built by this makefile are described in the book, # "PNG: The Definitive Guide," by Greg Roelofs (O'Reilly and # Associates, 1999). Go buy a copy, eh? Well, OK, it's not # generally for sale anymore, but it's the thought that counts, # right? (Hint: http://www.libpng.org/pub/png/book/ ) # # Invoke this makefile from a shell prompt in the usual way; for example: # # make -f Makefile.unx # # This makefile assumes libpng and zlib have already been built or downloaded # and are installed in /usr/local/{include,lib} or as otherwise indicated by # the PNG* and Z* macros below. Edit as appropriate--choose only ONE each of # the PNGINC, PNGLIBd, PNGLIBs, ZINC, ZLIBd and ZLIBs lines. # # This makefile builds both dynamically and statically linked executables # (against libpng and zlib, that is), but that can be changed by modifying # the "EXES =" line. (You need only one set, but for testing it can be handy # to have both.) # macros -------------------------------------------------------------------- #PNGDIR = /usr/local/lib #PNGINC = -I/usr/local/include/libpng16 #PNGLIBd = -L$(PNGDIR) -lpng16 # dynamically linked, installed libpng #PNGLIBs = $(PNGDIR)/libpng16.a # statically linked, installed libpng # or: PNGDIR = ../..# this one is for libpng-x.y.z/contrib/gregbook builds #PNGDIR = ../libpng PNGINC = -I$(PNGDIR) PNGLIBd = -Wl,-rpath,$(PNGDIR) -L$(PNGDIR) -lpng16 # dynamically linked PNGLIBs = $(PNGDIR)/libpng.a # statically linked, local libpng ZDIR = /usr/local/lib #ZDIR = /usr/lib64 ZINC = -I/usr/local/include ZLIBd = -L$(ZDIR) -lz # dynamically linked against zlib ZLIBs = $(ZDIR)/libz.a # statically linked against zlib # or: #ZDIR = ../zlib #ZINC = -I$(ZDIR) #ZLIBd = -Wl,-rpath,$(ZDIR) -L$(ZDIR) -lz # -rpath allows in-place testing #ZLIBs = $(ZDIR)/libz.a #XINC = -I/usr/include # old-style, stock X distributions #XLIB = -L/usr/lib/X11 -lX11 # (including SGI IRIX) #XINC = -I/usr/openwin/include # Sun workstations (OpenWindows) #XLIB = -L/usr/openwin/lib -lX11 XINC = -I/usr/X11R6/include # new X distributions (X.org, etc.) XLIB = -L/usr/X11R6/lib -lX11 #XLIB = -L/usr/X11R6/lib64 -lX11 # e.g., Red Hat on AMD64 INCS = $(PNGINC) $(ZINC) $(XINC) RLIBSd = $(PNGLIBd) $(ZLIBd) $(XLIB) -lm RLIBSs = $(PNGLIBs) $(ZLIBs) $(XLIB) -lm WLIBSd = $(PNGLIBd) $(ZLIBd) -lm WLIBSs = $(PNGLIBs) $(ZLIBs) -lm CC = gcc LD = gcc RM = rm -f CPPFLAGS = $(INCS) -DFEATURE_LOOP CFLAGS = -O -Wall #CFLAGS = -O -W -Wall -Wextra -pedantic -ansi # [note that -Wall is a gcc-specific compilation flag ("most warnings on")] # [-ansi, -pedantic, -Wextra, and -W can also be used] LDFLAGS = O = .o E = RPNG = rpng-x RPNG2 = rpng2-x WPNG = wpng RPNGs = $(RPNG)-static RPNG2s = $(RPNG2)-static WPNGs = $(WPNG)-static ROBJS = $(RPNG)$(O) readpng$(O) ROBJS2 = $(RPNG2)$(O) readpng2$(O) WOBJS = $(WPNG)$(O) writepng$(O) STATIC_EXES = $(RPNGs)$(E) $(RPNG2s)$(E) $(WPNGs)$(E) DYNAMIC_EXES = $(RPNG)$(E) $(RPNG2)$(E) $(WPNG)$(E) EXES = $(STATIC_EXES) $(DYNAMIC_EXES) # implicit make rules ------------------------------------------------------- .c$(O): $(CC) -c $(CPPFLAGS) $(CFLAGS) $< # dependencies -------------------------------------------------------------- all: $(EXES) $(RPNGs)$(E): $(ROBJS) $(LD) $(LDFLAGS) -o $@ $(ROBJS) $(RLIBSs) $(RPNG)$(E): $(ROBJS) $(LD) $(LDFLAGS) -o $@ $(ROBJS) $(RLIBSd) $(RPNG2s)$(E): $(ROBJS2) $(LD) $(LDFLAGS) -o $@ $(ROBJS2) $(RLIBSs) $(RPNG2)$(E): $(ROBJS2) $(LD) $(LDFLAGS) -o $@ $(ROBJS2) $(RLIBSd) $(WPNGs)$(E): $(WOBJS) $(LD) $(LDFLAGS) -o $@ $(WOBJS) $(WLIBSs) $(WPNG)$(E): $(WOBJS) $(LD) $(LDFLAGS) -o $@ $(WOBJS) $(WLIBSd) $(RPNG)$(O): $(RPNG).c readpng.h $(RPNG2)$(O): $(RPNG2).c readpng2.h $(WPNG)$(O): $(WPNG).c writepng.h readpng$(O): readpng.c readpng.h readpng2$(O): readpng2.c readpng2.h writepng$(O): writepng.c writepng.h # maintenance --------------------------------------------------------------- clean: $(RM) $(EXES) $(ROBJS) $(ROBJS2) $(WOBJS) libpng-1.6.43/contrib/gregbook/Makefile.w32000066400000000000000000000064351456606525400204160ustar00rootroot00000000000000# Sample makefile for rpng-win / rpng2-win / wpng using MSVC and NMAKE. # Greg Roelofs # Last modified: 2 June 2007 # # The programs built by this makefile are described in the book, # "PNG: The Definitive Guide," by Greg Roelofs (O'Reilly and # Associates, 1999). Go buy a copy, eh? Well, OK, it's not # generally for sale anymore, but it's the thought that counts, # right? (Hint: http://www.libpng.org/pub/png/book/ ) # # Invoke this makefile from a DOS prompt window via: # # %devstudio%\vc\bin\vcvars32.bat # nmake -nologo -f Makefile.w32 # # where %devstudio% is the installation directory for MSVC / DevStudio. If # you get "environment out of space" errors, create a desktop shortcut with # "c:\windows\command.com /e:4096" as the program command line and set the # working directory to this directory. Then double-click to open the new # DOS-prompt window with a bigger environment and retry the commands above. # # This makefile assumes libpng and zlib have already been built or downloaded # and are in subdirectories at the same level as the current subdirectory # (as indicated by the PNGPATH and ZPATH macros below). Edit as appropriate. # # Note that the names of the dynamic and static libpng and zlib libraries # used below may change in later releases of the libraries. This makefile # builds statically linked executables, but that can be changed by uncom- # menting the appropriate PNGLIB and ZLIB lines. !include # macros -------------------------------------------------------------------- PNGPATH = ../libpng PNGINC = -I$(PNGPATH) #PNGLIB = $(PNGPATH)/pngdll.lib PNGLIB = $(PNGPATH)/libpng.lib ZPATH = ../zlib ZINC = -I$(ZPATH) #ZLIB = $(ZPATH)/zlibdll.lib ZLIB = $(ZPATH)/zlibstat.lib WINLIBS = -defaultlib:user32.lib gdi32.lib # ["real" apps may also need comctl32.lib, comdlg32.lib, winmm.lib, etc.] INCS = $(PNGINC) $(ZINC) RLIBS = $(PNGLIB) $(ZLIB) $(WINLIBS) WLIBS = $(PNGLIB) $(ZLIB) CC = cl LD = link RM = del CPPFLAGS = $(INCS) CFLAGS = -nologo -O -W3 $(cvars) # [note that -W3 is an MSVC-specific compilation flag ("all warnings on")] # [see %devstudio%\vc\include\win32.mak for cvars macro definition] O = .obj E = .exe RLDFLAGS = -nologo -subsystem:windows WLDFLAGS = -nologo RPNG = rpng-win RPNG2 = rpng2-win WPNG = wpng ROBJS = $(RPNG)$(O) readpng$(O) ROBJS2 = $(RPNG2)$(O) readpng2$(O) WOBJS = $(WPNG)$(O) writepng$(O) EXES = $(RPNG)$(E) $(RPNG2)$(E) $(WPNG)$(E) # implicit make rules ------------------------------------------------------- .c$(O): $(CC) -c $(CPPFLAGS) $(CFLAGS) $< # dependencies -------------------------------------------------------------- all: $(EXES) $(RPNG)$(E): $(ROBJS) $(LD) $(RLDFLAGS) -out:$@ $(ROBJS) $(RLIBS) $(RPNG2)$(E): $(ROBJS2) $(LD) $(RLDFLAGS) -out:$@ $(ROBJS2) $(RLIBS) $(WPNG)$(E): $(WOBJS) $(LD) $(WLDFLAGS) -out:$@ $(WOBJS) $(WLIBS) $(RPNG)$(O): $(RPNG).c readpng.h $(RPNG2)$(O): $(RPNG2).c readpng2.h $(WPNG)$(O): $(WPNG).c writepng.h readpng$(O): readpng.c readpng.h readpng2$(O): readpng2.c readpng2.h writepng$(O): writepng.c writepng.h # maintenance --------------------------------------------------------------- clean: # ideally we could just do this: # $(RM) $(EXES) $(ROBJS) $(ROBJS2) $(WOBJS) # ...but the Windows "DEL" command is none too bright, so: $(RM) r*$(E) $(RM) w*$(E) $(RM) r*$(O) $(RM) w*$(O) libpng-1.6.43/contrib/gregbook/README000066400000000000000000000172541456606525400172250ustar00rootroot00000000000000 =========================== PNG: The Definitive Guide =========================== Source Code Chapters 13, 14 and 15 of "PNG: The Definitive Guide" discuss three free, cross-platform demo programs that show how to use the libpng reference library: rpng, rpng2 and wpng. rpng and rpng2 are viewers; the first is a very simple example that that shows how a standard file-viewer might use libpng, while the second is designed to process streaming data and shows how a web browser might be written. wpng is a simple command-line program that reads binary PGM and PPM files (the ``raw'' grayscale and RGB subsets of PBMPLUS/NetPBM) and converts them to PNG. The source code for all three demo programs currently compiles under Unix, OpenVMS, and 32-bit Windows. (Special thanks to Martin Zinser, zinser at decus.de, for making the necessary changes for OpenVMS and for providing an appropriate build script.) Build instructions can be found below. Files: README this file LICENSE terms of distribution and reuse (BSD-like or GNU GPL) COPYING GNU General Public License (GPL) Makefile.unx Unix makefile Makefile.w32 Windows (MSVC) makefile makevms.com OpenVMS build script rpng-win.c Windows front end for the basic viewer rpng-x.c X Window System (Unix, OpenVMS) front end readpng.c generic back end for the basic viewer readpng.h header file for the basic viewer rpng2-win.c Windows front end for the progressive viewer rpng2-x.c X front end for the progressive viewer readpng2.c generic back end for the progressive viewer readpng2.h header file for the progressive viewer wpng.c generic (text) front end for the converter writepng.c generic back end for the converter writepng.h header file for the converter toucan.png transparent PNG for testing (by Stefan Schneider) Note that, although the programs are designed to be functional, their primary purpose is to illustrate how to use libpng to add PNG support to other programs. As such, their user interfaces are crude and definitely are not intended for everyday use. Please see http://www.libpng.org/pub/png/pngbook.html for further infor- mation and links to the latest version of the source code, and Chapters 13-15 of the book for detailed discussion of the three programs. Greg Roelofs https://pobox.com/~newt/greg_contact.html 16 March 2008 BUILD INSTRUCTIONS - Prerequisites (in order of compilation): - zlib https://zlib.net/ - libpng http://www.libpng.org/pub/png/libpng.html - pngbook http://www.libpng.org/pub/png/book/sources.html The pngbook demo programs are explicitly designed to demonstrate proper coding techniques for using the libpng reference library. As a result, you need to download and build both zlib (on which libpng depends) and libpng. A common build setup is to place the zlib, libpng and pngbook subdirectory trees ("folders") in the same parent directory. Then the libpng build can refer to files in ../zlib (or ..\zlib or [-.zlib]), and similarly for the pngbook build. Note that all three packages are designed to be built from a command line by default; those who wish to use a graphical or other integrated development environments are on their own. - Unix: Unpack the latest pngbook sources (which should correspond to this README file) into a directory and change into that directory. Copy Makefile.unx to Makefile and edit the PNG* and Z* variables appropriately (possibly also the X* variables if necessary). make There is no "install" target, so copy the three executables somewhere in your path or run them from the current directory. All three will print a basic usage screen when run without any command-line arguments; see the book for more details. - Windows: Unpack the latest pngbook sources (which should correspond to this README file) into a folder, open a "DOS shell" or "command prompt" or equivalent command-line window, and cd into the folder where you unpacked the source code. For MSVC, set up the necessary environment variables by invoking %devstudio%\vc\bin\vcvars32.bat where where %devstudio% is the installation directory for MSVC / DevStudio. If you get "environment out of space" errors under 95/98, create a desktop shortcut with "c:\windows\command.com /e:4096" as the program command line and set the working directory to the pngbook directory. Then double-click to open the new DOS-prompt window with a bigger environment and retry the commands above. Copy Makefile.w32 to Makefile and edit the PNGPATH and ZPATH variables appropriately (possibly also the "INC" and "LIB" variables if needed). Note that the names of the dynamic and static libpng and zlib libraries used in the makefile may change in later releases of the libraries. Also note that, as of libpng version 1.0.5, MSVC DLL builds do not work. This makefile therefore builds statically linked executables, but if the DLL problems ever get fixed, uncommenting the appropriate PNGLIB and ZLIB lines will build dynamically linked executables instead. Do the build by typing nmake The result should be three executables: rpng-win.exe, rpng2-win.exe, and wpng.exe. Copy them somewhere in your PATH or run them from the current folder. Like the Unix versions, the two windowed programs (rpng and rpng2) now display a usage screen in a console window when invoked without command-line arguments; this is new behavior as of the June 2001 release. Note that the programs use the Unix-style "-" character to specify options, instead of the more common DOS/Windows "/" character. (For example: "rpng2-win -bgpat 4 foo.png", not "rpng2-win /bgpat 4 foo.png") - OpenVMS: Unpack the pngbook sources into a subdirectory and change into that subdirectory. Edit makevms.com appropriately, specifically the zpath and pngpath variables. @makevms To run the programs, they probably first need to be set up as "foreign symbols," with "disk" and "dir" set appropriately: $ rpng == "$disk:[dir]rpng-x.exe" $ rpng2 == "$disk:[dir]rpng2-x.exe" $ wpng == "$disk:[dir]wpng.exe" All three will print a basic usage screen when run without any command- line arguments; see the book for more details. Note that the options style is Unix-like, i.e., preceded by "-" rather than "/". RUNNING THE PROGRAMS: (VERY) BRIEF INTRO rpng is a simple PNG viewer that can display transparent PNGs with a specified background color; for example, rpng -bgcolor \#ff0000 toucan.png would display the image with a red background. rpng2 is a progressive viewer that simulates a web browser in some respects; it can display images against either a background color or a dynamically generated background image. For example: rpng2 -bgpat 16 toucan.png wpng is a purely command-line image converter from binary PBMPLUS/NetPBM format (.pgm or .ppm) to PNG; for example, wpng -time < toucan-notrans.ppm > toucan-notrans.png would convert the specified PPM file (using redirection) to PNG, auto- matically setting the PNG modification-time chunk. All options can be abbreviated to the shortest unique value; for example, "-bgc" for -bgcolor (versus "-bgp" for -bgpat), or "-g" for -gamma. libpng-1.6.43/contrib/gregbook/makevms.com000066400000000000000000000067431456606525400205110ustar00rootroot00000000000000$!------------------------------------------------------------------------------ $! make "PNG: The Definitive Guide" demo programs (for X) under OpenVMS $! $! Script created by Martin Zinser for libpng; modified by Greg Roelofs $! for standalone pngbook source distribution. $! $! $! Set locations where zlib and libpng sources live. $! $ zpath = "" $ pngpath = "" $! $ if f$search("[---.zlib]zlib.h").nes."" then zpath = "[---.zlib]" $ if f$search("[--]png.h").nes."" then pngpath = "[--]" $! $ if f$search("[-.zlib]zlib.h").nes."" then zpath = "[-.zlib]" $ if f$search("[-.libpng]png.h").nes."" then pngpath = "[-.libpng]" $! $ if zpath .eqs. "" $ then $ write sys$output "zlib include not found. Exiting..." $ exit 2 $ endif $! $ if pngpath .eqs. "" $ then $ write sys$output "libpng include not found. Exiting..." $ exit 2 $ endif $! $! Look for the compiler used. $! $ ccopt="/include=(''zpath',''pngpath')" $ if f$getsyi("HW_MODEL").ge.1024 $ then $ ccopt = "/prefix=all"+ccopt $ comp = "__decc__=1" $ if f$trnlnm("SYS").eqs."" then define sys sys$library: $ else $ if f$search("SYS$SYSTEM:DECC$COMPILER.EXE").eqs."" $ then $ if f$trnlnm("SYS").eqs."" then define sys sys$library: $ if f$search("SYS$SYSTEM:VAXC.EXE").eqs."" $ then $ comp = "__gcc__=1" $ CC :== GCC $ else $ comp = "__vaxc__=1" $ endif $ else $ if f$trnlnm("SYS").eqs."" then define sys decc$library_include: $ ccopt = "/decc/prefix=all"+ccopt $ comp = "__decc__=1" $ endif $ endif $ open/write lopt lib.opt $ write lopt "''pngpath'libpng.olb/lib" $ write lopt "''zpath'libz.olb/lib" $ close lopt $ open/write xopt x11.opt $ write xopt "sys$library:decw$xlibshr.exe/share" $ close xopt $! $! Build 'em. $! $ write sys$output "Compiling PNG book programs ..." $ CALL MAKE readpng.OBJ "cc ''CCOPT' readpng" - readpng.c readpng.h $ CALL MAKE readpng2.OBJ "cc ''CCOPT' readpng2" - readpng2.c readpng2.h $ CALL MAKE writepng.OBJ "cc ''CCOPT' writepng" - writepng.c writepng.h $ write sys$output "Building rpng-x..." $ CALL MAKE rpng-x.OBJ "cc ''CCOPT' rpng-x" - rpng-x.c readpng.h $ call make rpng-x.exe - "LINK rpng-x,readpng,lib.opt/opt,x11.opt/opt" - rpng-x.obj readpng.obj $ write sys$output "Building rpng2-x..." $ CALL MAKE rpng2-x.OBJ "cc ''CCOPT' rpng2-x" - rpng2-x.c readpng2.h $ call make rpng2-x.exe - "LINK rpng2-x,readpng2,lib.opt/opt,x11.opt/opt" - rpng2-x.obj readpng2.obj $ write sys$output "Building wpng..." $ CALL MAKE wpng.OBJ "cc ''CCOPT' wpng" - wpng.c writepng.h $ call make wpng.exe - "LINK wpng,writepng,lib.opt/opt" - wpng.obj writepng.obj $ exit $! $! $MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES $ V = 'F$Verify(0) $! P1 = What we are trying to make $! P2 = Command to make it $! P3 - P8 What it depends on $ $ If F$Search(P1) .Eqs. "" Then Goto Makeit $ Time = F$CvTime(F$File(P1,"RDT")) $arg=3 $Loop: $ Argument = P'arg $ If Argument .Eqs. "" Then Goto Exit $ El=0 $Loop2: $ File = F$Element(El," ",Argument) $ If File .Eqs. " " Then Goto Endl $ AFile = "" $Loop3: $ OFile = AFile $ AFile = F$Search(File) $ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl $ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit $ Goto Loop3 $NextEL: $ El = El + 1 $ Goto Loop2 $EndL: $ arg=arg+1 $ If arg .Le. 8 Then Goto Loop $ Goto Exit $ $Makeit: $ VV=F$VERIFY(0) $ write sys$output P2 $ 'P2 $ VV='F$Verify(VV) $Exit: $ If V Then Set Verify $ENDSUBROUTINE libpng-1.6.43/contrib/gregbook/readpng.c000066400000000000000000000237511456606525400201300ustar00rootroot00000000000000/*--------------------------------------------------------------------------- rpng - simple PNG display program readpng.c --------------------------------------------------------------------------- Copyright (c) 1998-2007,2017 Greg Roelofs. All rights reserved. This software is provided "as is," without warranty of any kind, express or implied. In no event shall the author or contributors be held liable for any damages arising in any way from the use of this software. The contents of this file are DUAL-LICENSED. You may modify and/or redistribute this software according to the terms of one of the following two licenses (at your option): LICENSE 1 ("BSD-like with advertising clause"): Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. Redistributions of source code must retain the above copyright notice, disclaimer, and this list of conditions. 2. Redistributions in binary form must reproduce the above copyright notice, disclaimer, and this list of conditions in the documenta- tion and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgment: This product includes software developed by Greg Roelofs and contributors for the book, "PNG: The Definitive Guide," published by O'Reilly and Associates. LICENSE 2 (GNU GPL v2 or later): This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ---------------------------------------------------------------------------*/ #include #include #include #include "png.h" /* libpng header */ #include "readpng.h" /* typedefs, common macros, public prototypes */ /* future versions of libpng will provide this macro: */ #ifndef png_jmpbuf # define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) #endif static png_structp png_ptr = NULL; static png_infop info_ptr = NULL; png_uint_32 width, height; int bit_depth, color_type; uch *image_data = NULL; void readpng_version_info(void) { fprintf(stderr, " Compiled with libpng %s; using libpng %s.\n", PNG_LIBPNG_VER_STRING, png_libpng_ver); fprintf(stderr, " Compiled with zlib %s; using zlib %s.\n", ZLIB_VERSION, zlib_version); } /* return value = 0 for success, 1 for bad sig, 2 for bad IHDR, 4 for no mem */ int readpng_init(FILE *infile, ulg *pWidth, ulg *pHeight) { uch sig[8]; /* first do a quick check that the file really is a PNG image; could * have used slightly more general png_sig_cmp() function instead */ fread(sig, 1, 8, infile); if (png_sig_cmp(sig, 0, 8)) return 1; /* bad signature */ /* could pass pointers to user-defined error handlers instead of NULLs: */ png_ptr = png_create_read_struct(png_get_libpng_ver(NULL), NULL, NULL, NULL); if (!png_ptr) return 4; /* out of memory */ info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, NULL, NULL); return 4; /* out of memory */ } /* we could create a second info struct here (end_info), but it's only * useful if we want to keep pre- and post-IDAT chunk info separated * (mainly for PNG-aware image editors and converters) */ /* setjmp() must be called in every function that calls a PNG-reading * libpng function */ if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return 2; } png_init_io(png_ptr, infile); png_set_sig_bytes(png_ptr, 8); /* we already read the 8 signature bytes */ png_read_info(png_ptr, info_ptr); /* read all PNG info up to image data */ /* alternatively, could make separate calls to png_get_image_width(), * etc., but want bit_depth and color_type for later [don't care about * compression_type and filter_type => NULLs] */ png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL); *pWidth = width; *pHeight = height; /* OK, that's all we need for now; return happy */ return 0; } /* returns 0 if succeeds, 1 if fails due to no bKGD chunk, 2 if libpng error; * scales values to 8-bit if necessary */ int readpng_get_bgcolor(uch *red, uch *green, uch *blue) { png_color_16p pBackground; /* setjmp() must be called in every function that calls a PNG-reading * libpng function */ if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return 2; } if (!png_get_valid(png_ptr, info_ptr, PNG_INFO_bKGD)) return 1; /* it is not obvious from the libpng documentation, but this function * takes a pointer to a pointer, and it always returns valid red, green * and blue values, regardless of color_type: */ png_get_bKGD(png_ptr, info_ptr, &pBackground); /* however, it always returns the raw bKGD data, regardless of any * bit-depth transformations, so check depth and adjust if necessary */ if (bit_depth == 16) { *red = pBackground->red >> 8; *green = pBackground->green >> 8; *blue = pBackground->blue >> 8; } else if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) { if (bit_depth == 1) *red = *green = *blue = pBackground->gray? 255 : 0; else if (bit_depth == 2) *red = *green = *blue = (255/3) * pBackground->gray; else /* bit_depth == 4 */ *red = *green = *blue = (255/15) * pBackground->gray; } else { *red = (uch)pBackground->red; *green = (uch)pBackground->green; *blue = (uch)pBackground->blue; } return 0; } /* display_exponent == LUT_exponent * CRT_exponent */ uch *readpng_get_image(double display_exponent, int *pChannels, ulg *pRowbytes) { double gamma; png_uint_32 i, rowbytes; png_bytepp row_pointers = NULL; /* setjmp() must be called in every function that calls a PNG-reading * libpng function */ if (setjmp(png_jmpbuf(png_ptr))) { free(image_data); image_data = NULL; free(row_pointers); row_pointers = NULL; png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return NULL; } /* expand palette images to RGB, low-bit-depth grayscale images to 8 bits, * transparency chunks to full alpha channel; strip 16-bit-per-sample * images to 8 bits per sample; and convert grayscale to RGB[A] */ if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_expand(png_ptr); if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_expand(png_ptr); if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_expand(png_ptr); #ifdef PNG_READ_16_TO_8_SUPPORTED if (bit_depth == 16) # ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED png_set_scale_16(png_ptr); # else png_set_strip_16(png_ptr); # endif #endif if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(png_ptr); /* unlike the example in the libpng documentation, we have *no* idea where * this file may have come from--so if it doesn't have a file gamma, don't * do any correction ("do no harm") */ if (png_get_gAMA(png_ptr, info_ptr, &gamma)) png_set_gamma(png_ptr, display_exponent, gamma); /* all transformations have been registered; now update info_ptr data, * get rowbytes and channels, and allocate image memory */ png_read_update_info(png_ptr, info_ptr); *pRowbytes = rowbytes = png_get_rowbytes(png_ptr, info_ptr); *pChannels = (int)png_get_channels(png_ptr, info_ptr); /* Guard against integer overflow */ if (height > ((size_t)(-1))/rowbytes) { fprintf(stderr, "readpng: image_data buffer would be too large\n", return NULL; } if ((image_data = (uch *)malloc(rowbytes*height)) == NULL) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return NULL; } if ((row_pointers = (png_bytepp)malloc(height*sizeof(png_bytep))) == NULL) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); free(image_data); image_data = NULL; return NULL; } Trace((stderr, "readpng_get_image: channels = %d, rowbytes = %ld, height = %ld\n", *pChannels, rowbytes, height)); /* set the individual row_pointers to point at the correct offsets */ for (i = 0; i < height; ++i) row_pointers[i] = image_data + i*rowbytes; /* now we can go ahead and just read the whole image */ png_read_image(png_ptr, row_pointers); /* and we're done! (png_read_end() can be omitted if no processing of * post-IDAT text/time/etc. is desired) */ free(row_pointers); row_pointers = NULL; png_read_end(png_ptr, NULL); return image_data; } void readpng_cleanup(int free_image_data) { if (free_image_data && image_data) { free(image_data); image_data = NULL; } if (png_ptr && info_ptr) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); png_ptr = NULL; info_ptr = NULL; } } libpng-1.6.43/contrib/gregbook/readpng.h000066400000000000000000000062741456606525400201360ustar00rootroot00000000000000/*--------------------------------------------------------------------------- rpng - simple PNG display program readpng.h --------------------------------------------------------------------------- Copyright (c) 1998-2007 Greg Roelofs. All rights reserved. This software is provided "as is," without warranty of any kind, express or implied. In no event shall the author or contributors be held liable for any damages arising in any way from the use of this software. The contents of this file are DUAL-LICENSED. You may modify and/or redistribute this software according to the terms of one of the following two licenses (at your option): LICENSE 1 ("BSD-like with advertising clause"): Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. Redistributions of source code must retain the above copyright notice, disclaimer, and this list of conditions. 2. Redistributions in binary form must reproduce the above copyright notice, disclaimer, and this list of conditions in the documenta- tion and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgment: This product includes software developed by Greg Roelofs and contributors for the book, "PNG: The Definitive Guide," published by O'Reilly and Associates. LICENSE 2 (GNU GPL v2 or later): This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ---------------------------------------------------------------------------*/ #ifndef TRUE # define TRUE 1 # define FALSE 0 #endif #ifndef MAX # define MAX(a,b) ((a) > (b)? (a) : (b)) # define MIN(a,b) ((a) < (b)? (a) : (b)) #endif #ifdef DEBUG # define Trace(x) {fprintf x ; fflush(stderr); fflush(stdout);} #else # define Trace(x) ; #endif typedef unsigned char uch; typedef unsigned short ush; typedef unsigned long ulg; /* prototypes for public functions in readpng.c */ void readpng_version_info(void); int readpng_init(FILE *infile, ulg *pWidth, ulg *pHeight); int readpng_get_bgcolor(uch *bg_red, uch *bg_green, uch *bg_blue); uch *readpng_get_image(double display_exponent, int *pChannels, ulg *pRowbytes); void readpng_cleanup(int free_image_data); libpng-1.6.43/contrib/gregbook/readpng2.c000066400000000000000000000433501456606525400202070ustar00rootroot00000000000000/*--------------------------------------------------------------------------- rpng2 - progressive-model PNG display program readpng2.c --------------------------------------------------------------------------- Copyright (c) 1998-2015 Greg Roelofs. All rights reserved. This software is provided "as is," without warranty of any kind, express or implied. In no event shall the author or contributors be held liable for any damages arising in any way from the use of this software. The contents of this file are DUAL-LICENSED. You may modify and/or redistribute this software according to the terms of one of the following two licenses (at your option): LICENSE 1 ("BSD-like with advertising clause"): Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. Redistributions of source code must retain the above copyright notice, disclaimer, and this list of conditions. 2. Redistributions in binary form must reproduce the above copyright notice, disclaimer, and this list of conditions in the documenta- tion and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgment: This product includes software developed by Greg Roelofs and contributors for the book, "PNG: The Definitive Guide," published by O'Reilly and Associates. LICENSE 2 (GNU GPL v2 or later): This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --------------------------------------------------------------------------- Changelog: 2015-11-12 - Check return value of png_get_bKGD() (Glenn R-P) 2017-04-22 - Guard against integer overflow (Glenn R-P) ---------------------------------------------------------------------------*/ #include /* for exit() prototype */ #include #include #include "png.h" /* libpng header from the local directory */ #include "readpng2.h" /* typedefs, common macros, public prototypes */ /* local prototypes */ static void readpng2_info_callback(png_structp png_ptr, png_infop info_ptr); static void readpng2_row_callback(png_structp png_ptr, png_bytep new_row, png_uint_32 row_num, int pass); static void readpng2_end_callback(png_structp png_ptr, png_infop info_ptr); static void readpng2_error_handler(png_structp png_ptr, png_const_charp msg); static void readpng2_warning_handler(png_structp png_ptr, png_const_charp msg); void readpng2_version_info(void) { fprintf(stderr, " Compiled with libpng %s; using libpng %s\n", PNG_LIBPNG_VER_STRING, png_libpng_ver); fprintf(stderr, " and with zlib %s; using zlib %s.\n", ZLIB_VERSION, zlib_version); } int readpng2_check_sig(uch *sig, int num) { return !png_sig_cmp(sig, 0, num); } /* returns 0 for success, 2 for libpng problem, 4 for out of memory */ int readpng2_init(mainprog_info *mainprog_ptr) { png_structp png_ptr; /* note: temporary variables! */ png_infop info_ptr; /* could also replace libpng warning-handler (final NULL), but no need: */ png_ptr = png_create_read_struct(png_get_libpng_ver(NULL), mainprog_ptr, readpng2_error_handler, readpng2_warning_handler); if (!png_ptr) return 4; /* out of memory */ info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, NULL, NULL); return 4; /* out of memory */ } /* we could create a second info struct here (end_info), but it's only * useful if we want to keep pre- and post-IDAT chunk info separated * (mainly for PNG-aware image editors and converters) */ /* setjmp() must be called in every function that calls a PNG-reading * libpng function, unless an alternate error handler was installed-- * but compatible error handlers must either use longjmp() themselves * (as in this program) or exit immediately, so here we are: */ if (setjmp(mainprog_ptr->jmpbuf)) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return 2; } #ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED /* prepare the reader to ignore all recognized chunks whose data won't be * used, i.e., all chunks recognized by libpng except for IHDR, PLTE, IDAT, * IEND, tRNS, bKGD, gAMA, and sRGB (small performance improvement) */ { /* These byte strings were copied from png.h. If a future version * of readpng2.c recognizes more chunks, add them to this list. */ static const png_byte chunks_to_process[] = { 98, 75, 71, 68, '\0', /* bKGD */ 103, 65, 77, 65, '\0', /* gAMA */ 115, 82, 71, 66, '\0', /* sRGB */ }; /* Ignore all chunks except for IHDR, PLTE, tRNS, IDAT, and IEND */ png_set_keep_unknown_chunks(png_ptr, -1 /* PNG_HANDLE_CHUNK_NEVER */, NULL, -1); /* But do not ignore chunks in the "chunks_to_process" list */ png_set_keep_unknown_chunks(png_ptr, 0 /* PNG_HANDLE_CHUNK_AS_DEFAULT */, chunks_to_process, sizeof(chunks_to_process)/5); } #endif /* PNG_HANDLE_AS_UNKNOWN_SUPPORTED */ /* instead of doing png_init_io() here, now we set up our callback * functions for progressive decoding */ png_set_progressive_read_fn(png_ptr, mainprog_ptr, readpng2_info_callback, readpng2_row_callback, readpng2_end_callback); /* make sure we save our pointers for use in readpng2_decode_data() */ mainprog_ptr->png_ptr = png_ptr; mainprog_ptr->info_ptr = info_ptr; /* and that's all there is to initialization */ return 0; } /* returns 0 for success, 2 for libpng (longjmp) problem */ int readpng2_decode_data(mainprog_info *mainprog_ptr, uch *rawbuf, ulg length) { png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr; png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr; /* setjmp() must be called in every function that calls a PNG-reading * libpng function */ if (setjmp(mainprog_ptr->jmpbuf)) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); mainprog_ptr->png_ptr = NULL; mainprog_ptr->info_ptr = NULL; return 2; } /* hand off the next chunk of input data to libpng for decoding */ png_process_data(png_ptr, info_ptr, rawbuf, length); return 0; } static void readpng2_info_callback(png_structp png_ptr, png_infop info_ptr) { mainprog_info *mainprog_ptr; int color_type, bit_depth; png_uint_32 width, height; #ifdef PNG_FLOATING_POINT_SUPPORTED double gamma; #else png_fixed_point gamma; #endif /* setjmp() doesn't make sense here, because we'd either have to exit(), * longjmp() ourselves, or return control to libpng, which doesn't want * to see us again. By not doing anything here, libpng will instead jump * to readpng2_decode_data(), which can return an error value to the main * program. */ /* retrieve the pointer to our special-purpose struct, using the png_ptr * that libpng passed back to us (i.e., not a global this time--there's * no real difference for a single image, but for a multithreaded browser * decoding several PNG images at the same time, one needs to avoid mixing * up different images' structs) */ mainprog_ptr = png_get_progressive_ptr(png_ptr); if (mainprog_ptr == NULL) { /* we be hosed */ fprintf(stderr, "readpng2 error: main struct not recoverable in info_callback.\n"); fflush(stderr); return; /* * Alternatively, we could call our error-handler just like libpng * does, which would effectively terminate the program. Since this * can only happen if png_ptr gets redirected somewhere odd or the * main PNG struct gets wiped, we're probably toast anyway. (If * png_ptr itself is NULL, we would not have been called.) */ } /* this is just like in the non-progressive case */ png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL); mainprog_ptr->width = (ulg)width; mainprog_ptr->height = (ulg)height; /* since we know we've read all of the PNG file's "header" (i.e., up * to IDAT), we can check for a background color here */ if (mainprog_ptr->need_bgcolor) { png_color_16p pBackground; /* it is not obvious from the libpng documentation, but this function * takes a pointer to a pointer, and it always returns valid red, * green and blue values, regardless of color_type: */ if (png_get_bKGD(png_ptr, info_ptr, &pBackground)) { /* however, it always returns the raw bKGD data, regardless of any * bit-depth transformations, so check depth and adjust if necessary */ if (bit_depth == 16) { mainprog_ptr->bg_red = pBackground->red >> 8; mainprog_ptr->bg_green = pBackground->green >> 8; mainprog_ptr->bg_blue = pBackground->blue >> 8; } else if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) { if (bit_depth == 1) mainprog_ptr->bg_red = mainprog_ptr->bg_green = mainprog_ptr->bg_blue = pBackground->gray? 255 : 0; else if (bit_depth == 2) mainprog_ptr->bg_red = mainprog_ptr->bg_green = mainprog_ptr->bg_blue = (255/3) * pBackground->gray; else /* bit_depth == 4 */ mainprog_ptr->bg_red = mainprog_ptr->bg_green = mainprog_ptr->bg_blue = (255/15) * pBackground->gray; } else { mainprog_ptr->bg_red = (uch)pBackground->red; mainprog_ptr->bg_green = (uch)pBackground->green; mainprog_ptr->bg_blue = (uch)pBackground->blue; } } } /* as before, let libpng expand palette images to RGB, low-bit-depth * grayscale images to 8 bits, transparency chunks to full alpha channel; * strip 16-bit-per-sample images to 8 bits per sample; and convert * grayscale to RGB[A] */ if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_expand(png_ptr); if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_expand(png_ptr); if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_expand(png_ptr); #ifdef PNG_READ_16_TO_8_SUPPORTED if (bit_depth == 16) # ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED png_set_scale_16(png_ptr); # else png_set_strip_16(png_ptr); # endif #endif if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(png_ptr); /* Unlike the basic viewer, which was designed to operate on local files, * this program is intended to simulate a web browser--even though we * actually read from a local file, too. But because we are pretending * that most of the images originate on the Internet, we follow the recom- * mendation of the sRGB proposal and treat unlabelled images (no gAMA * chunk) as existing in the sRGB color space. That is, we assume that * such images have a file gamma of 0.45455, which corresponds to a PC-like * display system. This change in assumptions will have no effect on a * PC-like system, but on a Mac, SGI, NeXT or other system with a non- * identity lookup table, it will darken unlabelled images, which effec- * tively favors images from PC-like systems over those originating on * the local platform. Note that mainprog_ptr->display_exponent is the * "gamma" value for the entire display system, i.e., the product of * LUT_exponent and CRT_exponent. */ #ifdef PNG_FLOATING_POINT_SUPPORTED if (png_get_gAMA(png_ptr, info_ptr, &gamma)) png_set_gamma(png_ptr, mainprog_ptr->display_exponent, gamma); else png_set_gamma(png_ptr, mainprog_ptr->display_exponent, 0.45455); #else if (png_get_gAMA_fixed(png_ptr, info_ptr, &gamma)) png_set_gamma_fixed(png_ptr, (png_fixed_point)(100000*mainprog_ptr->display_exponent+.5), gamma); else png_set_gamma_fixed(png_ptr, (png_fixed_point)(100000*mainprog_ptr->display_exponent+.5), 45455); #endif /* we'll let libpng expand interlaced images, too */ mainprog_ptr->passes = png_set_interlace_handling(png_ptr); /* all transformations have been registered; now update info_ptr data and * then get rowbytes and channels */ png_read_update_info(png_ptr, info_ptr); mainprog_ptr->rowbytes = (int)png_get_rowbytes(png_ptr, info_ptr); mainprog_ptr->channels = png_get_channels(png_ptr, info_ptr); /* Call the main program to allocate memory for the image buffer and * initialize windows and whatnot. (The old-style function-pointer * invocation is used for compatibility with a few supposedly ANSI * compilers that nevertheless barf on "fn_ptr()"-style syntax.) */ (*mainprog_ptr->mainprog_init)(); /* and that takes care of initialization */ return; } static void readpng2_row_callback(png_structp png_ptr, png_bytep new_row, png_uint_32 row_num, int pass) { mainprog_info *mainprog_ptr; /* first check whether the row differs from the previous pass; if not, * nothing to combine or display */ if (!new_row) return; /* retrieve the pointer to our special-purpose struct so we can access * the old rows and image-display callback function */ mainprog_ptr = png_get_progressive_ptr(png_ptr); /* save the pass number for optional use by the front end */ mainprog_ptr->pass = pass; /* have libpng either combine the new row data with the existing row data * from previous passes (if interlaced) or else just copy the new row * into the main program's image buffer */ png_progressive_combine_row(png_ptr, mainprog_ptr->row_pointers[row_num], new_row); /* finally, call the display routine in the main program with the number * of the row we just updated */ (*mainprog_ptr->mainprog_display_row)(row_num); /* and we're ready for more */ return; } static void readpng2_end_callback(png_structp png_ptr, png_infop info_ptr) { mainprog_info *mainprog_ptr; /* retrieve the pointer to our special-purpose struct */ mainprog_ptr = png_get_progressive_ptr(png_ptr); /* let the main program know that it should flush any buffered image * data to the display now and set a "done" flag or whatever, but note * that it SHOULD NOT DESTROY THE PNG STRUCTS YET--in other words, do * NOT call readpng2_cleanup() either here or in the finish_display() * routine; wait until control returns to the main program via * readpng2_decode_data() */ (*mainprog_ptr->mainprog_finish_display)(); /* all done */ (void)info_ptr; /* Unused */ return; } void readpng2_cleanup(mainprog_info *mainprog_ptr) { png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr; png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr; if (png_ptr && info_ptr) png_destroy_read_struct(&png_ptr, &info_ptr, NULL); mainprog_ptr->png_ptr = NULL; mainprog_ptr->info_ptr = NULL; } static void readpng2_warning_handler(png_structp png_ptr, png_const_charp msg) { fprintf(stderr, "readpng2 libpng warning: %s\n", msg); fflush(stderr); (void)png_ptr; /* Unused */ } static void readpng2_error_handler(png_structp png_ptr, png_const_charp msg) { mainprog_info *mainprog_ptr; /* This function, aside from the extra step of retrieving the "error * pointer" (below) and the fact that it exists within the application * rather than within libpng, is essentially identical to libpng's * default error handler. The second point is critical: since both * setjmp() and longjmp() are called from the same code, they are * guaranteed to have compatible notions of how big a jmp_buf is, * regardless of whether _BSD_SOURCE or anything else has (or has not) * been defined. */ fprintf(stderr, "readpng2 libpng error: %s\n", msg); fflush(stderr); mainprog_ptr = png_get_error_ptr(png_ptr); if (mainprog_ptr == NULL) { /* we are completely hosed now */ fprintf(stderr, "readpng2 severe error: jmpbuf not recoverable; terminating.\n"); fflush(stderr); exit(99); } /* Now we have our data structure we can use the information in it * to return control to our own higher level code (all the points * where 'setjmp' is called in this file.) This will work with other * error handling mechanisms as well - libpng always calls png_error * when it can proceed no further, thus, so long as the error handler * is intercepted, application code can do its own error recovery. */ longjmp(mainprog_ptr->jmpbuf, 1); } libpng-1.6.43/contrib/gregbook/readpng2.h000066400000000000000000000073301456606525400202120ustar00rootroot00000000000000/*--------------------------------------------------------------------------- rpng2 - progressive-model PNG display program readpng2.h --------------------------------------------------------------------------- Copyright (c) 1998-2008 Greg Roelofs. All rights reserved. This software is provided "as is," without warranty of any kind, express or implied. In no event shall the author or contributors be held liable for any damages arising in any way from the use of this software. The contents of this file are DUAL-LICENSED. You may modify and/or redistribute this software according to the terms of one of the following two licenses (at your option): LICENSE 1 ("BSD-like with advertising clause"): Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. Redistributions of source code must retain the above copyright notice, disclaimer, and this list of conditions. 2. Redistributions in binary form must reproduce the above copyright notice, disclaimer, and this list of conditions in the documenta- tion and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgment: This product includes software developed by Greg Roelofs and contributors for the book, "PNG: The Definitive Guide," published by O'Reilly and Associates. LICENSE 2 (GNU GPL v2 or later): This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ---------------------------------------------------------------------------*/ #ifndef TRUE # define TRUE 1 # define FALSE 0 #endif #ifndef MAX # define MAX(a,b) ((a) > (b)? (a) : (b)) # define MIN(a,b) ((a) < (b)? (a) : (b)) #endif #ifdef DEBUG # define Trace(x) {fprintf x ; fflush(stderr); fflush(stdout);} #else # define Trace(x) ; #endif enum rpng2_states { kPreInit = 0, kWindowInit, kDone }; typedef unsigned char uch; typedef unsigned short ush; typedef unsigned long ulg; typedef struct _mainprog_info { double display_exponent; ulg width; ulg height; void *png_ptr; void *info_ptr; void (*mainprog_init)(void); void (*mainprog_display_row)(ulg row_num); void (*mainprog_finish_display)(void); uch *image_data; uch **row_pointers; jmp_buf jmpbuf; int passes; /* not used */ int pass; int rowbytes; int channels; int need_bgcolor; int state; uch bg_red; uch bg_green; uch bg_blue; } mainprog_info; /* prototypes for public functions in readpng2.c */ void readpng2_version_info(void); int readpng2_check_sig(uch *sig, int num); int readpng2_init(mainprog_info *mainprog_ptr); int readpng2_decode_data(mainprog_info *mainprog_ptr, uch *rawbuf, ulg length); void readpng2_cleanup(mainprog_info *mainprog_ptr); libpng-1.6.43/contrib/gregbook/readppm.c000066400000000000000000000131421456606525400201310ustar00rootroot00000000000000/*--------------------------------------------------------------------------- rpng - simple PNG display program readppm.c --------------------------------------------------------------------------- This is a special-purpose replacement for readpng.c that allows binary PPM files to be used in place of PNG images. --------------------------------------------------------------------------- Copyright (c) 1998-2007,2017 Greg Roelofs. All rights reserved. This software is provided "as is," without warranty of any kind, express or implied. In no event shall the author or contributors be held liable for any damages arising in any way from the use of this software. The contents of this file are DUAL-LICENSED. You may modify and/or redistribute this software according to the terms of one of the following two licenses (at your option): LICENSE 1 ("BSD-like with advertising clause"): Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. Redistributions of source code must retain the above copyright notice, disclaimer, and this list of conditions. 2. Redistributions in binary form must reproduce the above copyright notice, disclaimer, and this list of conditions in the documenta- tion and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgment: This product includes software developed by Greg Roelofs and contributors for the book, "PNG: The Definitive Guide," published by O'Reilly and Associates. LICENSE 2 (GNU GPL v2 or later): This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ---------------------------------------------------------------------------*/ #include #include #include "readpng.h" /* typedefs, common macros, public prototypes */ ulg width, height; int bit_depth, color_type, channels; uch *image_data = NULL; FILE *saved_infile; void readpng_version_info() { fprintf(stderr, " Compiled without libpng, zlib or PBMPLUS/NetPBM.\n"); } /* return value = 0 for success, 1 for bad sig, 2 for bad IHDR, 4 for no mem */ int readpng_init(FILE *infile, ulg *pWidth, ulg *pHeight) { static uch ppmline[256]; int maxval; saved_infile = infile; fgets(ppmline, 256, infile); if (ppmline[0] != 'P' || ppmline[1] != '6') { fprintf(stderr, "ERROR: not a PPM file\n"); return 1; } /* possible color types: P5 = grayscale (0), P6 = RGB (2), P8 = RGBA (6) */ if (ppmline[1] == '6') { color_type = 2; channels = 3; } else if (ppmline[1] == '8') { color_type = 6; channels = 4; } else /* if (ppmline[1] == '5') */ { color_type = 0; channels = 1; } do { fgets(ppmline, 256, infile); } while (ppmline[0] == '#'); sscanf(ppmline, "%lu %lu", &width, &height); do { fgets(ppmline, 256, infile); } while (ppmline[0] == '#'); sscanf(ppmline, "%d", &maxval); if (maxval != 255) { fprintf(stderr, "ERROR: maxval = %d\n", maxval); return 2; } bit_depth = 8; *pWidth = width; *pHeight = height; return 0; } /* returns 0 if succeeds, 1 if fails due to no bKGD chunk, 2 if libpng error; * scales values to 8-bit if necessary */ int readpng_get_bgcolor(uch *red, uch *green, uch *blue) { return 1; } /* display_exponent == LUT_exponent * CRT_exponent */ uch *readpng_get_image(double display_exponent, int *pChannels, ulg *pRowbytes) { ulg rowbytes; /* expand palette images to RGB, low-bit-depth grayscale images to 8 bits, * transparency chunks to full alpha channel; strip 16-bit-per-sample * images to 8 bits per sample; and convert grayscale to RGB[A] */ /* GRR WARNING: grayscale needs to be expanded and channels reset! */ *pRowbytes = rowbytes = channels*width; *pChannels = channels; Trace((stderr, "readpng_get_image: rowbytes = %ld, height = %ld\n", rowbytes, height)); /* Guard against integer overflow */ if (height > ((size_t)(-1))/rowbytes) { fprintf(stderr, PROGNAME ": image_data buffer would be too large\n", return NULL; } if ((image_data = (uch *)malloc(rowbytes*height)) == NULL) { return NULL; } /* now we can go ahead and just read the whole image */ if (fread(image_data, 1L, rowbytes*height, saved_infile) < rowbytes*height) { free (image_data); image_data = NULL; return NULL; } return image_data; } void readpng_cleanup(int free_image_data) { if (free_image_data && image_data) { free(image_data); image_data = NULL; } } libpng-1.6.43/contrib/gregbook/rpng-win.c000066400000000000000000000567641456606525400202630ustar00rootroot00000000000000/*--------------------------------------------------------------------------- rpng - simple PNG display program rpng-win.c This program decodes and displays PNG images, with gamma correction and optionally with a user-specified background color (in case the image has transparency). It is very nearly the most basic PNG viewer possible. This version is for 32-bit Windows; it may compile under 16-bit Windows with a little tweaking (or maybe not). to do: - handle quoted command-line args (especially filenames with spaces) - have minimum window width: oh well - use %.1023s to simplify truncation of title-bar string? --------------------------------------------------------------------------- Changelog: - 1.00: initial public release - 1.01: modified to allow abbreviated options; fixed long/ulong mis- match; switched to png_jmpbuf() macro - 1.02: added extra set of parentheses to png_jmpbuf() macro; fixed command-line parsing bug - 1.10: enabled "message window"/console (thanks to David Geldreich) - 2.00: dual-licensed (added GNU GPL) - 2.01: fixed improper display of usage screen on PNG error(s) - 2.02: check for integer overflow (Glenn R-P) --------------------------------------------------------------------------- Copyright (c) 1998-2008, 2017 Greg Roelofs. All rights reserved. This software is provided "as is," without warranty of any kind, express or implied. In no event shall the author or contributors be held liable for any damages arising in any way from the use of this software. The contents of this file are DUAL-LICENSED. You may modify and/or redistribute this software according to the terms of one of the following two licenses (at your option): LICENSE 1 ("BSD-like with advertising clause"): Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. Redistributions of source code must retain the above copyright notice, disclaimer, and this list of conditions. 2. Redistributions in binary form must reproduce the above copyright notice, disclaimer, and this list of conditions in the documenta- tion and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgment: This product includes software developed by Greg Roelofs and contributors for the book, "PNG: The Definitive Guide," published by O'Reilly and Associates. LICENSE 2 (GNU GPL v2 or later): This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ---------------------------------------------------------------------------*/ #define PROGNAME "rpng-win" #define LONGNAME "Simple PNG Viewer for Windows" #define VERSION "2.01 of 16 March 2008" #include #include #include #include #include #ifdef __CYGWIN__ /* getch replacement. Turns out, we don't really need this, * but leave it here if we ever enable any of the uses of * _getch in the main code */ #include #include #include int repl_getch( void ) { char ch; int fd = fileno(stdin); struct termio old_tty, new_tty; ioctl(fd, TCGETA, &old_tty); new_tty = old_tty; new_tty.c_lflag &= ~(ICANON | ECHO | ISIG); ioctl(fd, TCSETA, &new_tty); fread(&ch, 1, sizeof(ch), stdin); ioctl(fd, TCSETA, &old_tty); return ch; } #define _getch repl_getch #else #include /* only for _getch() */ #endif /* #define DEBUG : this enables the Trace() macros */ #include "readpng.h" /* typedefs, common macros, readpng prototypes */ /* could just include png.h, but this macro is the only thing we need * (name and typedefs changed to local versions); note that side effects * only happen with alpha (which could easily be avoided with * "ush acopy = (alpha);") */ #define alpha_composite(composite, fg, alpha, bg) { \ ush temp = ((ush)(fg)*(ush)(alpha) + \ (ush)(bg)*(ush)(255 - (ush)(alpha)) + (ush)128); \ (composite) = (uch)((temp + (temp >> 8)) >> 8); \ } /* local prototypes */ static int rpng_win_create_window(HINSTANCE hInst, int showmode); static int rpng_win_display_image(void); static void rpng_win_cleanup(void); LRESULT CALLBACK rpng_win_wndproc(HWND, UINT, WPARAM, LPARAM); static char titlebar[1024]; static char *progname = PROGNAME; static char *appname = LONGNAME; static char *filename; static FILE *infile; static char *bgstr; static uch bg_red=0, bg_green=0, bg_blue=0; static double display_exponent; static ulg image_width, image_height, image_rowbytes; static int image_channels; static uch *image_data; /* Windows-specific variables */ static ulg wimage_rowbytes; static uch *dib; static uch *wimage_data; static BITMAPINFOHEADER *bmih; static HWND global_hwnd; int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, PSTR cmd, int showmode) { char *args[1024]; /* arbitrary limit, but should suffice */ char *p, *q, **argv = args; int argc = 0; int rc, alen, flen; int error = 0; int have_bg = FALSE; double LUT_exponent; /* just the lookup table */ double CRT_exponent = 2.2; /* just the monitor */ double default_display_exponent; /* whole display system */ MSG msg; filename = (char *)NULL; #ifndef __CYGWIN__ /* First reenable console output, which normally goes to the bit bucket * for windowed apps. Closing the console window will terminate the * app. Thanks to David.Geldreich at realviz.com for supplying the magical * incantation. */ AllocConsole(); freopen("CONOUT$", "a", stderr); freopen("CONOUT$", "a", stdout); #endif /* Next set the default value for our display-system exponent, i.e., * the product of the CRT exponent and the exponent corresponding to * the frame-buffer's lookup table (LUT), if any. This is not an * exhaustive list of LUT values (e.g., OpenStep has a lot of weird * ones), but it should cover 99% of the current possibilities. And * yes, these ifdefs are completely wasted in a Windows program... */ #if defined(NeXT) LUT_exponent = 1.0 / 2.2; /* if (some_next_function_that_returns_gamma(&next_gamma)) LUT_exponent = 1.0 / next_gamma; */ #elif defined(sgi) LUT_exponent = 1.0 / 1.7; /* there doesn't seem to be any documented function to get the * "gamma" value, so we do it the hard way */ infile = fopen("/etc/config/system.glGammaVal", "r"); if (infile) { double sgi_gamma; fgets(tmpline, 80, infile); fclose(infile); sgi_gamma = atof(tmpline); if (sgi_gamma > 0.0) LUT_exponent = 1.0 / sgi_gamma; } #elif defined(Macintosh) LUT_exponent = 1.8 / 2.61; /* if (some_mac_function_that_returns_gamma(&mac_gamma)) LUT_exponent = mac_gamma / 2.61; */ #else LUT_exponent = 1.0; /* assume no LUT: most PCs */ #endif /* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */ default_display_exponent = LUT_exponent * CRT_exponent; /* If the user has set the SCREEN_GAMMA environment variable as suggested * (somewhat imprecisely) in the libpng documentation, use that; otherwise * use the default value we just calculated. Either way, the user may * override this via a command-line option. */ if ((p = getenv("SCREEN_GAMMA")) != NULL) display_exponent = atof(p); else display_exponent = default_display_exponent; /* Windows really hates command lines, so we have to set up our own argv. * Note that we do NOT bother with quoted arguments here, so don't use * filenames with spaces in 'em! */ argv[argc++] = PROGNAME; p = cmd; for (;;) { if (*p == ' ') while (*++p == ' ') ; /* now p points at the first non-space after some spaces */ if (*p == '\0') break; /* nothing after the spaces: done */ argv[argc++] = q = p; while (*q && *q != ' ') ++q; /* now q points at a space or the end of the string */ if (*q == '\0') break; /* last argv already terminated; quit */ *q = '\0'; /* change space to terminator */ p = q + 1; } argv[argc] = NULL; /* terminate the argv array itself */ /* Now parse the command line for options and the PNG filename. */ while (*++argv && !error) { if (!strncmp(*argv, "-gamma", 2)) { if (!*++argv) ++error; else { display_exponent = atof(*argv); if (display_exponent <= 0.0) ++error; } } else if (!strncmp(*argv, "-bgcolor", 2)) { if (!*++argv) ++error; else { bgstr = *argv; if (strlen(bgstr) != 7 || bgstr[0] != '#') ++error; else have_bg = TRUE; } } else { if (**argv != '-') { filename = *argv; if (argv[1]) /* shouldn't be any more args after filename */ ++error; } else ++error; /* not expecting any other options */ } } if (!filename) ++error; /* print usage screen if any errors up to this point */ if (error) { #ifndef __CYGWIN__ int ch; #endif fprintf(stderr, "\n%s %s: %s\n\n", PROGNAME, VERSION, appname); readpng_version_info(); fprintf(stderr, "\n" "Usage: %s [-gamma exp] [-bgcolor bg] file.png\n" " exp \ttransfer-function exponent (``gamma'') of the display\n" "\t\t system in floating-point format (e.g., ``%.1f''); equal\n" "\t\t to the product of the lookup-table exponent (varies)\n" "\t\t and the CRT exponent (usually 2.2); must be positive\n" " bg \tdesired background color in 7-character hex RGB format\n" "\t\t (e.g., ``#ff7700'' for orange: same as HTML colors);\n" "\t\t used with transparent images\n" "\nPress Q, Esc or mouse button 1 after image is displayed to quit.\n" #ifndef __CYGWIN__ "Press Q or Esc to quit this usage screen.\n" #endif "\n", PROGNAME, default_display_exponent); #ifndef __CYGWIN__ do ch = _getch(); while (ch != 'q' && ch != 'Q' && ch != 0x1B); #endif exit(1); } if (!(infile = fopen(filename, "rb"))) { fprintf(stderr, PROGNAME ": can't open PNG file [%s]\n", filename); ++error; } else { if ((rc = readpng_init(infile, &image_width, &image_height)) != 0) { switch (rc) { case 1: fprintf(stderr, PROGNAME ": [%s] is not a PNG file: incorrect signature\n", filename); break; case 2: fprintf(stderr, PROGNAME ": [%s] has bad IHDR (libpng longjmp)\n", filename); break; case 4: fprintf(stderr, PROGNAME ": insufficient memory\n"); break; default: fprintf(stderr, PROGNAME ": unknown readpng_init() error\n"); break; } ++error; } if (error) fclose(infile); } if (error) { #ifndef __CYGWIN__ int ch; #endif fprintf(stderr, PROGNAME ": aborting.\n"); #ifndef __CYGWIN__ do ch = _getch(); while (ch != 'q' && ch != 'Q' && ch != 0x1B); #endif exit(2); } else { fprintf(stderr, "\n%s %s: %s\n", PROGNAME, VERSION, appname); #ifndef __CYGWIN__ fprintf(stderr, "\n [console window: closing this window will terminate %s]\n\n", PROGNAME); #endif } /* set the title-bar string, but make sure buffer doesn't overflow */ alen = strlen(appname); flen = strlen(filename); if (alen + flen + 3 > 1023) sprintf(titlebar, "%s: ...%s", appname, filename+(alen+flen+6-1023)); else sprintf(titlebar, "%s: %s", appname, filename); /* if the user didn't specify a background color on the command line, * check for one in the PNG file--if not, the initialized values of 0 * (black) will be used */ if (have_bg) { unsigned r, g, b; /* this approach quiets compiler warnings */ sscanf(bgstr+1, "%2x%2x%2x", &r, &g, &b); bg_red = (uch)r; bg_green = (uch)g; bg_blue = (uch)b; } else if (readpng_get_bgcolor(&bg_red, &bg_green, &bg_blue) > 1) { readpng_cleanup(TRUE); fprintf(stderr, PROGNAME ": libpng error while checking for background color\n"); exit(2); } /* do the basic Windows initialization stuff, make the window and fill it * with the background color */ if (rpng_win_create_window(hInst, showmode)) exit(2); /* decode the image, all at once */ Trace((stderr, "calling readpng_get_image()\n")) image_data = readpng_get_image(display_exponent, &image_channels, &image_rowbytes); Trace((stderr, "done with readpng_get_image()\n")) /* done with PNG file, so clean up to minimize memory usage (but do NOT * nuke image_data!) */ readpng_cleanup(FALSE); fclose(infile); if (!image_data) { fprintf(stderr, PROGNAME ": unable to decode PNG image\n"); exit(3); } /* display image (composite with background if requested) */ Trace((stderr, "calling rpng_win_display_image()\n")) if (rpng_win_display_image()) { free(image_data); exit(4); } Trace((stderr, "done with rpng_win_display_image()\n")) /* wait for the user to tell us when to quit */ printf( #ifndef __CYGWIN__ "Done. Press Q, Esc or mouse button 1 (within image window) to quit.\n" #else "Done. Press mouse button 1 (within image window) to quit.\n" #endif ); fflush(stdout); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } /* OK, we're done: clean up all image and Windows resources and go away */ rpng_win_cleanup(); return msg.wParam; } static int rpng_win_create_window(HINSTANCE hInst, int showmode) { uch *dest; int extra_width, extra_height; ulg i, j; WNDCLASSEX wndclass; /*--------------------------------------------------------------------------- Allocate memory for the display-specific version of the image (round up to multiple of 4 for Windows DIB). ---------------------------------------------------------------------------*/ wimage_rowbytes = ((3*image_width + 3L) >> 2) << 2; /* Guard against integer overflow */ if (image_height > ((size_t)(-1))/wimage_rowbytes) { fprintf(stderr, PROGNAME ": image_data buffer would be too large\n"); return 4; /* fail */ } if (!(dib = (uch *)malloc(sizeof(BITMAPINFOHEADER) + wimage_rowbytes*image_height))) { return 4; /* fail */ } /*--------------------------------------------------------------------------- Initialize the DIB. Negative height means to use top-down BMP ordering (must be uncompressed, but that's what we want). Bit count of 1, 4 or 8 implies a colormap of RGBX quads, but 24-bit BMPs just use B,G,R values directly => wimage_data begins immediately after BMP header. ---------------------------------------------------------------------------*/ memset(dib, 0, sizeof(BITMAPINFOHEADER)); bmih = (BITMAPINFOHEADER *)dib; bmih->biSize = sizeof(BITMAPINFOHEADER); bmih->biWidth = image_width; bmih->biHeight = -((long)image_height); bmih->biPlanes = 1; bmih->biBitCount = 24; bmih->biCompression = 0; wimage_data = dib + sizeof(BITMAPINFOHEADER); /*--------------------------------------------------------------------------- Fill in background color (black by default); data are in BGR order. ---------------------------------------------------------------------------*/ for (j = 0; j < image_height; ++j) { dest = wimage_data + j*wimage_rowbytes; for (i = image_width; i > 0; --i) { *dest++ = bg_blue; *dest++ = bg_green; *dest++ = bg_red; } } /*--------------------------------------------------------------------------- Set the window parameters. ---------------------------------------------------------------------------*/ memset(&wndclass, 0, sizeof(wndclass)); wndclass.cbSize = sizeof(wndclass); wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = rpng_win_wndproc; wndclass.hInstance = hInst; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(DKGRAY_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = progname; wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); RegisterClassEx(&wndclass); /*--------------------------------------------------------------------------- Finally, create the window. ---------------------------------------------------------------------------*/ extra_width = 2*(GetSystemMetrics(SM_CXBORDER) + GetSystemMetrics(SM_CXDLGFRAME)); extra_height = 2*(GetSystemMetrics(SM_CYBORDER) + GetSystemMetrics(SM_CYDLGFRAME)) + GetSystemMetrics(SM_CYCAPTION); global_hwnd = CreateWindow(progname, titlebar, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, image_width+extra_width, image_height+extra_height, NULL, NULL, hInst, NULL); ShowWindow(global_hwnd, showmode); UpdateWindow(global_hwnd); return 0; } /* end function rpng_win_create_window() */ static int rpng_win_display_image() { uch *src, *dest; uch r, g, b, a; ulg i, row, lastrow; RECT rect; Trace((stderr, "beginning display loop (image_channels == %d)\n", image_channels)) Trace((stderr, "(width = %ld, rowbytes = %ld, wimage_rowbytes = %d)\n", image_width, image_rowbytes, wimage_rowbytes)) /*--------------------------------------------------------------------------- Blast image data to buffer. This whole routine takes place before the message loop begins, so there's no real point in any pseudo-progressive display... ---------------------------------------------------------------------------*/ for (lastrow = row = 0; row < image_height; ++row) { src = image_data + row*image_rowbytes; dest = wimage_data + row*wimage_rowbytes; if (image_channels == 3) { for (i = image_width; i > 0; --i) { r = *src++; g = *src++; b = *src++; *dest++ = b; *dest++ = g; /* note reverse order */ *dest++ = r; } } else /* if (image_channels == 4) */ { for (i = image_width; i > 0; --i) { r = *src++; g = *src++; b = *src++; a = *src++; if (a == 255) { *dest++ = b; *dest++ = g; *dest++ = r; } else if (a == 0) { *dest++ = bg_blue; *dest++ = bg_green; *dest++ = bg_red; } else { /* this macro (copied from png.h) composites the * foreground and background values and puts the * result into the first argument; there are no * side effects with the first argument */ alpha_composite(*dest++, b, a, bg_blue); alpha_composite(*dest++, g, a, bg_green); alpha_composite(*dest++, r, a, bg_red); } } } /* display after every 16 lines */ if (((row+1) & 0xf) == 0) { rect.left = 0L; rect.top = (LONG)lastrow; rect.right = (LONG)image_width; /* possibly off by one? */ rect.bottom = (LONG)lastrow + 16L; /* possibly off by one? */ InvalidateRect(global_hwnd, &rect, FALSE); UpdateWindow(global_hwnd); /* similar to XFlush() */ lastrow = row + 1; } } Trace((stderr, "calling final image-flush routine\n")) if (lastrow < image_height) { rect.left = 0L; rect.top = (LONG)lastrow; rect.right = (LONG)image_width; /* possibly off by one? */ rect.bottom = (LONG)image_height; /* possibly off by one? */ InvalidateRect(global_hwnd, &rect, FALSE); UpdateWindow(global_hwnd); /* similar to XFlush() */ } /* last param determines whether or not background is wiped before paint InvalidateRect(global_hwnd, NULL, TRUE); UpdateWindow(global_hwnd); */ return 0; } static void rpng_win_cleanup() { if (image_data) { free(image_data); image_data = NULL; } if (dib) { free(dib); dib = NULL; } } LRESULT CALLBACK rpng_win_wndproc(HWND hwnd, UINT iMsg, WPARAM wP, LPARAM lP) { HDC hdc; PAINTSTRUCT ps; int rc; switch (iMsg) { case WM_CREATE: /* one-time processing here, if any */ return 0; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); /* dest */ rc = StretchDIBits(hdc, 0, 0, image_width, image_height, /* source */ 0, 0, image_width, image_height, wimage_data, (BITMAPINFO *)bmih, /* iUsage: no clue */ 0, SRCCOPY); EndPaint(hwnd, &ps); return 0; /* wait for the user to tell us when to quit */ case WM_CHAR: switch (wP) { /* only need one, so ignore repeat count */ case 'q': case 'Q': case 0x1B: /* Esc key */ PostQuitMessage(0); } return 0; case WM_LBUTTONDOWN: /* another way of quitting */ case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, iMsg, wP, lP); } libpng-1.6.43/contrib/gregbook/rpng-x.c000066400000000000000000000744601456606525400177260ustar00rootroot00000000000000/*--------------------------------------------------------------------------- rpng - simple PNG display program rpng-x.c This program decodes and displays PNG images, with gamma correction and optionally with a user-specified background color (in case the image has transparency). It is very nearly the most basic PNG viewer possible. This version is for the X Window System (tested by author under Unix and by Martin Zinser under OpenVMS; may work under OS/2 with some tweaking). to do: - 8-bit (colormapped) X support - use %.1023s to simplify truncation of title-bar string? --------------------------------------------------------------------------- Changelog: - 1.01: initial public release - 1.02: modified to allow abbreviated options; fixed long/ulong mis- match; switched to png_jmpbuf() macro - 1.10: added support for non-default visuals; fixed X pixel-conversion - 1.11: added extra set of parentheses to png_jmpbuf() macro; fixed command-line parsing bug - 1.12: fixed some small X memory leaks (thanks to François Petitjean) - 1.13: fixed XFreeGC() crash bug (thanks to Patrick Welche) - 1.14: added support for X resources (thanks to Gerhard Niklasch) - 2.00: dual-licensed (added GNU GPL) - 2.01: fixed improper display of usage screen on PNG error(s) - 2.02: Added "void(argc);" statement to quiet pedantic compiler warnings about unused variable (GR-P) - 2.03: check for integer overflow (Glenn R-P) --------------------------------------------------------------------------- Copyright (c) 1998-2008, 2017 Greg Roelofs. All rights reserved. This software is provided "as is," without warranty of any kind, express or implied. In no event shall the author or contributors be held liable for any damages arising in any way from the use of this software. The contents of this file are DUAL-LICENSED. You may modify and/or redistribute this software according to the terms of one of the following two licenses (at your option): LICENSE 1 ("BSD-like with advertising clause"): Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. Redistributions of source code must retain the above copyright notice, disclaimer, and this list of conditions. 2. Redistributions in binary form must reproduce the above copyright notice, disclaimer, and this list of conditions in the documenta- tion and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgment: This product includes software developed by Greg Roelofs and contributors for the book, "PNG: The Definitive Guide," published by O'Reilly and Associates. LICENSE 2 (GNU GPL v2 or later): This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ---------------------------------------------------------------------------*/ #define PROGNAME "rpng-x" #define LONGNAME "Simple PNG Viewer for X" #define VERSION "2.02 of 15 June 2014" #define RESNAME "rpng" /* our X resource application name */ #define RESCLASS "Rpng" /* our X resource class name */ #include #include #include #include #include #include #include #include /* #define DEBUG : this enables the Trace() macros */ #include "readpng.h" /* typedefs, common macros, readpng prototypes */ /* could just include png.h, but this macro is the only thing we need * (name and typedefs changed to local versions); note that side effects * only happen with alpha (which could easily be avoided with * "ush acopy = (alpha);") */ #define alpha_composite(composite, fg, alpha, bg) { \ ush temp = ((ush)(fg)*(ush)(alpha) + \ (ush)(bg)*(ush)(255 - (ush)(alpha)) + (ush)128); \ (composite) = (uch)((temp + (temp >> 8)) >> 8); \ } /* local prototypes */ static int rpng_x_create_window(void); static int rpng_x_display_image(void); static void rpng_x_cleanup(void); static int rpng_x_msb(ulg u32val); static char titlebar[1024], *window_name = titlebar; static char *appname = LONGNAME; static char *icon_name = PROGNAME; static char *res_name = RESNAME; static char *res_class = RESCLASS; static char *filename; static FILE *infile; static char *bgstr; static uch bg_red=0, bg_green=0, bg_blue=0; static double display_exponent; static ulg image_width, image_height, image_rowbytes; static int image_channels; static uch *image_data; /* X-specific variables */ static char *displayname; static XImage *ximage; static Display *display; static int depth; static Visual *visual; static XVisualInfo *visual_list; static int RShift, GShift, BShift; static ulg RMask, GMask, BMask; static Window window; static GC gc; static Colormap colormap; static int have_nondefault_visual = FALSE; static int have_colormap = FALSE; static int have_window = FALSE; static int have_gc = FALSE; /* ulg numcolors=0, pixels[256]; ush reds[256], greens[256], blues[256]; */ int main(int argc, char **argv) { #ifdef sgi char tmpline[80]; #endif char *p; int rc, alen, flen; int error = 0; int have_bg = FALSE; double LUT_exponent; /* just the lookup table */ double CRT_exponent = 2.2; /* just the monitor */ double default_display_exponent; /* whole display system */ XEvent e; KeySym k; displayname = (char *)NULL; filename = (char *)NULL; /* First set the default value for our display-system exponent, i.e., * the product of the CRT exponent and the exponent corresponding to * the frame-buffer's lookup table (LUT), if any. This is not an * exhaustive list of LUT values (e.g., OpenStep has a lot of weird * ones), but it should cover 99% of the current possibilities. */ #if defined(NeXT) LUT_exponent = 1.0 / 2.2; /* if (some_next_function_that_returns_gamma(&next_gamma)) LUT_exponent = 1.0 / next_gamma; */ #elif defined(sgi) LUT_exponent = 1.0 / 1.7; /* there doesn't seem to be any documented function to get the * "gamma" value, so we do it the hard way */ infile = fopen("/etc/config/system.glGammaVal", "r"); if (infile) { double sgi_gamma; fgets(tmpline, 80, infile); fclose(infile); sgi_gamma = atof(tmpline); if (sgi_gamma > 0.0) LUT_exponent = 1.0 / sgi_gamma; } #elif defined(Macintosh) LUT_exponent = 1.8 / 2.61; /* if (some_mac_function_that_returns_gamma(&mac_gamma)) LUT_exponent = mac_gamma / 2.61; */ #else LUT_exponent = 1.0; /* assume no LUT: most PCs */ #endif /* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */ default_display_exponent = LUT_exponent * CRT_exponent; /* If the user has set the SCREEN_GAMMA environment variable as suggested * (somewhat imprecisely) in the libpng documentation, use that; otherwise * use the default value we just calculated. Either way, the user may * override this via a command-line option. */ if ((p = getenv("SCREEN_GAMMA")) != NULL) display_exponent = atof(p); else display_exponent = default_display_exponent; /* Now parse the command line for options and the PNG filename. */ while (*++argv && !error) { if (!strncmp(*argv, "-display", 2)) { if (!*++argv) ++error; else displayname = *argv; } else if (!strncmp(*argv, "-gamma", 2)) { if (!*++argv) ++error; else { display_exponent = atof(*argv); if (display_exponent <= 0.0) ++error; } } else if (!strncmp(*argv, "-bgcolor", 2)) { if (!*++argv) ++error; else { bgstr = *argv; if (strlen(bgstr) != 7 || bgstr[0] != '#') ++error; else have_bg = TRUE; } } else { if (**argv != '-') { filename = *argv; if (argv[1]) /* shouldn't be any more args after filename */ ++error; } else ++error; /* not expecting any other options */ } } if (!filename) ++error; /* print usage screen if any errors up to this point */ if (error) { fprintf(stderr, "\n%s %s: %s\n", PROGNAME, VERSION, appname); readpng_version_info(); fprintf(stderr, "\n" "Usage: %s [-display xdpy] [-gamma exp] [-bgcolor bg] file.png\n" " xdpy\tname of the target X display (e.g., ``hostname:0'')\n" " exp \ttransfer-function exponent (``gamma'') of the display\n" "\t\t system in floating-point format (e.g., ``%.1f''); equal\n", PROGNAME, default_display_exponent); fprintf(stderr, "\n" "\t\t to the product of the lookup-table exponent (varies)\n" "\t\t and the CRT exponent (usually 2.2); must be positive\n" " bg \tdesired background color in 7-character hex RGB format\n" "\t\t (e.g., ``#ff7700'' for orange: same as HTML colors);\n" "\t\t used with transparent images\n" "\nPress Q, Esc or mouse button 1 (within image window, after image\n" "is displayed) to quit.\n"); exit(1); } if (!(infile = fopen(filename, "rb"))) { fprintf(stderr, PROGNAME ": can't open PNG file [%s]\n", filename); ++error; } else { if ((rc = readpng_init(infile, &image_width, &image_height)) != 0) { switch (rc) { case 1: fprintf(stderr, PROGNAME ": [%s] is not a PNG file: incorrect signature\n", filename); break; case 2: fprintf(stderr, PROGNAME ": [%s] has bad IHDR (libpng longjmp)\n", filename); break; case 4: fprintf(stderr, PROGNAME ": insufficient memory\n"); break; default: fprintf(stderr, PROGNAME ": unknown readpng_init() error\n"); break; } ++error; } else { display = XOpenDisplay(displayname); if (!display) { readpng_cleanup(TRUE); fprintf(stderr, PROGNAME ": can't open X display [%s]\n", displayname? displayname : "default"); ++error; } } if (error) fclose(infile); } if (error) { fprintf(stderr, PROGNAME ": aborting.\n"); exit(2); } /* set the title-bar string, but make sure buffer doesn't overflow */ alen = strlen(appname); flen = strlen(filename); if (alen + flen + 3 > 1023) sprintf(titlebar, "%s: ...%s", appname, filename+(alen+flen+6-1023)); else sprintf(titlebar, "%s: %s", appname, filename); /* if the user didn't specify a background color on the command line, * check for one in the PNG file--if not, the initialized values of 0 * (black) will be used */ if (have_bg) { unsigned r, g, b; /* this approach quiets compiler warnings */ sscanf(bgstr+1, "%2x%2x%2x", &r, &g, &b); bg_red = (uch)r; bg_green = (uch)g; bg_blue = (uch)b; } else if (readpng_get_bgcolor(&bg_red, &bg_green, &bg_blue) > 1) { readpng_cleanup(TRUE); fprintf(stderr, PROGNAME ": libpng error while checking for background color\n"); exit(2); } /* do the basic X initialization stuff, make the window and fill it * with the background color */ if (rpng_x_create_window()) exit(2); /* decode the image, all at once */ Trace((stderr, "calling readpng_get_image()\n")) image_data = readpng_get_image(display_exponent, &image_channels, &image_rowbytes); Trace((stderr, "done with readpng_get_image()\n")) /* done with PNG file, so clean up to minimize memory usage (but do NOT * nuke image_data!) */ readpng_cleanup(FALSE); fclose(infile); if (!image_data) { fprintf(stderr, PROGNAME ": unable to decode PNG image\n"); exit(3); } /* display image (composite with background if requested) */ Trace((stderr, "calling rpng_x_display_image()\n")) if (rpng_x_display_image()) { free(image_data); exit(4); } Trace((stderr, "done with rpng_x_display_image()\n")) /* wait for the user to tell us when to quit */ printf( "Done. Press Q, Esc or mouse button 1 (within image window) to quit.\n"); fflush(stdout); do XNextEvent(display, &e); while (!(e.type == ButtonPress && e.xbutton.button == Button1) && !(e.type == KeyPress && /* v--- or 1 for shifted keys */ ((k = XLookupKeysym(&e.xkey, 0)) == XK_q || k == XK_Escape) )); /* OK, we're done: clean up all image and X resources and go away */ rpng_x_cleanup(); (void)argc; /* Unused */ return 0; } static int rpng_x_create_window(void) { uch *xdata; int need_colormap = FALSE; int screen, pad; ulg bg_pixel = 0L; ulg attrmask; Window root; XEvent e; XGCValues gcvalues; XSetWindowAttributes attr; XTextProperty windowName, *pWindowName = &windowName; XTextProperty iconName, *pIconName = &iconName; XVisualInfo visual_info; XSizeHints *size_hints; XWMHints *wm_hints; XClassHint *class_hints; screen = DefaultScreen(display); depth = DisplayPlanes(display, screen); root = RootWindow(display, screen); #ifdef DEBUG XSynchronize(display, True); #endif #if 0 /* GRR: add 8-bit support */ if (/* depth != 8 && */ depth != 16 && depth != 24 && depth != 32) { fprintf(stderr, "screen depth %d not supported (only 16-, 24- or 32-bit TrueColor)\n", depth); return 2; } XMatchVisualInfo(display, screen, depth, (depth == 8)? PseudoColor : TrueColor, &visual_info); visual = visual_info.visual; #else if (depth != 16 && depth != 24 && depth != 32) { int visuals_matched = 0; Trace((stderr, "default depth is %d: checking other visuals\n", depth)) /* 24-bit first */ visual_info.screen = screen; visual_info.depth = 24; visual_list = XGetVisualInfo(display, VisualScreenMask | VisualDepthMask, &visual_info, &visuals_matched); if (visuals_matched == 0) { /* GRR: add 15-, 16- and 32-bit TrueColor visuals (also DirectColor?) */ fprintf(stderr, "default screen depth %d not supported, and no" " 24-bit visuals found\n", depth); return 2; } Trace((stderr, "XGetVisualInfo() returned %d 24-bit visuals\n", visuals_matched)) visual = visual_list[0].visual; depth = visual_list[0].depth; /* colormap_size = visual_list[0].colormap_size; visual_class = visual->class; visualID = XVisualIDFromVisual(visual); */ have_nondefault_visual = TRUE; need_colormap = TRUE; } else { XMatchVisualInfo(display, screen, depth, TrueColor, &visual_info); visual = visual_info.visual; } #endif RMask = visual->red_mask; GMask = visual->green_mask; BMask = visual->blue_mask; /* GRR: add/check 8-bit support */ if (depth == 8 || need_colormap) { colormap = XCreateColormap(display, root, visual, AllocNone); if (!colormap) { fprintf(stderr, "XCreateColormap() failed\n"); return 2; } have_colormap = TRUE; } if (depth == 15 || depth == 16) { RShift = 15 - rpng_x_msb(RMask); /* these are right-shifts */ GShift = 15 - rpng_x_msb(GMask); BShift = 15 - rpng_x_msb(BMask); } else if (depth > 16) { #define NO_24BIT_MASKS #ifdef NO_24BIT_MASKS RShift = rpng_x_msb(RMask) - 7; /* these are left-shifts */ GShift = rpng_x_msb(GMask) - 7; BShift = rpng_x_msb(BMask) - 7; #else RShift = 7 - rpng_x_msb(RMask); /* these are right-shifts, too */ GShift = 7 - rpng_x_msb(GMask); BShift = 7 - rpng_x_msb(BMask); #endif } if (depth >= 15 && (RShift < 0 || GShift < 0 || BShift < 0)) { fprintf(stderr, "rpng internal logic error: negative X shift(s)!\n"); return 2; } /*--------------------------------------------------------------------------- Finally, create the window. ---------------------------------------------------------------------------*/ attr.backing_store = Always; attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask; attrmask = CWBackingStore | CWEventMask; if (have_nondefault_visual) { attr.colormap = colormap; attr.background_pixel = 0; attr.border_pixel = 1; attrmask |= CWColormap | CWBackPixel | CWBorderPixel; } window = XCreateWindow(display, root, 0, 0, image_width, image_height, 0, depth, InputOutput, visual, attrmask, &attr); if (window == None) { fprintf(stderr, "XCreateWindow() failed\n"); return 2; } else have_window = TRUE; if (depth == 8) XSetWindowColormap(display, window, colormap); if (!XStringListToTextProperty(&window_name, 1, pWindowName)) pWindowName = NULL; if (!XStringListToTextProperty(&icon_name, 1, pIconName)) pIconName = NULL; /* OK if any hints allocation fails; XSetWMProperties() allows NULLs */ if ((size_hints = XAllocSizeHints()) != NULL) { /* window will not be resizable */ size_hints->flags = PMinSize | PMaxSize; size_hints->min_width = size_hints->max_width = (int)image_width; size_hints->min_height = size_hints->max_height = (int)image_height; } if ((wm_hints = XAllocWMHints()) != NULL) { wm_hints->initial_state = NormalState; wm_hints->input = True; /* wm_hints->icon_pixmap = icon_pixmap; */ wm_hints->flags = StateHint | InputHint /* | IconPixmapHint */ ; } if ((class_hints = XAllocClassHint()) != NULL) { class_hints->res_name = res_name; class_hints->res_class = res_class; } XSetWMProperties(display, window, pWindowName, pIconName, NULL, 0, size_hints, wm_hints, class_hints); /* various properties and hints no longer needed; free memory */ if (pWindowName) XFree(pWindowName->value); if (pIconName) XFree(pIconName->value); if (size_hints) XFree(size_hints); if (wm_hints) XFree(wm_hints); if (class_hints) XFree(class_hints); XMapWindow(display, window); gc = XCreateGC(display, window, 0, &gcvalues); have_gc = TRUE; /*--------------------------------------------------------------------------- Fill window with the specified background color. ---------------------------------------------------------------------------*/ if (depth == 24 || depth == 32) { bg_pixel = ((ulg)bg_red << RShift) | ((ulg)bg_green << GShift) | ((ulg)bg_blue << BShift); } else if (depth == 16) { bg_pixel = ((((ulg)bg_red << 8) >> RShift) & RMask) | ((((ulg)bg_green << 8) >> GShift) & GMask) | ((((ulg)bg_blue << 8) >> BShift) & BMask); } else /* depth == 8 */ { /* GRR: add 8-bit support */ } XSetForeground(display, gc, bg_pixel); XFillRectangle(display, window, gc, 0, 0, image_width, image_height); /*--------------------------------------------------------------------------- Wait for first Expose event to do any drawing, then flush. ---------------------------------------------------------------------------*/ do XNextEvent(display, &e); while (e.type != Expose || e.xexpose.count); XFlush(display); /*--------------------------------------------------------------------------- Allocate memory for the X- and display-specific version of the image. ---------------------------------------------------------------------------*/ if (depth == 24 || depth == 32) { xdata = (uch *)malloc(4*image_width*image_height); pad = 32; } else if (depth == 16) { xdata = (uch *)malloc(2*image_width*image_height); pad = 16; } else /* depth == 8 */ { xdata = (uch *)malloc(image_width*image_height); pad = 8; } if (!xdata) { fprintf(stderr, PROGNAME ": unable to allocate image memory\n"); return 4; } ximage = XCreateImage(display, visual, depth, ZPixmap, 0, (char *)xdata, image_width, image_height, pad, 0); if (!ximage) { fprintf(stderr, PROGNAME ": XCreateImage() failed\n"); free(xdata); return 3; } /* to avoid testing the byte order every pixel (or doubling the size of * the drawing routine with a giant if-test), we arbitrarily set the byte * order to MSBFirst and let Xlib worry about inverting things on little- * endian machines (like Linux/x86, old VAXen, etc.)--this is not the most * efficient approach (the giant if-test would be better), but in the * interest of clarity, we take the easy way out... */ ximage->byte_order = MSBFirst; return 0; } /* end function rpng_x_create_window() */ static int rpng_x_display_image(void) { uch *src; char *dest; uch r, g, b, a; ulg i, row, lastrow = 0; ulg pixel; int ximage_rowbytes = ximage->bytes_per_line; /* int bpp = ximage->bits_per_pixel; */ Trace((stderr, "beginning display loop (image_channels == %d)\n", image_channels)) Trace((stderr, " (width = %ld, rowbytes = %ld, ximage_rowbytes = %d)\n", image_width, image_rowbytes, ximage_rowbytes)) Trace((stderr, " (bpp = %d)\n", ximage->bits_per_pixel)) Trace((stderr, " (byte_order = %s)\n", ximage->byte_order == MSBFirst? "MSBFirst" : (ximage->byte_order == LSBFirst? "LSBFirst" : "unknown"))) if (depth == 24 || depth == 32) { ulg red, green, blue; for (lastrow = row = 0; row < image_height; ++row) { src = image_data + row*image_rowbytes; dest = ximage->data + row*ximage_rowbytes; if (image_channels == 3) { for (i = image_width; i > 0; --i) { red = *src++; green = *src++; blue = *src++; #ifdef NO_24BIT_MASKS pixel = (red << RShift) | (green << GShift) | (blue << BShift); /* recall that we set ximage->byte_order = MSBFirst above */ /* GRR BUG: this assumes bpp == 32, but may be 24: */ *dest++ = (char)((pixel >> 24) & 0xff); *dest++ = (char)((pixel >> 16) & 0xff); *dest++ = (char)((pixel >> 8) & 0xff); *dest++ = (char)( pixel & 0xff); #else red = (RShift < 0)? red << (-RShift) : red >> RShift; green = (GShift < 0)? green << (-GShift) : green >> GShift; blue = (BShift < 0)? blue << (-BShift) : blue >> BShift; pixel = (red & RMask) | (green & GMask) | (blue & BMask); /* recall that we set ximage->byte_order = MSBFirst above */ *dest++ = (char)((pixel >> 24) & 0xff); *dest++ = (char)((pixel >> 16) & 0xff); *dest++ = (char)((pixel >> 8) & 0xff); *dest++ = (char)( pixel & 0xff); #endif } } else /* if (image_channels == 4) */ { for (i = image_width; i > 0; --i) { r = *src++; g = *src++; b = *src++; a = *src++; if (a == 255) { red = r; green = g; blue = b; } else if (a == 0) { red = bg_red; green = bg_green; blue = bg_blue; } else { /* this macro (from png.h) composites the foreground * and background values and puts the result into the * first argument */ alpha_composite(red, r, a, bg_red); alpha_composite(green, g, a, bg_green); alpha_composite(blue, b, a, bg_blue); } pixel = (red << RShift) | (green << GShift) | (blue << BShift); /* recall that we set ximage->byte_order = MSBFirst above */ *dest++ = (char)((pixel >> 24) & 0xff); *dest++ = (char)((pixel >> 16) & 0xff); *dest++ = (char)((pixel >> 8) & 0xff); *dest++ = (char)( pixel & 0xff); } } /* display after every 16 lines */ if (((row+1) & 0xf) == 0) { XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0, (int)lastrow, image_width, 16); XFlush(display); lastrow = row + 1; } } } else if (depth == 16) { ush red, green, blue; for (lastrow = row = 0; row < image_height; ++row) { src = image_data + row*image_rowbytes; dest = ximage->data + row*ximage_rowbytes; if (image_channels == 3) { for (i = image_width; i > 0; --i) { red = ((ush)(*src) << 8); ++src; green = ((ush)(*src) << 8); ++src; blue = ((ush)(*src) << 8); ++src; pixel = ((red >> RShift) & RMask) | ((green >> GShift) & GMask) | ((blue >> BShift) & BMask); /* recall that we set ximage->byte_order = MSBFirst above */ *dest++ = (char)((pixel >> 8) & 0xff); *dest++ = (char)( pixel & 0xff); } } else /* if (image_channels == 4) */ { for (i = image_width; i > 0; --i) { r = *src++; g = *src++; b = *src++; a = *src++; if (a == 255) { red = ((ush)r << 8); green = ((ush)g << 8); blue = ((ush)b << 8); } else if (a == 0) { red = ((ush)bg_red << 8); green = ((ush)bg_green << 8); blue = ((ush)bg_blue << 8); } else { /* this macro (from png.h) composites the foreground * and background values and puts the result back into * the first argument (== fg byte here: safe) */ alpha_composite(r, r, a, bg_red); alpha_composite(g, g, a, bg_green); alpha_composite(b, b, a, bg_blue); red = ((ush)r << 8); green = ((ush)g << 8); blue = ((ush)b << 8); } pixel = ((red >> RShift) & RMask) | ((green >> GShift) & GMask) | ((blue >> BShift) & BMask); /* recall that we set ximage->byte_order = MSBFirst above */ *dest++ = (char)((pixel >> 8) & 0xff); *dest++ = (char)( pixel & 0xff); } } /* display after every 16 lines */ if (((row+1) & 0xf) == 0) { XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0, (int)lastrow, image_width, 16); XFlush(display); lastrow = row + 1; } } } else /* depth == 8 */ { /* GRR: add 8-bit support */ } Trace((stderr, "calling final XPutImage()\n")) if (lastrow < image_height) { XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0, (int)lastrow, image_width, image_height-lastrow); XFlush(display); } return 0; } static void rpng_x_cleanup(void) { if (image_data) { free(image_data); image_data = NULL; } if (ximage) { if (ximage->data) { free(ximage->data); /* we allocated it, so we free it */ ximage->data = (char *)NULL; /* instead of XDestroyImage() */ } XDestroyImage(ximage); ximage = NULL; } if (have_gc) XFreeGC(display, gc); if (have_window) XDestroyWindow(display, window); if (have_colormap) XFreeColormap(display, colormap); if (have_nondefault_visual) XFree(visual_list); } static int rpng_x_msb(ulg u32val) { int i; for (i = 31; i >= 0; --i) { if (u32val & 0x80000000L) break; u32val <<= 1; } return i; } libpng-1.6.43/contrib/gregbook/rpng2-win.c000066400000000000000000001311421456606525400203250ustar00rootroot00000000000000/*--------------------------------------------------------------------------- rpng2 - progressive-model PNG display program rpng2-win.c This program decodes and displays PNG files progressively, as if it were a web browser (though the front end is only set up to read from files). It supports gamma correction, user-specified background colors, and user- specified background patterns (for transparent images). This version is for 32-bit Windows; it may compile under 16-bit Windows with a little tweaking (or maybe not). Thanks to Adam Costello and Pieter S. van der Meulen for the "diamond" and "radial waves" patterns, respectively. to do (someday, maybe): - handle quoted command-line args (especially filenames with spaces) - finish resizable checkerboard-gradient (sizes 4-128?) - use %.1023s to simplify truncation of title-bar string? - have minimum window width: oh well --------------------------------------------------------------------------- Changelog: - 1.01: initial public release - 1.02: fixed cut-and-paste error in usage screen (oops...) - 1.03: modified to allow abbreviated options - 1.04: removed bogus extra argument from usage fprintf() [Glenn R-P?]; fixed command-line parsing bug - 1.10: enabled "message window"/console (thanks to David Geldreich) - 1.20: added runtime MMX-enabling/disabling and new -mmx* options - 1.21: made minor tweak to usage screen to fit within 25-line console - 1.22: added AMD64/EM64T support (__x86_64__) - 2.00: dual-licensed (added GNU GPL) - 2.01: fixed 64-bit typo in readpng2.c - 2.02: fixed improper display of usage screen on PNG error(s); fixed unexpected-EOF and file-read-error cases - 2.03: removed runtime MMX-enabling/disabling and obsolete -mmx* options - 2.04: check for integer overflow (Glenn R-P) --------------------------------------------------------------------------- Copyright (c) 1998-2008, 2017 Greg Roelofs. All rights reserved. This software is provided "as is," without warranty of any kind, express or implied. In no event shall the author or contributors be held liable for any damages arising in any way from the use of this software. The contents of this file are DUAL-LICENSED. You may modify and/or redistribute this software according to the terms of one of the following two licenses (at your option): LICENSE 1 ("BSD-like with advertising clause"): Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. Redistributions of source code must retain the above copyright notice, disclaimer, and this list of conditions. 2. Redistributions in binary form must reproduce the above copyright notice, disclaimer, and this list of conditions in the documenta- tion and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgment: This product includes software developed by Greg Roelofs and contributors for the book, "PNG: The Definitive Guide," published by O'Reilly and Associates. LICENSE 2 (GNU GPL v2 or later): This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ---------------------------------------------------------------------------*/ #define PROGNAME "rpng2-win" #define LONGNAME "Progressive PNG Viewer for Windows" #define VERSION "2.02 of 16 March 2008" #include #include #include #include /* for jmpbuf declaration in readpng2.h */ #include #include /* only for PvdM background code */ #include #ifdef __CYGWIN__ /* getch replacement. Turns out, we don't really need this, * but leave it here if we ever enable any of the uses of * _getch in the main code */ #include #include #include int repl_getch( void ) { char ch; int fd = fileno(stdin); struct termio old_tty, new_tty; ioctl(fd, TCGETA, &old_tty); new_tty = old_tty; new_tty.c_lflag &= ~(ICANON | ECHO | ISIG); ioctl(fd, TCSETA, &new_tty); fread(&ch, 1, sizeof(ch), stdin); ioctl(fd, TCSETA, &old_tty); return ch; } #define _getch repl_getch #else #include /* only for _getch() */ #endif /* all for PvdM background code: */ #ifndef PI # define PI 3.141592653589793238 #endif #define PI_2 (PI*0.5) #define INV_PI_360 (360.0 / PI) #define MAX(a,b) (a>b?a:b) #define MIN(a,b) (a> 8)) >> 8); \ } #define INBUFSIZE 4096 /* with pseudo-timing on (1 sec delay/block), this * block size corresponds roughly to a download * speed 10% faster than theoretical 33.6K maximum * (assuming 8 data bits, 1 stop bit and no other * overhead) */ /* local prototypes */ static void rpng2_win_init(void); static int rpng2_win_create_window(void); static int rpng2_win_load_bg_image(void); static void rpng2_win_display_row(ulg row); static void rpng2_win_finish_display(void); static void rpng2_win_cleanup(void); LRESULT CALLBACK rpng2_win_wndproc(HWND, UINT, WPARAM, LPARAM); static char titlebar[1024]; static char *progname = PROGNAME; static char *appname = LONGNAME; static char *filename; static FILE *infile; static mainprog_info rpng2_info; static uch inbuf[INBUFSIZE]; static int incount; static int pat = 6; /* must be less than num_bgpat */ static int bg_image = 0; static int bgscale = 16; static ulg bg_rowbytes; static uch *bg_data; static struct rgb_color { uch r, g, b; } rgb[] = { { 0, 0, 0}, /* 0: black */ {255, 255, 255}, /* 1: white */ {173, 132, 57}, /* 2: tan */ { 64, 132, 0}, /* 3: medium green */ {189, 117, 1}, /* 4: gold */ {253, 249, 1}, /* 5: yellow */ { 0, 0, 255}, /* 6: blue */ { 0, 0, 120}, /* 7: medium blue */ {255, 0, 255}, /* 8: magenta */ { 64, 0, 64}, /* 9: dark magenta */ {255, 0, 0}, /* 10: red */ { 64, 0, 0}, /* 11: dark red */ {255, 127, 0}, /* 12: orange */ {192, 96, 0}, /* 13: darker orange */ { 24, 60, 0}, /* 14: dark green-yellow */ { 85, 125, 200} /* 15: ice blue */ }; /* not used for now, but should be for error-checking: static int num_rgb = sizeof(rgb) / sizeof(struct rgb_color); */ /* This whole struct is a fairly cheesy way to keep the number of command-line options to a minimum. The radial-waves background type is a particularly poor fit to the integer elements of the struct...but a few macros and a little fixed-point math will do wonders for ya. type bits: F E D C B A 9 8 7 6 5 4 3 2 1 0 | | | | | | | +-+-+-- 0 = sharp-edged checkerboard | | 1 = soft diamonds | | 2 = radial waves | | 3-7 = undefined | +-- gradient #2 inverted? +-- alternating columns inverted? */ static struct background_pattern { ush type; int rgb1_max, rgb1_min; /* or bg_freq, bg_gray */ int rgb2_max, rgb2_min; /* or bg_bsat, bg_brot (both scaled by 10)*/ } bg[] = { {0+8, 2,0, 1,15}, /* checkered: tan/black vs. white/ice blue */ {0+24, 2,0, 1,0}, /* checkered: tan/black vs. white/black */ {0+8, 4,5, 0,2}, /* checkered: gold/yellow vs. black/tan */ {0+8, 4,5, 0,6}, /* checkered: gold/yellow vs. black/blue */ {0, 7,0, 8,9}, /* checkered: deep blue/black vs. magenta */ {0+8, 13,0, 5,14}, /* checkered: orange/black vs. yellow */ {0+8, 12,0, 10,11}, /* checkered: orange/black vs. red */ {1, 7,0, 8,0}, /* diamonds: deep blue/black vs. magenta */ {1, 12,0, 11,0}, /* diamonds: orange vs. dark red */ {1, 10,0, 7,0}, /* diamonds: red vs. medium blue */ {1, 4,0, 5,0}, /* diamonds: gold vs. yellow */ {1, 3,0, 0,0}, /* diamonds: medium green vs. black */ {2, 16, 100, 20, 0}, /* radial: ~hard radial color-beams */ {2, 18, 100, 10, 2}, /* radial: soft, curved radial color-beams */ {2, 16, 256, 100, 250}, /* radial: very tight spiral */ {2, 10000, 256, 11, 0} /* radial: dipole-moire' (almost fractal) */ }; static int num_bgpat = sizeof(bg) / sizeof(struct background_pattern); /* Windows-specific global variables (could go in struct, but messy...) */ static ulg wimage_rowbytes; static uch *dib; static uch *wimage_data; static BITMAPINFOHEADER *bmih; static HWND global_hwnd; static HINSTANCE global_hInst; static int global_showmode; int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, PSTR cmd, int showmode) { char *args[1024]; /* arbitrary limit, but should suffice */ char **argv = args; char *p, *q, *bgstr = NULL; int argc = 0; int rc, alen, flen; int error = 0; int timing = FALSE; int have_bg = FALSE; double LUT_exponent; /* just the lookup table */ double CRT_exponent = 2.2; /* just the monitor */ double default_display_exponent; /* whole display system */ MSG msg; /* First initialize a few things, just to be sure--memset takes care of * default background color (black), booleans (FALSE), pointers (NULL), * etc. */ global_hInst = hInst; global_showmode = showmode; filename = (char *)NULL; memset(&rpng2_info, 0, sizeof(mainprog_info)); #ifndef __CYGWIN__ /* Next reenable console output, which normally goes to the bit bucket * for windowed apps. Closing the console window will terminate the * app. Thanks to David.Geldreich at realviz.com for supplying the magical * incantation. */ AllocConsole(); freopen("CONOUT$", "a", stderr); freopen("CONOUT$", "a", stdout); #endif /* Set the default value for our display-system exponent, i.e., the * product of the CRT exponent and the exponent corresponding to * the frame-buffer's lookup table (LUT), if any. This is not an * exhaustive list of LUT values (e.g., OpenStep has a lot of weird * ones), but it should cover 99% of the current possibilities. And * yes, these ifdefs are completely wasted in a Windows program... */ #if defined(NeXT) /* third-party utilities can modify the default LUT exponent */ LUT_exponent = 1.0 / 2.2; /* if (some_next_function_that_returns_gamma(&next_gamma)) LUT_exponent = 1.0 / next_gamma; */ #elif defined(sgi) LUT_exponent = 1.0 / 1.7; /* there doesn't seem to be any documented function to * get the "gamma" value, so we do it the hard way */ infile = fopen("/etc/config/system.glGammaVal", "r"); if (infile) { double sgi_gamma; fgets(tmpline, 80, infile); fclose(infile); sgi_gamma = atof(tmpline); if (sgi_gamma > 0.0) LUT_exponent = 1.0 / sgi_gamma; } #elif defined(Macintosh) LUT_exponent = 1.8 / 2.61; /* if (some_mac_function_that_returns_gamma(&mac_gamma)) LUT_exponent = mac_gamma / 2.61; */ #else LUT_exponent = 1.0; /* assume no LUT: most PCs */ #endif /* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */ default_display_exponent = LUT_exponent * CRT_exponent; /* If the user has set the SCREEN_GAMMA environment variable as suggested * (somewhat imprecisely) in the libpng documentation, use that; otherwise * use the default value we just calculated. Either way, the user may * override this via a command-line option. */ if ((p = getenv("SCREEN_GAMMA")) != NULL) rpng2_info.display_exponent = atof(p); else rpng2_info.display_exponent = default_display_exponent; /* Windows really hates command lines, so we have to set up our own argv. * Note that we do NOT bother with quoted arguments here, so don't use * filenames with spaces in 'em! */ argv[argc++] = PROGNAME; p = cmd; for (;;) { if (*p == ' ') while (*++p == ' ') ; /* now p points at the first non-space after some spaces */ if (*p == '\0') break; /* nothing after the spaces: done */ argv[argc++] = q = p; while (*q && *q != ' ') ++q; /* now q points at a space or the end of the string */ if (*q == '\0') break; /* last argv already terminated; quit */ *q = '\0'; /* change space to terminator */ p = q + 1; } argv[argc] = NULL; /* terminate the argv array itself */ /* Now parse the command line for options and the PNG filename. */ while (*++argv && !error) { if (!strncmp(*argv, "-gamma", 2)) { if (!*++argv) ++error; else { rpng2_info.display_exponent = atof(*argv); if (rpng2_info.display_exponent <= 0.0) ++error; } } else if (!strncmp(*argv, "-bgcolor", 4)) { if (!*++argv) ++error; else { bgstr = *argv; if (strlen(bgstr) != 7 || bgstr[0] != '#') ++error; else { have_bg = TRUE; bg_image = FALSE; } } } else if (!strncmp(*argv, "-bgpat", 4)) { if (!*++argv) ++error; else { pat = atoi(*argv) - 1; if (pat < 0 || pat >= num_bgpat) ++error; else { bg_image = TRUE; have_bg = FALSE; } } } else if (!strncmp(*argv, "-timing", 2)) { timing = TRUE; } else { if (**argv != '-') { filename = *argv; if (argv[1]) /* shouldn't be any more args after filename */ ++error; } else ++error; /* not expecting any other options */ } } if (!filename) ++error; /* print usage screen if any errors up to this point */ if (error) { #ifndef __CYGWIN__ int ch; #endif fprintf(stderr, "\n%s %s: %s\n\n", PROGNAME, VERSION, appname); readpng2_version_info(); fprintf(stderr, "\n" "Usage: %s [-gamma exp] [-bgcolor bg | -bgpat pat] [-timing]\n" " %*s file.png\n\n" " exp \ttransfer-function exponent (``gamma'') of the display\n" "\t\t system in floating-point format (e.g., ``%.1f''); equal\n" "\t\t to the product of the lookup-table exponent (varies)\n" "\t\t and the CRT exponent (usually 2.2); must be positive\n" " bg \tdesired background color in 7-character hex RGB format\n" "\t\t (e.g., ``#ff7700'' for orange: same as HTML colors);\n" "\t\t used with transparent images; overrides -bgpat option\n" " pat \tdesired background pattern number (1-%d); used with\n" "\t\t transparent images; overrides -bgcolor option\n" " -timing\tenables delay for every block read, to simulate modem\n" "\t\t download of image (~36 Kbps)\n" "\nPress Q, Esc or mouse button 1 after image is displayed to quit.\n" #ifndef __CYGWIN__ "Press Q or Esc to quit this usage screen. ", #else , #endif PROGNAME, #if (defined(__i386__) || defined(_M_IX86) || defined(__x86_64__)) && \ !(defined(__CYGWIN__) || defined(__MINGW32__)) (int)strlen(PROGNAME), " ", #endif (int)strlen(PROGNAME), " ", default_display_exponent, num_bgpat); fflush(stderr); #ifndef __CYGWIN__ do ch = _getch(); while (ch != 'q' && ch != 'Q' && ch != 0x1B); #endif exit(1); } if (!(infile = fopen(filename, "rb"))) { fprintf(stderr, PROGNAME ": can't open PNG file [%s]\n", filename); ++error; } else { incount = fread(inbuf, 1, INBUFSIZE, infile); if (incount < 8 || !readpng2_check_sig(inbuf, 8)) { fprintf(stderr, PROGNAME ": [%s] is not a PNG file: incorrect signature\n", filename); ++error; } else if ((rc = readpng2_init(&rpng2_info)) != 0) { switch (rc) { case 2: fprintf(stderr, PROGNAME ": [%s] has bad IHDR (libpng longjmp)\n", filename); break; case 4: fprintf(stderr, PROGNAME ": insufficient memory\n"); break; default: fprintf(stderr, PROGNAME ": unknown readpng2_init() error\n"); break; } ++error; } if (error) fclose(infile); } if (error) { #ifndef __CYGWIN__ int ch; #endif fprintf(stderr, PROGNAME ": aborting.\n"); #ifndef __CYGWIN__ do ch = _getch(); while (ch != 'q' && ch != 'Q' && ch != 0x1B); #endif exit(2); } else { fprintf(stderr, "\n%s %s: %s\n", PROGNAME, VERSION, appname); #ifndef __CYGWIN__ fprintf(stderr, "\n [console window: closing this window will terminate %s]\n\n", PROGNAME); #endif fflush(stderr); } /* set the title-bar string, but make sure buffer doesn't overflow */ alen = strlen(appname); flen = strlen(filename); if (alen + flen + 3 > 1023) sprintf(titlebar, "%s: ...%s", appname, filename+(alen+flen+6-1023)); else sprintf(titlebar, "%s: %s", appname, filename); /* set some final rpng2_info variables before entering main data loop */ if (have_bg) { unsigned r, g, b; /* this approach quiets compiler warnings */ sscanf(bgstr+1, "%2x%2x%2x", &r, &g, &b); rpng2_info.bg_red = (uch)r; rpng2_info.bg_green = (uch)g; rpng2_info.bg_blue = (uch)b; } else rpng2_info.need_bgcolor = TRUE; rpng2_info.state = kPreInit; rpng2_info.mainprog_init = rpng2_win_init; rpng2_info.mainprog_display_row = rpng2_win_display_row; rpng2_info.mainprog_finish_display = rpng2_win_finish_display; /* OK, this is the fun part: call readpng2_decode_data() at the start of * the loop to deal with our first buffer of data (read in above to verify * that the file is a PNG image), then loop through the file and continue * calling the same routine to handle each chunk of data. It in turn * passes the data to libpng, which will invoke one or more of our call- * backs as decoded data become available. We optionally call Sleep() for * one second per iteration to simulate downloading the image via an analog * modem. */ for (;;) { Trace((stderr, "about to call readpng2_decode_data()\n")) if (readpng2_decode_data(&rpng2_info, inbuf, incount)) ++error; Trace((stderr, "done with readpng2_decode_data()\n")) if (error || incount != INBUFSIZE || rpng2_info.state == kDone) { if (rpng2_info.state == kDone) { Trace((stderr, "done decoding PNG image\n")) } else if (ferror(infile)) { fprintf(stderr, PROGNAME ": error while reading PNG image file\n"); exit(3); } else if (feof(infile)) { fprintf(stderr, PROGNAME ": end of file reached " "(unexpectedly) while reading PNG image file\n"); exit(3); } else /* if (error) */ { /* will print error message below */ } break; } if (timing) Sleep(1000L); incount = fread(inbuf, 1, INBUFSIZE, infile); } /* clean up PNG stuff and report any decoding errors */ fclose(infile); Trace((stderr, "about to call readpng2_cleanup()\n")) readpng2_cleanup(&rpng2_info); if (error) { fprintf(stderr, PROGNAME ": libpng error while decoding PNG image\n"); exit(3); } /* wait for the user to tell us when to quit */ while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } /* we're done: clean up all image and Windows resources and go away */ Trace((stderr, "about to call rpng2_win_cleanup()\n")) rpng2_win_cleanup(); return msg.wParam; } /* this function is called by readpng2_info_callback() in readpng2.c, which * in turn is called by libpng after all of the pre-IDAT chunks have been * read and processed--i.e., we now have enough info to finish initializing */ static void rpng2_win_init() { ulg i; ulg rowbytes = rpng2_info.rowbytes; Trace((stderr, "beginning rpng2_win_init()\n")) Trace((stderr, " rowbytes = %d\n", rpng2_info.rowbytes)) Trace((stderr, " width = %ld\n", rpng2_info.width)) Trace((stderr, " height = %ld\n", rpng2_info.height)) /* Guard against integer overflow */ if (rpng2_info.height > ((size_t)(-1))/rowbytes) { fprintf(stderr, PROGNAME ": image_data buffer would be too large\n", readpng2_cleanup(&rpng2_info); return; } rpng2_info.image_data = (uch *)malloc(rowbytes * rpng2_info.height); if (!rpng2_info.image_data) { readpng2_cleanup(&rpng2_info); return; } rpng2_info.row_pointers = (uch **)malloc(rpng2_info.height * sizeof(uch *)); if (!rpng2_info.row_pointers) { free(rpng2_info.image_data); rpng2_info.image_data = NULL; readpng2_cleanup(&rpng2_info); return; } for (i = 0; i < rpng2_info.height; ++i) rpng2_info.row_pointers[i] = rpng2_info.image_data + i*rowbytes; /*--------------------------------------------------------------------------- Do the basic Windows initialization stuff, make the window, and fill it with the user-specified, file-specified or default background color. ---------------------------------------------------------------------------*/ if (rpng2_win_create_window()) { readpng2_cleanup(&rpng2_info); return; } rpng2_info.state = kWindowInit; } static int rpng2_win_create_window() { uch bg_red = rpng2_info.bg_red; uch bg_green = rpng2_info.bg_green; uch bg_blue = rpng2_info.bg_blue; uch *dest; int extra_width, extra_height; ulg i, j; WNDCLASSEX wndclass; RECT rect; /*--------------------------------------------------------------------------- Allocate memory for the display-specific version of the image (round up to multiple of 4 for Windows DIB). ---------------------------------------------------------------------------*/ wimage_rowbytes = ((3*rpng2_info.width + 3L) >> 2) << 2; if (!(dib = (uch *)malloc(sizeof(BITMAPINFOHEADER) + wimage_rowbytes*rpng2_info.height))) { return 4; /* fail */ } /*--------------------------------------------------------------------------- Initialize the DIB. Negative height means to use top-down BMP ordering (must be uncompressed, but that's what we want). Bit count of 1, 4 or 8 implies a colormap of RGBX quads, but 24-bit BMPs just use B,G,R values directly => wimage_data begins immediately after BMP header. ---------------------------------------------------------------------------*/ memset(dib, 0, sizeof(BITMAPINFOHEADER)); bmih = (BITMAPINFOHEADER *)dib; bmih->biSize = sizeof(BITMAPINFOHEADER); bmih->biWidth = rpng2_info.width; bmih->biHeight = -((long)rpng2_info.height); bmih->biPlanes = 1; bmih->biBitCount = 24; bmih->biCompression = 0; wimage_data = dib + sizeof(BITMAPINFOHEADER); /*--------------------------------------------------------------------------- Fill window with the specified background color (default is black), but defer loading faked "background image" until window is displayed (may be slow to compute). Data are in BGR order. ---------------------------------------------------------------------------*/ if (bg_image) { /* just fill with black for now */ memset(wimage_data, 0, wimage_rowbytes*rpng2_info.height); } else { for (j = 0; j < rpng2_info.height; ++j) { dest = wimage_data + j*wimage_rowbytes; for (i = rpng2_info.width; i > 0; --i) { *dest++ = bg_blue; *dest++ = bg_green; *dest++ = bg_red; } } } /*--------------------------------------------------------------------------- Set the window parameters. ---------------------------------------------------------------------------*/ memset(&wndclass, 0, sizeof(wndclass)); wndclass.cbSize = sizeof(wndclass); wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = rpng2_win_wndproc; wndclass.hInstance = global_hInst; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(DKGRAY_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = progname; wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); RegisterClassEx(&wndclass); /*--------------------------------------------------------------------------- Finally, create the window. ---------------------------------------------------------------------------*/ extra_width = 2*(GetSystemMetrics(SM_CXBORDER) + GetSystemMetrics(SM_CXDLGFRAME)); extra_height = 2*(GetSystemMetrics(SM_CYBORDER) + GetSystemMetrics(SM_CYDLGFRAME)) + GetSystemMetrics(SM_CYCAPTION); global_hwnd = CreateWindow(progname, titlebar, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rpng2_info.width+extra_width, rpng2_info.height+extra_height, NULL, NULL, global_hInst, NULL); ShowWindow(global_hwnd, global_showmode); UpdateWindow(global_hwnd); /*--------------------------------------------------------------------------- Now compute the background image and display it. If it fails (memory allocation), revert to a plain background color. ---------------------------------------------------------------------------*/ if (bg_image) { static const char *msg = "Computing background image..."; int x, y, len = strlen(msg); HDC hdc = GetDC(global_hwnd); TEXTMETRIC tm; GetTextMetrics(hdc, &tm); x = (rpng2_info.width - len*tm.tmAveCharWidth)/2; y = (rpng2_info.height - tm.tmHeight)/2; SetBkMode(hdc, TRANSPARENT); SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT)); /* this can still begin out of bounds even if x is positive (???): */ TextOut(hdc, ((x < 0)? 0 : x), ((y < 0)? 0 : y), msg, len); ReleaseDC(global_hwnd, hdc); rpng2_win_load_bg_image(); /* resets bg_image if fails */ } if (!bg_image) { for (j = 0; j < rpng2_info.height; ++j) { dest = wimage_data + j*wimage_rowbytes; for (i = rpng2_info.width; i > 0; --i) { *dest++ = bg_blue; *dest++ = bg_green; *dest++ = bg_red; } } } rect.left = 0L; rect.top = 0L; rect.right = (LONG)rpng2_info.width; /* possibly off by one? */ rect.bottom = (LONG)rpng2_info.height; /* possibly off by one? */ InvalidateRect(global_hwnd, &rect, FALSE); UpdateWindow(global_hwnd); /* similar to XFlush() */ return 0; } /* end function rpng2_win_create_window() */ static int rpng2_win_load_bg_image() { uch *src, *dest; uch r1, r2, g1, g2, b1, b2; uch r1_inv, r2_inv, g1_inv, g2_inv, b1_inv, b2_inv; int k, hmax, max; int xidx, yidx, yidx_max = (bgscale-1); int even_odd_vert, even_odd_horiz, even_odd; int invert_gradient2 = (bg[pat].type & 0x08); int invert_column; ulg i, row; /*--------------------------------------------------------------------------- Allocate buffer for fake background image to be used with transparent images; if this fails, revert to plain background color. ---------------------------------------------------------------------------*/ bg_rowbytes = 3 * rpng2_info.width; bg_data = (uch *)malloc(bg_rowbytes * rpng2_info.height); if (!bg_data) { fprintf(stderr, PROGNAME ": unable to allocate memory for background image\n"); bg_image = 0; return 1; } /*--------------------------------------------------------------------------- Vertical gradients (ramps) in NxN squares, alternating direction and colors (N == bgscale). ---------------------------------------------------------------------------*/ if ((bg[pat].type & 0x07) == 0) { uch r1_min = rgb[bg[pat].rgb1_min].r; uch g1_min = rgb[bg[pat].rgb1_min].g; uch b1_min = rgb[bg[pat].rgb1_min].b; uch r2_min = rgb[bg[pat].rgb2_min].r; uch g2_min = rgb[bg[pat].rgb2_min].g; uch b2_min = rgb[bg[pat].rgb2_min].b; int r1_diff = rgb[bg[pat].rgb1_max].r - r1_min; int g1_diff = rgb[bg[pat].rgb1_max].g - g1_min; int b1_diff = rgb[bg[pat].rgb1_max].b - b1_min; int r2_diff = rgb[bg[pat].rgb2_max].r - r2_min; int g2_diff = rgb[bg[pat].rgb2_max].g - g2_min; int b2_diff = rgb[bg[pat].rgb2_max].b - b2_min; for (row = 0; row < rpng2_info.height; ++row) { yidx = row % bgscale; even_odd_vert = (row / bgscale) & 1; r1 = r1_min + (r1_diff * yidx) / yidx_max; g1 = g1_min + (g1_diff * yidx) / yidx_max; b1 = b1_min + (b1_diff * yidx) / yidx_max; r1_inv = r1_min + (r1_diff * (yidx_max-yidx)) / yidx_max; g1_inv = g1_min + (g1_diff * (yidx_max-yidx)) / yidx_max; b1_inv = b1_min + (b1_diff * (yidx_max-yidx)) / yidx_max; r2 = r2_min + (r2_diff * yidx) / yidx_max; g2 = g2_min + (g2_diff * yidx) / yidx_max; b2 = b2_min + (b2_diff * yidx) / yidx_max; r2_inv = r2_min + (r2_diff * (yidx_max-yidx)) / yidx_max; g2_inv = g2_min + (g2_diff * (yidx_max-yidx)) / yidx_max; b2_inv = b2_min + (b2_diff * (yidx_max-yidx)) / yidx_max; dest = bg_data + row*bg_rowbytes; for (i = 0; i < rpng2_info.width; ++i) { even_odd_horiz = (i / bgscale) & 1; even_odd = even_odd_vert ^ even_odd_horiz; invert_column = (even_odd_horiz && (bg[pat].type & 0x10)); if (even_odd == 0) { /* gradient #1 */ if (invert_column) { *dest++ = r1_inv; *dest++ = g1_inv; *dest++ = b1_inv; } else { *dest++ = r1; *dest++ = g1; *dest++ = b1; } } else { /* gradient #2 */ if ((invert_column && invert_gradient2) || (!invert_column && !invert_gradient2)) { *dest++ = r2; /* not inverted or */ *dest++ = g2; /* doubly inverted */ *dest++ = b2; } else { *dest++ = r2_inv; *dest++ = g2_inv; /* singly inverted */ *dest++ = b2_inv; } } } } /*--------------------------------------------------------------------------- Soft gradient-diamonds with scale = bgscale. Code contributed by Adam M. Costello. ---------------------------------------------------------------------------*/ } else if ((bg[pat].type & 0x07) == 1) { hmax = (bgscale-1)/2; /* half the max weight of a color */ max = 2*hmax; /* the max weight of a color */ r1 = rgb[bg[pat].rgb1_max].r; g1 = rgb[bg[pat].rgb1_max].g; b1 = rgb[bg[pat].rgb1_max].b; r2 = rgb[bg[pat].rgb2_max].r; g2 = rgb[bg[pat].rgb2_max].g; b2 = rgb[bg[pat].rgb2_max].b; for (row = 0; row < rpng2_info.height; ++row) { yidx = row % bgscale; if (yidx > hmax) yidx = bgscale-1 - yidx; dest = bg_data + row*bg_rowbytes; for (i = 0; i < rpng2_info.width; ++i) { xidx = i % bgscale; if (xidx > hmax) xidx = bgscale-1 - xidx; k = xidx + yidx; *dest++ = (k*r1 + (max-k)*r2) / max; *dest++ = (k*g1 + (max-k)*g2) / max; *dest++ = (k*b1 + (max-k)*b2) / max; } } /*--------------------------------------------------------------------------- Radial "starburst" with azimuthal sinusoids; [eventually number of sinu- soids will equal bgscale?]. This one is slow but very cool. Code con- tributed by Pieter S. van der Meulen (originally in Smalltalk). ---------------------------------------------------------------------------*/ } else if ((bg[pat].type & 0x07) == 2) { uch ch; int ii, x, y, hw, hh, grayspot; double freq, rotate, saturate, gray, intensity; double angle=0.0, aoffset=0.0, maxDist, dist; double red=0.0, green=0.0, blue=0.0, hue, s, v, f, p, q, t; fprintf(stderr, "%s: computing radial background...", PROGNAME); fflush(stderr); hh = rpng2_info.height / 2; hw = rpng2_info.width / 2; /* variables for radial waves: * aoffset: number of degrees to rotate hue [CURRENTLY NOT USED] * freq: number of color beams originating from the center * grayspot: size of the graying center area (anti-alias) * rotate: rotation of the beams as a function of radius * saturate: saturation of beams' shape azimuthally */ angle = CLIP(angle, 0.0, 360.0); grayspot = CLIP(bg[pat].bg_gray, 1, (hh + hw)); freq = MAX((double)bg[pat].bg_freq, 0.0); saturate = (double)bg[pat].bg_bsat * 0.1; rotate = (double)bg[pat].bg_brot * 0.1; gray = 0.0; intensity = 0.0; maxDist = (double)((hw*hw) + (hh*hh)); for (row = 0; row < rpng2_info.height; ++row) { y = row - hh; dest = bg_data + row*bg_rowbytes; for (i = 0; i < rpng2_info.width; ++i) { x = i - hw; angle = (x == 0)? PI_2 : atan((double)y / (double)x); gray = (double)MAX(ABS(y), ABS(x)) / grayspot; gray = MIN(1.0, gray); dist = (double)((x*x) + (y*y)) / maxDist; intensity = cos((angle+(rotate*dist*PI)) * freq) * gray * saturate; intensity = (MAX(MIN(intensity,1.0),-1.0) + 1.0) * 0.5; hue = (angle + PI) * INV_PI_360 + aoffset; s = gray * ((double)(ABS(x)+ABS(y)) / (double)(hw + hh)); s = MIN(MAX(s,0.0), 1.0); v = MIN(MAX(intensity,0.0), 1.0); if (s == 0.0) { ch = (uch)(v * 255.0); *dest++ = ch; *dest++ = ch; *dest++ = ch; } else { if ((hue < 0.0) || (hue >= 360.0)) hue -= (((int)(hue / 360.0)) * 360.0); hue /= 60.0; ii = (int)hue; f = hue - (double)ii; p = (1.0 - s) * v; q = (1.0 - (s * f)) * v; t = (1.0 - (s * (1.0 - f))) * v; if (ii == 0) { red = v; green = t; blue = p; } else if (ii == 1) { red = q; green = v; blue = p; } else if (ii == 2) { red = p; green = v; blue = t; } else if (ii == 3) { red = p; green = q; blue = v; } else if (ii == 4) { red = t; green = p; blue = v; } else if (ii == 5) { red = v; green = p; blue = q; } *dest++ = (uch)(red * 255.0); *dest++ = (uch)(green * 255.0); *dest++ = (uch)(blue * 255.0); } } } fprintf(stderr, "done.\n"); fflush(stderr); } /*--------------------------------------------------------------------------- Blast background image to display buffer before beginning PNG decode; calling function will handle invalidation and UpdateWindow() call. ---------------------------------------------------------------------------*/ for (row = 0; row < rpng2_info.height; ++row) { src = bg_data + row*bg_rowbytes; dest = wimage_data + row*wimage_rowbytes; for (i = rpng2_info.width; i > 0; --i) { r1 = *src++; g1 = *src++; b1 = *src++; *dest++ = b1; *dest++ = g1; /* note reverse order */ *dest++ = r1; } } return 0; } /* end function rpng2_win_load_bg_image() */ static void rpng2_win_display_row(ulg row) { uch bg_red = rpng2_info.bg_red; uch bg_green = rpng2_info.bg_green; uch bg_blue = rpng2_info.bg_blue; uch *src, *src2=NULL, *dest; uch r, g, b, a; ulg i; static int rows=0; static ulg firstrow; /*--------------------------------------------------------------------------- rows and firstrow simply track how many rows (and which ones) have not yet been displayed; alternatively, we could call InvalidateRect() for every row and not bother with the records-keeping. ---------------------------------------------------------------------------*/ Trace((stderr, "beginning rpng2_win_display_row()\n")) if (rows == 0) firstrow = row; /* first row not yet displayed */ ++rows; /* count of rows received but not yet displayed */ /*--------------------------------------------------------------------------- Aside from the use of the rpng2_info struct and the lack of an outer loop (over rows), this routine is identical to rpng_win_display_image() in the non-progressive version of the program. ---------------------------------------------------------------------------*/ src = rpng2_info.image_data + row*rpng2_info.rowbytes; if (bg_image) src2 = bg_data + row*bg_rowbytes; dest = wimage_data + row*wimage_rowbytes; if (rpng2_info.channels == 3) { for (i = rpng2_info.width; i > 0; --i) { r = *src++; g = *src++; b = *src++; *dest++ = b; *dest++ = g; /* note reverse order */ *dest++ = r; } } else /* if (rpng2_info.channels == 4) */ { for (i = rpng2_info.width; i > 0; --i) { r = *src++; g = *src++; b = *src++; a = *src++; if (bg_image) { bg_red = *src2++; bg_green = *src2++; bg_blue = *src2++; } if (a == 255) { *dest++ = b; *dest++ = g; *dest++ = r; } else if (a == 0) { *dest++ = bg_blue; *dest++ = bg_green; *dest++ = bg_red; } else { /* this macro (copied from png.h) composites the * foreground and background values and puts the * result into the first argument; there are no * side effects with the first argument */ alpha_composite(*dest++, b, a, bg_blue); alpha_composite(*dest++, g, a, bg_green); alpha_composite(*dest++, r, a, bg_red); } } } /*--------------------------------------------------------------------------- Display after every 16 rows or when on last row. (Region may include previously displayed lines due to interlacing--i.e., not contiguous.) ---------------------------------------------------------------------------*/ if ((rows & 0xf) == 0 || row == rpng2_info.height-1) { RECT rect; rect.left = 0L; rect.top = (LONG)firstrow; rect.right = (LONG)rpng2_info.width; /* possibly off by one? */ rect.bottom = (LONG)row + 1L; /* possibly off by one? */ InvalidateRect(global_hwnd, &rect, FALSE); UpdateWindow(global_hwnd); /* similar to XFlush() */ rows = 0; } } /* end function rpng2_win_display_row() */ static void rpng2_win_finish_display() { Trace((stderr, "beginning rpng2_win_finish_display()\n")) /* last row has already been displayed by rpng2_win_display_row(), so * we have nothing to do here except set a flag and let the user know * that the image is done */ rpng2_info.state = kDone; printf( #ifndef __CYGWIN__ "Done. Press Q, Esc or mouse button 1 (within image window) to quit.\n" #else "Done. Press mouse button 1 (within image window) to quit.\n" #endif ); fflush(stdout); } static void rpng2_win_cleanup() { if (bg_image && bg_data) { free(bg_data); bg_data = NULL; } if (rpng2_info.image_data) { free(rpng2_info.image_data); rpng2_info.image_data = NULL; } if (rpng2_info.row_pointers) { free(rpng2_info.row_pointers); rpng2_info.row_pointers = NULL; } if (dib) { free(dib); dib = NULL; } } LRESULT CALLBACK rpng2_win_wndproc(HWND hwnd, UINT iMsg, WPARAM wP, LPARAM lP) { HDC hdc; PAINTSTRUCT ps; int rc; switch (iMsg) { case WM_CREATE: /* one-time processing here, if any */ return 0; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); rc = StretchDIBits(hdc, 0, 0, rpng2_info.width, rpng2_info.height, 0, 0, rpng2_info.width, rpng2_info.height, wimage_data, (BITMAPINFO *)bmih, 0, SRCCOPY); EndPaint(hwnd, &ps); return 0; /* wait for the user to tell us when to quit */ case WM_CHAR: switch (wP) { /* only need one, so ignore repeat count */ case 'q': case 'Q': case 0x1B: /* Esc key */ PostQuitMessage(0); } return 0; case WM_LBUTTONDOWN: /* another way of quitting */ case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, iMsg, wP, lP); } libpng-1.6.43/contrib/gregbook/rpng2-x.c000066400000000000000000002407611456606525400200070ustar00rootroot00000000000000/*--------------------------------------------------------------------------- rpng2 - progressive-model PNG display program rpng2-x.c This program decodes and displays PNG files progressively, as if it were a web browser (though the front end is only set up to read from files). It supports gamma correction, user-specified background colors, and user- specified background patterns (for transparent images). This version is for the X Window System (tested by the author under Unix and by Martin Zinser under OpenVMS; may work under OS/2 with a little tweaking). Thanks to Adam Costello and Pieter S. van der Meulen for the "diamond" and "radial waves" patterns, respectively. to do (someday, maybe): - fix expose/redraw code: don't draw entire row if only part exposed - 8-bit (colormapped) X support - finish resizable checkerboard-gradient (sizes 4-128?) - use %.1023s to simplify truncation of title-bar string? --------------------------------------------------------------------------- Changelog: - 1.01: initial public release - 1.02: modified to allow abbreviated options; fixed char/uchar mismatch - 1.10: added support for non-default visuals; fixed X pixel-conversion - 1.11: added -usleep option for demos; fixed command-line parsing bug - 1.12: added -pause option for demos and testing - 1.20: added runtime MMX-enabling/disabling and new -mmx* options - 1.21: fixed some small X memory leaks (thanks to François Petitjean) - 1.22: fixed XFreeGC() crash bug (thanks to Patrick Welche) - 1.23: added -bgpat 0 mode (std white/gray checkerboard, 8x8 squares) - 1.30: added -loop option for -bgpat (ifdef FEATURE_LOOP); fixed bpp = 24; added support for X resources (thanks to Gerhard Niklasch) - 1.31: added code to skip unused chunks (thanks to Glenn Randers-Pehrson) - 1.32: added AMD64/EM64T support (__x86_64__); added basic expose/redraw handling - 2.00: dual-licensed (added GNU GPL) - 2.01: fixed 64-bit typo in readpng2.c; fixed -pause usage description - 2.02: fixed improper display of usage screen on PNG error(s); fixed unexpected-EOF and file-read-error cases; fixed Trace() cut-and- paste bugs - 2.03: deleted runtime MMX-enabling/disabling and obsolete -mmx* options - 2.04: Added "void(foo);" statements to quiet pedantic compiler warnings about unused variables (GR-P) - 2.05: Use nanosleep() instead of usleep(), which is deprecated (GR-P). - 2.06: check for integer overflow (Glenn R-P) --------------------------------------------------------------------------- Copyright (c) 1998-2010, 2014-2015, 2017 Greg Roelofs. All rights reserved. This software is provided "as is," without warranty of any kind, express or implied. In no event shall the author or contributors be held liable for any damages arising in any way from the use of this software. The contents of this file are DUAL-LICENSED. You may modify and/or redistribute this software according to the terms of one of the following two licenses (at your option): LICENSE 1 ("BSD-like with advertising clause"): Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. Redistributions of source code must retain the above copyright notice, disclaimer, and this list of conditions. 2. Redistributions in binary form must reproduce the above copyright notice, disclaimer, and this list of conditions in the documenta- tion and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgment: This product includes software developed by Greg Roelofs and contributors for the book, "PNG: The Definitive Guide," published by O'Reilly and Associates. LICENSE 2 (GNU GPL v2 or later): This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ---------------------------------------------------------------------------*/ #define PROGNAME "rpng2-x" #define LONGNAME "Progressive PNG Viewer for X" #define VERSION "2.04 of 15 June 2014" #define RESNAME "rpng2" /* our X resource application name */ #define RESCLASS "Rpng" /* our X resource class name */ #include #include #include #include #include /* for jmpbuf declaration in readpng2.h */ #include #include /* only for PvdM background code */ #include #include #include #include /* defines XK_* macros */ #if _POSIX_C_SOURCE >= 199309L /* have nanosleep() */ # undef usleep # define usleep(usec) { \ struct timespec ts; \ ts.tv_sec = 0; \ ts.tv_nsec = (usec) * 1000; \ nanosleep(&ts, NULL); } # endif #ifndef usleep /* have neither nanosleep() nor usleep() */ # define usleep(x) sleep(((x)+499999)/1000000) #endif #ifdef VMS # include #endif /* all for PvdM background code: */ #ifndef PI # define PI 3.141592653589793238 #endif #define PI_2 (PI*0.5) #define INV_PI_360 (360.0 / PI) #define MAX(a,b) (a>b?a:b) #define MIN(a,b) (a> 8)) >> 8); \ } #define INBUFSIZE 4096 /* with pseudo-timing on (1 sec delay/block), this * block size corresponds roughly to a download * speed 10% faster than theoretical 33.6K maximum * (assuming 8 data bits, 1 stop bit and no other * overhead) */ /* local prototypes */ static void rpng2_x_init (void); static int rpng2_x_create_window (void); static int rpng2_x_load_bg_image (void); static void rpng2_x_display_row (ulg row); static void rpng2_x_finish_display (void); static void rpng2_x_redisplay_image (ulg startcol, ulg startrow, ulg width, ulg height); #ifdef FEATURE_LOOP static void rpng2_x_reload_bg_image (void); static int is_number (char *p); #endif static void rpng2_x_cleanup (void); static int rpng2_x_msb (ulg u32val); static char titlebar[1024], *window_name = titlebar; static char *appname = LONGNAME; static char *icon_name = PROGNAME; static char *res_name = RESNAME; static char *res_class = RESCLASS; static char *filename; static FILE *infile; static mainprog_info rpng2_info; static uch inbuf[INBUFSIZE]; static int incount; static int pat = 6; /* must be less than num_bgpat */ static int bg_image = 0; static int bgscale, bgscale_default = 16; static ulg bg_rowbytes; static uch *bg_data; int pause_after_pass = FALSE; int demo_timing = FALSE; ulg usleep_duration = 0L; static struct rgb_color { uch r, g, b; } rgb[] = { { 0, 0, 0}, /* 0: black */ {255, 255, 255}, /* 1: white */ {173, 132, 57}, /* 2: tan */ { 64, 132, 0}, /* 3: medium green */ {189, 117, 1}, /* 4: gold */ {253, 249, 1}, /* 5: yellow */ { 0, 0, 255}, /* 6: blue */ { 0, 0, 120}, /* 7: medium blue */ {255, 0, 255}, /* 8: magenta */ { 64, 0, 64}, /* 9: dark magenta */ {255, 0, 0}, /* 10: red */ { 64, 0, 0}, /* 11: dark red */ {255, 127, 0}, /* 12: orange */ {192, 96, 0}, /* 13: darker orange */ { 24, 60, 0}, /* 14: dark green-yellow */ { 85, 125, 200}, /* 15: ice blue */ {192, 192, 192} /* 16: Netscape/Mosaic gray */ }; /* not used for now, but should be for error-checking: static int num_rgb = sizeof(rgb) / sizeof(struct rgb_color); */ /* This whole struct is a fairly cheesy way to keep the number of command-line options to a minimum. The radial-waves background type is a particularly poor fit to the integer elements of the struct...but a few macros and a little fixed-point math will do wonders for ya. type bits: F E D C B A 9 8 7 6 5 4 3 2 1 0 | | | | | | | +-+-+-- 0 = sharp-edged checkerboard | | 1 = soft diamonds | | 2 = radial waves | | 3-7 = undefined | +-- gradient #2 inverted? +-- alternating columns inverted? */ static struct background_pattern { ush type; int rgb1_max, rgb1_min; /* or bg_freq, bg_gray */ int rgb2_max, rgb2_min; /* or bg_bsat, bg_brot (both scaled by 10)*/ } bg[] = { {0, 1,1, 16,16}, /* checkered: white vs. light gray (basic) */ {0+8, 2,0, 1,15}, /* checkered: tan/black vs. white/ice blue */ {0+24, 2,0, 1,0}, /* checkered: tan/black vs. white/black */ {0+8, 4,5, 0,2}, /* checkered: gold/yellow vs. black/tan */ {0+8, 4,5, 0,6}, /* checkered: gold/yellow vs. black/blue */ {0, 7,0, 8,9}, /* checkered: deep blue/black vs. magenta */ {0+8, 13,0, 5,14}, /* checkered: orange/black vs. yellow */ {0+8, 12,0, 10,11}, /* checkered: orange/black vs. red */ {1, 7,0, 8,0}, /* diamonds: deep blue/black vs. magenta */ {1, 12,0, 11,0}, /* diamonds: orange vs. dark red */ {1, 10,0, 7,0}, /* diamonds: red vs. medium blue */ {1, 4,0, 5,0}, /* diamonds: gold vs. yellow */ {1, 3,0, 0,0}, /* diamonds: medium green vs. black */ {2, 16, 100, 20, 0}, /* radial: ~hard radial color-beams */ {2, 18, 100, 10, 2}, /* radial: soft, curved radial color-beams */ {2, 16, 256, 100, 250}, /* radial: very tight spiral */ {2, 10000, 256, 11, 0} /* radial: dipole-moire' (almost fractal) */ }; static int num_bgpat = sizeof(bg) / sizeof(struct background_pattern); /* X-specific variables */ static char *displayname; static XImage *ximage; static Display *display; static int depth; static Visual *visual; static XVisualInfo *visual_list; static int RShift, GShift, BShift; static ulg RMask, GMask, BMask; static Window window; static GC gc; static Colormap colormap; static int have_nondefault_visual = FALSE; static int have_colormap = FALSE; static int have_window = FALSE; static int have_gc = FALSE; int main(int argc, char **argv) { #ifdef sgi char tmpline[80]; #endif char *p, *bgstr = NULL; int rc, alen, flen; int error = 0; int timing = FALSE; int have_bg = FALSE; #ifdef FEATURE_LOOP int loop = FALSE; long loop_interval = -1; /* seconds (100,000 max) */ #endif double LUT_exponent; /* just the lookup table */ double CRT_exponent = 2.2; /* just the monitor */ double default_display_exponent; /* whole display system */ XEvent e; KeySym k; /* First initialize a few things, just to be sure--memset takes care of * default background color (black), booleans (FALSE), pointers (NULL), * etc. */ displayname = (char *)NULL; filename = (char *)NULL; memset(&rpng2_info, 0, sizeof(mainprog_info)); /* Set the default value for our display-system exponent, i.e., the * product of the CRT exponent and the exponent corresponding to * the frame-buffer's lookup table (LUT), if any. This is not an * exhaustive list of LUT values (e.g., OpenStep has a lot of weird * ones), but it should cover 99% of the current possibilities. */ #if defined(NeXT) /* third-party utilities can modify the default LUT exponent */ LUT_exponent = 1.0 / 2.2; /* if (some_next_function_that_returns_gamma(&next_gamma)) LUT_exponent = 1.0 / next_gamma; */ #elif defined(sgi) LUT_exponent = 1.0 / 1.7; /* there doesn't seem to be any documented function to * get the "gamma" value, so we do it the hard way */ infile = fopen("/etc/config/system.glGammaVal", "r"); if (infile) { double sgi_gamma; fgets(tmpline, 80, infile); fclose(infile); sgi_gamma = atof(tmpline); if (sgi_gamma > 0.0) LUT_exponent = 1.0 / sgi_gamma; } #elif defined(Macintosh) LUT_exponent = 1.8 / 2.61; /* if (some_mac_function_that_returns_gamma(&mac_gamma)) LUT_exponent = mac_gamma / 2.61; */ #else LUT_exponent = 1.0; /* assume no LUT: most PCs */ #endif /* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */ default_display_exponent = LUT_exponent * CRT_exponent; /* If the user has set the SCREEN_GAMMA environment variable as suggested * (somewhat imprecisely) in the libpng documentation, use that; otherwise * use the default value we just calculated. Either way, the user may * override this via a command-line option. */ if ((p = getenv("SCREEN_GAMMA")) != NULL) rpng2_info.display_exponent = atof(p); else rpng2_info.display_exponent = default_display_exponent; /* Now parse the command line for options and the PNG filename. */ while (*++argv && !error) { if (!strncmp(*argv, "-display", 2)) { if (!*++argv) ++error; else displayname = *argv; } else if (!strncmp(*argv, "-gamma", 2)) { if (!*++argv) ++error; else { rpng2_info.display_exponent = atof(*argv); if (rpng2_info.display_exponent <= 0.0) ++error; } } else if (!strncmp(*argv, "-bgcolor", 4)) { if (!*++argv) ++error; else { bgstr = *argv; if (strlen(bgstr) != 7 || bgstr[0] != '#') ++error; else { have_bg = TRUE; bg_image = FALSE; } } } else if (!strncmp(*argv, "-bgpat", 4)) { if (!*++argv) ++error; else { pat = atoi(*argv); if (pat >= 0 && pat < num_bgpat) { bg_image = TRUE; have_bg = FALSE; } else ++error; } } else if (!strncmp(*argv, "-usleep", 2)) { if (!*++argv) ++error; else { usleep_duration = (ulg)atol(*argv); demo_timing = TRUE; } } else if (!strncmp(*argv, "-pause", 2)) { pause_after_pass = TRUE; } else if (!strncmp(*argv, "-timing", 2)) { timing = TRUE; #ifdef FEATURE_LOOP } else if (!strncmp(*argv, "-loop", 2)) { loop = TRUE; if (!argv[1] || !is_number(argv[1])) loop_interval = 2; else { ++argv; loop_interval = atol(*argv); if (loop_interval < 0) loop_interval = 2; else if (loop_interval > 100000) /* bit more than one day */ loop_interval = 100000; } #endif } else { if (**argv != '-') { filename = *argv; if (argv[1]) /* shouldn't be any more args after filename */ ++error; } else ++error; /* not expecting any other options */ } } if (!filename) ++error; /* print usage screen if any errors up to this point */ if (error) { fprintf(stderr, "\n%s %s: %s\n\n", PROGNAME, VERSION, appname); readpng2_version_info(); fprintf(stderr, "\n" "Usage: "); fprintf(stderr, "%s [-display xdpy] [-gamma exp] [-bgcolor bg | -bgpat pat]\n" " %*s [-usleep dur | -timing] [-pause]\n", PROGNAME, (int)strlen(PROGNAME), " "); fprintf(stderr, #ifdef FEATURE_LOOP " [-loop [sec]]" #endif " file.png\n\n"); fprintf(stderr, " xdpy\tname of the target X display (e.g., ``hostname:0'')\n" " exp \ttransfer-function exponent (``gamma'') of the display\n" "\t\t system in floating-point format (e.g., ``%.1f''); equal\n" "\t\t to the product of the lookup-table exponent (varies)\n", default_display_exponent); fprintf(stderr, "\t\t and the CRT exponent (usually 2.2); must be positive\n" " bg \tdesired background color in 7-character hex RGB format\n" "\t\t (e.g., ``#ff7700'' for orange: same as HTML colors);\n" "\t\t used with transparent images; overrides -bgpat\n" " pat \tdesired background pattern number (0-%d); used with\n" "\t\t transparent images; overrides -bgcolor\n", num_bgpat-1); #ifdef FEATURE_LOOP fprintf(stderr, " -loop\tloops through background images after initial display\n" "\t\t is complete (depends on -bgpat)\n" " sec \tseconds to display each background image (default = 2)\n"); #endif fprintf(stderr, " dur \tduration in microseconds to wait after displaying each\n" "\t\t row (for demo purposes)\n" " -timing\tenables delay for every block read, to simulate modem\n" "\t\t download of image (~36 Kbps)\n" " -pause\tpauses after displaying each pass until mouse clicked\n" "\nPress Q, Esc or mouse button 1 (within image window, after image\n" "is displayed) to quit.\n"); exit(1); } if (!(infile = fopen(filename, "rb"))) { fprintf(stderr, PROGNAME ": can't open PNG file [%s]\n", filename); ++error; } else { incount = fread(inbuf, 1, INBUFSIZE, infile); if (incount < 8 || !readpng2_check_sig(inbuf, 8)) { fprintf(stderr, PROGNAME ": [%s] is not a PNG file: incorrect signature\n", filename); ++error; } else if ((rc = readpng2_init(&rpng2_info)) != 0) { switch (rc) { case 2: fprintf(stderr, PROGNAME ": [%s] has bad IHDR (libpng longjmp)\n", filename); break; case 4: fprintf(stderr, PROGNAME ": insufficient memory\n"); break; default: fprintf(stderr, PROGNAME ": unknown readpng2_init() error\n"); break; } ++error; } else { Trace((stderr, "about to call XOpenDisplay()\n")) display = XOpenDisplay(displayname); if (!display) { readpng2_cleanup(&rpng2_info); fprintf(stderr, PROGNAME ": can't open X display [%s]\n", displayname? displayname : "default"); ++error; } } if (error) fclose(infile); } if (error) { fprintf(stderr, PROGNAME ": aborting.\n"); exit(2); } /* set the title-bar string, but make sure buffer doesn't overflow */ alen = strlen(appname); flen = strlen(filename); if (alen + flen + 3 > 1023) sprintf(titlebar, "%s: ...%s", appname, filename+(alen+flen+6-1023)); else sprintf(titlebar, "%s: %s", appname, filename); /* set some final rpng2_info variables before entering main data loop */ if (have_bg) { unsigned r, g, b; /* this approach quiets compiler warnings */ sscanf(bgstr+1, "%2x%2x%2x", &r, &g, &b); rpng2_info.bg_red = (uch)r; rpng2_info.bg_green = (uch)g; rpng2_info.bg_blue = (uch)b; } else rpng2_info.need_bgcolor = TRUE; rpng2_info.state = kPreInit; rpng2_info.mainprog_init = rpng2_x_init; rpng2_info.mainprog_display_row = rpng2_x_display_row; rpng2_info.mainprog_finish_display = rpng2_x_finish_display; /* OK, this is the fun part: call readpng2_decode_data() at the start of * the loop to deal with our first buffer of data (read in above to verify * that the file is a PNG image), then loop through the file and continue * calling the same routine to handle each chunk of data. It in turn * passes the data to libpng, which will invoke one or more of our call- * backs as decoded data become available. We optionally call sleep() for * one second per iteration to simulate downloading the image via an analog * modem. */ for (;;) { Trace((stderr, "about to call readpng2_decode_data()\n")) if (readpng2_decode_data(&rpng2_info, inbuf, incount)) ++error; Trace((stderr, "done with readpng2_decode_data()\n")) if (error || incount != INBUFSIZE || rpng2_info.state == kDone) { if (rpng2_info.state == kDone) { Trace((stderr, "done decoding PNG image\n")) } else if (ferror(infile)) { fprintf(stderr, PROGNAME ": error while reading PNG image file\n"); exit(3); } else if (feof(infile)) { fprintf(stderr, PROGNAME ": end of file reached " "(unexpectedly) while reading PNG image file\n"); exit(3); } else /* if (error) */ { /* will print error message below */ } break; } if (timing) sleep(1); incount = fread(inbuf, 1, INBUFSIZE, infile); } /* clean up PNG stuff and report any decoding errors */ fclose(infile); Trace((stderr, "about to call readpng2_cleanup()\n")) readpng2_cleanup(&rpng2_info); if (error) { fprintf(stderr, PROGNAME ": libpng error while decoding PNG image\n"); exit(3); } #ifdef FEATURE_LOOP if (loop && bg_image) { Trace((stderr, "entering -loop loop (FEATURE_LOOP)\n")) for (;;) { int i, use_sleep; struct timeval now, then; /* get current time and add loop_interval to get target time */ if (gettimeofday(&then, NULL) == 0) { then.tv_sec += loop_interval; use_sleep = FALSE; } else use_sleep = TRUE; /* do quick check for a quit event but don't wait for it */ /* GRR BUG: should also check for Expose events and redraw... */ if (XCheckMaskEvent(display, KeyPressMask | ButtonPressMask, &e)) if (QUIT(e,k)) break; /* generate next background image */ if (++pat >= num_bgpat) pat = 0; rpng2_x_reload_bg_image(); /* wait for timeout, using whatever means are available */ if (use_sleep || gettimeofday(&now, NULL) != 0) { for (i = loop_interval; i > 0; --i) { sleep(1); /* GRR BUG: also need to check for Expose (and redraw!) */ if (XCheckMaskEvent(display, KeyPressMask | ButtonPressMask, &e) && QUIT(e,k)) break; } } else { /* Y2038 BUG! */ if (now.tv_sec < then.tv_sec || (now.tv_sec == then.tv_sec && now.tv_usec < then.tv_usec)) { int quit = FALSE; long seconds_to_go = then.tv_sec - now.tv_sec; long usleep_usec; /* basically chew up most of remaining loop-interval with * calls to sleep(1) interleaved with checks for quit * events, but also recalc time-to-go periodically; when * done, clean up any remaining time with usleep() call * (could also use SIGALRM, but signals are a pain...) */ while (seconds_to_go-- > 1) { int seconds_done = 0; for (i = seconds_to_go; i > 0 && !quit; --i) { sleep(1); /* GRR BUG: need to check for Expose and redraw */ if (XCheckMaskEvent(display, KeyPressMask | ButtonPressMask, &e) && QUIT(e,k)) quit = TRUE; if (++seconds_done > 1000) break; /* time to redo seconds_to_go meas. */ } if (quit) break; /* OK, more than 1000 seconds since last check: * correct the time-to-go measurement for drift */ if (gettimeofday(&now, NULL) == 0) { if (now.tv_sec >= then.tv_sec) break; seconds_to_go = then.tv_sec - now.tv_sec; } else ++seconds_to_go; /* restore what we subtracted */ } if (quit) break; /* breaks outer do-loop, skips redisplay */ /* since difference between "now" and "then" is already * eaten up to within a couple of seconds, don't need to * worry about overflow--but might have overshot (neg.) */ if (gettimeofday(&now, NULL) == 0) { usleep_usec = 1000000L*(then.tv_sec - now.tv_sec) + then.tv_usec - now.tv_usec; if (usleep_usec > 0) usleep((ulg)usleep_usec); } } } /* composite image against new background and display (note that * we do not take into account the time spent doing this...) */ rpng2_x_redisplay_image (0, 0, rpng2_info.width, rpng2_info.height); } } else /* FALL THROUGH and do the normal thing */ #endif /* FEATURE_LOOP */ /* wait for the user to tell us when to quit */ if (rpng2_info.state >= kWindowInit) { Trace((stderr, "entering final wait-for-quit-event loop\n")) do { XNextEvent(display, &e); if (e.type == Expose) { XExposeEvent *ex = (XExposeEvent *)&e; rpng2_x_redisplay_image (ex->x, ex->y, ex->width, ex->height); } } while (!QUIT(e,k)); } else { fprintf(stderr, PROGNAME ": init callback never called: probable " "libpng error while decoding PNG metadata\n"); exit(4); } /* we're done: clean up all image and X resources and go away */ Trace((stderr, "about to call rpng2_x_cleanup()\n")) rpng2_x_cleanup(); (void)argc; /* Unused */ return 0; } /* this function is called by readpng2_info_callback() in readpng2.c, which * in turn is called by libpng after all of the pre-IDAT chunks have been * read and processed--i.e., we now have enough info to finish initializing */ static void rpng2_x_init(void) { ulg i; ulg rowbytes = rpng2_info.rowbytes; Trace((stderr, "beginning rpng2_x_init()\n")) Trace((stderr, " rowbytes = %d\n", rpng2_info.rowbytes)) Trace((stderr, " width = %ld\n", rpng2_info.width)) Trace((stderr, " height = %ld\n", rpng2_info.height)) /* Guard against integer overflow */ if (rpng2_info.height > ((size_t)(-1))/rpng2_info.rowbytes) { fprintf(stderr, PROGNAME ": image_data buffer would be too large\n"); readpng2_cleanup(&rpng2_info); return; } rpng2_info.image_data = (uch *)malloc(rowbytes * rpng2_info.height); if (!rpng2_info.image_data) { readpng2_cleanup(&rpng2_info); return; } rpng2_info.row_pointers = (uch **)malloc(rpng2_info.height * sizeof(uch *)); if (!rpng2_info.row_pointers) { free(rpng2_info.image_data); rpng2_info.image_data = NULL; readpng2_cleanup(&rpng2_info); return; } for (i = 0; i < rpng2_info.height; ++i) rpng2_info.row_pointers[i] = rpng2_info.image_data + i*rowbytes; /* do the basic X initialization stuff, make the window, and fill it with * the user-specified, file-specified or default background color or * pattern */ if (rpng2_x_create_window()) { /* GRR TEMPORARY HACK: this is fundamentally no different from cases * above; libpng should call our error handler to longjmp() back to us * when png_ptr goes away. If we/it segfault instead, seems like a * libpng bug... */ /* we're here via libpng callback, so if window fails, clean and bail */ readpng2_cleanup(&rpng2_info); rpng2_x_cleanup(); exit(2); } rpng2_info.state = kWindowInit; } static int rpng2_x_create_window(void) { ulg bg_red = rpng2_info.bg_red; ulg bg_green = rpng2_info.bg_green; ulg bg_blue = rpng2_info.bg_blue; ulg bg_pixel = 0L; ulg attrmask; int need_colormap = FALSE; int screen, pad; uch *xdata; Window root; XEvent e; XGCValues gcvalues; XSetWindowAttributes attr; XTextProperty windowName, *pWindowName = &windowName; XTextProperty iconName, *pIconName = &iconName; XVisualInfo visual_info; XSizeHints *size_hints; XWMHints *wm_hints; XClassHint *class_hints; Trace((stderr, "beginning rpng2_x_create_window()\n")) screen = DefaultScreen(display); depth = DisplayPlanes(display, screen); root = RootWindow(display, screen); #ifdef DEBUG XSynchronize(display, True); #endif if (depth != 16 && depth != 24 && depth != 32) { int visuals_matched = 0; Trace((stderr, "default depth is %d: checking other visuals\n", depth)) /* 24-bit first */ visual_info.screen = screen; visual_info.depth = 24; visual_list = XGetVisualInfo(display, VisualScreenMask | VisualDepthMask, &visual_info, &visuals_matched); if (visuals_matched == 0) { /* GRR: add 15-, 16- and 32-bit TrueColor visuals (also DirectColor?) */ fprintf(stderr, "default screen depth %d not supported, and no" " 24-bit visuals found\n", depth); return 2; } Trace((stderr, "XGetVisualInfo() returned %d 24-bit visuals\n", visuals_matched)) visual = visual_list[0].visual; depth = visual_list[0].depth; /* colormap_size = visual_list[0].colormap_size; visual_class = visual->class; visualID = XVisualIDFromVisual(visual); */ have_nondefault_visual = TRUE; need_colormap = TRUE; } else { XMatchVisualInfo(display, screen, depth, TrueColor, &visual_info); visual = visual_info.visual; } RMask = visual->red_mask; GMask = visual->green_mask; BMask = visual->blue_mask; /* GRR: add/check 8-bit support */ if (depth == 8 || need_colormap) { colormap = XCreateColormap(display, root, visual, AllocNone); if (!colormap) { fprintf(stderr, "XCreateColormap() failed\n"); return 2; } have_colormap = TRUE; if (depth == 8) bg_image = FALSE; /* gradient just wastes palette entries */ } if (depth == 15 || depth == 16) { RShift = 15 - rpng2_x_msb(RMask); /* these are right-shifts */ GShift = 15 - rpng2_x_msb(GMask); BShift = 15 - rpng2_x_msb(BMask); } else if (depth > 16) { RShift = rpng2_x_msb(RMask) - 7; /* these are left-shifts */ GShift = rpng2_x_msb(GMask) - 7; BShift = rpng2_x_msb(BMask) - 7; } if (depth >= 15 && (RShift < 0 || GShift < 0 || BShift < 0)) { fprintf(stderr, "rpng2 internal logic error: negative X shift(s)!\n"); return 2; } /*--------------------------------------------------------------------------- Finally, create the window. ---------------------------------------------------------------------------*/ attr.backing_store = Always; attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask; attrmask = CWBackingStore | CWEventMask; if (have_nondefault_visual) { attr.colormap = colormap; attr.background_pixel = 0; attr.border_pixel = 1; attrmask |= CWColormap | CWBackPixel | CWBorderPixel; } window = XCreateWindow(display, root, 0, 0, rpng2_info.width, rpng2_info.height, 0, depth, InputOutput, visual, attrmask, &attr); if (window == None) { fprintf(stderr, "XCreateWindow() failed\n"); return 2; } else have_window = TRUE; if (depth == 8) XSetWindowColormap(display, window, colormap); if (!XStringListToTextProperty(&window_name, 1, pWindowName)) pWindowName = NULL; if (!XStringListToTextProperty(&icon_name, 1, pIconName)) pIconName = NULL; /* OK if either hints allocation fails; XSetWMProperties() allows NULLs */ if ((size_hints = XAllocSizeHints()) != NULL) { /* window will not be resizable */ size_hints->flags = PMinSize | PMaxSize; size_hints->min_width = size_hints->max_width = (int)rpng2_info.width; size_hints->min_height = size_hints->max_height = (int)rpng2_info.height; } if ((wm_hints = XAllocWMHints()) != NULL) { wm_hints->initial_state = NormalState; wm_hints->input = True; /* wm_hints->icon_pixmap = icon_pixmap; */ wm_hints->flags = StateHint | InputHint /* | IconPixmapHint */ ; } if ((class_hints = XAllocClassHint()) != NULL) { class_hints->res_name = res_name; class_hints->res_class = res_class; } XSetWMProperties(display, window, pWindowName, pIconName, NULL, 0, size_hints, wm_hints, class_hints); /* various properties and hints no longer needed; free memory */ if (pWindowName) XFree(pWindowName->value); if (pIconName) XFree(pIconName->value); if (size_hints) XFree(size_hints); if (wm_hints) XFree(wm_hints); if (class_hints) XFree(class_hints); XMapWindow(display, window); gc = XCreateGC(display, window, 0, &gcvalues); have_gc = TRUE; /*--------------------------------------------------------------------------- Allocate memory for the X- and display-specific version of the image. ---------------------------------------------------------------------------*/ if (depth == 24 || depth == 32) { xdata = (uch *)malloc(4*rpng2_info.width*rpng2_info.height); pad = 32; } else if (depth == 16) { xdata = (uch *)malloc(2*rpng2_info.width*rpng2_info.height); pad = 16; } else /* depth == 8 */ { xdata = (uch *)malloc(rpng2_info.width*rpng2_info.height); pad = 8; } if (!xdata) { fprintf(stderr, PROGNAME ": unable to allocate image memory\n"); return 4; } ximage = XCreateImage(display, visual, depth, ZPixmap, 0, (char *)xdata, rpng2_info.width, rpng2_info.height, pad, 0); if (!ximage) { fprintf(stderr, PROGNAME ": XCreateImage() failed\n"); free(xdata); return 3; } /* to avoid testing the byte order every pixel (or doubling the size of * the drawing routine with a giant if-test), we arbitrarily set the byte * order to MSBFirst and let Xlib worry about inverting things on little- * endian machines (e.g., Linux/x86, old VAXen, etc.)--this is not the * most efficient approach (the giant if-test would be better), but in * the interest of clarity, we'll take the easy way out... */ ximage->byte_order = MSBFirst; /*--------------------------------------------------------------------------- Fill window with the specified background color (default is black) or faked "background image" (but latter is disabled if 8-bit; gradients just waste palette entries). ---------------------------------------------------------------------------*/ if (bg_image) rpng2_x_load_bg_image(); /* resets bg_image if fails */ if (!bg_image) { if (depth == 24 || depth == 32) { bg_pixel = (bg_red << RShift) | (bg_green << GShift) | (bg_blue << BShift); } else if (depth == 16) { bg_pixel = (((bg_red << 8) >> RShift) & RMask) | (((bg_green << 8) >> GShift) & GMask) | (((bg_blue << 8) >> BShift) & BMask); } else /* depth == 8 */ { /* GRR: add 8-bit support */ } XSetForeground(display, gc, bg_pixel); XFillRectangle(display, window, gc, 0, 0, rpng2_info.width, rpng2_info.height); } /*--------------------------------------------------------------------------- Wait for first Expose event to do any drawing, then flush and return. ---------------------------------------------------------------------------*/ do XNextEvent(display, &e); while (e.type != Expose || e.xexpose.count); XFlush(display); return 0; } /* end function rpng2_x_create_window() */ static int rpng2_x_load_bg_image(void) { uch *src; char *dest; uch r1, r2, g1, g2, b1, b2; uch r1_inv, r2_inv, g1_inv, g2_inv, b1_inv, b2_inv; int k, hmax, max; int xidx, yidx, yidx_max; int even_odd_vert, even_odd_horiz, even_odd; int invert_gradient2 = (bg[pat].type & 0x08); int invert_column; int ximage_rowbytes = ximage->bytes_per_line; ulg i, row; ulg pixel; /*--------------------------------------------------------------------------- Allocate buffer for fake background image to be used with transparent images; if this fails, revert to plain background color. ---------------------------------------------------------------------------*/ bg_rowbytes = 3 * rpng2_info.width; bg_data = (uch *)malloc(bg_rowbytes * rpng2_info.height); if (!bg_data) { fprintf(stderr, PROGNAME ": unable to allocate memory for background image\n"); bg_image = 0; return 1; } bgscale = (pat == 0)? 8 : bgscale_default; yidx_max = bgscale - 1; /*--------------------------------------------------------------------------- Vertical gradients (ramps) in NxN squares, alternating direction and colors (N == bgscale). ---------------------------------------------------------------------------*/ if ((bg[pat].type & 0x07) == 0) { uch r1_min = rgb[bg[pat].rgb1_min].r; uch g1_min = rgb[bg[pat].rgb1_min].g; uch b1_min = rgb[bg[pat].rgb1_min].b; uch r2_min = rgb[bg[pat].rgb2_min].r; uch g2_min = rgb[bg[pat].rgb2_min].g; uch b2_min = rgb[bg[pat].rgb2_min].b; int r1_diff = rgb[bg[pat].rgb1_max].r - r1_min; int g1_diff = rgb[bg[pat].rgb1_max].g - g1_min; int b1_diff = rgb[bg[pat].rgb1_max].b - b1_min; int r2_diff = rgb[bg[pat].rgb2_max].r - r2_min; int g2_diff = rgb[bg[pat].rgb2_max].g - g2_min; int b2_diff = rgb[bg[pat].rgb2_max].b - b2_min; for (row = 0; row < rpng2_info.height; ++row) { yidx = (int)(row % bgscale); even_odd_vert = (int)((row / bgscale) & 1); r1 = r1_min + (r1_diff * yidx) / yidx_max; g1 = g1_min + (g1_diff * yidx) / yidx_max; b1 = b1_min + (b1_diff * yidx) / yidx_max; r1_inv = r1_min + (r1_diff * (yidx_max-yidx)) / yidx_max; g1_inv = g1_min + (g1_diff * (yidx_max-yidx)) / yidx_max; b1_inv = b1_min + (b1_diff * (yidx_max-yidx)) / yidx_max; r2 = r2_min + (r2_diff * yidx) / yidx_max; g2 = g2_min + (g2_diff * yidx) / yidx_max; b2 = b2_min + (b2_diff * yidx) / yidx_max; r2_inv = r2_min + (r2_diff * (yidx_max-yidx)) / yidx_max; g2_inv = g2_min + (g2_diff * (yidx_max-yidx)) / yidx_max; b2_inv = b2_min + (b2_diff * (yidx_max-yidx)) / yidx_max; dest = (char *)bg_data + row*bg_rowbytes; for (i = 0; i < rpng2_info.width; ++i) { even_odd_horiz = (int)((i / bgscale) & 1); even_odd = even_odd_vert ^ even_odd_horiz; invert_column = (even_odd_horiz && (bg[pat].type & 0x10)); if (even_odd == 0) { /* gradient #1 */ if (invert_column) { *dest++ = r1_inv; *dest++ = g1_inv; *dest++ = b1_inv; } else { *dest++ = r1; *dest++ = g1; *dest++ = b1; } } else { /* gradient #2 */ if ((invert_column && invert_gradient2) || (!invert_column && !invert_gradient2)) { *dest++ = r2; /* not inverted or */ *dest++ = g2; /* doubly inverted */ *dest++ = b2; } else { *dest++ = r2_inv; *dest++ = g2_inv; /* singly inverted */ *dest++ = b2_inv; } } } } /*--------------------------------------------------------------------------- Soft gradient-diamonds with scale = bgscale. Code contributed by Adam M. Costello. ---------------------------------------------------------------------------*/ } else if ((bg[pat].type & 0x07) == 1) { hmax = (bgscale-1)/2; /* half the max weight of a color */ max = 2*hmax; /* the max weight of a color */ r1 = rgb[bg[pat].rgb1_max].r; g1 = rgb[bg[pat].rgb1_max].g; b1 = rgb[bg[pat].rgb1_max].b; r2 = rgb[bg[pat].rgb2_max].r; g2 = rgb[bg[pat].rgb2_max].g; b2 = rgb[bg[pat].rgb2_max].b; for (row = 0; row < rpng2_info.height; ++row) { yidx = (int)(row % bgscale); if (yidx > hmax) yidx = bgscale-1 - yidx; dest = (char *)bg_data + row*bg_rowbytes; for (i = 0; i < rpng2_info.width; ++i) { xidx = (int)(i % bgscale); if (xidx > hmax) xidx = bgscale-1 - xidx; k = xidx + yidx; *dest++ = (k*r1 + (max-k)*r2) / max; *dest++ = (k*g1 + (max-k)*g2) / max; *dest++ = (k*b1 + (max-k)*b2) / max; } } /*--------------------------------------------------------------------------- Radial "starburst" with azimuthal sinusoids; [eventually number of sinu- soids will equal bgscale?]. This one is slow but very cool. Code con- tributed by Pieter S. van der Meulen (originally in Smalltalk). ---------------------------------------------------------------------------*/ } else if ((bg[pat].type & 0x07) == 2) { uch ch; int ii, x, y, hw, hh, grayspot; double freq, rotate, saturate, gray, intensity; double angle=0.0, aoffset=0.0, maxDist, dist; double red=0.0, green=0.0, blue=0.0, hue, s, v, f, p, q, t; fprintf(stderr, "%s: computing radial background...", PROGNAME); fflush(stderr); hh = (int)(rpng2_info.height / 2); hw = (int)(rpng2_info.width / 2); /* variables for radial waves: * aoffset: number of degrees to rotate hue [CURRENTLY NOT USED] * freq: number of color beams originating from the center * grayspot: size of the graying center area (anti-alias) * rotate: rotation of the beams as a function of radius * saturate: saturation of beams' shape azimuthally */ angle = CLIP(angle, 0.0, 360.0); grayspot = CLIP(bg[pat].bg_gray, 1, (hh + hw)); freq = MAX((double)bg[pat].bg_freq, 0.0); saturate = (double)bg[pat].bg_bsat * 0.1; rotate = (double)bg[pat].bg_brot * 0.1; gray = 0.0; intensity = 0.0; maxDist = (double)((hw*hw) + (hh*hh)); for (row = 0; row < rpng2_info.height; ++row) { y = (int)(row - hh); dest = (char *)bg_data + row*bg_rowbytes; for (i = 0; i < rpng2_info.width; ++i) { x = (int)(i - hw); angle = (x == 0)? PI_2 : atan((double)y / (double)x); gray = (double)MAX(ABS(y), ABS(x)) / grayspot; gray = MIN(1.0, gray); dist = (double)((x*x) + (y*y)) / maxDist; intensity = cos((angle+(rotate*dist*PI)) * freq) * gray * saturate; intensity = (MAX(MIN(intensity,1.0),-1.0) + 1.0) * 0.5; hue = (angle + PI) * INV_PI_360 + aoffset; s = gray * ((double)(ABS(x)+ABS(y)) / (double)(hw + hh)); s = MIN(MAX(s,0.0), 1.0); v = MIN(MAX(intensity,0.0), 1.0); if (s == 0.0) { ch = (uch)(v * 255.0); *dest++ = ch; *dest++ = ch; *dest++ = ch; } else { if ((hue < 0.0) || (hue >= 360.0)) hue -= (((int)(hue / 360.0)) * 360.0); hue /= 60.0; ii = (int)hue; f = hue - (double)ii; p = (1.0 - s) * v; q = (1.0 - (s * f)) * v; t = (1.0 - (s * (1.0 - f))) * v; if (ii == 0) { red = v; green = t; blue = p; } else if (ii == 1) { red = q; green = v; blue = p; } else if (ii == 2) { red = p; green = v; blue = t; } else if (ii == 3) { red = p; green = q; blue = v; } else if (ii == 4) { red = t; green = p; blue = v; } else if (ii == 5) { red = v; green = p; blue = q; } *dest++ = (uch)(red * 255.0); *dest++ = (uch)(green * 255.0); *dest++ = (uch)(blue * 255.0); } } } fprintf(stderr, "done.\n"); fflush(stderr); } /*--------------------------------------------------------------------------- Blast background image to display buffer before beginning PNG decode. ---------------------------------------------------------------------------*/ if (depth == 24 || depth == 32) { ulg red, green, blue; int bpp = ximage->bits_per_pixel; for (row = 0; row < rpng2_info.height; ++row) { src = bg_data + row*bg_rowbytes; dest = ximage->data + row*ximage_rowbytes; if (bpp == 32) { /* slightly optimized version */ for (i = rpng2_info.width; i > 0; --i) { red = *src++; green = *src++; blue = *src++; pixel = (red << RShift) | (green << GShift) | (blue << BShift); /* recall that we set ximage->byte_order = MSBFirst above */ *dest++ = (char)((pixel >> 24) & 0xff); *dest++ = (char)((pixel >> 16) & 0xff); *dest++ = (char)((pixel >> 8) & 0xff); *dest++ = (char)( pixel & 0xff); } } else { for (i = rpng2_info.width; i > 0; --i) { red = *src++; green = *src++; blue = *src++; pixel = (red << RShift) | (green << GShift) | (blue << BShift); /* recall that we set ximage->byte_order = MSBFirst above */ /* GRR BUG? this assumes bpp == 24 & bits are packed low */ /* (probably need to use RShift, RMask, etc.) */ *dest++ = (char)((pixel >> 16) & 0xff); *dest++ = (char)((pixel >> 8) & 0xff); *dest++ = (char)( pixel & 0xff); } } } } else if (depth == 16) { ush red, green, blue; for (row = 0; row < rpng2_info.height; ++row) { src = bg_data + row*bg_rowbytes; dest = ximage->data + row*ximage_rowbytes; for (i = rpng2_info.width; i > 0; --i) { red = ((ush)(*src) << 8); ++src; green = ((ush)(*src) << 8); ++src; blue = ((ush)(*src) << 8); ++src; pixel = ((red >> RShift) & RMask) | ((green >> GShift) & GMask) | ((blue >> BShift) & BMask); /* recall that we set ximage->byte_order = MSBFirst above */ *dest++ = (char)((pixel >> 8) & 0xff); *dest++ = (char)( pixel & 0xff); } } } else /* depth == 8 */ { /* GRR: add 8-bit support */ } XPutImage(display, window, gc, ximage, 0, 0, 0, 0, rpng2_info.width, rpng2_info.height); return 0; } /* end function rpng2_x_load_bg_image() */ static void rpng2_x_display_row(ulg row) { uch bg_red = rpng2_info.bg_red; uch bg_green = rpng2_info.bg_green; uch bg_blue = rpng2_info.bg_blue; uch *src, *src2=NULL; char *dest; uch r, g, b, a; int ximage_rowbytes = ximage->bytes_per_line; ulg i, pixel; static int rows=0, prevpass=(-1); static ulg firstrow; /*--------------------------------------------------------------------------- rows and firstrow simply track how many rows (and which ones) have not yet been displayed; alternatively, we could call XPutImage() for every row and not bother with the records-keeping. ---------------------------------------------------------------------------*/ Trace((stderr, "beginning rpng2_x_display_row()\n")) if (rpng2_info.pass != prevpass) { if (pause_after_pass && rpng2_info.pass > 0) { XEvent e; KeySym k; fprintf(stderr, "%s: end of pass %d of 7; click in image window to continue\n", PROGNAME, prevpass + 1); do XNextEvent(display, &e); while (!QUIT(e,k)); } fprintf(stderr, "%s: pass %d of 7\r", PROGNAME, rpng2_info.pass + 1); fflush(stderr); prevpass = rpng2_info.pass; } if (rows == 0) firstrow = row; /* first row that is not yet displayed */ ++rows; /* count of rows received but not yet displayed */ /*--------------------------------------------------------------------------- Aside from the use of the rpng2_info struct, the lack of an outer loop (over rows) and moving the XPutImage() call outside the "if (depth)" tests, this routine is identical to rpng_x_display_image() in the non- progressive version of the program. ---------------------------------------------------------------------------*/ if (depth == 24 || depth == 32) { ulg red, green, blue; int bpp = ximage->bits_per_pixel; src = rpng2_info.image_data + row*rpng2_info.rowbytes; if (bg_image) src2 = bg_data + row*bg_rowbytes; dest = ximage->data + row*ximage_rowbytes; if (rpng2_info.channels == 3) { for (i = rpng2_info.width; i > 0; --i) { red = *src++; green = *src++; blue = *src++; pixel = (red << RShift) | (green << GShift) | (blue << BShift); /* recall that we set ximage->byte_order = MSBFirst above */ if (bpp == 32) { *dest++ = (char)((pixel >> 24) & 0xff); *dest++ = (char)((pixel >> 16) & 0xff); *dest++ = (char)((pixel >> 8) & 0xff); *dest++ = (char)( pixel & 0xff); } else { /* GRR BUG? this assumes bpp == 24 & bits are packed low */ /* (probably need to use RShift, RMask, etc.) */ *dest++ = (char)((pixel >> 16) & 0xff); *dest++ = (char)((pixel >> 8) & 0xff); *dest++ = (char)( pixel & 0xff); } } } else /* if (rpng2_info.channels == 4) */ { for (i = rpng2_info.width; i > 0; --i) { r = *src++; g = *src++; b = *src++; a = *src++; if (bg_image) { bg_red = *src2++; bg_green = *src2++; bg_blue = *src2++; } if (a == 255) { red = r; green = g; blue = b; } else if (a == 0) { red = bg_red; green = bg_green; blue = bg_blue; } else { /* this macro (from png.h) composites the foreground * and background values and puts the result into the * first argument */ alpha_composite(red, r, a, bg_red); alpha_composite(green, g, a, bg_green); alpha_composite(blue, b, a, bg_blue); } pixel = (red << RShift) | (green << GShift) | (blue << BShift); /* recall that we set ximage->byte_order = MSBFirst above */ if (bpp == 32) { *dest++ = (char)((pixel >> 24) & 0xff); *dest++ = (char)((pixel >> 16) & 0xff); *dest++ = (char)((pixel >> 8) & 0xff); *dest++ = (char)( pixel & 0xff); } else { /* GRR BUG? this assumes bpp == 24 & bits are packed low */ /* (probably need to use RShift, RMask, etc.) */ *dest++ = (char)((pixel >> 16) & 0xff); *dest++ = (char)((pixel >> 8) & 0xff); *dest++ = (char)( pixel & 0xff); } } } } else if (depth == 16) { ush red, green, blue; src = rpng2_info.row_pointers[row]; if (bg_image) src2 = bg_data + row*bg_rowbytes; dest = ximage->data + row*ximage_rowbytes; if (rpng2_info.channels == 3) { for (i = rpng2_info.width; i > 0; --i) { red = ((ush)(*src) << 8); ++src; green = ((ush)(*src) << 8); ++src; blue = ((ush)(*src) << 8); ++src; pixel = ((red >> RShift) & RMask) | ((green >> GShift) & GMask) | ((blue >> BShift) & BMask); /* recall that we set ximage->byte_order = MSBFirst above */ *dest++ = (char)((pixel >> 8) & 0xff); *dest++ = (char)( pixel & 0xff); } } else /* if (rpng2_info.channels == 4) */ { for (i = rpng2_info.width; i > 0; --i) { r = *src++; g = *src++; b = *src++; a = *src++; if (bg_image) { bg_red = *src2++; bg_green = *src2++; bg_blue = *src2++; } if (a == 255) { red = ((ush)r << 8); green = ((ush)g << 8); blue = ((ush)b << 8); } else if (a == 0) { red = ((ush)bg_red << 8); green = ((ush)bg_green << 8); blue = ((ush)bg_blue << 8); } else { /* this macro (from png.h) composites the foreground * and background values and puts the result back into * the first argument (== fg byte here: safe) */ alpha_composite(r, r, a, bg_red); alpha_composite(g, g, a, bg_green); alpha_composite(b, b, a, bg_blue); red = ((ush)r << 8); green = ((ush)g << 8); blue = ((ush)b << 8); } pixel = ((red >> RShift) & RMask) | ((green >> GShift) & GMask) | ((blue >> BShift) & BMask); /* recall that we set ximage->byte_order = MSBFirst above */ *dest++ = (char)((pixel >> 8) & 0xff); *dest++ = (char)( pixel & 0xff); } } } else /* depth == 8 */ { /* GRR: add 8-bit support */ } /*--------------------------------------------------------------------------- Display after every 16 rows or when on one of last two rows. (Region may include previously displayed lines due to interlacing--i.e., not contiguous. Also, second-to-last row is final one in interlaced images with odd number of rows.) For demos, flush (and delay) after every 16th row so "sparse" passes don't go twice as fast. ---------------------------------------------------------------------------*/ if (demo_timing && (row - firstrow >= 16 || row >= rpng2_info.height-2)) { XPutImage(display, window, gc, ximage, 0, (int)firstrow, 0, (int)firstrow, rpng2_info.width, row - firstrow + 1); XFlush(display); rows = 0; usleep(usleep_duration); } else if (!demo_timing && ((rows & 0xf) == 0 || row >= rpng2_info.height-2)) { XPutImage(display, window, gc, ximage, 0, (int)firstrow, 0, (int)firstrow, rpng2_info.width, row - firstrow + 1); XFlush(display); rows = 0; } } static void rpng2_x_finish_display(void) { Trace((stderr, "beginning rpng2_x_finish_display()\n")) /* last row has already been displayed by rpng2_x_display_row(), so we * have nothing to do here except set a flag and let the user know that * the image is done */ rpng2_info.state = kDone; printf( "Done. Press Q, Esc or mouse button 1 (within image window) to quit.\n"); fflush(stdout); } static void rpng2_x_redisplay_image(ulg startcol, ulg startrow, ulg width, ulg height) { uch bg_red = rpng2_info.bg_red; uch bg_green = rpng2_info.bg_green; uch bg_blue = rpng2_info.bg_blue; uch *src, *src2=NULL; char *dest; uch r, g, b, a; ulg i, row, lastrow = 0; ulg pixel; int ximage_rowbytes = ximage->bytes_per_line; Trace((stderr, "beginning display loop (image_channels == %d)\n", rpng2_info.channels)) Trace((stderr, " (width = %ld, rowbytes = %d, ximage_rowbytes = %d)\n", rpng2_info.width, rpng2_info.rowbytes, ximage_rowbytes)) Trace((stderr, " (bpp = %d)\n", ximage->bits_per_pixel)) Trace((stderr, " (byte_order = %s)\n", ximage->byte_order == MSBFirst? "MSBFirst" : (ximage->byte_order == LSBFirst? "LSBFirst" : "unknown"))) /*--------------------------------------------------------------------------- Aside from the use of the rpng2_info struct and of src2 (for background image), this routine is identical to rpng_x_display_image() in the non- progressive version of the program--for the simple reason that redisplay of the image against a new background happens after the image is fully decoded and therefore is, by definition, non-progressive. ---------------------------------------------------------------------------*/ if (depth == 24 || depth == 32) { ulg red, green, blue; int bpp = ximage->bits_per_pixel; for (lastrow = row = startrow; row < startrow+height; ++row) { src = rpng2_info.image_data + row*rpng2_info.rowbytes; if (bg_image) src2 = bg_data + row*bg_rowbytes; dest = ximage->data + row*ximage_rowbytes; if (rpng2_info.channels == 3) { for (i = rpng2_info.width; i > 0; --i) { red = *src++; green = *src++; blue = *src++; #ifdef NO_24BIT_MASKS pixel = (red << RShift) | (green << GShift) | (blue << BShift); /* recall that we set ximage->byte_order = MSBFirst above */ if (bpp == 32) { *dest++ = (char)((pixel >> 24) & 0xff); *dest++ = (char)((pixel >> 16) & 0xff); *dest++ = (char)((pixel >> 8) & 0xff); *dest++ = (char)( pixel & 0xff); } else { /* this assumes bpp == 24 & bits are packed low */ /* (probably need to use RShift, RMask, etc.) */ *dest++ = (char)((pixel >> 16) & 0xff); *dest++ = (char)((pixel >> 8) & 0xff); *dest++ = (char)( pixel & 0xff); } #else red = (RShift < 0)? red << (-RShift) : red >> RShift; green = (GShift < 0)? green << (-GShift) : green >> GShift; blue = (BShift < 0)? blue << (-BShift) : blue >> BShift; pixel = (red & RMask) | (green & GMask) | (blue & BMask); /* recall that we set ximage->byte_order = MSBFirst above */ if (bpp == 32) { *dest++ = (char)((pixel >> 24) & 0xff); *dest++ = (char)((pixel >> 16) & 0xff); *dest++ = (char)((pixel >> 8) & 0xff); *dest++ = (char)( pixel & 0xff); } else { /* GRR BUG */ /* this assumes bpp == 24 & bits are packed low */ /* (probably need to use RShift/RMask/etc. here, too) */ *dest++ = (char)((pixel >> 16) & 0xff); *dest++ = (char)((pixel >> 8) & 0xff); *dest++ = (char)( pixel & 0xff); } #endif } } else /* if (rpng2_info.channels == 4) */ { for (i = rpng2_info.width; i > 0; --i) { r = *src++; g = *src++; b = *src++; a = *src++; if (bg_image) { bg_red = *src2++; bg_green = *src2++; bg_blue = *src2++; } if (a == 255) { red = r; green = g; blue = b; } else if (a == 0) { red = bg_red; green = bg_green; blue = bg_blue; } else { /* this macro (from png.h) composites the foreground * and background values and puts the result into the * first argument */ alpha_composite(red, r, a, bg_red); alpha_composite(green, g, a, bg_green); alpha_composite(blue, b, a, bg_blue); } #ifdef NO_24BIT_MASKS pixel = (red << RShift) | (green << GShift) | (blue << BShift); /* recall that we set ximage->byte_order = MSBFirst above */ if (bpp == 32) { *dest++ = (char)((pixel >> 24) & 0xff); *dest++ = (char)((pixel >> 16) & 0xff); *dest++ = (char)((pixel >> 8) & 0xff); *dest++ = (char)( pixel & 0xff); } else { /* this assumes bpp == 24 & bits are packed low */ /* (probably need to use RShift, RMask, etc.) */ *dest++ = (char)((pixel >> 16) & 0xff); *dest++ = (char)((pixel >> 8) & 0xff); *dest++ = (char)( pixel & 0xff); } #else red = (RShift < 0)? red << (-RShift) : red >> RShift; green = (GShift < 0)? green << (-GShift) : green >> GShift; blue = (BShift < 0)? blue << (-BShift) : blue >> BShift; pixel = (red & RMask) | (green & GMask) | (blue & BMask); /* recall that we set ximage->byte_order = MSBFirst above */ if (bpp == 32) { *dest++ = (char)((pixel >> 24) & 0xff); *dest++ = (char)((pixel >> 16) & 0xff); *dest++ = (char)((pixel >> 8) & 0xff); *dest++ = (char)( pixel & 0xff); } else { /* GRR BUG */ /* this assumes bpp == 24 & bits are packed low */ /* (probably need to use RShift/RMask/etc. here, too) */ *dest++ = (char)((pixel >> 16) & 0xff); *dest++ = (char)((pixel >> 8) & 0xff); *dest++ = (char)( pixel & 0xff); } #endif } } /* display after every 16 lines */ if (((row+1) & 0xf) == 0) { XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0, (int)lastrow, rpng2_info.width, 16); XFlush(display); lastrow = row + 1; } } } else if (depth == 16) { ush red, green, blue; for (lastrow = row = startrow; row < startrow+height; ++row) { src = rpng2_info.row_pointers[row]; if (bg_image) src2 = bg_data + row*bg_rowbytes; dest = ximage->data + row*ximage_rowbytes; if (rpng2_info.channels == 3) { for (i = rpng2_info.width; i > 0; --i) { red = ((ush)(*src) << 8); ++src; green = ((ush)(*src) << 8); ++src; blue = ((ush)(*src) << 8); ++src; pixel = ((red >> RShift) & RMask) | ((green >> GShift) & GMask) | ((blue >> BShift) & BMask); /* recall that we set ximage->byte_order = MSBFirst above */ *dest++ = (char)((pixel >> 8) & 0xff); *dest++ = (char)( pixel & 0xff); } } else /* if (rpng2_info.channels == 4) */ { for (i = rpng2_info.width; i > 0; --i) { r = *src++; g = *src++; b = *src++; a = *src++; if (bg_image) { bg_red = *src2++; bg_green = *src2++; bg_blue = *src2++; } if (a == 255) { red = ((ush)r << 8); green = ((ush)g << 8); blue = ((ush)b << 8); } else if (a == 0) { red = ((ush)bg_red << 8); green = ((ush)bg_green << 8); blue = ((ush)bg_blue << 8); } else { /* this macro (from png.h) composites the foreground * and background values and puts the result back into * the first argument (== fg byte here: safe) */ alpha_composite(r, r, a, bg_red); alpha_composite(g, g, a, bg_green); alpha_composite(b, b, a, bg_blue); red = ((ush)r << 8); green = ((ush)g << 8); blue = ((ush)b << 8); } pixel = ((red >> RShift) & RMask) | ((green >> GShift) & GMask) | ((blue >> BShift) & BMask); /* recall that we set ximage->byte_order = MSBFirst above */ *dest++ = (char)((pixel >> 8) & 0xff); *dest++ = (char)( pixel & 0xff); } } /* display after every 16 lines */ if (((row+1) & 0xf) == 0) { XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0, (int)lastrow, rpng2_info.width, 16); XFlush(display); lastrow = row + 1; } } } else /* depth == 8 */ { /* GRR: add 8-bit support */ } Trace((stderr, "calling final XPutImage()\n")) if (lastrow < startrow+height) { XPutImage(display, window, gc, ximage, 0, (int)lastrow, 0, (int)lastrow, rpng2_info.width, rpng2_info.height-lastrow); XFlush(display); } (void)startcol; (void)width; } /* end function rpng2_x_redisplay_image() */ #ifdef FEATURE_LOOP static void rpng2_x_reload_bg_image(void) { char *dest; uch r1, r2, g1, g2, b1, b2; uch r1_inv, r2_inv, g1_inv, g2_inv, b1_inv, b2_inv; int k, hmax, max; int xidx, yidx, yidx_max; int even_odd_vert, even_odd_horiz, even_odd; int invert_gradient2 = (bg[pat].type & 0x08); int invert_column; ulg i, row; bgscale = (pat == 0)? 8 : bgscale_default; yidx_max = bgscale - 1; /*--------------------------------------------------------------------------- Vertical gradients (ramps) in NxN squares, alternating direction and colors (N == bgscale). ---------------------------------------------------------------------------*/ if ((bg[pat].type & 0x07) == 0) { uch r1_min = rgb[bg[pat].rgb1_min].r; uch g1_min = rgb[bg[pat].rgb1_min].g; uch b1_min = rgb[bg[pat].rgb1_min].b; uch r2_min = rgb[bg[pat].rgb2_min].r; uch g2_min = rgb[bg[pat].rgb2_min].g; uch b2_min = rgb[bg[pat].rgb2_min].b; int r1_diff = rgb[bg[pat].rgb1_max].r - r1_min; int g1_diff = rgb[bg[pat].rgb1_max].g - g1_min; int b1_diff = rgb[bg[pat].rgb1_max].b - b1_min; int r2_diff = rgb[bg[pat].rgb2_max].r - r2_min; int g2_diff = rgb[bg[pat].rgb2_max].g - g2_min; int b2_diff = rgb[bg[pat].rgb2_max].b - b2_min; for (row = 0; row < rpng2_info.height; ++row) { yidx = (int)(row % bgscale); even_odd_vert = (int)((row / bgscale) & 1); r1 = r1_min + (r1_diff * yidx) / yidx_max; g1 = g1_min + (g1_diff * yidx) / yidx_max; b1 = b1_min + (b1_diff * yidx) / yidx_max; r1_inv = r1_min + (r1_diff * (yidx_max-yidx)) / yidx_max; g1_inv = g1_min + (g1_diff * (yidx_max-yidx)) / yidx_max; b1_inv = b1_min + (b1_diff * (yidx_max-yidx)) / yidx_max; r2 = r2_min + (r2_diff * yidx) / yidx_max; g2 = g2_min + (g2_diff * yidx) / yidx_max; b2 = b2_min + (b2_diff * yidx) / yidx_max; r2_inv = r2_min + (r2_diff * (yidx_max-yidx)) / yidx_max; g2_inv = g2_min + (g2_diff * (yidx_max-yidx)) / yidx_max; b2_inv = b2_min + (b2_diff * (yidx_max-yidx)) / yidx_max; dest = (char *)bg_data + row*bg_rowbytes; for (i = 0; i < rpng2_info.width; ++i) { even_odd_horiz = (int)((i / bgscale) & 1); even_odd = even_odd_vert ^ even_odd_horiz; invert_column = (even_odd_horiz && (bg[pat].type & 0x10)); if (even_odd == 0) { /* gradient #1 */ if (invert_column) { *dest++ = r1_inv; *dest++ = g1_inv; *dest++ = b1_inv; } else { *dest++ = r1; *dest++ = g1; *dest++ = b1; } } else { /* gradient #2 */ if ((invert_column && invert_gradient2) || (!invert_column && !invert_gradient2)) { *dest++ = r2; /* not inverted or */ *dest++ = g2; /* doubly inverted */ *dest++ = b2; } else { *dest++ = r2_inv; *dest++ = g2_inv; /* singly inverted */ *dest++ = b2_inv; } } } } /*--------------------------------------------------------------------------- Soft gradient-diamonds with scale = bgscale. Code contributed by Adam M. Costello. ---------------------------------------------------------------------------*/ } else if ((bg[pat].type & 0x07) == 1) { hmax = (bgscale-1)/2; /* half the max weight of a color */ max = 2*hmax; /* the max weight of a color */ r1 = rgb[bg[pat].rgb1_max].r; g1 = rgb[bg[pat].rgb1_max].g; b1 = rgb[bg[pat].rgb1_max].b; r2 = rgb[bg[pat].rgb2_max].r; g2 = rgb[bg[pat].rgb2_max].g; b2 = rgb[bg[pat].rgb2_max].b; for (row = 0; row < rpng2_info.height; ++row) { yidx = (int)(row % bgscale); if (yidx > hmax) yidx = bgscale-1 - yidx; dest = (char *)bg_data + row*bg_rowbytes; for (i = 0; i < rpng2_info.width; ++i) { xidx = (int)(i % bgscale); if (xidx > hmax) xidx = bgscale-1 - xidx; k = xidx + yidx; *dest++ = (k*r1 + (max-k)*r2) / max; *dest++ = (k*g1 + (max-k)*g2) / max; *dest++ = (k*b1 + (max-k)*b2) / max; } } /*--------------------------------------------------------------------------- Radial "starburst" with azimuthal sinusoids; [eventually number of sinu- soids will equal bgscale?]. This one is slow but very cool. Code con- tributed by Pieter S. van der Meulen (originally in Smalltalk). ---------------------------------------------------------------------------*/ } else if ((bg[pat].type & 0x07) == 2) { uch ch; int ii, x, y, hw, hh, grayspot; double freq, rotate, saturate, gray, intensity; double angle=0.0, aoffset=0.0, maxDist, dist; double red=0.0, green=0.0, blue=0.0, hue, s, v, f, p, q, t; hh = (int)(rpng2_info.height / 2); hw = (int)(rpng2_info.width / 2); /* variables for radial waves: * aoffset: number of degrees to rotate hue [CURRENTLY NOT USED] * freq: number of color beams originating from the center * grayspot: size of the graying center area (anti-alias) * rotate: rotation of the beams as a function of radius * saturate: saturation of beams' shape azimuthally */ angle = CLIP(angle, 0.0, 360.0); grayspot = CLIP(bg[pat].bg_gray, 1, (hh + hw)); freq = MAX((double)bg[pat].bg_freq, 0.0); saturate = (double)bg[pat].bg_bsat * 0.1; rotate = (double)bg[pat].bg_brot * 0.1; gray = 0.0; intensity = 0.0; maxDist = (double)((hw*hw) + (hh*hh)); for (row = 0; row < rpng2_info.height; ++row) { y = (int)(row - hh); dest = (char *)bg_data + row*bg_rowbytes; for (i = 0; i < rpng2_info.width; ++i) { x = (int)(i - hw); angle = (x == 0)? PI_2 : atan((double)y / (double)x); gray = (double)MAX(ABS(y), ABS(x)) / grayspot; gray = MIN(1.0, gray); dist = (double)((x*x) + (y*y)) / maxDist; intensity = cos((angle+(rotate*dist*PI)) * freq) * gray * saturate; intensity = (MAX(MIN(intensity,1.0),-1.0) + 1.0) * 0.5; hue = (angle + PI) * INV_PI_360 + aoffset; s = gray * ((double)(ABS(x)+ABS(y)) / (double)(hw + hh)); s = MIN(MAX(s,0.0), 1.0); v = MIN(MAX(intensity,0.0), 1.0); if (s == 0.0) { ch = (uch)(v * 255.0); *dest++ = ch; *dest++ = ch; *dest++ = ch; } else { if ((hue < 0.0) || (hue >= 360.0)) hue -= (((int)(hue / 360.0)) * 360.0); hue /= 60.0; ii = (int)hue; f = hue - (double)ii; p = (1.0 - s) * v; q = (1.0 - (s * f)) * v; t = (1.0 - (s * (1.0 - f))) * v; if (ii == 0) { red = v; green = t; blue = p; } else if (ii == 1) { red = q; green = v; blue = p; } else if (ii == 2) { red = p; green = v; blue = t; } else if (ii == 3) { red = p; green = q; blue = v; } else if (ii == 4) { red = t; green = p; blue = v; } else if (ii == 5) { red = v; green = p; blue = q; } *dest++ = (uch)(red * 255.0); *dest++ = (uch)(green * 255.0); *dest++ = (uch)(blue * 255.0); } } } } } /* end function rpng2_x_reload_bg_image() */ static int is_number(char *p) { while (*p) { if (!isdigit(*p)) return FALSE; ++p; } return TRUE; } #endif /* FEATURE_LOOP */ static void rpng2_x_cleanup(void) { if (bg_image && bg_data) { free(bg_data); bg_data = NULL; } if (rpng2_info.image_data) { free(rpng2_info.image_data); rpng2_info.image_data = NULL; } if (rpng2_info.row_pointers) { free(rpng2_info.row_pointers); rpng2_info.row_pointers = NULL; } if (ximage) { if (ximage->data) { free(ximage->data); /* we allocated it, so we free it */ ximage->data = (char *)NULL; /* instead of XDestroyImage() */ } XDestroyImage(ximage); ximage = NULL; } if (have_gc) XFreeGC(display, gc); if (have_window) XDestroyWindow(display, window); if (have_colormap) XFreeColormap(display, colormap); if (have_nondefault_visual) XFree(visual_list); } static int rpng2_x_msb(ulg u32val) { int i; for (i = 31; i >= 0; --i) { if (u32val & 0x80000000L) break; u32val <<= 1; } return i; } libpng-1.6.43/contrib/gregbook/toucan.png000066400000000000000000000311451456606525400203370ustar00rootroot00000000000000PNG  IHDRgAMA1_PLTE   Qw<..?S#  k  'zEl?=a$>QE!2;+1:N1 2  5Hz63;\: IDATx{ 8?3.#ĸ1[Ê1J3k]kOÆ#eIQ %T%E5Tl(t|G?Ͼ__y}޷RROcJϿ69=sLqs8DRAܶ+yj`CZeQÞmFF6;Cƨ"دWYXhBasG|h]kG<㊄s)ˇ9ՃeH܌5mcprtJj97dƗ\h[ƿUZJ2NV3?:g " P8*~ FNH7(aΰ Vv5NWcTU<`@.`8|6_c<}3%GIJ^$ܔz:Xd(ŇWavg}N)mlx@I0)+¤g)@t DqtT4Io ]_n={sU8B"H)W i 5i(`G oH;44%//.V)R۵57۸YДqErFE45V,&jLL$xS}iꝂ3 c|׿[4F&L'd}"Maw1 p^Cq,Wc(N&P rB6W6R}'Stm[/5ÒG=YAZ>%g[%"sgٖbi\*J+>HMFYy eOU%YYSJZ]솩)JE; f88Xb! }fn`q=~-tIj?O{% ˿",O솭ʑ^/QUWs8ZwXdaVywkl@EDf)˰?3Uf,}:ɓej4P8bOlK$X G_~EB۩BlO>YdS5 M5V()[d6߭LɌh8~nqbS)F{!ʀ QWٺG,A-0^nM$zH c!`i=SSa.㭭}أQھ}i'k55ڃ7Gxݐ+YGz-mD wtt2MՍ<=={γ]l;vozsBe6uGkQQ%G&#$Qp#kݞF?Ѧ꺺vLqktAAtPˌhˣ7 Z]OTړ5 v3=?qSMnc|td2h ` H$T99iVy8u6jnrW/H,\k58Oض>62(YMH@ QrK6>7r`K=z\sr?;v`&T2GDQW<>To[1W T #"-ѧfw ao{x{8;G ْosܕX]Sm"?`oiۂٖ fl?B_wz"Re 84/o .x{nÍ?Oׂ4/@Wr8sg㏗|aDl/uzڮ2F&OWN$y9m>֐xS9:;SzDxJSuu[kTvF5mQ;T?$MyW>DML^QQA=2LGO>IK+8sN5\a*U^WtaNoݺ?s""Ha:sVxv?__)H=&p槁>O;LOjLTqRwL~&h9-pۻͩK2ECt(#$Dz^Ew) C_CUu҇)HOo(T\$HAl ~yu'ttؤ$Am+P%7WW]vPpYQu9 B'8BEsDpxMk~1筆GD†N'`W3"6W/v<1TsJ\@A܄ {EayGݙ⮴Hx!4̆ z'Z1F`\]rBEP^EɈge)q 5H oH4Fi#Gw6jqJMZSی---%5~\@7CD)Y \JQ 26\ol[Y|h.;;B \mGWַhRGM}J7k2 MuB:xNHV:3"6W7]ZV^^ 5xBa[W +"v`= ʑDb?6`9ۤ5445$x]JŜLK8pgVPTRR\8zz_s sT]4cҚj2q.XY8]UIA^&9I< I wv!--^ sG_5d05(6k jXt0Y٭#F{5ЪMSf<)nxdܢD$7Ϊk49 >?;XXgd/:bXK]D_{b AqDς(r"#ΤͲ =}M0-X3ș0N,&yEU^>FhɏzՃy&3Z"q-0vsb-iоZ|5B$v2mk'8z)6_UR}QaD|Wshs)1CJ'&qL@胾7ٖ~..sv[)R&=oXrϬ鹉1p-o&@lF5lMMjIEKۿZP$Rn|dI=Psfp0ckٚ] MioP '82eX&ӧn;АL0>j`mFa54.`kIq)*9NcaDL4 MKk˸ L#CRJ廠 <# Uղv=PqaQY$2%Xδ6x{Fu}M cЦCN`c}:.*=M~er2iG$btcM=LX6Iw=FhooG G] Dk8H pJ+uٍ?Iڮ:Rkgw\Kf X~[wК]JXGM͇}ܹ3#F::d& k%埵H$-$R~;uaQViO=uшlî1a0uFGvo&ugnc쮏ȭ8 /#Vj۰]YYi^vloemqsױL4u 0$e?BHG ݏfUUtϭ {q p43imFz Lh2jJ[(ǖÙ;%JU<"a3~zdVH&7Y6oBAu߶i[sߩ&+XSk46!\eJAӦMd;/ (t!- 34q5,6dz;mt!m$+mZn!|d߆ dz'H%K 2 V[][[66,C>2T.L)1GVu*\p Cb|NRm6`Uދ~q̎JMQLFlszf[dX.r'^<`7xds(%5@E[mX ) {˖VjkKt}B;=ZD StORS*U*۟w Sޞfk|bR](N5k>g}TɪG>t\PǁE:AuWQ3ͨ?^/}` fXXX C2IB$`= @G#!ds4 !!0Lg /`8w@U֒ӧH !!AU "VR5] `s<04tn r Y VQi,?{ 9U@!$@909N4"7{E 2[e?$P` lghnxZ"0qXς~mx@Q[O:ռu+tr6=,&,ȈC[OD<ݞ,XOY6arlt4q,qHkF@!2H@66 z/5ʮe%ëm4xf&W+:=o .Cj"  F"*wlWTYk m2"S΂ $NL9|gx9RX.kkmհV}'xy*K;\7ihL](^.x<^^.$%1W_Xxrb@rRw뼈-O*; SrTE_@i b}}gM#ࠌx:T'B&W13oKgvgũ()(8@Gip9zAfGPO$&Pvvhhh}F{! :9u>M/K8 CVб@!}N0+I9Zo"V Iq #Oxɲ^}](;:gEwBMv)<3B,g Lr<\נɠ&}_ MtA Kmq AV*d&IIW.Hz$] ?=P dA̓E"p$NAwvg)Y޿xxœ l R{PP o3fOݭt {] (A# CeI,Hjhq{ᮧODzWi鋇z!hA ZZ 0N$!+{v -L ͈GaXhE^OI e=<,LKKmX{ CI<$n2k 4Bp$/E<M}IU ¡9TNKn)1tPo/[@bيuB@0;~KP%&`m5` &Ird_kl1}LMM]'q IDAT11aX|q69$=ssUͨ]ٖhgȒ) čz0zAz\ncFl HJp)pZ@hqJ#Iԭ!ny{~TDynYh",:ĄrDQK,ysjJ +8f lQ(P}Q1hk~@uҜv#4sp\Bq8?OH0zW+x͍iAኢC3S3ٮ{n9rKz|V;/u^3 ƵNgg8pOdJ)[n&x&"o?}8C39w!ߛ`0zS?ȣX"F8*ȱ Ii,\چgDE 0PE.s:"ҥccc.1{X@=~"gz v. z AlnRy?XI7BnbM gS&H4Њ"g1mƯ>DX=$;@Ďbj蠒tİq,4z@Ɛ ~w0]>lOҦפ`6Ehr5hfk`;v `lB;nL&EbZr1mL*T*a&T`(8) EOl/1!_fmϰؐc.  c³x({T{pqeĩ*~ 2Y\ 5‚ȓM\!wѴ/VD[o >mqG L/@-t-}|0j6@Br b f@6=OǏi:ѠD5;*Rs5Dq{*ּ|}6@"ۍ{XFsjœaIf,i4) ,a0.GzPP@`;Z}||hKXFW .?lĖ-y/ovtxB3r{͈ˏ]֢ٙL_{I>zu׏V4Sې#K/ !EQt%T! M&YQ@0=樓Q C6J<9=;Twv)Po`dPV[4bc7?O<8 56KTh+a-Kc%:w"Qx&N $ir]tǏP0 |}(^v1sr+ 3F?&\\'R<^:%H8A~ ữyl:DPd+V`\ܮP-ӓRd=b_<{˷GvF|!ǭg馝4=ŹN1^0Z8y K, bLr GPȓq):B0JJ2w{VF2*g*z=|yt~g@k7S6hmnRTmW=!fs1p {3|-vP{S 3't:2ڒʸqO[4F&X{eP<5U'| H:^_+ʎ-`J }b8Tp~\앲Xv 0) ylvXVٳǯ222JJ%.r҃ ^2T3z(u~@w>voˁ;?Bо!avmƆ\n bc8,;A5yxr2$!' 5:к>IᩙG;:r*~_3yۭ_nIUٮԴvVE5~ 9!>!9> =6m"ޑw.Wq024M2 *]EqmO'w j~Eά)m2[jvUpqL-1bvv0 SIw/rڟT *Tọ򺵦 i(,lWZϘ+ {a/Twd`1&<>;@d䷨w^7V88BL0 ݨ7**;]ZWYH];I'()q$GG;a\0$[(PT*etp%]+L0FDeվ_wtn6N^B&`,A%/ !X.N(胼d2U7A% rԬ)#rWzP6DDͶjpy*| $ An+G3F4Y̓@Pp1Xwm1B# Esi׮"ϟ^yx7wA7s^h( tb%SV8j^ڃWu,4Nv.[ '|wyfC.o2֢sN ۹s.d:$49 }zG'$NA5IENDB`libpng-1.6.43/contrib/gregbook/wpng.c000066400000000000000000000753241456606525400174660ustar00rootroot00000000000000/*--------------------------------------------------------------------------- wpng - simple PNG-writing program wpng.c This program converts certain NetPBM binary files (grayscale and RGB, maxval = 255) to PNG. Non-interlaced PNGs are written progressively; interlaced PNGs are read and written in one memory-intensive blast. Thanks to Jean-loup Gailly for providing the necessary trick to read interactive text from the keyboard while stdin is redirected. Thanks to Cosmin Truta for Cygwin fixes. NOTE: includes provisional support for PNM type "8" (portable alphamap) images, presumed to be a 32-bit interleaved RGBA format; no pro- vision for possible interleaved grayscale+alpha (16-bit) format. THIS IS UNLIKELY TO BECOME AN OFFICIAL NETPBM ALPHA FORMAT! to do: - delete output file if quit before calling any writepng routines - process backspace with -text option under DOS/Win? (currently get ^H) --------------------------------------------------------------------------- Changelog: - 1.01: initial public release - 1.02: modified to allow abbreviated options - 1.03: removed extraneous character from usage screen; fixed bug in command-line parsing - 1.04: fixed DOS/OS2/Win32 detection, including partial Cygwin fix (see http://home.att.net/~perlspinr/diffs/GregBook_cygwin.diff) - 2.00: dual-licensed (added GNU GPL) - 2.01: check for integer overflow (Glenn R-P) [REPORTED BUG (win32 only): "contrib/gregbook/wpng.c - cmd line dose not work! In order to do something useful I needed to redirect both input and output, with cygwin and with bcc32 as well. Under Linux, the same wpng appears to work fine. I don't know what is the problem."] --------------------------------------------------------------------------- Copyright (c) 1998-2007, 2017 Greg Roelofs. All rights reserved. This software is provided "as is," without warranty of any kind, express or implied. In no event shall the author or contributors be held liable for any damages arising in any way from the use of this software. The contents of this file are DUAL-LICENSED. You may modify and/or redistribute this software according to the terms of one of the following two licenses (at your option): LICENSE 1 ("BSD-like with advertising clause"): Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. Redistributions of source code must retain the above copyright notice, disclaimer, and this list of conditions. 2. Redistributions in binary form must reproduce the above copyright notice, disclaimer, and this list of conditions in the documenta- tion and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgment: This product includes software developed by Greg Roelofs and contributors for the book, "PNG: The Definitive Guide," published by O'Reilly and Associates. LICENSE 2 (GNU GPL v2 or later): This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ---------------------------------------------------------------------------*/ #define PROGNAME "wpng" #define VERSION "2.00 of 2 June 2007" #define APPNAME "Simple PGM/PPM/PAM to PNG Converter" #if defined(__MSDOS__) || defined(__OS2__) # define DOS_OS2_W32 #elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) # ifndef __GNUC__ /* treat Win32 native ports of gcc as Unix environments */ # define DOS_OS2_W32 # endif #endif #include #include #include #include /* for jmpbuf declaration in writepng.h */ #include #ifdef DOS_OS2_W32 # include /* for isatty(), setmode() prototypes */ # include /* O_BINARY for fdopen() without text translation */ # ifdef __EMX__ # ifndef getch # define getch() _read_kbd(0, 1, 0) /* need getche() */ # endif # else /* !__EMX__ */ # ifdef __GO32__ # include # define getch() getkey() /* GRR: need getche() */ # else # include /* for getche() console input */ # endif # endif /* ?__EMX__ */ # define FGETS(buf,len,stream) dos_kbd_gets(buf,len) #else # include /* for isatty() prototype */ # define FGETS fgets #endif /* #define DEBUG : this enables the Trace() macros */ /* #define FORBID_LATIN1_CTRL : this requires the user to re-enter any text that includes control characters discouraged by the PNG spec; text that includes an escape character (27) must be re-entered regardless */ #include "writepng.h" /* typedefs, common macros, writepng prototypes */ /* local prototypes */ static int wpng_isvalid_latin1(uch *p, int len); static void wpng_cleanup(void); #ifdef DOS_OS2_W32 static char *dos_kbd_gets(char *buf, int len); #endif static mainprog_info wpng_info; /* lone global */ int main(int argc, char **argv) { #ifndef DOS_OS2_W32 FILE *keybd; #endif #ifdef sgi FILE *tmpfile; /* or we could just use keybd, since no overlap */ char tmpline[80]; #endif char *inname = NULL, outname[256]; char *p, pnmchar, pnmline[256]; char *bgstr, *textbuf = NULL; ulg rowbytes; int rc, len = 0; int error = 0; int text = FALSE; int maxval; double LUT_exponent; /* just the lookup table */ double CRT_exponent = 2.2; /* just the monitor */ double default_display_exponent; /* whole display system */ double default_gamma = 0.0; wpng_info.infile = NULL; wpng_info.outfile = NULL; wpng_info.image_data = NULL; wpng_info.row_pointers = NULL; wpng_info.filter = FALSE; wpng_info.interlaced = FALSE; wpng_info.have_bg = FALSE; wpng_info.have_time = FALSE; wpng_info.have_text = 0; wpng_info.gamma = 0.0; /* First get the default value for our display-system exponent, i.e., * the product of the CRT exponent and the exponent corresponding to * the frame-buffer's lookup table (LUT), if any. If the PNM image * looks correct on the user's display system, its file gamma is the * inverse of this value. (Note that this is not an exhaustive list * of LUT values--e.g., OpenStep has a lot of weird ones--but it should * cover 99% of the current possibilities. This section must ensure * that default_display_exponent is positive.) */ #if defined(NeXT) /* third-party utilities can modify the default LUT exponent */ LUT_exponent = 1.0 / 2.2; /* if (some_next_function_that_returns_gamma(&next_gamma)) LUT_exponent = 1.0 / next_gamma; */ #elif defined(sgi) LUT_exponent = 1.0 / 1.7; /* there doesn't seem to be any documented function to * get the "gamma" value, so we do it the hard way */ tmpfile = fopen("/etc/config/system.glGammaVal", "r"); if (tmpfile) { double sgi_gamma; fgets(tmpline, 80, tmpfile); fclose(tmpfile); sgi_gamma = atof(tmpline); if (sgi_gamma > 0.0) LUT_exponent = 1.0 / sgi_gamma; } #elif defined(Macintosh) LUT_exponent = 1.8 / 2.61; /* if (some_mac_function_that_returns_gamma(&mac_gamma)) LUT_exponent = mac_gamma / 2.61; */ #else LUT_exponent = 1.0; /* assume no LUT: most PCs */ #endif /* the defaults above give 1.0, 1.3, 1.5 and 2.2, respectively: */ default_display_exponent = LUT_exponent * CRT_exponent; /* If the user has set the SCREEN_GAMMA environment variable as suggested * (somewhat imprecisely) in the libpng documentation, use that; otherwise * use the default value we just calculated. Either way, the user may * override this via a command-line option. */ if ((p = getenv("SCREEN_GAMMA")) != NULL) { double exponent = atof(p); if (exponent > 0.0) default_gamma = 1.0 / exponent; } if (default_gamma == 0.0) default_gamma = 1.0 / default_display_exponent; /* Now parse the command line for options and the PNM filename. */ while (*++argv && !error) { if (!strncmp(*argv, "-i", 2)) { wpng_info.interlaced = TRUE; } else if (!strncmp(*argv, "-time", 3)) { wpng_info.modtime = time(NULL); wpng_info.have_time = TRUE; } else if (!strncmp(*argv, "-text", 3)) { text = TRUE; } else if (!strncmp(*argv, "-gamma", 2)) { if (!*++argv) ++error; else { wpng_info.gamma = atof(*argv); if (wpng_info.gamma <= 0.0) ++error; else if (wpng_info.gamma > 1.01) fprintf(stderr, PROGNAME " warning: file gammas are usually less than 1.0\n"); } } else if (!strncmp(*argv, "-bgcolor", 4)) { if (!*++argv) ++error; else { bgstr = *argv; if (strlen(bgstr) != 7 || bgstr[0] != '#') ++error; else { unsigned r, g, b; /* this way quiets compiler warnings */ sscanf(bgstr+1, "%2x%2x%2x", &r, &g, &b); wpng_info.bg_red = (uch)r; wpng_info.bg_green = (uch)g; wpng_info.bg_blue = (uch)b; wpng_info.have_bg = TRUE; } } } else { if (**argv != '-') { inname = *argv; if (argv[1]) /* shouldn't be any more args after filename */ ++error; } else ++error; /* not expecting any other options */ } } /* open the input and output files, or register an error and abort */ if (!inname) { if (isatty(0)) { fprintf(stderr, PROGNAME ": must give input filename or provide image data via stdin\n"); ++error; } else { #ifdef DOS_OS2_W32 /* some buggy C libraries require BOTH setmode() and fdopen(bin) */ setmode(fileno(stdin), O_BINARY); setmode(fileno(stdout), O_BINARY); #endif if ((wpng_info.infile = fdopen(fileno(stdin), "rb")) == NULL) { fprintf(stderr, PROGNAME ": unable to reopen stdin in binary mode\n"); ++error; } else if ((wpng_info.outfile = fdopen(fileno(stdout), "wb")) == NULL) { fprintf(stderr, PROGNAME ": unable to reopen stdout in binary mode\n"); fclose(wpng_info.infile); ++error; } else wpng_info.filter = TRUE; } } else if ((len = strlen(inname)) > 250) { fprintf(stderr, PROGNAME ": input filename is too long [%d chars]\n", len); ++error; } else if (!(wpng_info.infile = fopen(inname, "rb"))) { fprintf(stderr, PROGNAME ": can't open input file [%s]\n", inname); ++error; } if (!error) { fgets(pnmline, 256, wpng_info.infile); if (pnmline[0] != 'P' || ((pnmchar = pnmline[1]) != '5' && pnmchar != '6' && pnmchar != '8')) { fprintf(stderr, PROGNAME ": input file [%s] is not a binary PGM, PPM or PAM file\n", inname); ++error; } else { wpng_info.pnmtype = (int)(pnmchar - '0'); if (wpng_info.pnmtype != 8) wpng_info.have_bg = FALSE; /* no need for bg if opaque */ do { fgets(pnmline, 256, wpng_info.infile); /* lose any comments */ } while (pnmline[0] == '#'); sscanf(pnmline, "%ld %ld", &wpng_info.width, &wpng_info.height); do { fgets(pnmline, 256, wpng_info.infile); /* more comment lines */ } while (pnmline[0] == '#'); sscanf(pnmline, "%d", &maxval); if (wpng_info.width <= 0L || wpng_info.height <= 0L || maxval != 255) { fprintf(stderr, PROGNAME ": only positive width/height, maxval == 255 allowed \n"); ++error; } wpng_info.sample_depth = 8; /* <==> maxval 255 */ if (!wpng_info.filter) { /* make outname from inname */ if ((p = strrchr(inname, '.')) == NULL || (p - inname) != (len - 4)) { strcpy(outname, inname); strcpy(outname+len, ".png"); } else { len -= 4; strncpy(outname, inname, len); strcpy(outname+len, ".png"); } /* check if outname already exists; if not, open */ if ((wpng_info.outfile = fopen(outname, "rb")) != NULL) { fprintf(stderr, PROGNAME ": output file exists [%s]\n", outname); fclose(wpng_info.outfile); ++error; } else if (!(wpng_info.outfile = fopen(outname, "wb"))) { fprintf(stderr, PROGNAME ": can't open output file [%s]\n", outname); ++error; } } } if (error) { fclose(wpng_info.infile); wpng_info.infile = NULL; if (wpng_info.filter) { fclose(wpng_info.outfile); wpng_info.outfile = NULL; } } } /* if we had any errors, print usage and die horrible death...arrr! */ if (error) { fprintf(stderr, "\n%s %s: %s\n", PROGNAME, VERSION, APPNAME); writepng_version_info(); fprintf(stderr, "\n" "Usage: %s [-gamma exp] [-bgcolor bg] [-text] [-time] [-interlace] pnmfile\n" "or: ... | %s [-gamma exp] [-bgcolor bg] [-text] [-time] [-interlace] | ...\n" " exp \ttransfer-function exponent (``gamma'') of the image in\n" "\t\t floating-point format (e.g., ``%.5f''); if image looks\n" "\t\t correct on given display system, image gamma is equal to\n" "\t\t inverse of display-system exponent, i.e., 1 / (LUT * CRT)\n" "\t\t (where LUT = lookup-table exponent and CRT = CRT exponent;\n" "\t\t first varies, second is usually 2.2, all are positive)\n" " bg \tdesired background color for alpha-channel images, in\n" "\t\t 7-character hex RGB format (e.g., ``#ff7700'' for orange:\n" "\t\t same as HTML colors)\n" " -text\tprompt interactively for text info (tEXt chunks)\n" " -time\tinclude a tIME chunk (last modification time)\n" " -interlace\twrite interlaced PNG image\n" "\n" "pnmfile or stdin must be a binary PGM (`P5'), PPM (`P6') or (extremely\n" "unofficial and unsupported!) PAM (`P8') file. Currently it is required\n" "to have maxval == 255 (i.e., no scaling). If pnmfile is specified, it\n" "is converted to the corresponding PNG file with the same base name but a\n" "``.png'' extension; files read from stdin are converted and sent to stdout.\n" "The conversion is progressive (low memory usage) unless interlacing is\n" "requested; in that case the whole image will be buffered in memory and\n" "written in one call.\n" "\n", PROGNAME, PROGNAME, default_gamma); exit(1); } /* prepare the text buffers for libpng's use; note that even though * PNG's png_text struct includes a length field, we don't have to fill * it out */ if (text && #ifndef DOS_OS2_W32 (keybd = fdopen(fileno(stderr), "r")) != NULL && #endif (textbuf = (char *)malloc((5 + 9)*75)) != NULL) { int i, valid, result; fprintf(stderr, "Enter text info (no more than 72 characters per line);\n"); fprintf(stderr, "to skip a field, hit the key.\n"); /* note: just leaves len == 1 */ do { valid = TRUE; p = textbuf + TEXT_TITLE_OFFSET; fprintf(stderr, " Title: "); fflush(stderr); if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) { if (p[len-1] == '\n') p[--len] = '\0'; wpng_info.title = p; wpng_info.have_text |= TEXT_TITLE; if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) { fprintf(stderr, " " PROGNAME " warning: character code" " %u is %sdiscouraged by the PNG\n specification " "[first occurrence was at character position #%d]\n", (unsigned)p[result], (p[result] == 27)? "strongly " : "", result+1); fflush(stderr); #ifdef FORBID_LATIN1_CTRL wpng_info.have_text &= ~TEXT_TITLE; valid = FALSE; #else if (p[result] == 27) { /* escape character */ wpng_info.have_text &= ~TEXT_TITLE; valid = FALSE; } #endif } } } while (!valid); do { valid = TRUE; p = textbuf + TEXT_AUTHOR_OFFSET; fprintf(stderr, " Author: "); fflush(stderr); if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) { if (p[len-1] == '\n') p[--len] = '\0'; wpng_info.author = p; wpng_info.have_text |= TEXT_AUTHOR; if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) { fprintf(stderr, " " PROGNAME " warning: character code" " %u is %sdiscouraged by the PNG\n specification " "[first occurrence was at character position #%d]\n", (unsigned)p[result], (p[result] == 27)? "strongly " : "", result+1); fflush(stderr); #ifdef FORBID_LATIN1_CTRL wpng_info.have_text &= ~TEXT_AUTHOR; valid = FALSE; #else if (p[result] == 27) { /* escape character */ wpng_info.have_text &= ~TEXT_AUTHOR; valid = FALSE; } #endif } } } while (!valid); do { valid = TRUE; p = textbuf + TEXT_DESC_OFFSET; fprintf(stderr, " Description (up to 9 lines):\n"); for (i = 1; i < 10; ++i) { fprintf(stderr, " [%d] ", i); fflush(stderr); if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) p += len; /* now points at NULL; char before is newline */ else break; } if ((len = p - (textbuf + TEXT_DESC_OFFSET)) > 1) { if (p[-1] == '\n') { p[-1] = '\0'; --len; } wpng_info.desc = textbuf + TEXT_DESC_OFFSET; wpng_info.have_text |= TEXT_DESC; p = textbuf + TEXT_DESC_OFFSET; if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) { fprintf(stderr, " " PROGNAME " warning: character code" " %u is %sdiscouraged by the PNG\n specification " "[first occurrence was at character position #%d]\n", (unsigned)p[result], (p[result] == 27)? "strongly " : "", result+1); fflush(stderr); #ifdef FORBID_LATIN1_CTRL wpng_info.have_text &= ~TEXT_DESC; valid = FALSE; #else if (p[result] == 27) { /* escape character */ wpng_info.have_text &= ~TEXT_DESC; valid = FALSE; } #endif } } } while (!valid); do { valid = TRUE; p = textbuf + TEXT_COPY_OFFSET; fprintf(stderr, " Copyright: "); fflush(stderr); if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) { if (p[len-1] == '\n') p[--len] = '\0'; wpng_info.copyright = p; wpng_info.have_text |= TEXT_COPY; if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) { fprintf(stderr, " " PROGNAME " warning: character code" " %u is %sdiscouraged by the PNG\n specification " "[first occurrence was at character position #%d]\n", (unsigned)p[result], (p[result] == 27)? "strongly " : "", result+1); fflush(stderr); #ifdef FORBID_LATIN1_CTRL wpng_info.have_text &= ~TEXT_COPY; valid = FALSE; #else if (p[result] == 27) { /* escape character */ wpng_info.have_text &= ~TEXT_COPY; valid = FALSE; } #endif } } } while (!valid); do { valid = TRUE; p = textbuf + TEXT_EMAIL_OFFSET; fprintf(stderr, " E-mail: "); fflush(stderr); if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) { if (p[len-1] == '\n') p[--len] = '\0'; wpng_info.email = p; wpng_info.have_text |= TEXT_EMAIL; if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) { fprintf(stderr, " " PROGNAME " warning: character code" " %u is %sdiscouraged by the PNG\n specification " "[first occurrence was at character position #%d]\n", (unsigned)p[result], (p[result] == 27)? "strongly " : "", result+1); fflush(stderr); #ifdef FORBID_LATIN1_CTRL wpng_info.have_text &= ~TEXT_EMAIL; valid = FALSE; #else if (p[result] == 27) { /* escape character */ wpng_info.have_text &= ~TEXT_EMAIL; valid = FALSE; } #endif } } } while (!valid); do { valid = TRUE; p = textbuf + TEXT_URL_OFFSET; fprintf(stderr, " URL: "); fflush(stderr); if (FGETS(p, 74, keybd) && (len = strlen(p)) > 1) { if (p[len-1] == '\n') p[--len] = '\0'; wpng_info.url = p; wpng_info.have_text |= TEXT_URL; if ((result = wpng_isvalid_latin1((uch *)p, len)) >= 0) { fprintf(stderr, " " PROGNAME " warning: character code" " %u is %sdiscouraged by the PNG\n specification " "[first occurrence was at character position #%d]\n", (unsigned)p[result], (p[result] == 27)? "strongly " : "", result+1); fflush(stderr); #ifdef FORBID_LATIN1_CTRL wpng_info.have_text &= ~TEXT_URL; valid = FALSE; #else if (p[result] == 27) { /* escape character */ wpng_info.have_text &= ~TEXT_URL; valid = FALSE; } #endif } } } while (!valid); #ifndef DOS_OS2_W32 fclose(keybd); #endif } else if (text) { fprintf(stderr, PROGNAME ": unable to allocate memory for text\n"); text = FALSE; wpng_info.have_text = 0; } /* allocate libpng stuff, initialize transformations, write pre-IDAT data */ if ((rc = writepng_init(&wpng_info)) != 0) { switch (rc) { case 2: fprintf(stderr, PROGNAME ": libpng initialization problem (longjmp)\n"); break; case 4: fprintf(stderr, PROGNAME ": insufficient memory\n"); break; case 11: fprintf(stderr, PROGNAME ": internal logic error (unexpected PNM type)\n"); break; default: fprintf(stderr, PROGNAME ": unknown writepng_init() error\n"); break; } exit(rc); } /* free textbuf, since it's a completely local variable and all text info * has just been written to the PNG file */ if (text && textbuf) { free(textbuf); textbuf = NULL; } /* calculate rowbytes on basis of image type; note that this becomes much * more complicated if we choose to support PBM type, ASCII PNM types, or * 16-bit-per-sample binary data [currently not an official NetPBM type] */ if (wpng_info.pnmtype == 5) rowbytes = wpng_info.width; else if (wpng_info.pnmtype == 6) rowbytes = wpng_info.width * 3; else /* if (wpng_info.pnmtype == 8) */ rowbytes = wpng_info.width * 4; /* read and write the image, either in its entirety (if writing interlaced * PNG) or row by row (if non-interlaced) */ fprintf(stderr, "Encoding image data...\n"); fflush(stderr); if (wpng_info.interlaced) { long i; ulg bytes; ulg image_bytes; /* Guard against integer overflow */ if (wpng_info_height > ((size_t)(-1)/rowbytes || wpng_info_height > ((ulg)(-1)/rowbytes) { fprintf(stderr, PROGNAME ": image_data buffer too large\n"); writepng_cleanup(&wpng_info); wpng_cleanup(); exit(5); } image_bytes = rowbytes * wpng_info.height; wpng_info.image_data = (uch *)malloc(image_bytes); wpng_info.row_pointers = (uch **)malloc(wpng_info.height*sizeof(uch *)); if (wpng_info.image_data == NULL || wpng_info.row_pointers == NULL) { fprintf(stderr, PROGNAME ": insufficient memory for image data\n"); writepng_cleanup(&wpng_info); wpng_cleanup(); exit(5); } for (i = 0; i < wpng_info.height; ++i) wpng_info.row_pointers[i] = wpng_info.image_data + i*rowbytes; bytes = fread(wpng_info.image_data, 1, image_bytes, wpng_info.infile); if (bytes != image_bytes) { fprintf(stderr, PROGNAME ": expected %lu bytes, got %lu bytes\n", image_bytes, bytes); fprintf(stderr, " (continuing anyway)\n"); } if (writepng_encode_image(&wpng_info) != 0) { fprintf(stderr, PROGNAME ": libpng problem (longjmp) while writing image data\n"); writepng_cleanup(&wpng_info); wpng_cleanup(); exit(2); } } else /* not interlaced: write progressively (row by row) */ { long j; ulg bytes; wpng_info.image_data = (uch *)malloc(rowbytes); if (wpng_info.image_data == NULL) { fprintf(stderr, PROGNAME ": insufficient memory for row data\n"); writepng_cleanup(&wpng_info); wpng_cleanup(); exit(5); } error = 0; for (j = wpng_info.height; j > 0L; --j) { bytes = fread(wpng_info.image_data, 1, rowbytes, wpng_info.infile); if (bytes != rowbytes) { fprintf(stderr, PROGNAME ": expected %lu bytes, got %lu bytes (row %ld)\n", rowbytes, bytes, wpng_info.height-j); ++error; break; } if (writepng_encode_row(&wpng_info) != 0) { fprintf(stderr, PROGNAME ": libpng problem (longjmp) while writing row %ld\n", wpng_info.height-j); ++error; break; } } if (error) { writepng_cleanup(&wpng_info); wpng_cleanup(); exit(2); } if (writepng_encode_finish(&wpng_info) != 0) { fprintf(stderr, PROGNAME ": error on final libpng call\n"); writepng_cleanup(&wpng_info); wpng_cleanup(); exit(2); } } /* OK, we're done (successfully): clean up all resources and quit */ fprintf(stderr, "Done.\n"); fflush(stderr); writepng_cleanup(&wpng_info); wpng_cleanup(); return 0; } static int wpng_isvalid_latin1(uch *p, int len) { int i, result = -1; for (i = 0; i < len; ++i) { if (p[i] == 10 || (p[i] > 31 && p[i] < 127) || p[i] > 160) continue; /* character is completely OK */ if (result < 0 || (p[result] != 27 && p[i] == 27)) result = i; /* mark location of first questionable one */ } /* or of first escape character (bad) */ return result; } static void wpng_cleanup(void) { if (wpng_info.outfile) { fclose(wpng_info.outfile); wpng_info.outfile = NULL; } if (wpng_info.infile) { fclose(wpng_info.infile); wpng_info.infile = NULL; } if (wpng_info.image_data) { free(wpng_info.image_data); wpng_info.image_data = NULL; } if (wpng_info.row_pointers) { free(wpng_info.row_pointers); wpng_info.row_pointers = NULL; } } #ifdef DOS_OS2_W32 static char *dos_kbd_gets(char *buf, int len) { int ch, count=0; do { buf[count++] = ch = getche(); } while (ch != '\r' && count < len-1); buf[count--] = '\0'; /* terminate string */ if (buf[count] == '\r') /* Enter key makes CR, so change to newline */ buf[count] = '\n'; fprintf(stderr, "\n"); /* Enter key does *not* cause a newline */ fflush(stderr); return buf; } #endif /* DOS_OS2_W32 */ libpng-1.6.43/contrib/gregbook/writepng.c000066400000000000000000000317541456606525400203510ustar00rootroot00000000000000/*--------------------------------------------------------------------------- wpng - simple PNG-writing program writepng.c --------------------------------------------------------------------------- Copyright (c) 1998-2007, 2017 Greg Roelofs. All rights reserved. This software is provided "as is," without warranty of any kind, express or implied. In no event shall the author or contributors be held liable for any damages arising in any way from the use of this software. The contents of this file are DUAL-LICENSED. You may modify and/or redistribute this software according to the terms of one of the following two licenses (at your option): LICENSE 1 ("BSD-like with advertising clause"): Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. Redistributions of source code must retain the above copyright notice, disclaimer, and this list of conditions. 2. Redistributions in binary form must reproduce the above copyright notice, disclaimer, and this list of conditions in the documenta- tion and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgment: This product includes software developed by Greg Roelofs and contributors for the book, "PNG: The Definitive Guide," published by O'Reilly and Associates. LICENSE 2 (GNU GPL v2 or later): This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ---------------------------------------------------------------------------*/ #include /* for exit() prototype */ #include #include "png.h" /* libpng header, includes setjmp.h */ #include "writepng.h" /* typedefs, common macros, public prototypes */ /* local prototype */ static void writepng_error_handler(png_structp png_ptr, png_const_charp msg); void writepng_version_info(void) { fprintf(stderr, " Compiled with libpng %s; using libpng %s.\n", PNG_LIBPNG_VER_STRING, png_libpng_ver); fprintf(stderr, " Compiled with zlib %s; using zlib %s.\n", ZLIB_VERSION, zlib_version); } /* returns 0 for success, 2 for libpng problem, 4 for out of memory, 11 for * unexpected pnmtype; note that outfile might be stdout */ int writepng_init(mainprog_info *mainprog_ptr) { png_structp png_ptr; /* note: temporary variables! */ png_infop info_ptr; int color_type, interlace_type; /* could also replace libpng warning-handler (final NULL), but no need: */ png_ptr = png_create_write_struct(png_get_libpng_ver(NULL), mainprog_ptr, writepng_error_handler, NULL); if (!png_ptr) return 4; /* out of memory */ info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_write_struct(&png_ptr, NULL); return 4; /* out of memory */ } /* setjmp() must be called in every function that calls a PNG-writing * libpng function, unless an alternate error handler was installed-- * but compatible error handlers must either use longjmp() themselves * (as in this program) or some other method to return control to * application code, so here we go: */ if (setjmp(mainprog_ptr->jmpbuf)) { png_destroy_write_struct(&png_ptr, &info_ptr); return 2; } /* make sure outfile is (re)opened in BINARY mode */ png_init_io(png_ptr, mainprog_ptr->outfile); /* set the compression levels--in general, always want to leave filtering * turned on (except for palette images) and allow all of the filters, * which is the default; want 32K zlib window, unless entire image buffer * is 16K or smaller (unknown here)--also the default; usually want max * compression (NOT the default); and remaining compression flags should * be left alone */ png_set_compression_level(png_ptr, Z_BEST_COMPRESSION); /* >> this is default for no filtering; Z_FILTERED is default otherwise: png_set_compression_strategy(png_ptr, Z_DEFAULT_STRATEGY); >> these are all defaults: png_set_compression_mem_level(png_ptr, 8); png_set_compression_window_bits(png_ptr, 15); png_set_compression_method(png_ptr, 8); */ /* set the image parameters appropriately */ if (mainprog_ptr->pnmtype == 5) color_type = PNG_COLOR_TYPE_GRAY; else if (mainprog_ptr->pnmtype == 6) color_type = PNG_COLOR_TYPE_RGB; else if (mainprog_ptr->pnmtype == 8) color_type = PNG_COLOR_TYPE_RGB_ALPHA; else { png_destroy_write_struct(&png_ptr, &info_ptr); return 11; } interlace_type = mainprog_ptr->interlaced? PNG_INTERLACE_ADAM7 : PNG_INTERLACE_NONE; png_set_IHDR(png_ptr, info_ptr, mainprog_ptr->width, mainprog_ptr->height, mainprog_ptr->sample_depth, color_type, interlace_type, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); if (mainprog_ptr->gamma > 0.0) png_set_gAMA(png_ptr, info_ptr, mainprog_ptr->gamma); if (mainprog_ptr->have_bg) { /* we know it's RGBA, not gray+alpha */ png_color_16 background; background.red = mainprog_ptr->bg_red; background.green = mainprog_ptr->bg_green; background.blue = mainprog_ptr->bg_blue; png_set_bKGD(png_ptr, info_ptr, &background); } if (mainprog_ptr->have_time) { png_time modtime; png_convert_from_time_t(&modtime, mainprog_ptr->modtime); png_set_tIME(png_ptr, info_ptr, &modtime); } if (mainprog_ptr->have_text) { png_text text[6]; int num_text = 0; if (mainprog_ptr->have_text & TEXT_TITLE) { text[num_text].compression = PNG_TEXT_COMPRESSION_NONE; text[num_text].key = "Title"; text[num_text].text = mainprog_ptr->title; ++num_text; } if (mainprog_ptr->have_text & TEXT_AUTHOR) { text[num_text].compression = PNG_TEXT_COMPRESSION_NONE; text[num_text].key = "Author"; text[num_text].text = mainprog_ptr->author; ++num_text; } if (mainprog_ptr->have_text & TEXT_DESC) { text[num_text].compression = PNG_TEXT_COMPRESSION_NONE; text[num_text].key = "Description"; text[num_text].text = mainprog_ptr->desc; ++num_text; } if (mainprog_ptr->have_text & TEXT_COPY) { text[num_text].compression = PNG_TEXT_COMPRESSION_NONE; text[num_text].key = "Copyright"; text[num_text].text = mainprog_ptr->copyright; ++num_text; } if (mainprog_ptr->have_text & TEXT_EMAIL) { text[num_text].compression = PNG_TEXT_COMPRESSION_NONE; text[num_text].key = "E-mail"; text[num_text].text = mainprog_ptr->email; ++num_text; } if (mainprog_ptr->have_text & TEXT_URL) { text[num_text].compression = PNG_TEXT_COMPRESSION_NONE; text[num_text].key = "URL"; text[num_text].text = mainprog_ptr->url; ++num_text; } png_set_text(png_ptr, info_ptr, text, num_text); } /* write all chunks up to (but not including) first IDAT */ png_write_info(png_ptr, info_ptr); /* if we wanted to write any more text info *after* the image data, we * would set up text struct(s) here and call png_set_text() again, with * just the new data; png_set_tIME() could also go here, but it would * have no effect since we already called it above (only one tIME chunk * allowed) */ /* set up the transformations: for now, just pack low-bit-depth pixels * into bytes (one, two or four pixels per byte) */ png_set_packing(png_ptr); /* png_set_shift(png_ptr, &sig_bit); to scale low-bit-depth values */ /* make sure we save our pointers for use in writepng_encode_image() */ mainprog_ptr->png_ptr = png_ptr; mainprog_ptr->info_ptr = info_ptr; /* OK, that's all we need to do for now; return happy */ return 0; } /* returns 0 for success, 2 for libpng (longjmp) problem */ int writepng_encode_image(mainprog_info *mainprog_ptr) { png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr; png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr; /* as always, setjmp() must be called in every function that calls a * PNG-writing libpng function */ if (setjmp(mainprog_ptr->jmpbuf)) { png_destroy_write_struct(&png_ptr, &info_ptr); mainprog_ptr->png_ptr = NULL; mainprog_ptr->info_ptr = NULL; return 2; } /* and now we just write the whole image; libpng takes care of interlacing * for us */ png_write_image(png_ptr, mainprog_ptr->row_pointers); /* since that's it, we also close out the end of the PNG file now--if we * had any text or time info to write after the IDATs, second argument * would be info_ptr, but we optimize slightly by sending NULL pointer: */ png_write_end(png_ptr, NULL); return 0; } /* returns 0 if succeeds, 2 if libpng problem */ int writepng_encode_row(mainprog_info *mainprog_ptr) /* NON-interlaced only! */ { png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr; png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr; /* as always, setjmp() must be called in every function that calls a * PNG-writing libpng function */ if (setjmp(mainprog_ptr->jmpbuf)) { png_destroy_write_struct(&png_ptr, &info_ptr); mainprog_ptr->png_ptr = NULL; mainprog_ptr->info_ptr = NULL; return 2; } /* image_data points at our one row of image data */ png_write_row(png_ptr, mainprog_ptr->image_data); return 0; } /* returns 0 if succeeds, 2 if libpng problem */ int writepng_encode_finish(mainprog_info *mainprog_ptr) /* NON-interlaced! */ { png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr; png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr; /* as always, setjmp() must be called in every function that calls a * PNG-writing libpng function */ if (setjmp(mainprog_ptr->jmpbuf)) { png_destroy_write_struct(&png_ptr, &info_ptr); mainprog_ptr->png_ptr = NULL; mainprog_ptr->info_ptr = NULL; return 2; } /* close out PNG file; if we had any text or time info to write after * the IDATs, second argument would be info_ptr: */ png_write_end(png_ptr, NULL); return 0; } void writepng_cleanup(mainprog_info *mainprog_ptr) { png_structp png_ptr = (png_structp)mainprog_ptr->png_ptr; png_infop info_ptr = (png_infop)mainprog_ptr->info_ptr; if (png_ptr && info_ptr) png_destroy_write_struct(&png_ptr, &info_ptr); } static void writepng_error_handler(png_structp png_ptr, png_const_charp msg) { mainprog_info *mainprog_ptr; /* This function, aside from the extra step of retrieving the "error * pointer" (below) and the fact that it exists within the application * rather than within libpng, is essentially identical to libpng's * default error handler. The second point is critical: since both * setjmp() and longjmp() are called from the same code, they are * guaranteed to have compatible notions of how big a jmp_buf is, * regardless of whether _BSD_SOURCE or anything else has (or has not) * been defined. */ fprintf(stderr, "writepng libpng error: %s\n", msg); fflush(stderr); mainprog_ptr = png_get_error_ptr(png_ptr); if (mainprog_ptr == NULL) { /* we are completely hosed now */ fprintf(stderr, "writepng severe error: jmpbuf not recoverable; terminating.\n"); fflush(stderr); exit(99); } /* Now we have our data structure we can use the information in it * to return control to our own higher level code (all the points * where 'setjmp' is called in this file.) This will work with other * error handling mechanisms as well - libpng always calls png_error * when it can proceed no further, thus, so long as the error handler * is intercepted, application code can do its own error recovery. */ longjmp(mainprog_ptr->jmpbuf, 1); } libpng-1.6.43/contrib/gregbook/writepng.h000066400000000000000000000102151456606525400203430ustar00rootroot00000000000000/*--------------------------------------------------------------------------- wpng - simple PNG-writing program writepng.h --------------------------------------------------------------------------- Copyright (c) 1998-2007 Greg Roelofs. All rights reserved. This software is provided "as is," without warranty of any kind, express or implied. In no event shall the author or contributors be held liable for any damages arising in any way from the use of this software. The contents of this file are DUAL-LICENSED. You may modify and/or redistribute this software according to the terms of one of the following two licenses (at your option): LICENSE 1 ("BSD-like with advertising clause"): Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. Redistributions of source code must retain the above copyright notice, disclaimer, and this list of conditions. 2. Redistributions in binary form must reproduce the above copyright notice, disclaimer, and this list of conditions in the documenta- tion and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgment: This product includes software developed by Greg Roelofs and contributors for the book, "PNG: The Definitive Guide," published by O'Reilly and Associates. LICENSE 2 (GNU GPL v2 or later): This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ---------------------------------------------------------------------------*/ #ifndef TRUE # define TRUE 1 # define FALSE 0 #endif #ifndef MAX # define MAX(a,b) ((a) > (b)? (a) : (b)) # define MIN(a,b) ((a) < (b)? (a) : (b)) #endif #ifdef DEBUG # define Trace(x) {fprintf x ; fflush(stderr); fflush(stdout);} #else # define Trace(x) ; #endif #define TEXT_TITLE 0x01 #define TEXT_AUTHOR 0x02 #define TEXT_DESC 0x04 #define TEXT_COPY 0x08 #define TEXT_EMAIL 0x10 #define TEXT_URL 0x20 #define TEXT_TITLE_OFFSET 0 #define TEXT_AUTHOR_OFFSET 72 #define TEXT_COPY_OFFSET (2*72) #define TEXT_EMAIL_OFFSET (3*72) #define TEXT_URL_OFFSET (4*72) #define TEXT_DESC_OFFSET (5*72) typedef unsigned char uch; typedef unsigned short ush; typedef unsigned long ulg; typedef struct _mainprog_info { double gamma; long width; long height; time_t modtime; FILE *infile; FILE *outfile; void *png_ptr; void *info_ptr; uch *image_data; uch **row_pointers; char *title; char *author; char *desc; char *copyright; char *email; char *url; int filter; /* command-line-filter flag, not PNG row filter! */ int pnmtype; int sample_depth; int interlaced; int have_bg; int have_time; int have_text; jmp_buf jmpbuf; uch bg_red; uch bg_green; uch bg_blue; } mainprog_info; /* prototypes for public functions in writepng.c */ void writepng_version_info(void); int writepng_init(mainprog_info *mainprog_ptr); int writepng_encode_image(mainprog_info *mainprog_ptr); int writepng_encode_row(mainprog_info *mainprog_ptr); int writepng_encode_finish(mainprog_info *mainprog_ptr); void writepng_cleanup(mainprog_info *mainprog_ptr); libpng-1.6.43/contrib/libtests/000077500000000000000000000000001456606525400163665ustar00rootroot00000000000000libpng-1.6.43/contrib/libtests/fakepng.c000066400000000000000000000024101456606525400201420ustar00rootroot00000000000000/* Fake a PNG - just write it out directly. * * COPYRIGHT: Written by John Cunningham Bowler, 2014. * To the extent possible under law, the author has waived all copyright and * related or neighboring rights to this work. This work is published from: * United States. * */ #include #include /* for crc32 */ void put_uLong(uLong val) { putchar(val >> 24); putchar(val >> 16); putchar(val >> 8); putchar(val >> 0); } void put_chunk(const unsigned char *chunk, uInt length) { uLong crc; put_uLong(length-4); /* Exclude the tag */ fwrite(chunk, length, 1, stdout); crc = crc32(0, Z_NULL, 0); put_uLong(crc32(crc, chunk, length)); } const unsigned char signature[] = { 137, 80, 78, 71, 13, 10, 26, 10 }; const unsigned char IHDR[] = { 73, 72, 68, 82, /* IHDR */ 0, 0, 0, 1, /* width */ 0, 0, 0, 1, /* height */ 1, /* bit depth */ 0, /* color type: greyscale */ 0, /* compression method */ 0, /* filter method */ 0 /* interlace method: none */ }; const unsigned char unknown[] = { 'u', 'n', 'K', 'n' /* "unKn" - private safe to copy */ }; int main(void) { fwrite(signature, sizeof signature, 1, stdout); put_chunk(IHDR, sizeof IHDR); for (;;) put_chunk(unknown, sizeof unknown); } libpng-1.6.43/contrib/libtests/gentests.sh000077500000000000000000000042451456606525400205660ustar00rootroot00000000000000#!/bin/sh # # Copyright (c) 2013 John Cunningham Bowler # # This code is released under the libpng license. # For conditions of distribution and use, see the disclaimer # and license in png.h # # Generate a set of PNG test images. The images are generated in a # sub-directory called 'tests' by default, however a command line argument will # change that name. The generation requires a built version of makepng in the # current directory. # usage(){ exec >&2 echo "$0 []" echo ' Generate a set of PNG test files in "directory" ("tests" by default)' exit 1 } mp="$PWD/makepng" test -x "$mp" || { exec >&2 echo "$0: the 'makepng' program must exist" echo " in the directory within which this program:" echo " $mp" echo " is executed" usage } # Just one argument: the directory testdir="tests" test $# -gt 1 && { testdir="$1" shift } test $# -eq 0 || usage # Take care not to clobber something if test -e "$testdir" then test -d "$testdir" || usage else # mkdir -p isn't portable, so do the following mkdir "$testdir" 2>/dev/null || mkdir -p "$testdir" || usage fi # This fails in a very satisfactory way if it's not accessible cd "$testdir" :>"test$$.png" || { exec >&2 echo "$testdir: directory not writable" usage } rm "test$$.png" || { exec >&2 echo "$testdir: you have create but not write privileges here." echo " This is unexpected. You have a spurion; "'"'"test$$.png"'"'"." echo " You need to remove this yourself. Try a different directory." exit 1 } # Now call makepng ($mp) to create every file we can think of with a # reasonable name doit(){ for gamma in "" --sRGB --linear --1.8 do case "$gamma" in "") gname=;; --sRGB) gname="-srgb";; --linear) gname="-lin";; --1.8) gname="-18";; *) gname="-$gamma";; esac "$mp" $gamma "$1" "$2" "test-$1-$2$gname.png" done } # for ct in gray palette do for bd in 1 2 4 8 do doit "$ct" "$bd" done done # doit "gray" "16" # for ct in gray-alpha rgb rgb-alpha do for bd in 8 16 do doit "$ct" "$bd" done done libpng-1.6.43/contrib/libtests/makepng.c000066400000000000000000001517451456606525400201710ustar00rootroot00000000000000/* makepng.c */ #define _ISOC99_SOURCE /* Copyright: */ #define COPYRIGHT "\251 2013,2015 John Cunningham Bowler" /* * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer * and license in png.h * * Make a test PNG image. The arguments are as follows: * * makepng [--sRGB|--linear|--1.8] [--tRNS] [--nofilters] \ * color-type bit-depth [file-name] * * The color-type may be numeric (and must match the numbers used by the PNG * specification) or one of the format names listed below. The bit-depth is the * component bit depth, or the pixel bit-depth for a color-mapped image. * * Without any options no color-space information is written, with the options * an sRGB or the appropriate gAMA chunk is written. "1.8" refers to the * display system used on older Apple computers to correct for high ambient * light levels in the viewing environment; it applies a transform of * approximately value^(1/1.45) to the color values and so a gAMA chunk of 65909 * is written (1.45/2.2). * * The image data is generated internally. Unless --color is given the images * used are as follows: * * 1 channel: a square image with a diamond, the least luminous colors are on * the edge of the image, the most luminous in the center. * * 2 channels: the color channel increases in luminosity from top to bottom, the * alpha channel increases in opacity from left to right. * * 3 channels: linear combinations of, from the top-left corner clockwise, * black, green, white, red. * * 4 channels: linear combinations of, from the top-left corner clockwise, * transparent, red, green, blue. * * For color-mapped images a four channel color-map is used and if --tRNS is * given the PNG file has a tRNS chunk, as follows: * * 1-bit: entry 0 is transparent-red, entry 1 is opaque-white * 2-bit: entry 0: transparent-green * entry 1: 40%-red * entry 2: 80%-blue * entry 3: opaque-white * 4-bit: the 16 combinations of the 2-bit case * 8-bit: the 256 combinations of the 4-bit case * * The palette always has 2^bit-depth entries and the tRNS chunk one fewer. The * image is the 1-channel diamond, but using palette index, not luminosity. * * For formats other than color-mapped ones if --tRNS is specified a tRNS chunk * is generated with all channels equal to the low bits of 0x0101. * * Image size is determined by the final pixel depth in bits, i.e. channels x * bit-depth, as follows: * * 8 bits or less: 64x64 * 16 bits: 256x256 * More than 16 bits: 1024x1024 * * Row filtering is the libpng default but may be turned off (the 'none' filter * is used on every row) with the --nofilters option. * * The images are not interlaced. * * If file-name is given then the PNG is written to that file, else it is * written to stdout. Notice that stdout is not supported on systems where, by * default, it assumes text output; this program makes no attempt to change the * text mode of stdout! * * makepng --color= ... * * If --color is given then the whole image has that color, color-mapped images * will have exactly one palette entry and all image files with be 16x16 in * size. The color value is 1 to 4 decimal numbers as appropriate for the color * type. * * makepng --small ... * * If --small is given the images are no larger than required to include every * possible pixel value for the format. * * For formats with pixels 8 bits or fewer in size the images consist of a * single row with 2^pixel-depth pixels, one of every possible value. * * For formats with 16-bit pixels a 256x256 image is generated containing every * possible pixel value. * * For larger pixel sizes a 256x256 image is generated where the first row * consists of each pixel that has identical byte values throughout the pixel * followed by rows where the byte values differ within the pixel. * * In all cases the pixel values are arranged in such a way that the SUB and UP * filters give byte sequences for maximal zlib compression. By default (if * --nofilters is not given) the SUB filter is used on the first row and the UP * filter on all following rows. * * The --small option is meant to provide good test-case coverage, however the * images are not easy to examine visually. Without the --small option the * images contain identical color values; the pixel values are adjusted * according to the gamma encoding with no gamma encoding being interpreted as * sRGB. * * LICENSING * ========= * * This code is copyright of the authors, see the COPYRIGHT define above. The * code is licensed as above, using the libpng license. The code generates * images which are solely the product of the code; the options choose which of * the many possibilities to generate. The images that result (but not the code * which generates them) are licensed as defined here: * * IMPORTANT: the COPYRIGHT #define must contain ISO-Latin-1 characters, the * IMAGE_LICENSING #define must contain UTF-8 characters. The 'copyright' * symbol 0xA9U (\251) in ISO-Latin-1 encoding and 0xC20xA9 (\302\251) in UTF-8. */ #define IMAGE_LICENSING "Dedicated to the public domain per Creative Commons "\ "license \"CC0 1.0\"; https://creativecommons.org/publicdomain/zero/1.0/" #include /* for offsetof */ #include #include #include #include #include #include #include #include #if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H) # include #endif /* Define the following to use this test against your installed libpng, rather * than the one being built here: */ #ifdef PNG_FREESTANDING_TESTS # include #else # include "../../png.h" #endif #include /* Work round for GCC complaints about casting a (double) function result to * an unsigned: */ static unsigned int flooru(double d) { d = floor(d); return (unsigned int)d; } static png_byte floorb(double d) { d = floor(d); return (png_byte)d; } /* This structure is used for inserting extra chunks (the --insert argument, not * documented above.) */ typedef struct chunk_insert { struct chunk_insert *next; void (*insert)(png_structp, png_infop, int, png_charpp); int nparams; png_charp parameters[1]; } chunk_insert; static unsigned int channels_of_type(int color_type) { if (color_type & PNG_COLOR_MASK_PALETTE) return 1; else { int channels = 1; if (color_type & PNG_COLOR_MASK_COLOR) channels = 3; if (color_type & PNG_COLOR_MASK_ALPHA) return channels + 1; else return channels; } } static unsigned int pixel_depth_of_type(int color_type, int bit_depth) { return channels_of_type(color_type) * bit_depth; } static unsigned int image_size_of_type(int color_type, int bit_depth, unsigned int *colors, int small) { if (*colors) return 16; else { int pixel_depth = pixel_depth_of_type(color_type, bit_depth); if (small) { if (pixel_depth <= 8) /* there will be one row */ return 1 << pixel_depth; else return 256; } else if (pixel_depth < 8) return 64; else if (pixel_depth > 16) return 1024; else return 256; } } static void set_color(png_colorp color, png_bytep trans, unsigned int red, unsigned int green, unsigned int blue, unsigned int alpha, png_const_bytep gamma_table) { color->red = gamma_table[red]; color->green = gamma_table[green]; color->blue = gamma_table[blue]; *trans = (png_byte)alpha; } static int generate_palette(png_colorp palette, png_bytep trans, int bit_depth, png_const_bytep gamma_table, unsigned int *colors) { /* * 1-bit: entry 0 is transparent-red, entry 1 is opaque-white * 2-bit: entry 0: transparent-green * entry 1: 40%-red * entry 2: 80%-blue * entry 3: opaque-white * 4-bit: the 16 combinations of the 2-bit case * 8-bit: the 256 combinations of the 4-bit case */ switch (colors[0]) { default: fprintf(stderr, "makepng: --colors=...: invalid count %u\n", colors[0]); exit(1); case 1: set_color(palette+0, trans+0, colors[1], colors[1], colors[1], 255, gamma_table); return 1; case 2: set_color(palette+0, trans+0, colors[1], colors[1], colors[1], colors[2], gamma_table); return 1; case 3: set_color(palette+0, trans+0, colors[1], colors[2], colors[3], 255, gamma_table); return 1; case 4: set_color(palette+0, trans+0, colors[1], colors[2], colors[3], colors[4], gamma_table); return 1; case 0: if (bit_depth == 1) { set_color(palette+0, trans+0, 255, 0, 0, 0, gamma_table); set_color(palette+1, trans+1, 255, 255, 255, 255, gamma_table); return 2; } else { unsigned int size = 1U << (bit_depth/2); /* 2, 4 or 16 */ unsigned int x, y; volatile unsigned int ip = 0; for (x=0; x> 3; if (offset < rowbytes && (bit_depth < 16 || offset+1 < rowbytes)) { row += offset; switch (bit_depth) { case 1: case 2: case 4: /* Don't gamma correct - values get smashed */ { unsigned int shift = (8 - bit_depth) - (x & 0x7U); mask <<= shift; value = (value << shift) & mask; *row = (png_byte)((*row & ~mask) | value); } return; default: fprintf(stderr, "makepng: bad bit depth (internal error)\n"); exit(1); case 16: value = flooru(65535*pow(value/65535.,conv)+.5); *row++ = (png_byte)(value >> 8); *row = (png_byte)value; return; case 8: *row = gamma_table[value]; return; } } else { fprintf(stderr, "makepng: row buffer overflow (internal error)\n"); exit(1); } } else { fprintf(stderr, "makepng: component overflow (internal error)\n"); exit(1); } } static int /* filter mask for row */ generate_row(png_bytep row, size_t rowbytes, unsigned int y, int color_type, int bit_depth, png_const_bytep gamma_table, double conv, unsigned int *colors, int small) { int filters = 0; /* file *MASK*, 0 means the default, not NONE */ png_uint_32 size_max = image_size_of_type(color_type, bit_depth, colors, small)-1; png_uint_32 depth_max = (1U << bit_depth)-1; /* up to 65536 */ if (colors[0] == 0 && small) { unsigned int pixel_depth = pixel_depth_of_type(color_type, bit_depth); /* For pixel depths less than 16 generate a single row containing all the * possible pixel values. For 16 generate all 65536 byte pair * combinations in a 256x256 pixel array. */ switch (pixel_depth) { case 1: assert(y == 0 && rowbytes == 1 && size_max == 1); row[0] = 0x6CU; /* binary: 01101100, only top 2 bits used */ filters = PNG_FILTER_NONE; break; case 2: assert(y == 0 && rowbytes == 1 && size_max == 3); row[0] = 0x1BU; /* binary 00011011, all bits used */ filters = PNG_FILTER_NONE; break; case 4: assert(y == 0 && rowbytes == 8 && size_max == 15); row[0] = 0x01U; row[1] = 0x23U; /* SUB gives 0x22U for all following bytes */ row[2] = 0x45U; row[3] = 0x67U; row[4] = 0x89U; row[5] = 0xABU; row[6] = 0xCDU; row[7] = 0xEFU; filters = PNG_FILTER_SUB; break; case 8: /* The row will have all the pixel values in order starting with * '1', the SUB filter will change every byte into '1' (including * the last, which generates pixel value '0'). Since the SUB filter * has value 1 this should result in maximum compression. */ assert(y == 0 && rowbytes == 256 && size_max == 255); for (;;) { row[size_max] = 0xFFU & (size_max+1); if (size_max == 0) break; --size_max; } filters = PNG_FILTER_SUB; break; case 16: /* Rows are generated such that each row has a constant difference * between the first and second byte of each pixel and so that the * difference increases by 1 at each row. The rows start with the * first byte value of 0 and the value increases to 255 across the * row. * * The difference starts at 1, so the first row is: * * 0 1 1 2 2 3 3 4 ... 254 255 255 0 * * This means that running the SUB filter on the first row produces: * * [SUB==1] 0 1 0 1 0 1... * * Then the difference is 2 on the next row, giving: * * 0 2 1 3 2 4 3 5 ... 254 0 255 1 * * When the UP filter is run on this libpng produces: * * [UP ==2] 0 1 0 1 0 1... * * And so on for all the remain rows to the final two * rows: * * row 254: 0 255 1 0 2 1 3 2 4 3 ... 254 253 255 254 * row 255: 0 0 1 1 2 2 3 3 4 4 ... 254 254 255 255 */ assert(rowbytes == 512 && size_max == 255); for (;;) { row[2*size_max ] = 0xFFU & size_max; row[2*size_max+1] = 0xFFU & (size_max+y+1); if (size_max == 0) break; --size_max; } /* The first row must include PNG_FILTER_UP so that libpng knows we * need to keep it for the following row: */ filters = (y == 0 ? PNG_FILTER_SUB+PNG_FILTER_UP : PNG_FILTER_UP); break; case 24: case 32: case 48: case 64: /* The rows are filled by an algorithm similar to the above, in the * first row pixel bytes are all equal, increasing from 0 by 1 for * each pixel. In the second row the bytes within a pixel are * incremented 1,3,5,7,... from the previous row byte. Using an odd * number ensures all the possible byte values are used. */ assert(size_max == 255 && rowbytes == 256*(pixel_depth>>3)); pixel_depth >>= 3; /* now in bytes */ while (rowbytes > 0) { const size_t pixel_index = --rowbytes/pixel_depth; if (y == 0) row[rowbytes] = 0xFFU & pixel_index; else { const size_t byte_offset = rowbytes - pixel_index * pixel_depth; row[rowbytes] = 0xFFU & (pixel_index + (byte_offset * 2*y) + 1); } } filters = (y == 0 ? PNG_FILTER_SUB+PNG_FILTER_UP : PNG_FILTER_UP); break; default: assert(0/*NOT REACHED*/); } } else switch (channels_of_type(color_type)) { /* 1 channel: a square image with a diamond, the least luminous colors are on * the edge of the image, the most luminous in the center. */ case 1: { png_uint_32 x; png_uint_32 base = 2*size_max - abs(2*y-size_max); for (x=0; x<=size_max; ++x) { png_uint_32 luma = base - abs(2*x-size_max); /* 'luma' is now in the range 0..2*size_max, we need * 0..depth_max */ luma = (luma*depth_max + size_max) / (2*size_max); set_value(row, rowbytes, x, bit_depth, luma, gamma_table, conv); } } break; /* 2 channels: the color channel increases in luminosity from top to bottom, * the alpha channel increases in opacity from left to right. */ case 2: { png_uint_32 alpha = (depth_max * y * 2 + size_max) / (2 * size_max); png_uint_32 x; for (x=0; x<=size_max; ++x) { set_value(row, rowbytes, 2*x, bit_depth, (depth_max * x * 2 + size_max) / (2 * size_max), gamma_table, conv); set_value(row, rowbytes, 2*x+1, bit_depth, alpha, gamma_table, conv); } } break; /* 3 channels: linear combinations of, from the top-left corner clockwise, * black, green, white, red. */ case 3: { /* x0: the black->red scale (the value of the red component) at the * start of the row (blue and green are 0). * x1: the green->white scale (the value of the red and blue * components at the end of the row; green is depth_max). */ png_uint_32 Y = (depth_max * y * 2 + size_max) / (2 * size_max); png_uint_32 x; /* Interpolate x/depth_max from start to end: * * start end difference * red: Y Y 0 * green: 0 depth_max depth_max * blue: 0 Y Y */ for (x=0; x<=size_max; ++x) { set_value(row, rowbytes, 3*x+0, bit_depth, /* red */ Y, gamma_table, conv); set_value(row, rowbytes, 3*x+1, bit_depth, /* green */ (depth_max * x * 2 + size_max) / (2 * size_max), gamma_table, conv); set_value(row, rowbytes, 3*x+2, bit_depth, /* blue */ (Y * x * 2 + size_max) / (2 * size_max), gamma_table, conv); } } break; /* 4 channels: linear combinations of, from the top-left corner clockwise, * transparent, red, green, blue. */ case 4: { /* x0: the transparent->blue scale (the value of the blue and alpha * components) at the start of the row (red and green are 0). * x1: the red->green scale (the value of the red and green * components at the end of the row; blue is 0 and alpha is * depth_max). */ png_uint_32 Y = (depth_max * y * 2 + size_max) / (2 * size_max); png_uint_32 x; /* Interpolate x/depth_max from start to end: * * start end difference * red: 0 depth_max-Y depth_max-Y * green: 0 Y Y * blue: Y 0 -Y * alpha: Y depth_max depth_max-Y */ for (x=0; x<=size_max; ++x) { set_value(row, rowbytes, 4*x+0, bit_depth, /* red */ ((depth_max-Y) * x * 2 + size_max) / (2 * size_max), gamma_table, conv); set_value(row, rowbytes, 4*x+1, bit_depth, /* green */ (Y * x * 2 + size_max) / (2 * size_max), gamma_table, conv); set_value(row, rowbytes, 4*x+2, bit_depth, /* blue */ Y - (Y * x * 2 + size_max) / (2 * size_max), gamma_table, conv); set_value(row, rowbytes, 4*x+3, bit_depth, /* alpha */ Y + ((depth_max-Y) * x * 2 + size_max) / (2 * size_max), gamma_table, conv); } } break; default: fprintf(stderr, "makepng: internal bad channel count\n"); exit(2); } else if (color_type & PNG_COLOR_MASK_PALETTE) { /* Palette with fixed color: the image rows are all 0 and the image width * is 16. */ memset(row, 0, rowbytes); } else if (colors[0] == channels_of_type(color_type)) switch (channels_of_type(color_type)) { case 1: { png_uint_32 luma = colors[1]; png_uint_32 x; for (x=0; x<=size_max; ++x) set_value(row, rowbytes, x, bit_depth, luma, gamma_table, conv); } break; case 2: { png_uint_32 luma = colors[1]; png_uint_32 alpha = colors[2]; png_uint_32 x; for (x=0; x 0 && gamma < 1000) gamma = PNG_FP_1; if (gamma > 0) real_gamma = gamma; { unsigned int i; if (real_gamma == 45455) { for (i=0; i<256; ++i) { gamma_table[i] = (png_byte)i; conv = 1.; } } else { /* Convert 'i' from sRGB (45455) to real_gamma, this makes * the images look the same regardless of the gAMA chunk. */ conv = real_gamma; conv /= 45455; gamma_table[0] = 0; for (i=1; i<255; ++i) gamma_table[i] = floorb(pow(i/255.,conv) * 255 + .5); gamma_table[255] = 255; } } png_set_IHDR(png_ptr, info_ptr, size, ysize, bit_depth, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); if (color_type & PNG_COLOR_MASK_PALETTE) { int npalette; png_color palette[256]; png_byte trans[256]; npalette = generate_palette(palette, trans, bit_depth, gamma_table, colors); png_set_PLTE(png_ptr, info_ptr, palette, npalette); if (tRNS) png_set_tRNS(png_ptr, info_ptr, trans, npalette-1, NULL/*transparent color*/); /* Reset gamma_table to prevent the image rows being changed */ for (npalette=0; npalette<256; ++npalette) gamma_table[npalette] = (png_byte)npalette; } else if (tRNS) { png_color_16 col; col.red = col.green = col.blue = col.gray = 0x0101U & ((1U< 0) /* Else don't set color space information */ { png_set_gAMA_fixed(png_ptr, info_ptr, real_gamma); /* Just use the sRGB values here. */ png_set_cHRM_fixed(png_ptr, info_ptr, /* color x y */ /* white */ 31270, 32900, /* red */ 64000, 33000, /* green */ 30000, 60000, /* blue */ 15000, 6000 ); } /* Insert extra information. */ while (insert != NULL) { insert->insert(png_ptr, info_ptr, insert->nparams, insert->parameters); insert = insert->next; } /* Write the file header. */ png_write_info(png_ptr, info_ptr); /* Restrict the filters */ png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, filters); { # ifdef PNG_WRITE_INTERLACING_SUPPORTED int passes = png_set_interlace_handling(png_ptr); # else /* !WRITE_INTERLACING */ int passes = 1; # endif /* !WRITE_INTERLACING */ int pass; size_t rowbytes = png_get_rowbytes(png_ptr, info_ptr); row = malloc(rowbytes); if (row == NULL) png_error(png_ptr, "OOM allocating row buffer"); for (pass = 0; pass < passes; ++pass) { unsigned int y; for (y=0; y 0) { /* Round up to a multiple of 4 here to allow an iCCP profile * to be padded to a 4x boundary. */ png_bytep data = malloc((total+3)&~3); if (data != NULL) { size_t new_size = 0; for (;;) { ch = getc(fp); if (ch == EOF) break; data[new_size++] = (png_byte)ch; } if (ferror(fp) || new_size != total) { perror("temporary file"); fprintf(stderr, "temporary file read error\n"); free(data); } else { (void)fclose(fp); *result = data; return total; } } else fprintf(stderr, "%s: out of memory loading file\n", name); } else fprintf(stderr, "%s: empty file\n", name); } } } else { perror(name); fprintf(stderr, "%s: open failed\n", name); } fclose(fp); } else fprintf(stderr, "makepng: %s: could not open temporary file\n", name); exit(1); return 0; } static size_t load_fake(png_charp param, png_bytepp profile) { char *endptr = NULL; uint64_t size = strtoull(param, &endptr, 0/*base*/); /* The 'fake' format is *[string] */ if (endptr != NULL && *endptr == '*') { size_t len = strlen(++endptr); size_t result = (size_t)size; if (len == 0) len = 1; /* capture the terminating '\0' */ /* Now repeat that string to fill 'size' bytes. */ if (result == size && (*profile = malloc(result)) != NULL) { png_bytep out = *profile; if (len == 1) memset(out, *endptr, result); else { while (size >= len) { memcpy(out, endptr, len); out += len; size -= len; } memcpy(out, endptr, size); } return result; } else { fprintf(stderr, "%s: size exceeds system limits\n", param); exit(1); } } return 0; } static void check_param_count(int nparams, int expect) { if (nparams != expect) { fprintf(stderr, "bad parameter count (internal error)\n"); exit(1); } } static void insert_iCCP(png_structp png_ptr, png_infop info_ptr, int nparams, png_charpp params) { png_bytep profile = NULL; png_uint_32 proflen = 0; int result; check_param_count(nparams, 2); switch (params[1][0]) { case '<': { size_t filelen = load_file(params[1]+1, &profile); if (filelen > 0xfffffffc) /* Maximum profile length */ { fprintf(stderr, "%s: file too long (%lu) for an ICC profile\n", params[1]+1, (unsigned long)filelen); exit(1); } proflen = (png_uint_32)filelen; } break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { size_t fake_len = load_fake(params[1], &profile); if (fake_len > 0) /* else a simple parameter */ { if (fake_len > 0xffffffff) /* Maximum profile length */ { fprintf(stderr, "%s: fake data too long (%lu) for an ICC profile\n", params[1], (unsigned long)fake_len); exit(1); } proflen = (png_uint_32)(fake_len & ~3U); /* Always fix up the profile length. */ png_save_uint_32(profile, proflen); break; } } default: fprintf(stderr, "--insert iCCP \"%s\": unrecognized\n", params[1]); fprintf(stderr, " use '<' to read a file: \" 3) { png_uint_32 prof_header = png_get_uint_32(profile); if (prof_header != proflen) { fprintf(stderr, "--insert iCCP %s: profile length field wrong:\n", params[1]); fprintf(stderr, " actual %lu, recorded value %lu (corrected)\n", (unsigned long)proflen, (unsigned long)prof_header); png_save_uint_32(profile, proflen); } } if (result && profile != NULL && proflen >=4) png_set_iCCP(png_ptr, info_ptr, params[0], PNG_COMPRESSION_TYPE_BASE, profile, proflen); if (profile) free(profile); if (!result) exit(1); } static void clear_text(png_text *text, png_charp keyword) { text->compression = -1; /* none */ text->key = keyword; text->text = NULL; text->text_length = 0; /* libpng calculates this */ text->itxt_length = 0; /* libpng calculates this */ text->lang = NULL; text->lang_key = NULL; } static void set_text(png_structp png_ptr, png_infop info_ptr, png_textp text, png_charp param) { switch (param[0]) { case '<': { png_bytep file = NULL; text->text_length = load_file(param+1, &file); text->text = (png_charp)file; } break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { png_bytep data = NULL; size_t fake_len = load_fake(param, &data); if (fake_len > 0) /* else a simple parameter */ { text->text_length = fake_len; text->text = (png_charp)data; break; } } default: text->text = param; break; } png_set_text(png_ptr, info_ptr, text, 1); if (text->text != param) free(text->text); } static void insert_tEXt(png_structp png_ptr, png_infop info_ptr, int nparams, png_charpp params) { png_text text; check_param_count(nparams, 2); clear_text(&text, params[0]); set_text(png_ptr, info_ptr, &text, params[1]); } static void insert_zTXt(png_structp png_ptr, png_infop info_ptr, int nparams, png_charpp params) { png_text text; check_param_count(nparams, 2); clear_text(&text, params[0]); text.compression = 0; /* deflate */ set_text(png_ptr, info_ptr, &text, params[1]); } static void insert_iTXt(png_structp png_ptr, png_infop info_ptr, int nparams, png_charpp params) { png_text text; check_param_count(nparams, 4); clear_text(&text, params[0]); text.compression = 2; /* iTXt + deflate */ text.lang = params[1];/* language tag */ text.lang_key = params[2]; /* translated keyword */ set_text(png_ptr, info_ptr, &text, params[3]); } static void insert_hIST(png_structp png_ptr, png_infop info_ptr, int nparams, png_charpp params) { int i; png_uint_16 freq[256]; /* libpng takes the count from the PLTE count; we don't check it here but we * do set the array to 0 for unspecified entries. */ memset(freq, 0, sizeof freq); for (i=0; inext = NULL; cip->insert = insert; cip->nparams = nparams; for (i=0; iparameters[i] = list[i]; return cip; } static chunk_insert * find_insert(png_const_charp what, png_charp param) { png_uint_32 chunk = 0; png_charp parameter_list[1024]; int i, nparams; /* Assemble the chunk name */ for (i=0; i<4; ++i) { char ch = what[i]; if ((ch >= 65 && ch <= 90) || (ch >= 97 && ch <= 122)) chunk = (chunk << 8) + what[i]; else break; } if (i < 4 || what[4] != 0) { fprintf(stderr, "makepng --insert \"%s\": invalid chunk name\n", what); exit(1); } /* Assemble the parameter list. */ nparams = find_parameters(what, param, parameter_list, 1024); # define CHUNK(a,b,c,d) (((a)<<24)+((b)<<16)+((c)<<8)+(d)) switch (chunk) { case CHUNK(105,67,67,80): /* iCCP */ if (nparams == 2) return make_insert(what, insert_iCCP, nparams, parameter_list); break; case CHUNK(116,69,88,116): /* tEXt */ if (nparams == 2) return make_insert(what, insert_tEXt, nparams, parameter_list); break; case CHUNK(122,84,88,116): /* zTXt */ if (nparams == 2) return make_insert(what, insert_zTXt, nparams, parameter_list); break; case CHUNK(105,84,88,116): /* iTXt */ if (nparams == 4) return make_insert(what, insert_iTXt, nparams, parameter_list); break; case CHUNK(104,73,83,84): /* hIST */ if (nparams <= 256) return make_insert(what, insert_hIST, nparams, parameter_list); break; case CHUNK(115,66,73,84): /* sBIT */ if (nparams <= 4) return make_insert(what, insert_sBIT, nparams, parameter_list); break; #if 0 case CHUNK(115,80,76,84): /* sPLT */ return make_insert(what, insert_sPLT, nparams, parameter_list); #endif default: fprintf(stderr, "makepng --insert \"%s\": unrecognized chunk name\n", what); exit(1); } bad_parameter_count(what, nparams); return NULL; } /* This is necessary because libpng expects writeable strings for things like * text chunks (maybe this should be fixed...) */ static png_charp strstash(png_const_charp foo) { /* The program indicates a memory allocation error by crashing, this is by * design. */ if (foo != NULL) { png_charp bar = malloc(strlen(foo)+1); return strcpy(bar, foo); } return NULL; } static png_charp strstash_list(const png_const_charp *text) { size_t foo = 0; png_charp result, bar; const png_const_charp *line = text; while (*line != NULL) foo += strlen(*line++); result = bar = malloc(foo+1); line = text; while (*line != NULL) { foo = strlen(*line); memcpy(bar, *line++, foo); bar += foo; } *bar = 0; return result; } /* These are used to insert Copyright and Licence fields, they allow the text to * have \n unlike the --insert option. */ static chunk_insert * add_tEXt(const char *key, const png_const_charp *text) { static char what[5] = { 116, 69, 88, 116, 0 }; png_charp parameter_list[3]; parameter_list[0] = strstash(key); parameter_list[1] = strstash_list(text); parameter_list[2] = NULL; return make_insert(what, insert_tEXt, 2, parameter_list); } static chunk_insert * add_iTXt(const char *key, const char *language, const char *language_key, const png_const_charp *text) { static char what[5] = { 105, 84, 88, 116, 0 }; png_charp parameter_list[5]; parameter_list[0] = strstash(key); parameter_list[1] = strstash(language); parameter_list[2] = strstash(language_key); parameter_list[3] = strstash_list(text); parameter_list[4] = NULL; return make_insert(what, insert_iTXt, 4, parameter_list); } /* This is a not-very-good parser for a sequence of numbers (including 0). It * doesn't accept some apparently valid things, but it accepts all the sensible * combinations. */ static void parse_color(char *arg, unsigned int *colors) { unsigned int ncolors = 0; while (*arg && ncolors < 4) { char *ep = arg; unsigned long ul = strtoul(arg, &ep, 0); if (ul > 65535) { fprintf(stderr, "makepng --color=...'%s': too big\n", arg); exit(1); } if (ep == arg) { fprintf(stderr, "makepng --color=...'%s': not a valid color\n", arg); exit(1); } if (*ep) ++ep; /* skip a separator */ arg = ep; colors[++ncolors] = (unsigned int)ul; /* checked above */ } if (*arg) { fprintf(stderr, "makepng --color=...'%s': too many values\n", arg); exit(1); } *colors = ncolors; } int main(int argc, char **argv) { FILE *fp = stdout; const char *file_name = NULL; int color_type = 8; /* invalid */ int bit_depth = 32; /* invalid */ int small = 0; /* make full size images */ int tRNS = 0; /* don't output a tRNS chunk */ unsigned int colors[5]; unsigned int filters = PNG_ALL_FILTERS; png_fixed_point gamma = 0; /* not set */ chunk_insert *head_insert = NULL; chunk_insert **insert_ptr = &head_insert; memset(colors, 0, sizeof colors); while (--argc > 0) { char *arg = *++argv; if (strcmp(arg, "--small") == 0) { small = 1; continue; } if (strcmp(arg, "--tRNS") == 0) { tRNS = 1; continue; } if (strcmp(arg, "--sRGB") == 0) { gamma = PNG_DEFAULT_sRGB; continue; } if (strcmp(arg, "--linear") == 0) { gamma = PNG_FP_1; continue; } if (strcmp(arg, "--1.8") == 0) { gamma = PNG_GAMMA_MAC_18; continue; } if (strcmp(arg, "--nofilters") == 0) { filters = PNG_FILTER_NONE; continue; } if (strncmp(arg, "--color=", 8) == 0) { parse_color(arg+8, colors); continue; } if (argc >= 3 && strcmp(arg, "--insert") == 0) { png_const_charp what = *++argv; png_charp param = *++argv; chunk_insert *new_insert; argc -= 2; new_insert = find_insert(what, param); if (new_insert != NULL) { *insert_ptr = new_insert; insert_ptr = &new_insert->next; } continue; } if (arg[0] == '-') { fprintf(stderr, "makepng: %s: invalid option\n", arg); exit(1); } if (strcmp(arg, "palette") == 0) { color_type = PNG_COLOR_TYPE_PALETTE; continue; } if (strncmp(arg, "gray", 4) == 0) { if (arg[4] == 0) { color_type = PNG_COLOR_TYPE_GRAY; continue; } else if (strcmp(arg+4, "a") == 0 || strcmp(arg+4, "alpha") == 0 || strcmp(arg+4, "-alpha") == 0) { color_type = PNG_COLOR_TYPE_GRAY_ALPHA; continue; } } if (strncmp(arg, "rgb", 3) == 0) { if (arg[3] == 0) { color_type = PNG_COLOR_TYPE_RGB; continue; } else if (strcmp(arg+3, "a") == 0 || strcmp(arg+3, "alpha") == 0 || strcmp(arg+3, "-alpha") == 0) { color_type = PNG_COLOR_TYPE_RGB_ALPHA; continue; } } if (color_type == 8 && isdigit(arg[0])) { color_type = atoi(arg); if (color_type < 0 || color_type > 6 || color_type == 1 || color_type == 5) { fprintf(stderr, "makepng: %s: not a valid color type\n", arg); exit(1); } continue; } if (bit_depth == 32 && isdigit(arg[0])) { bit_depth = atoi(arg); if (bit_depth <= 0 || bit_depth > 16 || (bit_depth & -bit_depth) != bit_depth) { fprintf(stderr, "makepng: %s: not a valid bit depth\n", arg); exit(1); } continue; } if (argc == 1) /* It's the file name */ { fp = fopen(arg, "wb"); if (fp == NULL) { fprintf(stderr, "%s: %s: could not open\n", arg, strerror(errno)); exit(1); } file_name = arg; continue; } fprintf(stderr, "makepng: %s: unknown argument\n", arg); exit(1); } /* argument while loop */ if (color_type == 8 || bit_depth == 32) { fprintf(stderr, "usage: makepng [--small] [--sRGB|--linear|--1.8] " "[--color=...] color-type bit-depth [file-name]\n" " Make a test PNG file, by default writes to stdout.\n" " Other options are available, UTSL.\n"); exit(1); } /* Check the colors */ { unsigned int lim = (color_type == PNG_COLOR_TYPE_PALETTE ? 255U : (1U< lim) { fprintf(stderr, "makepng: --color=...: %u out of range [0..%u]\n", colors[i], lim); exit(1); } } /* small and colors are incompatible (will probably crash if both are used at * the same time!) */ if (small && colors[0] != 0) { fprintf(stderr, "makepng: --color --small: only one at a time!\n"); exit(1); } /* Restrict the filters for more speed to those we know are used for the * generated images. */ if (filters == PNG_ALL_FILTERS && !small/*small provides defaults*/) { if ((color_type & PNG_COLOR_MASK_PALETTE) != 0 || bit_depth < 8) filters = PNG_FILTER_NONE; else if (color_type & PNG_COLOR_MASK_COLOR) /* rgb */ { if (bit_depth == 8) filters &= ~(PNG_FILTER_NONE | PNG_FILTER_AVG); else filters = PNG_FILTER_SUB | PNG_FILTER_PAETH; } else /* gray 8 or 16-bit */ filters &= ~PNG_FILTER_NONE; } /* Insert standard copyright and licence text. */ { static png_const_charp copyright[] = { COPYRIGHT, /* ISO-Latin-1 */ NULL }; static png_const_charp licensing[] = { IMAGE_LICENSING, /* UTF-8 */ NULL }; chunk_insert *new_insert; new_insert = add_tEXt("Copyright", copyright); if (new_insert != NULL) { *insert_ptr = new_insert; insert_ptr = &new_insert->next; } new_insert = add_iTXt("Licensing", "en", NULL, licensing); if (new_insert != NULL) { *insert_ptr = new_insert; insert_ptr = &new_insert->next; } } { int ret = write_png(&file_name, fp, color_type, bit_depth, gamma, head_insert, filters, colors, small, tRNS); if (ret != 0 && file_name != NULL) remove(file_name); return ret; } } libpng-1.6.43/contrib/libtests/pngimage.c000066400000000000000000001451121456606525400203250ustar00rootroot00000000000000 /* pngimage.c * * Copyright (c) 2021 Cosmin Truta * Copyright (c) 2015,2016 John Cunningham Bowler * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer * and license in png.h * * Test the png_read_png and png_write_png interfaces. Given a PNG file load it * using png_read_png and then write with png_write_png. Test all possible * transforms. */ #include #include #include #include #include #include #if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H) # include #endif /* Define the following to use this test against your installed libpng, rather * than the one being built here: */ #ifdef PNG_FREESTANDING_TESTS # include #else # include "../../png.h" #endif #ifndef PNG_SETJMP_SUPPORTED # include /* because png.h did *not* include this */ #endif /* 1.6.1 added support for the configure test harness, which uses 77 to indicate * a skipped test, in earlier versions we need to succeed on a skipped test, so: */ #if PNG_LIBPNG_VER >= 10601 && defined(HAVE_CONFIG_H) # define SKIP 77 #else # define SKIP 0 #endif #if PNG_LIBPNG_VER < 10700 /* READ_PNG and WRITE_PNG were not defined, so: */ # ifdef PNG_INFO_IMAGE_SUPPORTED # ifdef PNG_SEQUENTIAL_READ_SUPPORTED # define PNG_READ_PNG_SUPPORTED # endif /* SEQUENTIAL_READ */ # ifdef PNG_WRITE_SUPPORTED # define PNG_WRITE_PNG_SUPPORTED # endif /* WRITE */ # endif /* INFO_IMAGE */ #endif /* pre 1.7.0 */ #ifdef PNG_READ_PNG_SUPPORTED /* If a transform is valid on both read and write this implies that if the * transform is applied to read it must also be applied on write to produce * meaningful data. This is because these transforms when performed on read * produce data with a memory format that does not correspond to a PNG format. * * Most of these transforms are invertible; after applying the transform on * write the result is the original PNG data that would have would have been * read if no transform were applied. * * The exception is _SHIFT, which destroys the low order bits marked as not * significant in a PNG with the sBIT chunk. * * The following table lists, for each transform, the conditions under which it * is expected to do anything. Conditions are defined as follows: * * 1) Color mask bits required - simply a mask to AND with color_type; one of * these must be present for the transform to fire, except that 0 means * 'always'. * 2) Color mask bits which must be absent - another mask - none of these must * be present. * 3) Bit depths - a mask of component bit depths for the transform to fire. * 4) 'read' - the transform works in png_read_png. * 5) 'write' - the transform works in png_write_png. * 6) PNG_INFO_chunk; a mask of the chunks that must be present for the * transform to fire. All must be present - the requirement is that * png_get_valid() & mask == mask, so if mask is 0 there is no requirement. * * The condition refers to the original image state - if multiple transforms are * used together it is possible to cause a transform that wouldn't fire on the * original image to fire. */ static struct transform_info { const char *name; int transform; png_uint_32 valid_chunks; # define CHUNK_NONE 0 # define CHUNK_sBIT PNG_INFO_sBIT # define CHUNK_tRNS PNG_INFO_tRNS png_byte color_mask_required; png_byte color_mask_absent; # define COLOR_MASK_X 0 # define COLOR_MASK_P PNG_COLOR_MASK_PALETTE # define COLOR_MASK_C PNG_COLOR_MASK_COLOR # define COLOR_MASK_A PNG_COLOR_MASK_ALPHA # define COLOR_MASK_ALL (PALETTE+COLOR+ALPHA) /* absent = gray, no alpha */ png_byte bit_depths; # define BD_ALL (1 + 2 + 4 + 8 + 16) # define BD_PAL (1 + 2 + 4 + 8) # define BD_LOW (1 + 2 + 4) # define BD_16 16 # define BD_TRUE (8+16) /* i.e. true-color depths */ png_byte when; # define TRANSFORM_R 1 # define TRANSFORM_W 2 # define TRANSFORM_RW 3 png_byte tested; /* the transform was tested somewhere */ } transform_info[] = { /* List ALL the PNG_TRANSFORM_ macros here. Check for support using the READ * macros; even if the transform is supported on write it cannot be tested * without the read support. */ # define T(name,chunk,cm_required,cm_absent,bd,when)\ { #name, PNG_TRANSFORM_ ## name, CHUNK_ ## chunk,\ COLOR_MASK_ ## cm_required, COLOR_MASK_ ## cm_absent, BD_ ## bd,\ TRANSFORM_ ## when, 0/*!tested*/ } #ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED T(STRIP_16, NONE, X, X, 16, R), /* drops the bottom 8 bits when bit depth is 16 */ #endif #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED T(STRIP_ALPHA, NONE, A, X, ALL, R), /* removes the alpha channel if present */ #endif #ifdef PNG_WRITE_PACK_SUPPORTED # define TRANSFORM_RW_PACK TRANSFORM_RW #else # define TRANSFORM_RW_PACK TRANSFORM_R #endif #ifdef PNG_READ_PACK_SUPPORTED T(PACKING, NONE, X, X, LOW, RW_PACK), /* unpacks low-bit-depth components into 1 byte per component on read, * reverses this on write. */ #endif #ifdef PNG_WRITE_PACKSWAP_SUPPORTED # define TRANSFORM_RW_PACKSWAP TRANSFORM_RW #else # define TRANSFORM_RW_PACKSWAP TRANSFORM_R #endif #ifdef PNG_READ_PACKSWAP_SUPPORTED T(PACKSWAP, NONE, X, X, LOW, RW_PACKSWAP), /* reverses the order of low-bit-depth components packed into a byte */ #endif #ifdef PNG_READ_EXPAND_SUPPORTED T(EXPAND, NONE, P, X, ALL, R), /* expands PLTE PNG files to RGB (no tRNS) or RGBA (tRNS) * * Note that the 'EXPAND' transform does lots of different things: */ T(EXPAND, NONE, X, C, ALL, R), /* expands grayscale PNG files to RGB, or RGBA */ T(EXPAND, tRNS, X, A, ALL, R), /* expands the tRNS chunk in files without alpha */ #endif #ifdef PNG_WRITE_INVERT_SUPPORTED # define TRANSFORM_RW_INVERT TRANSFORM_RW #else # define TRANSFORM_RW_INVERT TRANSFORM_R #endif #ifdef PNG_READ_INVERT_SUPPORTED T(INVERT_MONO, NONE, X, C, ALL, RW_INVERT), /* converts gray-scale components to 1..0 from 0..1 */ #endif #ifdef PNG_WRITE_SHIFT_SUPPORTED # define TRANSFORM_RW_SHIFT TRANSFORM_RW #else # define TRANSFORM_RW_SHIFT TRANSFORM_R #endif #ifdef PNG_READ_SHIFT_SUPPORTED T(SHIFT, sBIT, X, X, ALL, RW_SHIFT), /* reduces component values to the original range based on the sBIT chunk, * this is only partially reversible - the low bits are lost and cannot be * recovered on write. In fact write code replicates the bits to generate * new low-order bits. */ #endif #ifdef PNG_WRITE_BGR_SUPPORTED # define TRANSFORM_RW_BGR TRANSFORM_RW #else # define TRANSFORM_RW_BGR TRANSFORM_R #endif #ifdef PNG_READ_BGR_SUPPORTED T(BGR, NONE, C, P, TRUE, RW_BGR), /* reverses the rgb component values of true-color pixels */ #endif #ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED # define TRANSFORM_RW_SWAP_ALPHA TRANSFORM_RW #else # define TRANSFORM_RW_SWAP_ALPHA TRANSFORM_R #endif #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED T(SWAP_ALPHA, NONE, A, X, TRUE, RW_SWAP_ALPHA), /* swaps the alpha channel of RGBA or GA pixels to the front - ARGB or * AG, on write reverses the process. */ #endif #ifdef PNG_WRITE_SWAP_SUPPORTED # define TRANSFORM_RW_SWAP TRANSFORM_RW #else # define TRANSFORM_RW_SWAP TRANSFORM_R #endif #ifdef PNG_READ_SWAP_SUPPORTED T(SWAP_ENDIAN, NONE, X, P, 16, RW_SWAP), /* byte-swaps 16-bit component values */ #endif #ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED # define TRANSFORM_RW_INVERT_ALPHA TRANSFORM_RW #else # define TRANSFORM_RW_INVERT_ALPHA TRANSFORM_R #endif #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED T(INVERT_ALPHA, NONE, A, X, TRUE, RW_INVERT_ALPHA), /* converts an alpha channel from 0..1 to 1..0 */ #endif #ifdef PNG_WRITE_FILLER_SUPPORTED T(STRIP_FILLER_BEFORE, NONE, A, P, TRUE, W), /* 'A' for a filler! */ /* on write skips a leading filler channel; testing requires data with a * filler channel so this is produced from RGBA or GA images by removing * the 'alpha' flag from the color type in place. */ T(STRIP_FILLER_AFTER, NONE, A, P, TRUE, W), /* on write strips a trailing filler channel */ #endif #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED T(GRAY_TO_RGB, NONE, X, C, ALL, R), /* expands grayscale images to RGB, also causes the palette part of * 'EXPAND' to happen. Low bit depth grayscale images are expanded to * 8-bits per component and no attempt is made to convert the image to a * palette image. While this transform is partially reversible * png_write_png does not currently support this. */ T(GRAY_TO_RGB, NONE, P, X, ALL, R), /* The 'palette' side effect mentioned above; a bit bogus but this is the * way the libpng code works. */ #endif #ifdef PNG_READ_EXPAND_16_SUPPORTED T(EXPAND_16, NONE, X, X, PAL, R), /* expands images to 16-bits per component, as a side effect expands * palette images to RGB and expands the tRNS chunk if present, so it can * modify 16-bit per component images as well: */ T(EXPAND_16, tRNS, X, A, 16, R), /* side effect of EXPAND_16 - expands the tRNS chunk in an RGB or G 16-bit * image. */ #endif #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED T(SCALE_16, NONE, X, X, 16, R), /* scales 16-bit components to 8-bits. */ #endif { NULL /*name*/, 0, 0, 0, 0, 0, 0, 0/*!tested*/ } #undef T }; #define ARRAY_SIZE(a) ((sizeof a)/(sizeof a[0])) #define TTABLE_SIZE ARRAY_SIZE(transform_info) /* Some combinations of options that should be reversible are not; these cases * are bugs. */ static int known_bad_combos[][2] = { /* problem, antidote */ { PNG_TRANSFORM_SHIFT | PNG_TRANSFORM_INVERT_ALPHA, 0/*antidote*/ } }; static int is_combo(int transforms) { return transforms & (transforms-1); /* non-zero if more than one set bit */ } static int first_transform(int transforms) { return transforms & -transforms; /* lowest set bit */ } static int is_bad_combo(int transforms) { unsigned int i; for (i=0; ifirst.next = NULL; buffer->last = NULL; buffer->current = NULL; } static void buffer_destroy_list(struct buffer_list *list) { if (list != NULL) { struct buffer_list *next = list->next; DELETE(list); buffer_destroy_list(next); } } static void buffer_destroy(struct buffer *buffer) { struct buffer_list *list = buffer->first.next; buffer_init(buffer); buffer_destroy_list(list); } #ifdef PNG_WRITE_PNG_SUPPORTED static void buffer_start_write(struct buffer *buffer) { buffer->last = &buffer->first; buffer->end_count = 0; buffer->current = NULL; } #endif static void buffer_start_read(struct buffer *buffer) { buffer->current = &buffer->first; buffer->read_count = 0; } #ifdef ENOMEM /* required by POSIX 1003.1 */ # define MEMORY ENOMEM #else # define MEMORY ERANGE /* required by ANSI-C */ #endif static struct buffer * get_buffer(png_structp pp) /* Used from libpng callbacks to get the current buffer */ { return (struct buffer*)png_get_io_ptr(pp); } static struct buffer_list * buffer_extend(struct buffer_list *current) { struct buffer_list *add; assert(current->next == NULL); add = NEW(struct buffer_list); if (add == NULL) return NULL; add->next = NULL; current->next = add; return add; } /* Load a buffer from a file; does the equivalent of buffer_start_write. On a * read error returns an errno value, else returns 0. */ static int buffer_from_file(struct buffer *buffer, FILE *fp) { struct buffer_list *last = &buffer->first; size_t count = 0; for (;;) { size_t r = fread(last->buffer+count, 1/*size*/, (sizeof last->buffer)-count, fp); if (r > 0) { count += r; if (count >= sizeof last->buffer) { assert(count == sizeof last->buffer); count = 0; if (last->next == NULL) { last = buffer_extend(last); if (last == NULL) return MEMORY; } else last = last->next; } } else /* fread failed - probably end of file */ { if (feof(fp)) { buffer->last = last; buffer->end_count = count; return 0; /* no error */ } /* Some kind of funky error; errno should be non-zero */ return errno == 0 ? ERANGE : errno; } } } /* This structure is used to control the test of a single file. */ typedef enum { VERBOSE, /* switches on all messages */ INFORMATION, WARNINGS, /* switches on warnings */ LIBPNG_WARNING, APP_WARNING, ERRORS, /* just errors */ APP_FAIL, /* continuable error - no need to longjmp */ LIBPNG_ERROR, /* this and higher cause a longjmp */ LIBPNG_BUG, /* erroneous behavior in libpng */ APP_ERROR, /* such as out-of-memory in a callback */ QUIET, /* no normal messages */ USER_ERROR, /* such as file-not-found */ INTERNAL_ERROR } error_level; #define LEVEL_MASK 0xf /* where the level is in 'options' */ #define EXHAUSTIVE 0x010 /* Test all combinations of active options */ #define STRICT 0x020 /* Fail on warnings as well as errors */ #define LOG 0x040 /* Log pass/fail to stdout */ #define CONTINUE 0x080 /* Continue on APP_FAIL errors */ #define SKIP_BUGS 0x100 /* Skip over known bugs */ #define LOG_SKIPPED 0x200 /* Log skipped bugs */ #define FIND_BAD_COMBOS 0x400 /* Attempt to deduce bad combos */ #define LIST_COMBOS 0x800 /* List combos by name */ /* Result masks apply to the result bits in the 'results' field below; these * bits are simple 1U<options = WARNINGS; /* default to !verbose, !quiet */ dp->filename = NULL; dp->operation = NULL; dp->original_pp = NULL; dp->original_ip = NULL; dp->original_rows = NULL; dp->read_pp = NULL; dp->read_ip = NULL; buffer_init(&dp->original_file); # ifdef PNG_WRITE_PNG_SUPPORTED dp->write_pp = NULL; buffer_init(&dp->written_file); # endif } static void display_clean_read(struct display *dp) { if (dp->read_pp != NULL) png_destroy_read_struct(&dp->read_pp, &dp->read_ip, NULL); } #ifdef PNG_WRITE_PNG_SUPPORTED static void display_clean_write(struct display *dp) { if (dp->write_pp != NULL) png_destroy_write_struct(&dp->write_pp, NULL); } #endif static void display_clean(struct display *dp) { # ifdef PNG_WRITE_PNG_SUPPORTED display_clean_write(dp); # endif display_clean_read(dp); dp->original_rowbytes = 0; dp->original_rows = NULL; dp->chunks = 0; png_destroy_read_struct(&dp->original_pp, &dp->original_ip, NULL); /* leave the filename for error detection */ dp->results = 0; /* reset for next time */ } static void display_destroy(struct display *dp) { /* Release any memory held in the display. */ # ifdef PNG_WRITE_PNG_SUPPORTED buffer_destroy(&dp->written_file); # endif buffer_destroy(&dp->original_file); } static struct display * get_dp(png_structp pp) /* The display pointer is always stored in the png_struct error pointer */ { struct display *dp = (struct display*)png_get_error_ptr(pp); if (dp == NULL) { fprintf(stderr, "pngimage: internal error (no display)\n"); exit(99); /* prevents a crash */ } return dp; } /* error handling */ #ifdef __GNUC__ # define VGATTR __attribute__((__format__ (__printf__,3,4))) /* Required to quiet GNUC warnings when the compiler sees a stdarg function * that calls one of the stdio v APIs. */ #else # define VGATTR #endif static void VGATTR display_log(struct display *dp, error_level level, const char *fmt, ...) /* 'level' is as above, fmt is a stdio style format string. This routine * does not return if level is above LIBPNG_WARNING */ { dp->results |= 1U << level; if (level > (error_level)(dp->options & LEVEL_MASK)) { const char *lp; va_list ap; switch (level) { case INFORMATION: lp = "information"; break; case LIBPNG_WARNING: lp = "warning(libpng)"; break; case APP_WARNING: lp = "warning(pngimage)"; break; case APP_FAIL: lp = "error(continuable)"; break; case LIBPNG_ERROR: lp = "error(libpng)"; break; case LIBPNG_BUG: lp = "bug(libpng)"; break; case APP_ERROR: lp = "error(pngimage)"; break; case USER_ERROR: lp = "error(user)"; break; case INTERNAL_ERROR: /* anything unexpected is an internal error: */ case VERBOSE: case WARNINGS: case ERRORS: case QUIET: default: lp = "bug(pngimage)"; break; } fprintf(stderr, "%s: %s: %s", dp->filename != NULL ? dp->filename : "", lp, dp->operation); if (dp->transforms != 0) { int tr = dp->transforms; if (is_combo(tr)) { if (dp->options & LIST_COMBOS) { int trx = tr; fprintf(stderr, "("); if (trx) { int start = 0; while (trx) { int trz = trx & -trx; if (start) fprintf(stderr, "+"); fprintf(stderr, "%s", transform_name(trz)); start = 1; trx &= ~trz; } } else fprintf(stderr, "-"); fprintf(stderr, ")"); } else fprintf(stderr, "(0x%x)", tr); } else fprintf(stderr, "(%s)", transform_name(tr)); } fprintf(stderr, ": "); va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); fputc('\n', stderr); } /* else do not output any message */ /* Errors cause this routine to exit to the fail code */ if (level > APP_FAIL || (level > ERRORS && !(dp->options & CONTINUE))) longjmp(dp->error_return, level); } /* error handler callbacks for libpng */ static void PNGCBAPI display_warning(png_structp pp, png_const_charp warning) { display_log(get_dp(pp), LIBPNG_WARNING, "%s", warning); } static void PNGCBAPI display_error(png_structp pp, png_const_charp error) { struct display *dp = get_dp(pp); display_log(dp, LIBPNG_ERROR, "%s", error); } static void display_cache_file(struct display *dp, const char *filename) /* Does the initial cache of the file. */ { FILE *fp; int ret; dp->filename = filename; if (filename != NULL) { fp = fopen(filename, "rb"); if (fp == NULL) display_log(dp, USER_ERROR, "open failed: %s", strerror(errno)); } else fp = stdin; ret = buffer_from_file(&dp->original_file, fp); fclose(fp); if (ret != 0) display_log(dp, APP_ERROR, "read failed: %s", strerror(ret)); } static void buffer_read(struct display *dp, struct buffer *bp, png_bytep data, size_t size) { struct buffer_list *last = bp->current; size_t read_count = bp->read_count; while (size > 0) { size_t avail; if (last == NULL || (last == bp->last && read_count >= bp->end_count)) { display_log(dp, USER_ERROR, "file truncated (%lu bytes)", (unsigned long)size); /*NOTREACHED*/ break; } else if (read_count >= sizeof last->buffer) { /* Move to the next buffer: */ last = last->next; read_count = 0; bp->current = last; /* Avoid update outside the loop */ /* And do a sanity check (the EOF case is caught above) */ if (last == NULL) { display_log(dp, INTERNAL_ERROR, "damaged buffer list"); /*NOTREACHED*/ break; } } avail = (sizeof last->buffer) - read_count; if (avail > size) avail = size; memcpy(data, last->buffer + read_count, avail); read_count += avail; size -= avail; data += avail; } bp->read_count = read_count; } static void PNGCBAPI read_function(png_structp pp, png_bytep data, size_t size) { buffer_read(get_dp(pp), get_buffer(pp), data, size); } static void read_png(struct display *dp, struct buffer *bp, const char *operation, int transforms) { png_structp pp; png_infop ip; /* This cleans out any previous read and sets operation and transforms to * empty. */ display_clean_read(dp); if (operation != NULL) /* else this is a verify and do not overwrite info */ { dp->operation = operation; dp->transforms = transforms; } dp->read_pp = pp = png_create_read_struct(PNG_LIBPNG_VER_STRING, dp, display_error, display_warning); if (pp == NULL) display_log(dp, LIBPNG_ERROR, "failed to create read struct"); /* The png_read_png API requires us to make the info struct, but it does the * call to png_read_info. */ dp->read_ip = ip = png_create_info_struct(pp); if (ip == NULL) display_log(dp, LIBPNG_ERROR, "failed to create info struct"); # ifdef PNG_SET_USER_LIMITS_SUPPORTED /* Remove the user limits, if any */ png_set_user_limits(pp, 0x7fffffff, 0x7fffffff); # endif /* Set the IO handling */ buffer_start_read(bp); png_set_read_fn(pp, bp, read_function); png_read_png(pp, ip, transforms, NULL/*params*/); #if 0 /* crazy debugging */ { png_bytep pr = png_get_rows(pp, ip)[0]; size_t rb = png_get_rowbytes(pp, ip); size_t cb; char c = ' '; fprintf(stderr, "%.4x %2d (%3lu bytes):", transforms, png_get_bit_depth(pp,ip), (unsigned long)rb); for (cb=0; cboriginal_file, "original read", 0/*no transform*/); /* Move the result to the 'original' fields */ dp->original_pp = pp = dp->read_pp, dp->read_pp = NULL; dp->original_ip = ip = dp->read_ip, dp->read_ip = NULL; dp->original_rowbytes = png_get_rowbytes(pp, ip); if (dp->original_rowbytes == 0) display_log(dp, LIBPNG_BUG, "png_get_rowbytes returned 0"); dp->chunks = png_get_valid(pp, ip, 0xffffffff); if ((dp->chunks & PNG_INFO_IDAT) == 0) /* set by png_read_png */ display_log(dp, LIBPNG_BUG, "png_read_png did not set IDAT flag"); dp->original_rows = png_get_rows(pp, ip); if (dp->original_rows == NULL) display_log(dp, LIBPNG_BUG, "png_read_png did not create row buffers"); if (!png_get_IHDR(pp, ip, &dp->width, &dp->height, &dp->bit_depth, &dp->color_type, &dp->interlace_method, &dp->compression_method, &dp->filter_method)) display_log(dp, LIBPNG_BUG, "png_get_IHDR failed"); /* 'active' transforms are discovered based on the original image format; * running one active transform can activate others. At present the code * does not attempt to determine the closure. */ { png_uint_32 chunks = dp->chunks; int active = 0, inactive = 0; int ct = dp->color_type; int bd = dp->bit_depth; unsigned int i; for (i=0; iactive_transforms = active; dp->ignored_transforms = inactive; /* excluding write-only transforms */ } } static int compare_read(struct display *dp, int applied_transforms) { /* Compare the png_info from read_ip with original_info */ size_t rowbytes; png_uint_32 width, height; int bit_depth, color_type; int interlace_method, compression_method, filter_method; const char *e = NULL; if (!png_get_IHDR(dp->read_pp, dp->read_ip, &width, &height, &bit_depth, &color_type, &interlace_method, &compression_method, &filter_method)) display_log(dp, LIBPNG_BUG, "png_get_IHDR failed"); # define C(item) if (item != dp->item) \ display_log(dp, APP_WARNING, "IHDR " #item "(%lu) changed to %lu",\ (unsigned long)dp->item, (unsigned long)item), e = #item /* The IHDR should be identical: */ C(width); C(height); C(bit_depth); C(color_type); C(interlace_method); C(compression_method); C(filter_method); /* 'e' remains set to the name of the last thing changed: */ if (e) display_log(dp, APP_ERROR, "IHDR changed (%s)", e); /* All the chunks from the original PNG should be preserved in the output PNG * because the PNG format has not been changed. */ { unsigned long chunks = png_get_valid(dp->read_pp, dp->read_ip, 0xffffffff); if (chunks != dp->chunks) display_log(dp, APP_FAIL, "PNG chunks changed from 0x%lx to 0x%lx", (unsigned long)dp->chunks, chunks); } /* rowbytes should be the same */ rowbytes = png_get_rowbytes(dp->read_pp, dp->read_ip); /* NOTE: on 64-bit systems this may trash the top bits of rowbytes, * which could lead to weird error messages. */ if (rowbytes != dp->original_rowbytes) display_log(dp, APP_ERROR, "PNG rowbytes changed from %lu to %lu", (unsigned long)dp->original_rowbytes, (unsigned long)rowbytes); /* The rows should be the same too, unless the applied transforms includes * the shift transform, in which case low bits may have been lost. */ { png_bytepp rows = png_get_rows(dp->read_pp, dp->read_ip); unsigned int mask; /* mask (if not zero) for the final byte */ if (bit_depth < 8) { /* Need the stray bits at the end, this depends only on the low bits * of the image width; overflow does not matter. If the width is an * exact multiple of 8 bits this gives a mask of 0, not 0xff. */ mask = 0xff & (0xff00 >> ((bit_depth * width) & 7)); } else mask = 0; if (rows == NULL) display_log(dp, LIBPNG_BUG, "png_get_rows returned NULL"); if ((applied_transforms & PNG_TRANSFORM_SHIFT) == 0 || (dp->active_transforms & PNG_TRANSFORM_SHIFT) == 0 || color_type == PNG_COLOR_TYPE_PALETTE) { unsigned long y; for (y=0; yoriginal_rows[y]; if (memcmp(row, orig, rowbytes-(mask != 0)) != 0 || (mask != 0 && ((row[rowbytes-1] & mask) != (orig[rowbytes-1] & mask)))) { size_t x; /* Find the first error */ for (x=0; x 0x%.2x", (unsigned long)x, (unsigned long)y, orig[x], row[x]); return 0; /* don't keep reporting failed rows on 'continue' */ } } } else # ifdef PNG_sBIT_SUPPORTED { unsigned long y; int bpp; /* bits-per-pixel then bytes-per-pixel */ /* components are up to 8 bytes in size */ png_byte sig_bits[8]; png_color_8p sBIT; if (png_get_sBIT(dp->read_pp, dp->read_ip, &sBIT) != PNG_INFO_sBIT) display_log(dp, INTERNAL_ERROR, "active shift transform but no sBIT in file"); switch (color_type) { case PNG_COLOR_TYPE_GRAY: sig_bits[0] = sBIT->gray; bpp = bit_depth; break; case PNG_COLOR_TYPE_GA: sig_bits[0] = sBIT->gray; sig_bits[1] = sBIT->alpha; bpp = 2 * bit_depth; break; case PNG_COLOR_TYPE_RGB: sig_bits[0] = sBIT->red; sig_bits[1] = sBIT->green; sig_bits[2] = sBIT->blue; bpp = 3 * bit_depth; break; case PNG_COLOR_TYPE_RGBA: sig_bits[0] = sBIT->red; sig_bits[1] = sBIT->green; sig_bits[2] = sBIT->blue; sig_bits[3] = sBIT->alpha; bpp = 4 * bit_depth; break; default: display_log(dp, LIBPNG_ERROR, "invalid colour type %d", color_type); /*NOTREACHED*/ memset(sig_bits, 0, sizeof(sig_bits)); bpp = 0; break; } { int b; for (b=0; 8*b bit_depth/*!palette*/) display_log(dp, LIBPNG_BUG, "invalid sBIT[%u] value %d returned for PNG bit depth %d", b, sig_bits[b], bit_depth); } } if (bpp < 8 && bpp != bit_depth) { /* sanity check; this is a grayscale PNG; something is wrong in the * code above. */ display_log(dp, INTERNAL_ERROR, "invalid bpp %u for bit_depth %u", bpp, bit_depth); } switch (bit_depth) { int b; case 16: /* Two bytes per component, big-endian */ for (b = (bpp >> 4); b > 0; --b) { unsigned int sig = (unsigned int)(0xffff0000 >> sig_bits[b]); sig_bits[2*b+1] = (png_byte)sig; sig_bits[2*b+0] = (png_byte)(sig >> 8); /* big-endian */ } break; case 8: /* One byte per component */ for (b=0; b*8 < bpp; ++b) sig_bits[b] = (png_byte)(0xff00 >> sig_bits[b]); break; case 1: /* allowed, but dumb */ /* Value is 1 */ sig_bits[0] = 0xff; break; case 2: /* Replicate 4 times */ /* Value is 1 or 2 */ b = 0x3 & ((0x3<<2) >> sig_bits[0]); b |= b << 2; b |= b << 4; sig_bits[0] = (png_byte)b; break; case 4: /* Replicate twice */ /* Value is 1, 2, 3 or 4 */ b = 0xf & ((0xf << 4) >> sig_bits[0]); b |= b << 4; sig_bits[0] = (png_byte)b; break; default: display_log(dp, LIBPNG_BUG, "invalid bit depth %d", bit_depth); break; } /* Convert bpp to bytes; this gives '1' for low-bit depth grayscale, * where there are multiple pixels per byte. */ bpp = (bpp+7) >> 3; /* The mask can be combined with sig_bits[0] */ if (mask != 0) { mask &= sig_bits[0]; if (bpp != 1 || mask == 0) display_log(dp, INTERNAL_ERROR, "mask calculation error %u, %u", bpp, mask); } for (y=0; yoriginal_rows[y]; unsigned long x; for (x=0; x<(width-(mask!=0)); ++x) { int b; for (b=0; b%.2x", x, b, y, orig[-1], row[-1]); return 0; } } } if (mask != 0 && (*row & mask) != (*orig & mask)) { display_log(dp, APP_FAIL, "significant bits at (%lu[end],%lu) changed", x, y); return 0; } } /* for y */ } # else /* !sBIT */ display_log(dp, INTERNAL_ERROR, "active shift transform but no sBIT support"); # endif /* !sBIT */ } return 1; /* compare succeeded */ } #ifdef PNG_WRITE_PNG_SUPPORTED static void buffer_write(struct display *dp, struct buffer *buffer, png_bytep data, size_t size) /* Generic write function used both from the write callback provided to * libpng and from the generic read code. */ { /* Write the data into the buffer, adding buffers as required */ struct buffer_list *last = buffer->last; size_t end_count = buffer->end_count; while (size > 0) { size_t avail; if (end_count >= sizeof last->buffer) { if (last->next == NULL) { last = buffer_extend(last); if (last == NULL) display_log(dp, APP_ERROR, "out of memory saving file"); } else last = last->next; buffer->last = last; /* avoid the need to rewrite every time */ end_count = 0; } avail = (sizeof last->buffer) - end_count; if (avail > size) avail = size; memcpy(last->buffer + end_count, data, avail); end_count += avail; size -= avail; data += avail; } buffer->end_count = end_count; } static void PNGCBAPI write_function(png_structp pp, png_bytep data, size_t size) { buffer_write(get_dp(pp), get_buffer(pp), data, size); } static void write_png(struct display *dp, png_infop ip, int transforms) { display_clean_write(dp); /* safety */ buffer_start_write(&dp->written_file); dp->operation = "write"; dp->transforms = transforms; dp->write_pp = png_create_write_struct(PNG_LIBPNG_VER_STRING, dp, display_error, display_warning); if (dp->write_pp == NULL) display_log(dp, APP_ERROR, "failed to create write png_struct"); png_set_write_fn(dp->write_pp, &dp->written_file, write_function, NULL/*flush*/); # ifdef PNG_SET_USER_LIMITS_SUPPORTED /* Remove the user limits, if any */ png_set_user_limits(dp->write_pp, 0x7fffffff, 0x7fffffff); # endif /* Certain transforms require the png_info to be zapped to allow the * transform to work correctly. */ if (transforms & (PNG_TRANSFORM_PACKING| PNG_TRANSFORM_STRIP_FILLER| PNG_TRANSFORM_STRIP_FILLER_BEFORE)) { int ct = dp->color_type; if (transforms & (PNG_TRANSFORM_STRIP_FILLER| PNG_TRANSFORM_STRIP_FILLER_BEFORE)) ct &= ~PNG_COLOR_MASK_ALPHA; png_set_IHDR(dp->write_pp, ip, dp->width, dp->height, dp->bit_depth, ct, dp->interlace_method, dp->compression_method, dp->filter_method); } png_write_png(dp->write_pp, ip, transforms, NULL/*params*/); /* Clean it on the way out - if control returns to the caller then the * written_file contains the required data. */ display_clean_write(dp); } #endif /* WRITE_PNG */ static int skip_transform(struct display *dp, int tr) /* Helper to test for a bad combo and log it if it is skipped */ { if ((dp->options & SKIP_BUGS) != 0 && is_bad_combo(tr)) { /* Log this to stdout if logging is on, otherwise just do an information * display_log. */ if ((dp->options & LOG_SKIPPED) != 0) { printf("SKIP: %s transforms ", dp->filename); while (tr != 0) { int next = first_transform(tr); tr &= ~next; printf("%s", transform_name(next)); if (tr != 0) putchar('+'); } putchar('\n'); } else display_log(dp, INFORMATION, "%s: skipped known bad combo 0x%x", dp->filename, tr); return 1; /* skip */ } return 0; /* don't skip */ } static void test_one_file(struct display *dp, const char *filename) { /* First cache the file and update the display original file * information for the new file. */ dp->operation = "cache file"; dp->transforms = 0; display_cache_file(dp, filename); update_display(dp); /* First test: if there are options that should be ignored for this file * verify that they really are ignored. */ if (dp->ignored_transforms != 0) { read_png(dp, &dp->original_file, "ignored transforms", dp->ignored_transforms); /* The result should be identical to the original_rows */ if (!compare_read(dp, 0/*transforms applied*/)) return; /* no point testing more */ } #ifdef PNG_WRITE_PNG_SUPPORTED /* Second test: write the original PNG data out to a new file (to test the * write side) then read the result back in and make sure that it hasn't * changed. */ dp->operation = "write"; write_png(dp, dp->original_ip, 0/*transforms*/); read_png(dp, &dp->written_file, NULL, 0/*transforms*/); if (!compare_read(dp, 0/*transforms applied*/)) return; #endif /* Third test: the active options. Test each in turn, or, with the * EXHAUSTIVE option, test all possible combinations. */ { /* Use unsigned int here because the code below to increment through all * the possibilities exhaustively has to use a compare and that must be * unsigned, because some transforms are negative on a 16-bit system. */ unsigned int active = dp->active_transforms; int exhaustive = (dp->options & EXHAUSTIVE) != 0; unsigned int current = first_transform(active); unsigned int bad_transforms = 0; unsigned int bad_combo = ~0U; /* bitwise AND of failing transforms */ unsigned int bad_combo_list = 0; /* bitwise OR of failures */ for (;;) { read_png(dp, &dp->original_file, "active transforms", current); /* If this involved any irreversible transformations then if we write * it out with just the reversible transformations and read it in again * with the same transforms we should get the same thing. At present * this isn't done - it just seems like a waste of time and it would * require two sets of read png_struct/png_info. * * If there were no irreversible transformations then if we write it * out and read it back in again (without the reversible transforms) * we should get back to the place where we started. */ #ifdef PNG_WRITE_PNG_SUPPORTED if ((current & write_transforms) == current) { /* All transforms reversible: write the PNG with the transformations * reversed, then read it back in with no transformations. The * result should be the same as the original apart from the loss of * low order bits because of the SHIFT/sBIT transform. */ dp->operation = "reversible transforms"; write_png(dp, dp->read_ip, current); /* And if this is read back in, because all the transformations were * reversible, the result should be the same. */ read_png(dp, &dp->written_file, NULL, 0); if (!compare_read(dp, current/*for the SHIFT/sBIT transform*/)) { /* This set of transforms failed. If a single bit is set - if * there is just one transform - don't include this in further * 'exhaustive' tests. Notice that each transform is tested on * its own before testing combos in the exhaustive case. */ if (is_combo(current)) { bad_combo &= current; bad_combo_list |= current; } else bad_transforms |= current; } } #endif /* Now move to the next transform */ if (exhaustive) /* all combinations */ { unsigned int next = current; do { if (next == read_transforms) /* Everything tested */ goto combo; ++next; } /* skip known bad combos if the relevant option is set; skip * combos involving known bad single transforms in all cases. */ while ( (next & read_transforms) <= current || (next & active) == 0 /* skip cases that do nothing */ || (next & bad_transforms) != 0 || skip_transform(dp, next)); assert((next & read_transforms) == next); current = next; } else /* one at a time */ { active &= ~current; if (active == 0) goto combo; current = first_transform(active); } } combo: if (dp->options & FIND_BAD_COMBOS) { /* bad_combos identifies the combos that occur in all failing cases; * bad_combo_list identifies transforms that do not prevent the * failure. */ if (bad_combo != ~0U) printf("%s[0x%x]: PROBLEM: 0x%x[0x%x] ANTIDOTE: 0x%x\n", dp->filename, active, bad_combo, bad_combo_list, rw_transforms & ~bad_combo_list); else printf("%s: no %sbad combos found\n", dp->filename, (dp->options & SKIP_BUGS) ? "additional " : ""); } } } static int do_test(struct display *dp, const char *file) /* Exists solely to isolate the setjmp clobbers */ { int ret = setjmp(dp->error_return); if (ret == 0) { test_one_file(dp, file); return 0; } else if (ret < ERRORS) /* shouldn't longjmp on warnings */ display_log(dp, INTERNAL_ERROR, "unexpected return code %d", ret); return ret; } int main(int argc, char **argv) { /* For each file on the command line test it with a range of transforms */ int option_end, ilog = 0; struct display d; validate_T(); display_init(&d); for (option_end=1; option_end QUIET) /* abort on user or internal error */ return 99; } /* Here on any return, including failures, except user/internal issues */ { int pass = (d.options & STRICT) ? RESULT_STRICT(d.results) : RESULT_RELAXED(d.results); if (!pass) ++errors; if (d.options & LOG) { int j; printf("%s: pngimage ", pass ? "PASS" : "FAIL"); for (j=1; j #include #include #include #include #include #include #if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H) # include #endif /* Define the following to use this test against your installed libpng, rather * than the one being built here: */ #ifdef PNG_FREESTANDING_TESTS # include #else # include "../../png.h" #endif /* 1.6.1 added support for the configure test harness, which uses 77 to indicate * a skipped test, in earlier versions we need to succeed on a skipped test, so: */ #if PNG_LIBPNG_VER >= 10601 && defined(HAVE_CONFIG_H) # define SKIP 77 #else # define SKIP 0 #endif #ifdef PNG_SIMPLIFIED_READ_SUPPORTED /* Else nothing can be done */ #include "../tools/sRGB.h" /* KNOWN ISSUES * * These defines switch on alternate algorithms for format conversions to match * the current libpng implementation; they are set to allow pngstest to pass * even though libpng is producing answers that are not as correct as they * should be. */ #define ALLOW_UNUSED_GPC 0 /* If true include unused static GPC functions and declare an external array * of them to hide the fact that they are unused. This is for development * use while testing the correct function to use to take into account libpng * misbehavior, such as using a simple power law to correct sRGB to linear. */ /* The following is to support direct compilation of this file as C++ */ #ifdef __cplusplus # define voidcast(type, value) static_cast(value) # define aligncastconst(type, value) \ static_cast(static_cast(value)) #else # define voidcast(type, value) (value) # define aligncastconst(type, value) ((const void*)(value)) #endif /* __cplusplus */ /* During parallel runs of pngstest each temporary file needs a unique name, * this is used to permit uniqueness using a command line argument which can be * up to 22 characters long. */ static char tmpf[23] = "TMP"; /* Generate random bytes. This uses a boring repeatable algorithm and it * is implemented here so that it gives the same set of numbers on every * architecture. It's a linear congruential generator (Knuth or Sedgewick * "Algorithms") but it comes from the 'feedback taps' table in Horowitz and * Hill, "The Art of Electronics". */ static void make_random_bytes(png_uint_32* seed, void* pv, size_t size) { png_uint_32 u0 = seed[0], u1 = seed[1]; png_bytep bytes = voidcast(png_bytep, pv); /* There are thirty three bits, the next bit in the sequence is bit-33 XOR * bit-20. The top 1 bit is in u1, the bottom 32 are in u0. */ size_t i; for (i=0; i> (20-8)) ^ ((u1 << 7) | (u0 >> (32-7)))) & 0xff; u1 <<= 8; u1 |= u0 >> 24; u0 <<= 8; u0 |= u; *bytes++ = (png_byte)u; } seed[0] = u0; seed[1] = u1; } static png_uint_32 color_seed[2]; static void reseed(void) { color_seed[0] = 0x12345678U; color_seed[1] = 0x9abcdefU; } static void random_color(png_colorp color) { make_random_bytes(color_seed, color, sizeof *color); } /* Math support - neither Cygwin nor Visual Studio have C99 support and we need * a predictable rounding function, so make one here: */ static double closestinteger(double x) { return floor(x + .5); } /* Cast support: remove GCC whines. */ static png_byte u8d(double d) { d = closestinteger(d); return (png_byte)d; } static png_uint_16 u16d(double d) { d = closestinteger(d); return (png_uint_16)d; } /* sRGB support: use exact calculations rounded to the nearest int, see the * fesetround() call in main(). sRGB_to_d optimizes the 8 to 16-bit conversion. */ static double sRGB_to_d[256]; static double g22_to_d[256]; static void init_sRGB_to_d(void) { int i; sRGB_to_d[0] = 0; for (i=1; i<255; ++i) sRGB_to_d[i] = linear_from_sRGB(i/255.); sRGB_to_d[255] = 1; g22_to_d[0] = 0; for (i=1; i<255; ++i) g22_to_d[i] = pow(i/255., 1/.45455); g22_to_d[255] = 1; } static png_byte sRGB(double linear /*range 0.0 .. 1.0*/) { return u8d(255 * sRGB_from_linear(linear)); } static png_byte isRGB(int fixed_linear) { return sRGB(fixed_linear / 65535.); } #if 0 /* not used */ static png_byte unpremultiply(int component, int alpha) { if (alpha <= component) return 255; /* Arbitrary, but consistent with the libpng code */ else if (alpha >= 65535) return isRGB(component); else return sRGB((double)component / alpha); } #endif static png_uint_16 ilinear(int fixed_srgb) { return u16d(65535 * sRGB_to_d[fixed_srgb]); } static png_uint_16 ilineara(int fixed_srgb, int alpha) { return u16d((257 * alpha) * sRGB_to_d[fixed_srgb]); } static png_uint_16 ilinear_g22(int fixed_srgb) { return u16d(65535 * g22_to_d[fixed_srgb]); } #if ALLOW_UNUSED_GPC static png_uint_16 ilineara_g22(int fixed_srgb, int alpha) { return u16d((257 * alpha) * g22_to_d[fixed_srgb]); } #endif static double YfromRGBint(int ir, int ig, int ib) { double r = ir; double g = ig; double b = ib; return YfromRGB(r, g, b); } #if 0 /* unused */ /* The error that results from using a 2.2 power law in place of the correct * sRGB transform, given an 8-bit value which might be either sRGB or power-law. */ static int power_law_error8(int value) { if (value > 0 && value < 255) { double vd = value / 255.; double e = fabs( pow(sRGB_to_d[value], 1/2.2) - sRGB_from_linear(pow(vd, 2.2))); /* Always allow an extra 1 here for rounding errors */ e = 1+floor(255 * e); return (int)e; } return 0; } static int error_in_sRGB_roundtrip = 56; /* by experiment */ static int power_law_error16(int value) { if (value > 0 && value < 65535) { /* Round trip the value through an 8-bit representation but using * non-matching to/from conversions. */ double vd = value / 65535.; double e = fabs( pow(sRGB_from_linear(vd), 2.2) - linear_from_sRGB(pow(vd, 1/2.2))); /* Always allow an extra 1 here for rounding errors */ e = error_in_sRGB_roundtrip+floor(65535 * e); return (int)e; } return 0; } static int compare_8bit(int v1, int v2, int error_limit, int multiple_algorithms) { int e = abs(v1-v2); int ev1, ev2; if (e <= error_limit) return 1; if (!multiple_algorithms) return 0; ev1 = power_law_error8(v1); if (e <= ev1) return 1; ev2 = power_law_error8(v2); if (e <= ev2) return 1; return 0; } static int compare_16bit(int v1, int v2, int error_limit, int multiple_algorithms) { int e = abs(v1-v2); int ev1, ev2; if (e <= error_limit) return 1; /* "multiple_algorithms" in this case means that a color-map has been * involved somewhere, so we can deduce that the values were forced to 8-bit * (like the via_linear case for 8-bit.) */ if (!multiple_algorithms) return 0; ev1 = power_law_error16(v1); if (e <= ev1) return 1; ev2 = power_law_error16(v2); if (e <= ev2) return 1; return 0; } #endif /* unused */ #define USE_FILE 1 /* else memory */ #define USE_STDIO 2 /* else use file name */ #define STRICT 4 /* fail on warnings too */ #define VERBOSE 8 #define KEEP_TMPFILES 16 /* else delete temporary files */ #define KEEP_GOING 32 #define ACCUMULATE 64 #define FAST_WRITE 128 #define sRGB_16BIT 256 #define NO_RESEED 512 /* do not reseed on each new file */ #define GBG_ERROR 1024 /* do not ignore the gamma+background_rgb_to_gray * libpng warning. */ static void print_opts(png_uint_32 opts) { if (opts & USE_FILE) printf(" --file"); if (opts & USE_STDIO) printf(" --stdio"); if (!(opts & STRICT)) printf(" --nostrict"); if (opts & VERBOSE) printf(" --verbose"); if (opts & KEEP_TMPFILES) printf(" --preserve"); if (opts & KEEP_GOING) printf(" --keep-going"); if (opts & ACCUMULATE) printf(" --accumulate"); if (!(opts & FAST_WRITE)) /* --fast is currently the default */ printf(" --slow"); if (opts & sRGB_16BIT) printf(" --sRGB-16bit"); if (opts & NO_RESEED) printf(" --noreseed"); #if PNG_LIBPNG_VER < 10700 /* else on by default */ if (opts & GBG_ERROR) printf(" --fault-gbg-warning"); #endif } #define FORMAT_NO_CHANGE 0x80000000 /* additional flag */ /* A name table for all the formats - defines the format of the '+' arguments to * pngstest. */ #define FORMAT_COUNT 64 #define FORMAT_MASK 0x3f static const char * const format_names[FORMAT_COUNT] = { "sRGB-gray", "sRGB-gray+alpha", "sRGB-rgb", "sRGB-rgb+alpha", "linear-gray", "linear-gray+alpha", "linear-rgb", "linear-rgb+alpha", "color-mapped-sRGB-gray", "color-mapped-sRGB-gray+alpha", "color-mapped-sRGB-rgb", "color-mapped-sRGB-rgb+alpha", "color-mapped-linear-gray", "color-mapped-linear-gray+alpha", "color-mapped-linear-rgb", "color-mapped-linear-rgb+alpha", "sRGB-gray", "sRGB-gray+alpha", "sRGB-bgr", "sRGB-bgr+alpha", "linear-gray", "linear-gray+alpha", "linear-bgr", "linear-bgr+alpha", "color-mapped-sRGB-gray", "color-mapped-sRGB-gray+alpha", "color-mapped-sRGB-bgr", "color-mapped-sRGB-bgr+alpha", "color-mapped-linear-gray", "color-mapped-linear-gray+alpha", "color-mapped-linear-bgr", "color-mapped-linear-bgr+alpha", "sRGB-gray", "alpha+sRGB-gray", "sRGB-rgb", "alpha+sRGB-rgb", "linear-gray", "alpha+linear-gray", "linear-rgb", "alpha+linear-rgb", "color-mapped-sRGB-gray", "color-mapped-alpha+sRGB-gray", "color-mapped-sRGB-rgb", "color-mapped-alpha+sRGB-rgb", "color-mapped-linear-gray", "color-mapped-alpha+linear-gray", "color-mapped-linear-rgb", "color-mapped-alpha+linear-rgb", "sRGB-gray", "alpha+sRGB-gray", "sRGB-bgr", "alpha+sRGB-bgr", "linear-gray", "alpha+linear-gray", "linear-bgr", "alpha+linear-bgr", "color-mapped-sRGB-gray", "color-mapped-alpha+sRGB-gray", "color-mapped-sRGB-bgr", "color-mapped-alpha+sRGB-bgr", "color-mapped-linear-gray", "color-mapped-alpha+linear-gray", "color-mapped-linear-bgr", "color-mapped-alpha+linear-bgr", }; /* Decode an argument to a format number. */ static png_uint_32 formatof(const char *arg) { char *ep; unsigned long format = strtoul(arg, &ep, 0); if (ep > arg && *ep == 0 && format < FORMAT_COUNT) return (png_uint_32)format; else for (format=0; format < FORMAT_COUNT; ++format) { if (strcmp(format_names[format], arg) == 0) return (png_uint_32)format; } fprintf(stderr, "pngstest: format name '%s' invalid\n", arg); return FORMAT_COUNT; } /* Bitset/test functions for formats */ #define FORMAT_SET_COUNT (FORMAT_COUNT / 32) typedef struct { png_uint_32 bits[FORMAT_SET_COUNT]; } format_list; static void format_init(format_list *pf) { int i; for (i=0; ibits[i] = 0; /* All off */ } #if 0 /* currently unused */ static void format_clear(format_list *pf) { int i; for (i=0; ibits[i] = 0; } #endif static int format_is_initial(format_list *pf) { int i; for (i=0; ibits[i] != 0) return 0; return 1; } static int format_set(format_list *pf, png_uint_32 format) { if (format < FORMAT_COUNT) return pf->bits[format >> 5] |= ((png_uint_32)1) << (format & 31); return 0; } #if 0 /* currently unused */ static int format_unset(format_list *pf, png_uint_32 format) { if (format < FORMAT_COUNT) return pf->bits[format >> 5] &= ~((png_uint_32)1) << (format & 31); return 0; } #endif static int format_isset(format_list *pf, png_uint_32 format) { return format < FORMAT_COUNT && (pf->bits[format >> 5] & (((png_uint_32)1) << (format & 31))) != 0; } static void format_default(format_list *pf, int redundant) { if (redundant) { int i; /* set everything, including flags that are pointless */ for (i=0; ibits[i] = ~(png_uint_32)0; } else { png_uint_32 f; for (f=0; finput_file != NULL) rewind(image->input_file); } /* Free the image buffer; the buffer is re-used on a re-read, this is just for * cleanup. */ static void freebuffer(Image *image) { if (image->buffer) free(image->buffer); image->buffer = NULL; image->bufsize = 0; image->allocsize = 0; } /* Delete function; cleans out all the allocated data and the temporary file in * the image. */ static void freeimage(Image *image) { freebuffer(image); png_image_free(&image->image); if (image->input_file != NULL) { fclose(image->input_file); image->input_file = NULL; } if (image->input_memory != NULL) { free(image->input_memory); image->input_memory = NULL; image->input_memory_size = 0; } if (image->tmpfile_name[0] != 0 && (image->opts & KEEP_TMPFILES) == 0) { (void)remove(image->tmpfile_name); image->tmpfile_name[0] = 0; } } /* This is actually a re-initializer; allows an image structure to be re-used by * freeing everything that relates to an old image. */ static void initimage(Image *image, png_uint_32 opts, const char *file_name, int stride_extra) { freeimage(image); memset(&image->image, 0, sizeof image->image); image->opts = opts; image->file_name = file_name; image->stride_extra = stride_extra; } /* Make sure the image buffer is big enough; allows re-use of the buffer if the * image is re-read. */ #define BUFFER_INIT8 73 static void allocbuffer(Image *image) { size_t size = PNG_IMAGE_BUFFER_SIZE(image->image, image->stride); if (size+32 > image->bufsize) { freebuffer(image); image->buffer = voidcast(png_bytep, malloc(size+32)); if (image->buffer == NULL) { fflush(stdout); fprintf(stderr, "simpletest: out of memory allocating %lu(+32) byte buffer\n", (unsigned long)size); exit(1); } image->bufsize = size+32; } memset(image->buffer, 95, image->bufsize); memset(image->buffer+16, BUFFER_INIT8, size); image->allocsize = size; } /* Make sure 16 bytes match the given byte. */ static int check16(png_const_bytep bp, int b) { int i = 16; do if (*bp != b) return 1; while (--i); return 0; } /* Check for overwrite in the image buffer. */ static void checkbuffer(Image *image, const char *arg) { if (check16(image->buffer, 95)) { fflush(stdout); fprintf(stderr, "%s: overwrite at start of image buffer\n", arg); exit(1); } if (check16(image->buffer+16+image->allocsize, 95)) { fflush(stdout); fprintf(stderr, "%s: overwrite at end of image buffer\n", arg); exit(1); } } /* ERROR HANDLING */ /* Log a terminal error, also frees the libpng part of the image if necessary. */ static int logerror(Image *image, const char *a1, const char *a2, const char *a3) { fflush(stdout); if (image->image.warning_or_error) fprintf(stderr, "%s%s%s: %s\n", a1, a2, a3, image->image.message); else fprintf(stderr, "%s%s%s\n", a1, a2, a3); if (image->image.opaque != NULL) { fprintf(stderr, "%s: image opaque pointer non-NULL on error\n", image->file_name); png_image_free(&image->image); } return 0; } /* Log an error and close a file (just a utility to do both things in one * function call.) */ static int logclose(Image *image, FILE *f, const char *name, const char *operation) { int e = errno; fclose(f); return logerror(image, name, operation, strerror(e)); } /* Make sure the png_image has been freed - validates that libpng is doing what * the spec says and freeing the image. */ static int checkopaque(Image *image) { if (image->image.opaque != NULL) { png_image_free(&image->image); return logerror(image, image->file_name, ": opaque not NULL", ""); } /* Separate out the gamma+background_rgb_to_gray warning because it may * produce opaque component errors: */ else if (image->image.warning_or_error != 0 && (strcmp(image->image.message, "libpng does not support gamma+background+rgb_to_gray") == 0 ? (image->opts & GBG_ERROR) != 0 : (image->opts & STRICT) != 0)) return logerror(image, image->file_name, (image->opts & GBG_ERROR) != 0 ? " --fault-gbg-warning" : " --strict", ""); else return 1; } /* IMAGE COMPARISON/CHECKING */ /* Compare the pixels of two images, which should be the same but aren't. The * images must have been checked for a size match. */ typedef struct { /* The components, for grayscale images the gray value is in 'g' and if alpha * is not present 'a' is set to 255 or 65535 according to format. */ int r, g, b, a; } Pixel; typedef struct { /* The background as the original sRGB 8-bit value converted to the final * integer format and as a double precision linear value in the range 0..1 * for with partially transparent pixels. */ int ir, ig, ib; double dr, dg, db; /* linear r,g,b scaled to 0..1 */ } Background; /* Basic image formats; control the data but not the layout thereof. */ #define BASE_FORMATS\ (PNG_FORMAT_FLAG_ALPHA|PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_LINEAR) /* Read a Pixel from a buffer. The code below stores the correct routine for * the format in a function pointer, these are the routines: */ static void gp_g8(Pixel *p, png_const_voidp pb) { png_const_bytep pp = voidcast(png_const_bytep, pb); p->r = p->g = p->b = pp[0]; p->a = 255; } static void gp_ga8(Pixel *p, png_const_voidp pb) { png_const_bytep pp = voidcast(png_const_bytep, pb); p->r = p->g = p->b = pp[0]; p->a = pp[1]; } #ifdef PNG_FORMAT_AFIRST_SUPPORTED static void gp_ag8(Pixel *p, png_const_voidp pb) { png_const_bytep pp = voidcast(png_const_bytep, pb); p->r = p->g = p->b = pp[1]; p->a = pp[0]; } #endif static void gp_rgb8(Pixel *p, png_const_voidp pb) { png_const_bytep pp = voidcast(png_const_bytep, pb); p->r = pp[0]; p->g = pp[1]; p->b = pp[2]; p->a = 255; } #ifdef PNG_FORMAT_BGR_SUPPORTED static void gp_bgr8(Pixel *p, png_const_voidp pb) { png_const_bytep pp = voidcast(png_const_bytep, pb); p->r = pp[2]; p->g = pp[1]; p->b = pp[0]; p->a = 255; } #endif static void gp_rgba8(Pixel *p, png_const_voidp pb) { png_const_bytep pp = voidcast(png_const_bytep, pb); p->r = pp[0]; p->g = pp[1]; p->b = pp[2]; p->a = pp[3]; } #ifdef PNG_FORMAT_BGR_SUPPORTED static void gp_bgra8(Pixel *p, png_const_voidp pb) { png_const_bytep pp = voidcast(png_const_bytep, pb); p->r = pp[2]; p->g = pp[1]; p->b = pp[0]; p->a = pp[3]; } #endif #ifdef PNG_FORMAT_AFIRST_SUPPORTED static void gp_argb8(Pixel *p, png_const_voidp pb) { png_const_bytep pp = voidcast(png_const_bytep, pb); p->r = pp[1]; p->g = pp[2]; p->b = pp[3]; p->a = pp[0]; } #endif #if defined(PNG_FORMAT_AFIRST_SUPPORTED) && defined(PNG_FORMAT_BGR_SUPPORTED) static void gp_abgr8(Pixel *p, png_const_voidp pb) { png_const_bytep pp = voidcast(png_const_bytep, pb); p->r = pp[3]; p->g = pp[2]; p->b = pp[1]; p->a = pp[0]; } #endif static void gp_g16(Pixel *p, png_const_voidp pb) { png_const_uint_16p pp = voidcast(png_const_uint_16p, pb); p->r = p->g = p->b = pp[0]; p->a = 65535; } static void gp_ga16(Pixel *p, png_const_voidp pb) { png_const_uint_16p pp = voidcast(png_const_uint_16p, pb); p->r = p->g = p->b = pp[0]; p->a = pp[1]; } #ifdef PNG_FORMAT_AFIRST_SUPPORTED static void gp_ag16(Pixel *p, png_const_voidp pb) { png_const_uint_16p pp = voidcast(png_const_uint_16p, pb); p->r = p->g = p->b = pp[1]; p->a = pp[0]; } #endif static void gp_rgb16(Pixel *p, png_const_voidp pb) { png_const_uint_16p pp = voidcast(png_const_uint_16p, pb); p->r = pp[0]; p->g = pp[1]; p->b = pp[2]; p->a = 65535; } #ifdef PNG_FORMAT_BGR_SUPPORTED static void gp_bgr16(Pixel *p, png_const_voidp pb) { png_const_uint_16p pp = voidcast(png_const_uint_16p, pb); p->r = pp[2]; p->g = pp[1]; p->b = pp[0]; p->a = 65535; } #endif static void gp_rgba16(Pixel *p, png_const_voidp pb) { png_const_uint_16p pp = voidcast(png_const_uint_16p, pb); p->r = pp[0]; p->g = pp[1]; p->b = pp[2]; p->a = pp[3]; } #ifdef PNG_FORMAT_BGR_SUPPORTED static void gp_bgra16(Pixel *p, png_const_voidp pb) { png_const_uint_16p pp = voidcast(png_const_uint_16p, pb); p->r = pp[2]; p->g = pp[1]; p->b = pp[0]; p->a = pp[3]; } #endif #ifdef PNG_FORMAT_AFIRST_SUPPORTED static void gp_argb16(Pixel *p, png_const_voidp pb) { png_const_uint_16p pp = voidcast(png_const_uint_16p, pb); p->r = pp[1]; p->g = pp[2]; p->b = pp[3]; p->a = pp[0]; } #endif #if defined(PNG_FORMAT_AFIRST_SUPPORTED) && defined(PNG_FORMAT_BGR_SUPPORTED) static void gp_abgr16(Pixel *p, png_const_voidp pb) { png_const_uint_16p pp = voidcast(png_const_uint_16p, pb); p->r = pp[3]; p->g = pp[2]; p->b = pp[1]; p->a = pp[0]; } #endif /* Given a format, return the correct one of the above functions. */ static void (* get_pixel(png_uint_32 format))(Pixel *p, png_const_voidp pb) { /* The color-map flag is irrelevant here - the caller of the function * returned must either pass the buffer or, for a color-mapped image, the * correct entry in the color-map. */ if (format & PNG_FORMAT_FLAG_LINEAR) { if (format & PNG_FORMAT_FLAG_COLOR) { # ifdef PNG_FORMAT_BGR_SUPPORTED if (format & PNG_FORMAT_FLAG_BGR) { if (format & PNG_FORMAT_FLAG_ALPHA) { # ifdef PNG_FORMAT_AFIRST_SUPPORTED if (format & PNG_FORMAT_FLAG_AFIRST) return gp_abgr16; else # endif return gp_bgra16; } else return gp_bgr16; } else # endif { if (format & PNG_FORMAT_FLAG_ALPHA) { # ifdef PNG_FORMAT_AFIRST_SUPPORTED if (format & PNG_FORMAT_FLAG_AFIRST) return gp_argb16; else # endif return gp_rgba16; } else return gp_rgb16; } } else { if (format & PNG_FORMAT_FLAG_ALPHA) { # ifdef PNG_FORMAT_AFIRST_SUPPORTED if (format & PNG_FORMAT_FLAG_AFIRST) return gp_ag16; else # endif return gp_ga16; } else return gp_g16; } } else { if (format & PNG_FORMAT_FLAG_COLOR) { # ifdef PNG_FORMAT_BGR_SUPPORTED if (format & PNG_FORMAT_FLAG_BGR) { if (format & PNG_FORMAT_FLAG_ALPHA) { # ifdef PNG_FORMAT_AFIRST_SUPPORTED if (format & PNG_FORMAT_FLAG_AFIRST) return gp_abgr8; else # endif return gp_bgra8; } else return gp_bgr8; } else # endif { if (format & PNG_FORMAT_FLAG_ALPHA) { # ifdef PNG_FORMAT_AFIRST_SUPPORTED if (format & PNG_FORMAT_FLAG_AFIRST) return gp_argb8; else # endif return gp_rgba8; } else return gp_rgb8; } } else { if (format & PNG_FORMAT_FLAG_ALPHA) { # ifdef PNG_FORMAT_AFIRST_SUPPORTED if (format & PNG_FORMAT_FLAG_AFIRST) return gp_ag8; else # endif return gp_ga8; } else return gp_g8; } } } /* Conversion between pixel formats. The code above effectively eliminates the * component ordering changes leaving three basic changes: * * 1) Remove an alpha channel by pre-multiplication or compositing on a * background color. (Adding an alpha channel is a no-op.) * * 2) Remove color by mapping to grayscale. (Grayscale to color is a no-op.) * * 3) Convert between 8-bit and 16-bit components. (Both directions are * relevant.) * * This gives the following base format conversion matrix: * * OUT: ----- 8-bit ----- ----- 16-bit ----- * IN G GA RGB RGBA G GA RGB RGBA * 8 G . . . . lin lin lin lin * 8 GA bckg . bckc . pre' pre pre' pre * 8 RGB g8 g8 . . glin glin lin lin * 8 RGBA g8b g8 bckc . gpr' gpre pre' pre * 16 G sRGB sRGB sRGB sRGB . . . . * 16 GA b16g unpg b16c unpc A . A . * 16 RGB sG sG sRGB sRGB g16 g16 . . * 16 RGBA gb16 sGp cb16 sCp g16 g16' A . * * 8-bit to 8-bit: * bckg: composite on gray background * bckc: composite on color background * g8: convert sRGB components to sRGB grayscale * g8b: convert sRGB components to grayscale and composite on gray background * * 8-bit to 16-bit: * lin: make sRGB components linear, alpha := 65535 * pre: make sRGB components linear and premultiply by alpha (scale alpha) * pre': as 'pre' but alpha := 65535 * glin: make sRGB components linear, convert to grayscale, alpha := 65535 * gpre: make sRGB components grayscale and linear and premultiply by alpha * gpr': as 'gpre' but alpha := 65535 * * 16-bit to 8-bit: * sRGB: convert linear components to sRGB, alpha := 255 * unpg: unpremultiply gray component and convert to sRGB (scale alpha) * unpc: unpremultiply color components and convert to sRGB (scale alpha) * b16g: composite linear onto gray background and convert the result to sRGB * b16c: composite linear onto color background and convert the result to sRGB * sG: convert linear RGB to sRGB grayscale * sGp: unpremultiply RGB then convert to sRGB grayscale * sCp: unpremultiply RGB then convert to sRGB * gb16: composite linear onto background and convert to sRGB grayscale * (order doesn't matter, the composite and grayscale operations permute) * cb16: composite linear onto background and convert to sRGB * * 16-bit to 16-bit: * A: set alpha to 65535 * g16: convert linear RGB to linear grayscale (alpha := 65535) * g16': as 'g16' but alpha is unchanged */ /* Simple copy: */ static void gpc_noop(Pixel *out, const Pixel *in, const Background *back) { (void)back; out->r = in->r; out->g = in->g; out->b = in->b; out->a = in->a; } #if ALLOW_UNUSED_GPC static void gpc_nop8(Pixel *out, const Pixel *in, const Background *back) { (void)back; if (in->a == 0) out->r = out->g = out->b = 255; else { out->r = in->r; out->g = in->g; out->b = in->b; } out->a = in->a; } #endif #if ALLOW_UNUSED_GPC static void gpc_nop6(Pixel *out, const Pixel *in, const Background *back) { (void)back; if (in->a == 0) out->r = out->g = out->b = 65535; else { out->r = in->r; out->g = in->g; out->b = in->b; } out->a = in->a; } #endif /* 8-bit to 8-bit conversions */ /* bckg: composite on gray background */ static void gpc_bckg(Pixel *out, const Pixel *in, const Background *back) { if (in->a <= 0) out->r = out->g = out->b = back->ig; else if (in->a >= 255) out->r = out->g = out->b = in->g; else { double a = in->a / 255.; out->r = out->g = out->b = sRGB(sRGB_to_d[in->g] * a + back->dg * (1-a)); } out->a = 255; } /* bckc: composite on color background */ static void gpc_bckc(Pixel *out, const Pixel *in, const Background *back) { if (in->a <= 0) { out->r = back->ir; out->g = back->ig; out->b = back->ib; } else if (in->a >= 255) { out->r = in->r; out->g = in->g; out->b = in->b; } else { double a = in->a / 255.; out->r = sRGB(sRGB_to_d[in->r] * a + back->dr * (1-a)); out->g = sRGB(sRGB_to_d[in->g] * a + back->dg * (1-a)); out->b = sRGB(sRGB_to_d[in->b] * a + back->db * (1-a)); } out->a = 255; } /* g8: convert sRGB components to sRGB grayscale */ static void gpc_g8(Pixel *out, const Pixel *in, const Background *back) { (void)back; if (in->r == in->g && in->g == in->b) out->r = out->g = out->b = in->g; else out->r = out->g = out->b = sRGB(YfromRGB(sRGB_to_d[in->r], sRGB_to_d[in->g], sRGB_to_d[in->b])); out->a = in->a; } /* g8b: convert sRGB components to grayscale and composite on gray background */ static void gpc_g8b(Pixel *out, const Pixel *in, const Background *back) { if (in->a <= 0) out->r = out->g = out->b = back->ig; else if (in->a >= 255) { if (in->r == in->g && in->g == in->b) out->r = out->g = out->b = in->g; else out->r = out->g = out->b = sRGB(YfromRGB( sRGB_to_d[in->r], sRGB_to_d[in->g], sRGB_to_d[in->b])); } else { double a = in->a/255.; out->r = out->g = out->b = sRGB(a * YfromRGB(sRGB_to_d[in->r], sRGB_to_d[in->g], sRGB_to_d[in->b]) + back->dg * (1-a)); } out->a = 255; } /* 8-bit to 16-bit conversions */ /* lin: make sRGB components linear, alpha := 65535 */ static void gpc_lin(Pixel *out, const Pixel *in, const Background *back) { (void)back; out->r = ilinear(in->r); if (in->g == in->r) { out->g = out->r; if (in->b == in->r) out->b = out->r; else out->b = ilinear(in->b); } else { out->g = ilinear(in->g); if (in->b == in->r) out->b = out->r; else if (in->b == in->g) out->b = out->g; else out->b = ilinear(in->b); } out->a = 65535; } /* pre: make sRGB components linear and premultiply by alpha (scale alpha) */ static void gpc_pre(Pixel *out, const Pixel *in, const Background *back) { (void)back; out->r = ilineara(in->r, in->a); if (in->g == in->r) { out->g = out->r; if (in->b == in->r) out->b = out->r; else out->b = ilineara(in->b, in->a); } else { out->g = ilineara(in->g, in->a); if (in->b == in->r) out->b = out->r; else if (in->b == in->g) out->b = out->g; else out->b = ilineara(in->b, in->a); } out->a = in->a * 257; } /* pre': as 'pre' but alpha := 65535 */ static void gpc_preq(Pixel *out, const Pixel *in, const Background *back) { (void)back; out->r = ilineara(in->r, in->a); if (in->g == in->r) { out->g = out->r; if (in->b == in->r) out->b = out->r; else out->b = ilineara(in->b, in->a); } else { out->g = ilineara(in->g, in->a); if (in->b == in->r) out->b = out->r; else if (in->b == in->g) out->b = out->g; else out->b = ilineara(in->b, in->a); } out->a = 65535; } /* glin: make sRGB components linear, convert to grayscale, alpha := 65535 */ static void gpc_glin(Pixel *out, const Pixel *in, const Background *back) { (void)back; if (in->r == in->g && in->g == in->b) out->r = out->g = out->b = ilinear(in->g); else out->r = out->g = out->b = u16d(65535 * YfromRGB(sRGB_to_d[in->r], sRGB_to_d[in->g], sRGB_to_d[in->b])); out->a = 65535; } /* gpre: make sRGB components grayscale and linear and premultiply by alpha */ static void gpc_gpre(Pixel *out, const Pixel *in, const Background *back) { (void)back; if (in->r == in->g && in->g == in->b) out->r = out->g = out->b = ilineara(in->g, in->a); else out->r = out->g = out->b = u16d(in->a * 257 * YfromRGB(sRGB_to_d[in->r], sRGB_to_d[in->g], sRGB_to_d[in->b])); out->a = 257 * in->a; } /* gpr': as 'gpre' but alpha := 65535 */ static void gpc_gprq(Pixel *out, const Pixel *in, const Background *back) { (void)back; if (in->r == in->g && in->g == in->b) out->r = out->g = out->b = ilineara(in->g, in->a); else out->r = out->g = out->b = u16d(in->a * 257 * YfromRGB(sRGB_to_d[in->r], sRGB_to_d[in->g], sRGB_to_d[in->b])); out->a = 65535; } /* 8-bit to 16-bit conversions for gAMA 45455 encoded values */ /* Lin: make gAMA 45455 components linear, alpha := 65535 */ static void gpc_Lin(Pixel *out, const Pixel *in, const Background *back) { (void)back; out->r = ilinear_g22(in->r); if (in->g == in->r) { out->g = out->r; if (in->b == in->r) out->b = out->r; else out->b = ilinear_g22(in->b); } else { out->g = ilinear_g22(in->g); if (in->b == in->r) out->b = out->r; else if (in->b == in->g) out->b = out->g; else out->b = ilinear_g22(in->b); } out->a = 65535; } #if ALLOW_UNUSED_GPC /* Pre: make gAMA 45455 components linear and premultiply by alpha (scale alpha) */ static void gpc_Pre(Pixel *out, const Pixel *in, const Background *back) { (void)back; out->r = ilineara_g22(in->r, in->a); if (in->g == in->r) { out->g = out->r; if (in->b == in->r) out->b = out->r; else out->b = ilineara_g22(in->b, in->a); } else { out->g = ilineara_g22(in->g, in->a); if (in->b == in->r) out->b = out->r; else if (in->b == in->g) out->b = out->g; else out->b = ilineara_g22(in->b, in->a); } out->a = in->a * 257; } #endif #if ALLOW_UNUSED_GPC /* Pre': as 'Pre' but alpha := 65535 */ static void gpc_Preq(Pixel *out, const Pixel *in, const Background *back) { (void)back; out->r = ilineara_g22(in->r, in->a); if (in->g == in->r) { out->g = out->r; if (in->b == in->r) out->b = out->r; else out->b = ilineara_g22(in->b, in->a); } else { out->g = ilineara_g22(in->g, in->a); if (in->b == in->r) out->b = out->r; else if (in->b == in->g) out->b = out->g; else out->b = ilineara_g22(in->b, in->a); } out->a = 65535; } #endif #if ALLOW_UNUSED_GPC /* Glin: make gAMA 45455 components linear, convert to grayscale, alpha := 65535 */ static void gpc_Glin(Pixel *out, const Pixel *in, const Background *back) { (void)back; if (in->r == in->g && in->g == in->b) out->r = out->g = out->b = ilinear_g22(in->g); else out->r = out->g = out->b = u16d(65535 * YfromRGB(g22_to_d[in->r], g22_to_d[in->g], g22_to_d[in->b])); out->a = 65535; } #endif #if ALLOW_UNUSED_GPC /* Gpre: make gAMA 45455 components grayscale and linear and premultiply by * alpha. */ static void gpc_Gpre(Pixel *out, const Pixel *in, const Background *back) { (void)back; if (in->r == in->g && in->g == in->b) out->r = out->g = out->b = ilineara_g22(in->g, in->a); else out->r = out->g = out->b = u16d(in->a * 257 * YfromRGB(g22_to_d[in->r], g22_to_d[in->g], g22_to_d[in->b])); out->a = 257 * in->a; } #endif #if ALLOW_UNUSED_GPC /* Gpr': as 'Gpre' but alpha := 65535 */ static void gpc_Gprq(Pixel *out, const Pixel *in, const Background *back) { (void)back; if (in->r == in->g && in->g == in->b) out->r = out->g = out->b = ilineara_g22(in->g, in->a); else out->r = out->g = out->b = u16d(in->a * 257 * YfromRGB(g22_to_d[in->r], g22_to_d[in->g], g22_to_d[in->b])); out->a = 65535; } #endif /* 16-bit to 8-bit conversions */ /* sRGB: convert linear components to sRGB, alpha := 255 */ static void gpc_sRGB(Pixel *out, const Pixel *in, const Background *back) { (void)back; out->r = isRGB(in->r); if (in->g == in->r) { out->g = out->r; if (in->b == in->r) out->b = out->r; else out->b = isRGB(in->b); } else { out->g = isRGB(in->g); if (in->b == in->r) out->b = out->r; else if (in->b == in->g) out->b = out->g; else out->b = isRGB(in->b); } out->a = 255; } /* unpg: unpremultiply gray component and convert to sRGB (scale alpha) */ static void gpc_unpg(Pixel *out, const Pixel *in, const Background *back) { (void)back; if (in->a <= 128) { out->r = out->g = out->b = 255; out->a = 0; } else { out->r = out->g = out->b = sRGB((double)in->g / in->a); out->a = u8d(in->a / 257.); } } /* unpc: unpremultiply color components and convert to sRGB (scale alpha) */ static void gpc_unpc(Pixel *out, const Pixel *in, const Background *back) { (void)back; if (in->a <= 128) { out->r = out->g = out->b = 255; out->a = 0; } else { out->r = sRGB((double)in->r / in->a); out->g = sRGB((double)in->g / in->a); out->b = sRGB((double)in->b / in->a); out->a = u8d(in->a / 257.); } } /* b16g: composite linear onto gray background and convert the result to sRGB */ static void gpc_b16g(Pixel *out, const Pixel *in, const Background *back) { if (in->a <= 0) out->r = out->g = out->b = back->ig; else { double a = in->a/65535.; double a1 = 1-a; a /= 65535; out->r = out->g = out->b = sRGB(in->g * a + back->dg * a1); } out->a = 255; } /* b16c: composite linear onto color background and convert the result to sRGB*/ static void gpc_b16c(Pixel *out, const Pixel *in, const Background *back) { if (in->a <= 0) { out->r = back->ir; out->g = back->ig; out->b = back->ib; } else { double a = in->a/65535.; double a1 = 1-a; a /= 65535; out->r = sRGB(in->r * a + back->dr * a1); out->g = sRGB(in->g * a + back->dg * a1); out->b = sRGB(in->b * a + back->db * a1); } out->a = 255; } /* sG: convert linear RGB to sRGB grayscale */ static void gpc_sG(Pixel *out, const Pixel *in, const Background *back) { (void)back; out->r = out->g = out->b = sRGB(YfromRGBint(in->r, in->g, in->b)/65535); out->a = 255; } /* sGp: unpremultiply RGB then convert to sRGB grayscale */ static void gpc_sGp(Pixel *out, const Pixel *in, const Background *back) { (void)back; if (in->a <= 128) { out->r = out->g = out->b = 255; out->a = 0; } else { out->r = out->g = out->b = sRGB(YfromRGBint(in->r, in->g, in->b)/in->a); out->a = u8d(in->a / 257.); } } /* sCp: unpremultiply RGB then convert to sRGB */ static void gpc_sCp(Pixel *out, const Pixel *in, const Background *back) { (void)back; if (in->a <= 128) { out->r = out->g = out->b = 255; out->a = 0; } else { out->r = sRGB((double)in->r / in->a); out->g = sRGB((double)in->g / in->a); out->b = sRGB((double)in->b / in->a); out->a = u8d(in->a / 257.); } } /* gb16: composite linear onto background and convert to sRGB grayscale */ /* (order doesn't matter, the composite and grayscale operations permute) */ static void gpc_gb16(Pixel *out, const Pixel *in, const Background *back) { if (in->a <= 0) out->r = out->g = out->b = back->ig; else if (in->a >= 65535) out->r = out->g = out->b = isRGB(in->g); else { double a = in->a / 65535.; double a1 = 1-a; a /= 65535; out->r = out->g = out->b = sRGB(in->g * a + back->dg * a1); } out->a = 255; } /* cb16: composite linear onto background and convert to sRGB */ static void gpc_cb16(Pixel *out, const Pixel *in, const Background *back) { if (in->a <= 0) { out->r = back->ir; out->g = back->ig; out->b = back->ib; } else if (in->a >= 65535) { out->r = isRGB(in->r); out->g = isRGB(in->g); out->b = isRGB(in->b); } else { double a = in->a / 65535.; double a1 = 1-a; a /= 65535; out->r = sRGB(in->r * a + back->dr * a1); out->g = sRGB(in->g * a + back->dg * a1); out->b = sRGB(in->b * a + back->db * a1); } out->a = 255; } /* 16-bit to 16-bit conversions */ /* A: set alpha to 65535 */ static void gpc_A(Pixel *out, const Pixel *in, const Background *back) { (void)back; out->r = in->r; out->g = in->g; out->b = in->b; out->a = 65535; } /* g16: convert linear RGB to linear grayscale (alpha := 65535) */ static void gpc_g16(Pixel *out, const Pixel *in, const Background *back) { (void)back; out->r = out->g = out->b = u16d(YfromRGBint(in->r, in->g, in->b)); out->a = 65535; } /* g16': as 'g16' but alpha is unchanged */ static void gpc_g16q(Pixel *out, const Pixel *in, const Background *back) { (void)back; out->r = out->g = out->b = u16d(YfromRGBint(in->r, in->g, in->b)); out->a = in->a; } #if ALLOW_UNUSED_GPC /* Unused functions (to hide them from GCC unused function warnings) */ void (* const gpc_unused[]) (Pixel *out, const Pixel *in, const Background *back) = { gpc_Pre, gpc_Preq, gpc_Glin, gpc_Gpre, gpc_Gprq, gpc_nop8, gpc_nop6 }; #endif /* OUT: ----- 8-bit ----- ----- 16-bit ----- * IN G GA RGB RGBA G GA RGB RGBA * 8 G . . . . lin lin lin lin * 8 GA bckg . bckc . pre' pre pre' pre * 8 RGB g8 g8 . . glin glin lin lin * 8 RGBA g8b g8 bckc . gpr' gpre pre' pre * 16 G sRGB sRGB sRGB sRGB . . . . * 16 GA b16g unpg b16c unpc A . A . * 16 RGB sG sG sRGB sRGB g16 g16 . . * 16 RGBA gb16 sGp cb16 sCp g16 g16' A . * * The matrix is held in an array indexed thus: * * gpc_fn[out_format & BASE_FORMATS][in_format & BASE_FORMATS]; */ /* This will produce a compile time error if the FORMAT_FLAG values don't * match the above matrix! */ #if PNG_FORMAT_FLAG_ALPHA == 1 && PNG_FORMAT_FLAG_COLOR == 2 &&\ PNG_FORMAT_FLAG_LINEAR == 4 static void (* const gpc_fn[8/*in*/][8/*out*/]) (Pixel *out, const Pixel *in, const Background *back) = { /*out: G-8 GA-8 RGB-8 RGBA-8 G-16 GA-16 RGB-16 RGBA-16 */ {gpc_noop,gpc_noop,gpc_noop,gpc_noop, gpc_Lin, gpc_Lin, gpc_Lin, gpc_Lin }, {gpc_bckg,gpc_noop,gpc_bckc,gpc_noop, gpc_preq,gpc_pre, gpc_preq,gpc_pre }, {gpc_g8, gpc_g8, gpc_noop,gpc_noop, gpc_glin,gpc_glin,gpc_lin, gpc_lin }, {gpc_g8b, gpc_g8, gpc_bckc,gpc_noop, gpc_gprq,gpc_gpre,gpc_preq,gpc_pre }, {gpc_sRGB,gpc_sRGB,gpc_sRGB,gpc_sRGB, gpc_noop,gpc_noop,gpc_noop,gpc_noop}, {gpc_b16g,gpc_unpg,gpc_b16c,gpc_unpc, gpc_A, gpc_noop,gpc_A, gpc_noop}, {gpc_sG, gpc_sG, gpc_sRGB,gpc_sRGB, gpc_g16, gpc_g16, gpc_noop,gpc_noop}, {gpc_gb16,gpc_sGp, gpc_cb16,gpc_sCp, gpc_g16, gpc_g16q,gpc_A, gpc_noop} }; /* The array is repeated for the cases where both the input and output are color * mapped because then different algorithms are used. */ static void (* const gpc_fn_colormapped[8/*in*/][8/*out*/]) (Pixel *out, const Pixel *in, const Background *back) = { /*out: G-8 GA-8 RGB-8 RGBA-8 G-16 GA-16 RGB-16 RGBA-16 */ {gpc_noop,gpc_noop,gpc_noop,gpc_noop, gpc_lin, gpc_lin, gpc_lin, gpc_lin }, {gpc_bckg,gpc_noop,gpc_bckc,gpc_noop, gpc_preq,gpc_pre, gpc_preq,gpc_pre }, {gpc_g8, gpc_g8, gpc_noop,gpc_noop, gpc_glin,gpc_glin,gpc_lin, gpc_lin }, {gpc_g8b, gpc_g8, gpc_bckc,gpc_noop, gpc_gprq,gpc_gpre,gpc_preq,gpc_pre }, {gpc_sRGB,gpc_sRGB,gpc_sRGB,gpc_sRGB, gpc_noop,gpc_noop,gpc_noop,gpc_noop}, {gpc_b16g,gpc_unpg,gpc_b16c,gpc_unpc, gpc_A, gpc_noop,gpc_A, gpc_noop}, {gpc_sG, gpc_sG, gpc_sRGB,gpc_sRGB, gpc_g16, gpc_g16, gpc_noop,gpc_noop}, {gpc_gb16,gpc_sGp, gpc_cb16,gpc_sCp, gpc_g16, gpc_g16q,gpc_A, gpc_noop} }; /* The error arrays record the error in the same matrix; 64 entries, however * the different algorithms used in libpng for colormap and direct conversions * mean that four separate matrices are used (for each combination of * colormapped and direct.) * * In some cases the conversion between sRGB formats goes via a linear * intermediate; an sRGB to linear conversion (as above) is followed by a simple * linear to sRGB step with no other conversions. This is done by a separate * error array from an arbitrary 'in' format to one of the four basic outputs * (since final output is always sRGB not colormapped). * * These arrays may be modified if the --accumulate flag is set during the run; * then instead of logging errors they are simply added in. * * The three entries are currently for transparent, partially transparent and * opaque input pixel values. Notice that alpha should be exact in each case. * * Errors in alpha should only occur when converting from a direct format * to a colormapped format, when alpha is effectively smashed (so large * errors can occur.) There should be no error in the '0' and 'opaque' * values. The fourth entry in the array is used for the alpha error (and it * should always be zero for the 'via linear' case since this is never color * mapped.) * * Mapping to a colormap smashes the colors, it is necessary to have separate * values for these cases because they are much larger; it is very much * impossible to obtain a reasonable result, these are held in * gpc_error_to_colormap. */ #if PNG_FORMAT_FLAG_COLORMAP == 8 /* extra check also required */ # include "pngstest-errors.h" /* machine generated */ #endif /* COLORMAP flag check */ #endif /* flag checks */ typedef struct { /* Basic pixel information: */ Image* in_image; /* Input image */ const Image* out_image; /* Output image */ /* 'background' is the value passed to the gpc_ routines, it may be NULL if * it should not be used (*this* program has an error if it crashes as a * result!) */ Background background_color; const Background* background; /* Precalculated values: */ int in_opaque; /* Value of input alpha that is opaque */ int is_palette; /* Sample values come from the palette */ int accumulate; /* Accumulate component errors (don't log) */ int output_8bit; /* Output is 8-bit (else 16-bit) */ void (*in_gp)(Pixel*, png_const_voidp); void (*out_gp)(Pixel*, png_const_voidp); void (*transform)(Pixel *out, const Pixel *in, const Background *back); /* A function to perform the required transform */ void (*from_linear)(Pixel *out, const Pixel *in, const Background *back); /* For 'via_linear' transforms the final, from linear, step, else NULL */ png_uint_16 error[4]; /* Three error values for transparent, partially transparent and opaque * input pixels (in turn). */ png_uint_16 *error_ptr; /* Where these are stored in the static array (for 'accumulate') */ } Transform; /* Return a 'transform' as above for the given format conversion. */ static void transform_from_formats(Transform *result, Image *in_image, const Image *out_image, png_const_colorp background, int via_linear) { png_uint_32 in_format, out_format; png_uint_32 in_base, out_base; memset(result, 0, sizeof *result); /* Store the original images for error messages */ result->in_image = in_image; result->out_image = out_image; in_format = in_image->image.format; out_format = out_image->image.format; if (in_format & PNG_FORMAT_FLAG_LINEAR) result->in_opaque = 65535; else result->in_opaque = 255; result->output_8bit = (out_format & PNG_FORMAT_FLAG_LINEAR) == 0; result->is_palette = 0; /* set by caller if required */ result->accumulate = (in_image->opts & ACCUMULATE) != 0; /* The loaders (which need the ordering information) */ result->in_gp = get_pixel(in_format); result->out_gp = get_pixel(out_format); /* Remove the ordering information: */ in_format &= BASE_FORMATS | PNG_FORMAT_FLAG_COLORMAP; in_base = in_format & BASE_FORMATS; out_format &= BASE_FORMATS | PNG_FORMAT_FLAG_COLORMAP; out_base = out_format & BASE_FORMATS; if (via_linear) { /* Check for an error in this program: */ if (out_format & (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLORMAP)) { fprintf(stderr, "internal transform via linear error 0x%x->0x%x\n", in_format, out_format); exit(1); } result->transform = gpc_fn[in_base][out_base | PNG_FORMAT_FLAG_LINEAR]; result->from_linear = gpc_fn[out_base | PNG_FORMAT_FLAG_LINEAR][out_base]; result->error_ptr = gpc_error_via_linear[in_format][out_format]; } else if (~in_format & out_format & PNG_FORMAT_FLAG_COLORMAP) { /* The input is not colormapped but the output is, the errors will * typically be large (only the grayscale-no-alpha case permits preserving * even 8-bit values.) */ result->transform = gpc_fn[in_base][out_base]; result->from_linear = NULL; result->error_ptr = gpc_error_to_colormap[in_base][out_base]; } else { /* The caller handles the colormap->pixel value conversion, so the * transform function just gets a pixel value, however because libpng * currently contains a different implementation for mapping a colormap if * both input and output are colormapped we need different conversion * functions to deal with errors in the libpng implementation. */ if (in_format & out_format & PNG_FORMAT_FLAG_COLORMAP) result->transform = gpc_fn_colormapped[in_base][out_base]; else result->transform = gpc_fn[in_base][out_base]; result->from_linear = NULL; result->error_ptr = gpc_error[in_format][out_format]; } /* Follow the libpng simplified API rules to work out what to pass to the gpc * routines as a background value, if one is not required pass NULL so that * this program crashes in the even of a programming error. */ result->background = NULL; /* default: not required */ /* Rule 1: background only need be supplied if alpha is to be removed */ if (in_format & ~out_format & PNG_FORMAT_FLAG_ALPHA) { /* The input value is 'NULL' to use the background and (otherwise) an sRGB * background color (to use a solid color). The code above uses a fixed * byte value, BUFFER_INIT8, for buffer even for 16-bit output. For * linear (16-bit) output the sRGB background color is ignored; the * composition is always on the background (so BUFFER_INIT8 * 257), except * that for the colormap (i.e. linear colormapped output) black is used. */ result->background = &result->background_color; if (out_format & PNG_FORMAT_FLAG_LINEAR || via_linear) { if (out_format & PNG_FORMAT_FLAG_COLORMAP) { result->background_color.ir = result->background_color.ig = result->background_color.ib = 0; result->background_color.dr = result->background_color.dg = result->background_color.db = 0; } else { result->background_color.ir = result->background_color.ig = result->background_color.ib = BUFFER_INIT8 * 257; result->background_color.dr = result->background_color.dg = result->background_color.db = 0; } } else /* sRGB output */ { if (background != NULL) { if (out_format & PNG_FORMAT_FLAG_COLOR) { result->background_color.ir = background->red; result->background_color.ig = background->green; result->background_color.ib = background->blue; /* TODO: sometimes libpng uses the power law conversion here, how * to handle this? */ result->background_color.dr = sRGB_to_d[background->red]; result->background_color.dg = sRGB_to_d[background->green]; result->background_color.db = sRGB_to_d[background->blue]; } else /* grayscale: libpng only looks at 'g' */ { result->background_color.ir = result->background_color.ig = result->background_color.ib = background->green; /* TODO: sometimes libpng uses the power law conversion here, how * to handle this? */ result->background_color.dr = result->background_color.dg = result->background_color.db = sRGB_to_d[background->green]; } } else if ((out_format & PNG_FORMAT_FLAG_COLORMAP) == 0) { result->background_color.ir = result->background_color.ig = result->background_color.ib = BUFFER_INIT8; /* TODO: sometimes libpng uses the power law conversion here, how * to handle this? */ result->background_color.dr = result->background_color.dg = result->background_color.db = sRGB_to_d[BUFFER_INIT8]; } /* Else the output is colormapped and a background color must be * provided; if pngstest crashes then that is a bug in this program * (though libpng should png_error as well.) */ else result->background = NULL; } } if (result->background == NULL) { result->background_color.ir = result->background_color.ig = result->background_color.ib = -1; /* not used */ result->background_color.dr = result->background_color.dg = result->background_color.db = 1E30; /* not used */ } /* Copy the error values into the Transform: */ result->error[0] = result->error_ptr[0]; result->error[1] = result->error_ptr[1]; result->error[2] = result->error_ptr[2]; result->error[3] = result->error_ptr[3]; } /* Compare two pixels. * * OLD error values: static int error_to_linear = 811; * by experiment * static int error_to_linear_grayscale = 424; * by experiment * static int error_to_sRGB = 6; * by experiment * static int error_to_sRGB_grayscale = 17; * libpng error by calculation + 2 by experiment * static int error_in_compose = 2; * by experiment * static int error_in_premultiply = 1; * * The following is *just* the result of a round trip from 8-bit sRGB to linear * then back to 8-bit sRGB when it is done by libpng. There are two problems: * * 1) libpng currently uses a 2.2 power law with no linear segment, this results * in instability in the low values and even with 16-bit precision sRGB(1) ends * up mapping to sRGB(0) as a result of rounding in the 16-bit representation. * This gives an error of 1 in the handling of value 1 only. * * 2) libpng currently uses an intermediate 8-bit linear value in gamma * correction of 8-bit values. This results in many more errors, the worse of * which is mapping sRGB(14) to sRGB(0). * * The general 'error_via_linear' is more complex because of pre-multiplication, * this compounds the 8-bit errors according to the alpha value of the pixel. * As a result 256 values are pre-calculated for error_via_linear. */ #if 0 static int error_in_libpng_gamma; static int error_via_linear[256]; /* Indexed by 8-bit alpha */ static void init_error_via_linear(void) { int alpha; error_via_linear[0] = 255; /* transparent pixel */ for (alpha=1; alpha<=255; ++alpha) { /* 16-bit values less than 128.5 get rounded to 8-bit 0 and so the worst * case error arises with 16-bit 128.5, work out what sRGB * (non-associated) value generates 128.5; any value less than this is * going to map to 0, so the worst error is floor(value). * * Note that errors are considerably higher (more than a factor of 2) * because libpng uses a simple power law for sRGB data at present. * * Add .1 for arithmetic errors inside libpng. */ double v = floor(255*pow(.5/*(128.5 * 255 / 65535)*/ / alpha, 1/2.2)+.1); error_via_linear[alpha] = (int)v; } /* This is actually 14.99, but, despite the closeness to 15, 14 seems to work * ok in this case. */ error_in_libpng_gamma = 14; } #endif static void print_pixel(char string[64], const Pixel *pixel, png_uint_32 format) { switch (format & (PNG_FORMAT_FLAG_ALPHA|PNG_FORMAT_FLAG_COLOR)) { case 0: sprintf(string, "%s(%d)", format_names[format], pixel->g); break; case PNG_FORMAT_FLAG_ALPHA: sprintf(string, "%s(%d,%d)", format_names[format], pixel->g, pixel->a); break; case PNG_FORMAT_FLAG_COLOR: sprintf(string, "%s(%d,%d,%d)", format_names[format], pixel->r, pixel->g, pixel->b); break; case PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA: sprintf(string, "%s(%d,%d,%d,%d)", format_names[format], pixel->r, pixel->g, pixel->b, pixel->a); break; default: sprintf(string, "invalid-format"); break; } } static int logpixel(const Transform *transform, png_uint_32 x, png_uint_32 y, const Pixel *in, const Pixel *calc, const Pixel *out, const char *reason) { png_uint_32 in_format = transform->in_image->image.format; png_uint_32 out_format = transform->out_image->image.format; png_uint_32 back_format = out_format & ~PNG_FORMAT_FLAG_ALPHA; const char *via_linear = ""; char pixel_in[64], pixel_calc[64], pixel_out[64], pixel_loc[64]; char background_info[100]; print_pixel(pixel_in, in, in_format); print_pixel(pixel_calc, calc, out_format); print_pixel(pixel_out, out, out_format); if (transform->is_palette) sprintf(pixel_loc, "palette: %lu", (unsigned long)y); else sprintf(pixel_loc, "%lu,%lu", (unsigned long)x, (unsigned long)y); if (transform->from_linear != NULL) { via_linear = " (via linear)"; /* And as a result the *read* format which did any background processing * was itself linear, so the background color information is also * linear. */ back_format |= PNG_FORMAT_FLAG_LINEAR; } if (transform->background != NULL) { Pixel back; char pixel_back[64]; back.r = transform->background->ir; back.g = transform->background->ig; back.b = transform->background->ib; back.a = -1; /* not used */ print_pixel(pixel_back, &back, back_format); sprintf(background_info, " on background %s", pixel_back); } else background_info[0] = 0; if (transform->in_image->file_name != transform->out_image->file_name) { char error_buffer[512]; sprintf(error_buffer, "(%s) %s error%s:\n %s%s ->\n %s\n not: %s.\n" "Use --preserve and examine: ", pixel_loc, reason, via_linear, pixel_in, background_info, pixel_out, pixel_calc); return logerror(transform->in_image, transform->in_image->file_name, error_buffer, transform->out_image->file_name); } else { char error_buffer[512]; sprintf(error_buffer, "(%s) %s error%s:\n %s%s ->\n %s\n not: %s.\n" " The error happened when reading the original file with this format.", pixel_loc, reason, via_linear, pixel_in, background_info, pixel_out, pixel_calc); return logerror(transform->in_image, transform->in_image->file_name, error_buffer, ""); } } static int cmppixel(Transform *transform, png_const_voidp in, png_const_voidp out, png_uint_32 x, png_uint_32 y/*or palette index*/) { int maxerr; png_const_charp errmsg; Pixel pixel_in, pixel_calc, pixel_out; transform->in_gp(&pixel_in, in); if (transform->from_linear == NULL) transform->transform(&pixel_calc, &pixel_in, transform->background); else { transform->transform(&pixel_out, &pixel_in, transform->background); transform->from_linear(&pixel_calc, &pixel_out, NULL); } transform->out_gp(&pixel_out, out); /* Eliminate the case where the input and output values match exactly. */ if (pixel_calc.a == pixel_out.a && pixel_calc.r == pixel_out.r && pixel_calc.g == pixel_out.g && pixel_calc.b == pixel_out.b) return 1; /* Eliminate the case where the output pixel is transparent and the output * is 8-bit - any component values are valid. Don't check the input alpha * here to also skip the 16-bit small alpha cases. */ if (transform->output_8bit && pixel_calc.a == 0 && pixel_out.a == 0) return 1; /* Check for alpha errors first; an alpha error can damage the components too * so avoid spurious checks on components if one is found. */ errmsg = NULL; { int err_a = abs(pixel_calc.a-pixel_out.a); if (err_a > transform->error[3]) { /* If accumulating check the components too */ if (transform->accumulate) transform->error[3] = (png_uint_16)err_a; else errmsg = "alpha"; } } /* Now if *either* of the output alphas are 0 but alpha is within tolerance * eliminate the 8-bit component comparison. */ if (errmsg == NULL && transform->output_8bit && (pixel_calc.a == 0 || pixel_out.a == 0)) return 1; if (errmsg == NULL) /* else just signal an alpha error */ { int err_r = abs(pixel_calc.r - pixel_out.r); int err_g = abs(pixel_calc.g - pixel_out.g); int err_b = abs(pixel_calc.b - pixel_out.b); int limit; if ((err_r | err_g | err_b) == 0) return 1; /* exact match */ /* Mismatch on a component, check the input alpha */ if (pixel_in.a >= transform->in_opaque) { errmsg = "opaque component"; limit = 2; /* opaque */ } else if (pixel_in.a > 0) { errmsg = "alpha component"; limit = 1; /* partially transparent */ } else { errmsg = "transparent component (background)"; limit = 0; /* transparent */ } maxerr = err_r; if (maxerr < err_g) maxerr = err_g; if (maxerr < err_b) maxerr = err_b; if (maxerr <= transform->error[limit]) return 1; /* within the error limits */ /* Handle a component mis-match; log it, just return an error code, or * accumulate it. */ if (transform->accumulate) { transform->error[limit] = (png_uint_16)maxerr; return 1; /* to cause the caller to keep going */ } } /* Failure to match and not accumulating, so the error must be logged. */ return logpixel(transform, x, y, &pixel_in, &pixel_calc, &pixel_out, errmsg); } static png_byte component_loc(png_byte loc[4], png_uint_32 format) { /* Given a format return the number of channels and the location of * each channel. * * The mask 'loc' contains the component offset of the channels in the * following order. Note that if 'format' is grayscale the entries 1-3 must * all contain the location of the gray channel. * * 0: alpha * 1: red or gray * 2: green or gray * 3: blue or gray */ png_byte channels; if (format & PNG_FORMAT_FLAG_COLOR) { channels = 3; loc[2] = 1; # ifdef PNG_FORMAT_BGR_SUPPORTED if (format & PNG_FORMAT_FLAG_BGR) { loc[1] = 2; loc[3] = 0; } else # endif { loc[1] = 0; loc[3] = 2; } } else { channels = 1; loc[1] = loc[2] = loc[3] = 0; } if (format & PNG_FORMAT_FLAG_ALPHA) { # ifdef PNG_FORMAT_AFIRST_SUPPORTED if (format & PNG_FORMAT_FLAG_AFIRST) { loc[0] = 0; ++loc[1]; ++loc[2]; ++loc[3]; } else # endif loc[0] = channels; ++channels; } else loc[0] = 4; /* not present */ return channels; } /* Compare two images, the original 'a', which was written out then read back in * to * give image 'b'. The formats may have been changed. */ static int compare_two_images(Image *a, Image *b, int via_linear, png_const_colorp background) { ptrdiff_t stridea = a->stride; ptrdiff_t strideb = b->stride; png_const_bytep rowa = a->buffer+16; png_const_bytep rowb = b->buffer+16; png_uint_32 width = a->image.width; png_uint_32 height = a->image.height; png_uint_32 formata = a->image.format; png_uint_32 formatb = b->image.format; unsigned int a_sample = PNG_IMAGE_SAMPLE_SIZE(formata); unsigned int b_sample = PNG_IMAGE_SAMPLE_SIZE(formatb); int alpha_added, alpha_removed; int bchannels; png_uint_32 y; Transform tr; int btoa[4]={0,0,0,0}; /* This should never happen: */ if (width != b->image.width || height != b->image.height) return logerror(a, a->file_name, ": width x height changed: ", b->file_name); /* Set up the background and the transform */ transform_from_formats(&tr, a, b, background, via_linear); /* Find the first row and inter-row space. */ if (!(formata & PNG_FORMAT_FLAG_COLORMAP) && (formata & PNG_FORMAT_FLAG_LINEAR)) stridea *= 2; if (!(formatb & PNG_FORMAT_FLAG_COLORMAP) && (formatb & PNG_FORMAT_FLAG_LINEAR)) strideb *= 2; if (stridea < 0) rowa += (height-1) * (-stridea); if (strideb < 0) rowb += (height-1) * (-strideb); /* First shortcut the two colormap case by comparing the image data; if it * matches then we expect the colormaps to match, although this is not * absolutely necessary for an image match. If the colormaps fail to match * then there is a problem in libpng. */ if (formata & formatb & PNG_FORMAT_FLAG_COLORMAP) { /* Only check colormap entries that actually exist; */ png_const_bytep ppa, ppb; int match; png_byte in_use[256], amax = 0, bmax = 0; memset(in_use, 0, sizeof in_use); ppa = rowa; ppb = rowb; /* Do this the slow way to accumulate the 'in_use' flags, don't break out * of the loop until the end; this validates the color-mapped data to * ensure all pixels are valid color-map indexes. */ for (y=0, match=1; y bmax) bmax = bval; if (bval != aval) match = 0; in_use[aval] = 1; if (aval > amax) amax = aval; } } /* If the buffers match then the colormaps must too. */ if (match) { /* Do the color-maps match, entry by entry? Only check the 'in_use' * entries. An error here should be logged as a color-map error. */ png_const_bytep a_cmap = (png_const_bytep)a->colormap; png_const_bytep b_cmap = (png_const_bytep)b->colormap; int result = 1; /* match by default */ /* This is used in logpixel to get the error message correct. */ tr.is_palette = 1; for (y=0; y<256; ++y, a_cmap += a_sample, b_cmap += b_sample) if (in_use[y]) { /* The colormap entries should be valid, but because libpng doesn't * do any checking at present the original image may contain invalid * pixel values. These cause an error here (at present) unless * accumulating errors in which case the program just ignores them. */ if (y >= a->image.colormap_entries) { if ((a->opts & ACCUMULATE) == 0) { char pindex[16]; sprintf(pindex, "%lu[%lu]", (unsigned long)y, (unsigned long)a->image.colormap_entries); logerror(a, a->file_name, ": bad pixel index: ", pindex); } result = 0; } else if (y >= b->image.colormap_entries) { if ((b->opts & ACCUMULATE) == 0) { char pindex[16]; sprintf(pindex, "%lu[%lu]", (unsigned long)y, (unsigned long)b->image.colormap_entries); logerror(b, b->file_name, ": bad pixel index: ", pindex); } result = 0; } /* All the mismatches are logged here; there can only be 256! */ else if (!cmppixel(&tr, a_cmap, b_cmap, 0, y)) result = 0; } /* If requested, copy the error values back from the Transform. */ if (a->opts & ACCUMULATE) { tr.error_ptr[0] = tr.error[0]; tr.error_ptr[1] = tr.error[1]; tr.error_ptr[2] = tr.error[2]; tr.error_ptr[3] = tr.error[3]; result = 1; /* force a continue */ } return result; } /* else the image buffers don't match pixel-wise so compare sample values * instead, but first validate that the pixel indexes are in range (but * only if not accumulating, when the error is ignored.) */ else if ((a->opts & ACCUMULATE) == 0) { # ifdef __GNUC__ # define BYTE_CHARS 20 /* 2^32: GCC sprintf warning */ # else # define BYTE_CHARS 3 /* 2^8: real maximum value */ # endif /* Check the original image first, * TODO: deal with input images with bad pixel values? */ if (amax >= a->image.colormap_entries) { char pindex[3+2*BYTE_CHARS]; sprintf(pindex, "%d[%u]", amax, (png_byte)/*SAFE*/a->image.colormap_entries); return logerror(a, a->file_name, ": bad pixel index: ", pindex); } else if (bmax >= b->image.colormap_entries) { char pindex[3+2*BYTE_CHARS]; sprintf(pindex, "%d[%u]", bmax, (png_byte)/*SAFE*/b->image.colormap_entries); return logerror(b, b->file_name, ": bad pixel index: ", pindex); } } } /* We can directly compare pixel values without the need to use the read * or transform support (i.e. a memory compare) if: * * 1) The bit depth has not changed. * 2) RGB to grayscale has not been done (the reverse is ok; we just compare * the three RGB values to the original grayscale.) * 3) An alpha channel has not been removed from an 8-bit format, or the * 8-bit alpha value of the pixel was 255 (opaque). * * If an alpha channel has been *added* then it must have the relevant opaque * value (255 or 65535). * * The fist two the tests (in the order given above) (using the boolean * equivalence !a && !b == !(a || b)) */ if (!(((formata ^ formatb) & PNG_FORMAT_FLAG_LINEAR) | (formata & (formatb ^ PNG_FORMAT_FLAG_COLOR) & PNG_FORMAT_FLAG_COLOR))) { /* Was an alpha channel changed? */ png_uint_32 alpha_changed = (formata ^ formatb) & PNG_FORMAT_FLAG_ALPHA; /* Was an alpha channel removed? (The third test.) If so the direct * comparison is only possible if the input alpha is opaque. */ alpha_removed = (formata & alpha_changed) != 0; /* Was an alpha channel added? */ alpha_added = (formatb & alpha_changed) != 0; /* The channels may have been moved between input and output, this finds * out how, recording the result in the btoa array, which says where in * 'a' to find each channel of 'b'. If alpha was added then btoa[alpha] * ends up as 4 (and is not used.) */ { int i; png_byte aloc[4]; png_byte bloc[4]; /* The following are used only if the formats match, except that * 'bchannels' is a flag for matching formats. btoa[x] says, for each * channel in b, where to find the corresponding value in a, for the * bchannels. achannels may be different for a gray to rgb transform * (a will be 1 or 2, b will be 3 or 4 channels.) */ (void)component_loc(aloc, formata); bchannels = component_loc(bloc, formatb); /* Hence the btoa array. */ for (i=0; i<4; ++i) { if (bloc[i] < 4) btoa[bloc[i]] = aloc[i]; /* may be '4' for alpha */ } if (alpha_added) alpha_added = bloc[0]; /* location of alpha channel in image b */ else alpha_added = 4; /* Won't match an image b channel */ if (alpha_removed) alpha_removed = aloc[0]; /* location of alpha channel in image a */ else alpha_removed = 4; } } else { /* Direct compare is not possible, cancel out all the corresponding local * variables. */ bchannels = 0; alpha_removed = alpha_added = 4; btoa[3] = btoa[2] = btoa[1] = btoa[0] = 4; /* 4 == not present */ } for (y=0; ycolormap + a_sample * *ppa++; else psa = ppa, ppa += a_sample; if (formatb & PNG_FORMAT_FLAG_COLORMAP) psb = (png_const_bytep)b->colormap + b_sample * *ppb++; else psb = ppb, ppb += b_sample; /* Do the fast test if possible. */ if (bchannels) { /* Check each 'b' channel against either the corresponding 'a' * channel or the opaque alpha value, as appropriate. If * alpha_removed value is set (not 4) then also do this only if the * 'a' alpha channel (alpha_removed) is opaque; only relevant for * the 8-bit case. */ if (formatb & PNG_FORMAT_FLAG_LINEAR) /* 16-bit checks */ { png_const_uint_16p pua = aligncastconst(png_const_uint_16p, psa); png_const_uint_16p pub = aligncastconst(png_const_uint_16p, psb); switch (bchannels) { case 4: if (pua[btoa[3]] != pub[3]) break; /* FALLTHROUGH */ case 3: if (pua[btoa[2]] != pub[2]) break; /* FALLTHROUGH */ case 2: if (pua[btoa[1]] != pub[1]) break; /* FALLTHROUGH */ case 1: if (pua[btoa[0]] != pub[0]) break; if (alpha_added != 4 && pub[alpha_added] != 65535) break; continue; /* x loop */ default: break; /* impossible */ } } else if (alpha_removed == 4 || psa[alpha_removed] == 255) { switch (bchannels) { case 4: if (psa[btoa[3]] != psb[3]) break; /* FALLTHROUGH */ case 3: if (psa[btoa[2]] != psb[2]) break; /* FALLTHROUGH */ case 2: if (psa[btoa[1]] != psb[1]) break; /* FALLTHROUGH */ case 1: if (psa[btoa[0]] != psb[0]) break; if (alpha_added != 4 && psb[alpha_added] != 255) break; continue; /* x loop */ default: break; /* impossible */ } } } /* If we get to here the fast match failed; do the slow match for this * pixel. */ if (!cmppixel(&tr, psa, psb, x, y) && (a->opts & KEEP_GOING) == 0) return 0; /* error case */ } } /* If requested, copy the error values back from the Transform. */ if (a->opts & ACCUMULATE) { tr.error_ptr[0] = tr.error[0]; tr.error_ptr[1] = tr.error[1]; tr.error_ptr[2] = tr.error[2]; tr.error_ptr[3] = tr.error[3]; } return 1; } /* Read the file; how the read gets done depends on which of input_file and * input_memory have been set. */ static int read_file(Image *image, png_uint_32 format, png_const_colorp background) { memset(&image->image, 0, sizeof image->image); image->image.version = PNG_IMAGE_VERSION; if (image->input_memory != NULL) { if (!png_image_begin_read_from_memory(&image->image, image->input_memory, image->input_memory_size)) return logerror(image, "memory init: ", image->file_name, ""); } # ifdef PNG_STDIO_SUPPORTED else if (image->input_file != NULL) { if (!png_image_begin_read_from_stdio(&image->image, image->input_file)) return logerror(image, "stdio init: ", image->file_name, ""); } else { if (!png_image_begin_read_from_file(&image->image, image->file_name)) return logerror(image, "file init: ", image->file_name, ""); } # else else { return logerror(image, "unsupported file/stdio init: ", image->file_name, ""); } # endif /* This must be set after the begin_read call: */ if (image->opts & sRGB_16BIT) image->image.flags |= PNG_IMAGE_FLAG_16BIT_sRGB; /* Have an initialized image with all the data we need plus, maybe, an * allocated file (myfile) or buffer (mybuffer) that need to be freed. */ { int result; png_uint_32 image_format; /* Print both original and output formats. */ image_format = image->image.format; if (image->opts & VERBOSE) { printf("%s %lu x %lu %s -> %s", image->file_name, (unsigned long)image->image.width, (unsigned long)image->image.height, format_names[image_format & FORMAT_MASK], (format & FORMAT_NO_CHANGE) != 0 || image->image.format == format ? "no change" : format_names[format & FORMAT_MASK]); if (background != NULL) printf(" background(%d,%d,%d)\n", background->red, background->green, background->blue); else printf("\n"); fflush(stdout); } /* 'NO_CHANGE' combined with the color-map flag forces the base format * flags to be set on read to ensure that the original representation is * not lost in the pass through a colormap format. */ if ((format & FORMAT_NO_CHANGE) != 0) { if ((format & PNG_FORMAT_FLAG_COLORMAP) != 0 && (image_format & PNG_FORMAT_FLAG_COLORMAP) != 0) format = (image_format & ~BASE_FORMATS) | (format & BASE_FORMATS); else format = image_format; } image->image.format = format; image->stride = PNG_IMAGE_ROW_STRIDE(image->image) + image->stride_extra; allocbuffer(image); result = png_image_finish_read(&image->image, background, image->buffer+16, (png_int_32)image->stride, image->colormap); checkbuffer(image, image->file_name); if (result) return checkopaque(image); else return logerror(image, image->file_name, ": image read failed", ""); } } /* Reads from a filename, which must be in image->file_name, but uses * image->opts to choose the method. The file is always read in its native * format (the one the simplified API suggests). */ static int read_one_file(Image *image) { if (!(image->opts & USE_FILE) || (image->opts & USE_STDIO)) { /* memory or stdio. */ FILE *f = fopen(image->file_name, "rb"); if (f != NULL) { if (image->opts & USE_FILE) image->input_file = f; else /* memory */ { if (fseek(f, 0, SEEK_END) == 0) { long int cb = ftell(f); if (cb > 0) { #ifndef __COVERITY__ if ((unsigned long int)cb <= (size_t)~(size_t)0) #endif { png_bytep b = voidcast(png_bytep, malloc((size_t)cb)); if (b != NULL) { rewind(f); if (fread(b, (size_t)cb, 1, f) == 1) { fclose(f); image->input_memory_size = cb; image->input_memory = b; } else { free(b); return logclose(image, f, image->file_name, ": read failed: "); } } else return logclose(image, f, image->file_name, ": out of memory: "); } else return logclose(image, f, image->file_name, ": file too big for this architecture: "); /* cb is the length of the file as a (long) and * this is greater than the maximum amount of * memory that can be requested from malloc. */ } else if (cb == 0) return logclose(image, f, image->file_name, ": zero length: "); else return logclose(image, f, image->file_name, ": tell failed: "); } else return logclose(image, f, image->file_name, ": seek failed: "); } } else return logerror(image, image->file_name, ": open failed: ", strerror(errno)); } return read_file(image, FORMAT_NO_CHANGE, NULL); } #ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED static int write_one_file(Image *output, Image *image, int convert_to_8bit) { if (image->opts & FAST_WRITE) image->image.flags |= PNG_IMAGE_FLAG_FAST; if (image->opts & USE_STDIO) { #ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED #ifndef __COVERITY__ FILE *f = tmpfile(); #else /* Experimental. Coverity says tmpfile() is insecure because it * generates predictable names. * * It is possible to satisfy Coverity by using mkstemp(); however, * any platform supporting mkstemp() undoubtedly has a secure tmpfile() * implementation as well, and doesn't need the fix. Note that * the fix won't work on platforms that don't support mkstemp(). * * https://www.securecoding.cert.org/confluence/display/c/ * FIO21-C.+Do+not+create+temporary+files+in+shared+directories * says that most historic implementations of tmpfile() provide * only a limited number of possible temporary file names * (usually 26) before file names are recycled. That article also * provides a secure solution that unfortunately depends upon mkstemp(). */ char tmpfile[] = "pngstest-XXXXXX"; int filedes; FILE *f; umask(0177); filedes = mkstemp(tmpfile); if (filedes < 0) f = NULL; else { f = fdopen(filedes,"w+"); /* Hide the filename immediately and ensure that the file does * not exist after the program ends */ (void) unlink(tmpfile); } #endif if (f != NULL) { if (png_image_write_to_stdio(&image->image, f, convert_to_8bit, image->buffer+16, (png_int_32)image->stride, image->colormap)) { if (fflush(f) == 0) { rewind(f); initimage(output, image->opts, "tmpfile", image->stride_extra); output->input_file = f; if (!checkopaque(image)) return 0; } else return logclose(image, f, "tmpfile", ": flush: "); } else { fclose(f); return logerror(image, "tmpfile", ": write failed", ""); } } else return logerror(image, "tmpfile", ": open: ", strerror(errno)); #else /* SIMPLIFIED_WRITE_STDIO */ return logerror(image, "tmpfile", ": open: unsupported", ""); #endif /* SIMPLIFIED_WRITE_STDIO */ } else if (image->opts & USE_FILE) { #ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED static unsigned int counter = 0; char name[32]; sprintf(name, "%s%u.png", tmpf, ++counter); if (png_image_write_to_file(&image->image, name, convert_to_8bit, image->buffer+16, (png_int_32)image->stride, image->colormap)) { initimage(output, image->opts, output->tmpfile_name, image->stride_extra); /* Afterwards, or freeimage will delete it! */ strcpy(output->tmpfile_name, name); if (!checkopaque(image)) return 0; } else return logerror(image, name, ": write failed", ""); #else /* SIMPLIFIED_WRITE_STDIO */ return logerror(image, "stdio", ": open: unsupported", ""); #endif /* SIMPLIFIED_WRITE_STDIO */ } else /* use memory */ { png_alloc_size_t size; if (png_image_write_get_memory_size(image->image, size, convert_to_8bit, image->buffer+16, (png_int_32)image->stride, image->colormap)) { /* This is non-fatal but ignoring it was causing serious problems in * the macro to be ignored: */ if (size > PNG_IMAGE_PNG_SIZE_MAX(image->image)) return logerror(image, "memory", ": PNG_IMAGE_SIZE_MAX wrong", ""); initimage(output, image->opts, "memory", image->stride_extra); output->input_memory = malloc(size); if (output->input_memory != NULL) { output->input_memory_size = size; if (png_image_write_to_memory(&image->image, output->input_memory, &output->input_memory_size, convert_to_8bit, image->buffer+16, (png_int_32)image->stride, image->colormap)) { /* This is also non-fatal but it safes safer to error out anyway: */ if (size != output->input_memory_size) return logerror(image, "memory", ": memory size wrong", ""); } else return logerror(image, "memory", ": write failed", ""); } else return logerror(image, "memory", ": out of memory", ""); } else return logerror(image, "memory", ": get size:", ""); } /* 'output' has an initialized temporary image, read this back in and compare * this against the original: there should be no change since the original * format was written unmodified unless 'convert_to_8bit' was specified. * However, if the original image was color-mapped, a simple read will zap * the linear, color and maybe alpha flags, this will cause spurious failures * under some circumstances. */ if (read_file(output, image->image.format | FORMAT_NO_CHANGE, NULL)) { png_uint_32 original_format = image->image.format; if (convert_to_8bit) original_format &= ~PNG_FORMAT_FLAG_LINEAR; if ((output->image.format & BASE_FORMATS) != (original_format & BASE_FORMATS)) return logerror(image, image->file_name, ": format changed on read: ", output->file_name); return compare_two_images(image, output, 0/*via linear*/, NULL); } else return logerror(output, output->tmpfile_name, ": read of new file failed", ""); } #endif static int testimage(Image *image, png_uint_32 opts, format_list *pf) { int result; Image copy; /* Copy the original data, stealing it from 'image' */ checkopaque(image); copy = *image; copy.opts = opts; copy.buffer = NULL; copy.bufsize = 0; copy.allocsize = 0; image->input_file = NULL; image->input_memory = NULL; image->input_memory_size = 0; image->tmpfile_name[0] = 0; { png_uint_32 counter; Image output; newimage(&output); result = 1; /* Use the low bit of 'counter' to indicate whether or not to do alpha * removal with a background color or by composting onto the image; this * step gets skipped if it isn't relevant */ for (counter=0; counter<2*FORMAT_COUNT; ++counter) if (format_isset(pf, counter >> 1)) { png_uint_32 format = counter >> 1; png_color background_color; png_colorp background = NULL; /* If there is a format change that removes the alpha channel then * the background is relevant. If the output is 8-bit color-mapped * then a background color *must* be provided, otherwise there are * two tests to do - one with a color, the other with NULL. The * NULL test happens second. */ if ((counter & 1) == 0) { if ((format & PNG_FORMAT_FLAG_ALPHA) == 0 && (image->image.format & PNG_FORMAT_FLAG_ALPHA) != 0) { /* Alpha/transparency will be removed, the background is * relevant: make it a color the first time */ random_color(&background_color); background = &background_color; /* BUT if the output is to a color-mapped 8-bit format then * the background must always be a color, so increment 'counter' * to skip the NULL test. */ if ((format & PNG_FORMAT_FLAG_COLORMAP) != 0 && (format & PNG_FORMAT_FLAG_LINEAR) == 0) ++counter; } /* Otherwise an alpha channel is not being eliminated, just leave * background NULL and skip the (counter & 1) NULL test. */ else ++counter; } /* else just use NULL for background */ resetimage(©); copy.opts = opts; /* in case read_file needs to change it */ result = read_file(©, format, background); if (!result) break; /* Make sure the file just read matches the original file. */ result = compare_two_images(image, ©, 0/*via linear*/, background); if (!result) break; # ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED /* Write the *copy* just made to a new file to make sure the write * side works ok. Check the conversion to sRGB if the copy is * linear. */ output.opts = opts; result = write_one_file(&output, ©, 0/*convert to 8bit*/); if (!result) break; /* Validate against the original too; the background is needed here * as well so that compare_two_images knows what color was used. */ result = compare_two_images(image, &output, 0, background); if (!result) break; if ((format & PNG_FORMAT_FLAG_LINEAR) != 0 && (format & PNG_FORMAT_FLAG_COLORMAP) == 0) { /* 'output' is linear, convert to the corresponding sRGB format. */ output.opts = opts; result = write_one_file(&output, ©, 1/*convert to 8bit*/); if (!result) break; /* This may involve a conversion via linear; in the ideal world * this would round-trip correctly, but libpng 1.5.7 is not the * ideal world so allow a drift (error_via_linear). * * 'image' has an alpha channel but 'output' does not then there * will a strip-alpha-channel operation (because 'output' is * linear), handle this by composing on black when doing the * comparison. */ result = compare_two_images(image, &output, 1/*via_linear*/, background); if (!result) break; } # endif /* PNG_SIMPLIFIED_WRITE_SUPPORTED */ } freeimage(&output); } freeimage(©); return result; } static int test_one_file(const char *file_name, format_list *formats, png_uint_32 opts, int stride_extra, int log_pass) { int result; Image image; if (!(opts & NO_RESEED)) reseed(); /* ensure that the random numbers don't depend on file order */ newimage(&image); initimage(&image, opts, file_name, stride_extra); result = read_one_file(&image); if (result) result = testimage(&image, opts, formats); freeimage(&image); /* Ensure that stderr is flushed into any log file */ fflush(stderr); if (log_pass) { if (result) printf("PASS:"); else printf("FAIL:"); # ifndef PNG_SIMPLIFIED_WRITE_SUPPORTED printf(" (no write)"); # endif print_opts(opts); printf(" %s\n", file_name); /* stdout may not be line-buffered if it is piped to a file, so: */ fflush(stdout); } else if (!result) exit(1); return result; } int main(int argc, char **argv) { png_uint_32 opts = FAST_WRITE | STRICT; format_list formats; const char *touch = NULL; int log_pass = 0; int redundant = 0; int stride_extra = 0; int retval = 0; int c; #if PNG_LIBPNG_VER >= 10700 /* This error should not exist in 1.7 or later: */ opts |= GBG_ERROR; #endif init_sRGB_to_d(); #if 0 init_error_via_linear(); #endif format_init(&formats); reseed(); /* initialize random number seeds */ for (c=1; c= sizeof tmpf) { fflush(stdout); fprintf(stderr, "%s: %s is too long for a temp file prefix\n", argv[0], argv[c]); exit(99); } /* Safe: checked above */ strncpy(tmpf, argv[c], sizeof (tmpf)-1); } else { fflush(stdout); fprintf(stderr, "%s: %s requires a temporary file prefix\n", argv[0], arg); exit(99); } } else if (strcmp(arg, "--touch") == 0) { if (c+1 < argc) touch = argv[++c]; else { fflush(stdout); fprintf(stderr, "%s: %s requires a file name argument\n", argv[0], arg); exit(99); } } else if (arg[0] == '+') { png_uint_32 format = formatof(arg+1); if (format > FORMAT_COUNT) exit(99); format_set(&formats, format); } else if (arg[0] == '-' && arg[1] != 0 && (arg[1] != '0' || arg[2] != 0)) { fflush(stdout); fprintf(stderr, "%s: unknown option: %s\n", argv[0], arg); exit(99); } else { if (format_is_initial(&formats)) format_default(&formats, redundant); if (arg[0] == '-') { int term = (arg[1] == '0' ? 0 : '\n'); unsigned int ich = 0; /* Loop reading files, use a static buffer to simplify this and just * stop if the name gets to long. */ static char buffer[4096]; do { int ch = getchar(); /* Don't allow '\0' in file names, and terminate with '\n' or, * for -0, just '\0' (use -print0 to find to make this work!) */ if (ch == EOF || ch == term || ch == 0) { buffer[ich] = 0; if (ich > 0 && !test_one_file(buffer, &formats, opts, stride_extra, log_pass)) retval = 1; if (ch == EOF) break; ich = 0; --ich; /* so that the increment below sets it to 0 again */ } else buffer[ich] = (char)ch; } while (++ich < sizeof buffer); if (ich) { buffer[32] = 0; buffer[4095] = 0; fprintf(stderr, "%s...%s: file name too long\n", buffer, buffer+(4096-32)); exit(99); } } else if (!test_one_file(arg, &formats, opts, stride_extra, log_pass)) retval = 1; } } if (opts & ACCUMULATE) { unsigned int in; printf("/* contrib/libtests/pngstest-errors.h\n"); printf(" *\n"); printf(" * BUILT USING:" PNG_HEADER_VERSION_STRING); printf(" *\n"); printf(" * This code is released under the libpng license.\n"); printf(" * For conditions of distribution and use, see the disclaimer\n"); printf(" * and license in png.h\n"); printf(" *\n"); printf(" * THIS IS A MACHINE GENERATED FILE: do not edit it directly!\n"); printf(" * Instead run:\n"); printf(" *\n"); printf(" * pngstest --accumulate\n"); printf(" *\n"); printf(" * on as many PNG files as possible; at least PNGSuite and\n"); printf(" * contrib/libtests/testpngs.\n"); printf(" */\n"); printf("static png_uint_16 gpc_error[16/*in*/][16/*out*/][4/*a*/] =\n"); printf("{\n"); for (in=0; in<16; ++in) { unsigned int out; printf(" { /* input: %s */\n ", format_names[in]); for (out=0; out<16; ++out) { unsigned int alpha; printf(" {"); for (alpha=0; alpha<4; ++alpha) { printf(" %d", gpc_error[in][out][alpha]); if (alpha < 3) putchar(','); } printf(" }"); if (out < 15) { putchar(','); if (out % 4 == 3) printf("\n "); } } printf("\n }"); if (in < 15) putchar(','); else putchar('\n'); } printf("};\n"); printf("static png_uint_16 gpc_error_via_linear[16][4/*out*/][4] =\n"); printf("{\n"); for (in=0; in<16; ++in) { unsigned int out; printf(" { /* input: %s */\n ", format_names[in]); for (out=0; out<4; ++out) { unsigned int alpha; printf(" {"); for (alpha=0; alpha<4; ++alpha) { printf(" %d", gpc_error_via_linear[in][out][alpha]); if (alpha < 3) putchar(','); } printf(" }"); if (out < 3) putchar(','); } printf("\n }"); if (in < 15) putchar(','); else putchar('\n'); } printf("};\n"); printf("static png_uint_16 gpc_error_to_colormap[8/*i*/][8/*o*/][4] =\n"); printf("{\n"); for (in=0; in<8; ++in) { unsigned int out; printf(" { /* input: %s */\n ", format_names[in]); for (out=0; out<8; ++out) { unsigned int alpha; printf(" {"); for (alpha=0; alpha<4; ++alpha) { printf(" %d", gpc_error_to_colormap[in][out][alpha]); if (alpha < 3) putchar(','); } printf(" }"); if (out < 7) { putchar(','); if (out % 4 == 3) printf("\n "); } } printf("\n }"); if (in < 7) putchar(','); else putchar('\n'); } printf("};\n"); printf("/* END MACHINE GENERATED */\n"); } if (retval == 0 && touch != NULL) { FILE *fsuccess = fopen(touch, "wt"); if (fsuccess != NULL) { int error = 0; fprintf(fsuccess, "PNG simple API tests succeeded\n"); fflush(fsuccess); error = ferror(fsuccess); if (fclose(fsuccess) || error) { fflush(stdout); fprintf(stderr, "%s: write failed\n", touch); exit(99); } } else { fflush(stdout); fprintf(stderr, "%s: open failed\n", touch); exit(99); } } return retval; } #else /* !PNG_SIMPLIFIED_READ_SUPPORTED */ int main(void) { fprintf(stderr, "pngstest: no read support in libpng, test skipped\n"); /* So the test is skipped: */ return SKIP; } #endif /* PNG_SIMPLIFIED_READ_SUPPORTED */ libpng-1.6.43/contrib/libtests/pngunknown.c000066400000000000000000001100121456606525400207310ustar00rootroot00000000000000 /* pngunknown.c - test the read side unknown chunk handling * * Copyright (c) 2021 Cosmin Truta * Copyright (c) 2015,2017 Glenn Randers-Pehrson * Written by John Cunningham Bowler * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer * and license in png.h * * NOTES: * This is a C program that is intended to be linked against libpng. It * allows the libpng unknown handling code to be tested by interpreting * arguments to save or discard combinations of chunks. The program is * currently just a minimal validation for the built-in libpng facilities. */ #include #include #include #include /* Define the following to use this test against your installed libpng, rather * than the one being built here: */ #ifdef PNG_FREESTANDING_TESTS # include #else # include "../../png.h" #endif /* 1.6.1 added support for the configure test harness, which uses 77 to indicate * a skipped test, in earlier versions we need to succeed on a skipped test, so: */ #if PNG_LIBPNG_VER >= 10601 && defined(HAVE_CONFIG_H) # define SKIP 77 #else # define SKIP 0 #endif /* Since this program tests the ability to change the unknown chunk handling * these must be defined: */ #if defined(PNG_SET_UNKNOWN_CHUNKS_SUPPORTED) &&\ defined(PNG_STDIO_SUPPORTED) &&\ defined(PNG_READ_SUPPORTED) /* One of these must be defined to allow us to find out what happened. It is * still useful to set unknown chunk handling without either of these in order * to cause *known* chunks to be discarded. This can be a significant * efficiency gain, but it can't really be tested here. */ #if defined(PNG_READ_USER_CHUNKS_SUPPORTED) ||\ defined(PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED) #if PNG_LIBPNG_VER < 10500 /* This deliberately lacks the const. */ typedef png_byte *png_const_bytep; /* This is copied from 1.5.1 png.h: */ #define PNG_INTERLACE_ADAM7_PASSES 7 #define PNG_PASS_START_ROW(pass) (((1U&~(pass))<<(3-((pass)>>1)))&7) #define PNG_PASS_START_COL(pass) (((1U& (pass))<<(3-(((pass)+1)>>1)))&7) #define PNG_PASS_ROW_SHIFT(pass) ((pass)>2?(8-(pass))>>1:3) #define PNG_PASS_COL_SHIFT(pass) ((pass)>1?(7-(pass))>>1:3) #define PNG_PASS_ROWS(height, pass) (((height)+(((1<>PNG_PASS_ROW_SHIFT(pass)) #define PNG_PASS_COLS(width, pass) (((width)+(((1<>PNG_PASS_COL_SHIFT(pass)) #define PNG_ROW_FROM_PASS_ROW(yIn, pass) \ (((yIn)<>(((7-(off))-(pass))<<2)) & 0xFU) | \ ((0x01145AF0U>>(((7-(off))-(pass))<<2)) & 0xF0U)) #define PNG_ROW_IN_INTERLACE_PASS(y, pass) \ ((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1) #define PNG_COL_IN_INTERLACE_PASS(x, pass) \ ((PNG_PASS_MASK(pass,1) >> ((x)&7)) & 1) /* These are needed too for the default build: */ #define PNG_WRITE_16BIT_SUPPORTED #define PNG_READ_16BIT_SUPPORTED /* This comes from pnglibconf.h after 1.5: */ #define PNG_FP_1 100000 #define PNG_GAMMA_THRESHOLD_FIXED\ ((png_fixed_point)(PNG_GAMMA_THRESHOLD * PNG_FP_1)) #endif #if PNG_LIBPNG_VER < 10600 /* 1.6.0 constifies many APIs. The following exists to allow pngvalid to be * compiled against earlier versions. */ # define png_const_structp png_structp #endif #if PNG_LIBPNG_VER < 10700 /* Copied from libpng 1.7.0 png.h */ #define PNG_u2(b1, b2) (((unsigned int)(b1) << 8) + (b2)) #define PNG_U16(b1, b2) ((png_uint_16)PNG_u2(b1, b2)) #define PNG_U32(b1, b2, b3, b4)\ (((png_uint_32)PNG_u2(b1, b2) << 16) + PNG_u2(b3, b4)) /* Constants for known chunk types. */ #define png_IDAT PNG_U32( 73, 68, 65, 84) #define png_IEND PNG_U32( 73, 69, 78, 68) #define png_IHDR PNG_U32( 73, 72, 68, 82) #define png_PLTE PNG_U32( 80, 76, 84, 69) #define png_bKGD PNG_U32( 98, 75, 71, 68) #define png_cHRM PNG_U32( 99, 72, 82, 77) #define png_eXIf PNG_U32(101, 88, 73, 102) /* registered July 2017 */ #define png_fRAc PNG_U32(102, 82, 65, 99) /* registered, not defined */ #define png_gAMA PNG_U32(103, 65, 77, 65) #define png_gIFg PNG_U32(103, 73, 70, 103) #define png_gIFt PNG_U32(103, 73, 70, 116) /* deprecated */ #define png_gIFx PNG_U32(103, 73, 70, 120) #define png_hIST PNG_U32(104, 73, 83, 84) #define png_iCCP PNG_U32(105, 67, 67, 80) #define png_iTXt PNG_U32(105, 84, 88, 116) #define png_oFFs PNG_U32(111, 70, 70, 115) #define png_pCAL PNG_U32(112, 67, 65, 76) #define png_pHYs PNG_U32(112, 72, 89, 115) #define png_sBIT PNG_U32(115, 66, 73, 84) #define png_sCAL PNG_U32(115, 67, 65, 76) #define png_sPLT PNG_U32(115, 80, 76, 84) #define png_sRGB PNG_U32(115, 82, 71, 66) #define png_sTER PNG_U32(115, 84, 69, 82) #define png_tEXt PNG_U32(116, 69, 88, 116) #define png_tIME PNG_U32(116, 73, 77, 69) #define png_tRNS PNG_U32(116, 82, 78, 83) #define png_zTXt PNG_U32(122, 84, 88, 116) /* Test on flag values as defined in the spec (section 5.4): */ #define PNG_CHUNK_ANCILLARY(c) (1 & ((c) >> 29)) #define PNG_CHUNK_CRITICAL(c) (!PNG_CHUNK_ANCILLARY(c)) #define PNG_CHUNK_PRIVATE(c) (1 & ((c) >> 21)) #define PNG_CHUNK_RESERVED(c) (1 & ((c) >> 13)) #define PNG_CHUNK_SAFE_TO_COPY(c) (1 & ((c) >> 5)) #endif /* PNG_LIBPNG_VER < 10700 */ #ifdef __cplusplus # define this not_the_cpp_this # define new not_the_cpp_new # define voidcast(type, value) static_cast(value) #else # define voidcast(type, value) (value) #endif /* __cplusplus */ /* Unused formal parameter errors are removed using the following macro which is * expected to have no bad effects on performance. */ #ifndef UNUSED # if defined(__GNUC__) || defined(_MSC_VER) # define UNUSED(param) (void)param; # else # define UNUSED(param) # endif #endif /* Types of chunks not known to libpng */ #define png_vpAg PNG_U32(118, 112, 65, 103) /* Chunk information */ #define PNG_INFO_tEXt 0x10000000U #define PNG_INFO_iTXt 0x20000000U #define PNG_INFO_zTXt 0x40000000U #define PNG_INFO_sTER 0x01000000U #define PNG_INFO_vpAg 0x02000000U #define ABSENT 0 #define START 1 #define END 2 static struct { char name[5]; png_uint_32 flag; png_uint_32 tag; int unknown; /* Chunk not known to libpng */ int all; /* Chunk set by the '-1' option */ int position; /* position in pngtest.png */ int keep; /* unknown handling setting */ } chunk_info[] = { /* Critical chunks */ { "IDAT", PNG_INFO_IDAT, png_IDAT, 0, 0, START, 0 }, /* must be [0] */ { "PLTE", PNG_INFO_PLTE, png_PLTE, 0, 0, ABSENT, 0 }, /* Non-critical chunks that libpng handles */ /* This is a mess but it seems to be the only way to do it - there is no way * to check for a definition outside a #if. */ { "bKGD", PNG_INFO_bKGD, png_bKGD, # ifdef PNG_READ_bKGD_SUPPORTED 0, # else 1, # endif 1, START, 0 }, { "cHRM", PNG_INFO_cHRM, png_cHRM, # ifdef PNG_READ_cHRM_SUPPORTED 0, # else 1, # endif 1, START, 0 }, { "eXIf", PNG_INFO_eXIf, png_eXIf, # ifdef PNG_READ_eXIf_SUPPORTED 0, # else 1, # endif 1, END, 0 }, { "gAMA", PNG_INFO_gAMA, png_gAMA, # ifdef PNG_READ_gAMA_SUPPORTED 0, # else 1, # endif 1, START, 0 }, { "hIST", PNG_INFO_hIST, png_hIST, # ifdef PNG_READ_hIST_SUPPORTED 0, # else 1, # endif 1, ABSENT, 0 }, { "iCCP", PNG_INFO_iCCP, png_iCCP, # ifdef PNG_READ_iCCP_SUPPORTED 0, # else 1, # endif 1, ABSENT, 0 }, { "iTXt", PNG_INFO_iTXt, png_iTXt, # ifdef PNG_READ_iTXt_SUPPORTED 0, # else 1, # endif 1, ABSENT, 0 }, { "oFFs", PNG_INFO_oFFs, png_oFFs, # ifdef PNG_READ_oFFs_SUPPORTED 0, # else 1, # endif 1, START, 0 }, { "pCAL", PNG_INFO_pCAL, png_pCAL, # ifdef PNG_READ_pCAL_SUPPORTED 0, # else 1, # endif 1, START, 0 }, { "pHYs", PNG_INFO_pHYs, png_pHYs, # ifdef PNG_READ_pHYs_SUPPORTED 0, # else 1, # endif 1, START, 0 }, { "sBIT", PNG_INFO_sBIT, png_sBIT, # ifdef PNG_READ_sBIT_SUPPORTED 0, # else 1, # endif 1, START, 0 }, { "sCAL", PNG_INFO_sCAL, png_sCAL, # ifdef PNG_READ_sCAL_SUPPORTED 0, # else 1, # endif 1, START, 0 }, { "sPLT", PNG_INFO_sPLT, png_sPLT, # ifdef PNG_READ_sPLT_SUPPORTED 0, # else 1, # endif 1, ABSENT, 0 }, { "sRGB", PNG_INFO_sRGB, png_sRGB, # ifdef PNG_READ_sRGB_SUPPORTED 0, # else 1, # endif 1, START, 0 }, { "tEXt", PNG_INFO_tEXt, png_tEXt, # ifdef PNG_READ_tEXt_SUPPORTED 0, # else 1, # endif 1, START, 0 }, { "tIME", PNG_INFO_tIME, png_tIME, # ifdef PNG_READ_tIME_SUPPORTED 0, # else 1, # endif 1, START, 0 }, { "tRNS", PNG_INFO_tRNS, png_tRNS, # ifdef PNG_READ_tRNS_SUPPORTED 0, # else 1, # endif 0, ABSENT, 0 }, { "zTXt", PNG_INFO_zTXt, png_zTXt, # ifdef PNG_READ_zTXt_SUPPORTED 0, # else 1, # endif 1, END, 0 }, /* No libpng handling */ { "sTER", PNG_INFO_sTER, png_sTER, 1, 1, START, 0 }, { "vpAg", PNG_INFO_vpAg, png_vpAg, 1, 0, START, 0 }, }; #define NINFO ((int)((sizeof chunk_info)/(sizeof chunk_info[0]))) static void clear_keep(void) { int i = NINFO; while (--i >= 0) chunk_info[i].keep = 0; } static int find(const char *name) { int i = NINFO; while (--i >= 0) { if (memcmp(chunk_info[i].name, name, 4) == 0) break; } return i; } static int findb(const png_byte *name) { int i = NINFO; while (--i >= 0) { if (memcmp(chunk_info[i].name, name, 4) == 0) break; } return i; } static int find_by_flag(png_uint_32 flag) { int i = NINFO; while (--i >= 0) if (chunk_info[i].flag == flag) return i; fprintf(stderr, "pngunknown: internal error\n"); exit(4); } static int ancillary(const char *name) { return PNG_CHUNK_ANCILLARY(PNG_U32(name[0], name[1], name[2], name[3])); } #ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED static int ancillaryb(const png_byte *name) { return PNG_CHUNK_ANCILLARY(PNG_U32(name[0], name[1], name[2], name[3])); } #endif /* Type of an error_ptr */ typedef struct { jmp_buf error_return; png_structp png_ptr; png_infop info_ptr, end_ptr; png_uint_32 before_IDAT; png_uint_32 after_IDAT; int error_count; int warning_count; int keep; /* the default value */ const char *program; const char *file; const char *test; } display; static const char init[] = "initialization"; static const char cmd[] = "command line"; static void init_display(display *d, const char *program) { memset(d, 0, sizeof *d); d->png_ptr = NULL; d->info_ptr = d->end_ptr = NULL; d->error_count = d->warning_count = 0; d->program = program; d->file = program; d->test = init; } static void clean_display(display *d) { png_destroy_read_struct(&d->png_ptr, &d->info_ptr, &d->end_ptr); /* This must not happen - it might cause an app crash */ if (d->png_ptr != NULL || d->info_ptr != NULL || d->end_ptr != NULL) { fprintf(stderr, "%s(%s): png_destroy_read_struct error\n", d->file, d->test); exit(1); } } PNG_FUNCTION(void, display_exit, (display *d), static PNG_NORETURN) { ++(d->error_count); if (d->png_ptr != NULL) clean_display(d); /* During initialization and if this is a single command line argument set * exit now - there is only one test, otherwise longjmp to do the next test. */ if (d->test == init || d->test == cmd) exit(1); longjmp(d->error_return, 1); } static int display_rc(const display *d, int strict) { return d->error_count + (strict ? d->warning_count : 0); } /* libpng error and warning callbacks */ PNG_FUNCTION(void, (PNGCBAPI error), (png_structp png_ptr, const char *message), static PNG_NORETURN) { display *d = (display*)png_get_error_ptr(png_ptr); fprintf(stderr, "%s(%s): libpng error: %s\n", d->file, d->test, message); display_exit(d); } static void PNGCBAPI warning(png_structp png_ptr, const char *message) { display *d = (display*)png_get_error_ptr(png_ptr); fprintf(stderr, "%s(%s): libpng warning: %s\n", d->file, d->test, message); ++(d->warning_count); } static png_uint_32 get_valid(display *d, png_infop info_ptr) { png_uint_32 flags = png_get_valid(d->png_ptr, info_ptr, (png_uint_32)~0); /* Map the text chunks back into the flags */ { png_textp text; png_uint_32 ntext = png_get_text(d->png_ptr, info_ptr, &text, NULL); while (ntext > 0) switch (text[--ntext].compression) { case -1: flags |= PNG_INFO_tEXt; break; case 0: flags |= PNG_INFO_zTXt; break; case 1: case 2: flags |= PNG_INFO_iTXt; break; default: fprintf(stderr, "%s(%s): unknown text compression %d\n", d->file, d->test, text[ntext].compression); display_exit(d); } } return flags; } #ifdef PNG_READ_USER_CHUNKS_SUPPORTED static int PNGCBAPI read_callback(png_structp pp, png_unknown_chunkp pc) { /* This function mimics the behavior of png_set_keep_unknown_chunks by * returning '0' to keep the chunk and '1' to discard it. */ display *d = voidcast(display*, png_get_user_chunk_ptr(pp)); int chunk = findb(pc->name); int keep, discard; if (chunk < 0) /* not one in our list, so not a known chunk */ keep = d->keep; else { keep = chunk_info[chunk].keep; if (keep == PNG_HANDLE_CHUNK_AS_DEFAULT) { /* See the comments in png.h - use the default for unknown chunks, * do not keep known chunks. */ if (chunk_info[chunk].unknown) keep = d->keep; else keep = PNG_HANDLE_CHUNK_NEVER; } } switch (keep) { default: fprintf(stderr, "%s(%s): %d: unrecognized chunk option\n", d->file, d->test, chunk_info[chunk].keep); display_exit(d); case PNG_HANDLE_CHUNK_AS_DEFAULT: case PNG_HANDLE_CHUNK_NEVER: discard = 1; /*handled; discard*/ break; case PNG_HANDLE_CHUNK_IF_SAFE: case PNG_HANDLE_CHUNK_ALWAYS: discard = 0; /*not handled; keep*/ break; } /* Also store information about this chunk in the display, the relevant flag * is set if the chunk is to be kept ('not handled'.) */ if (chunk >= 0) { if (!discard) /* stupidity to stop a GCC warning */ { png_uint_32 flag = chunk_info[chunk].flag; if (pc->location & PNG_AFTER_IDAT) d->after_IDAT |= flag; else d->before_IDAT |= flag; } } /* However if there is no support to store unknown chunks don't ask libpng to * do it; there will be an png_error. */ # ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED return discard; # else return 1; /*handled; discard*/ # endif } #endif /* READ_USER_CHUNKS_SUPPORTED */ #ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED static png_uint_32 get_unknown(display *d, png_infop info_ptr, int after_IDAT) { /* Create corresponding 'unknown' flags */ png_uint_32 flags = 0; UNUSED(after_IDAT) { png_unknown_chunkp unknown; int num_unknown = png_get_unknown_chunks(d->png_ptr, info_ptr, &unknown); while (--num_unknown >= 0) { int chunk = findb(unknown[num_unknown].name); /* Chunks not known to pngunknown must be validated here; since they * must also be unknown to libpng the 'display->keep' behavior should * have been used. */ if (chunk < 0) switch (d->keep) { default: /* impossible */ case PNG_HANDLE_CHUNK_AS_DEFAULT: case PNG_HANDLE_CHUNK_NEVER: fprintf(stderr, "%s(%s): %s: %s: unknown chunk saved\n", d->file, d->test, d->keep ? "discard" : "default", unknown[num_unknown].name); ++(d->error_count); break; case PNG_HANDLE_CHUNK_IF_SAFE: if (!ancillaryb(unknown[num_unknown].name)) { fprintf(stderr, "%s(%s): if-safe: %s: unknown critical chunk saved\n", d->file, d->test, unknown[num_unknown].name); ++(d->error_count); break; } /* FALLTHROUGH */ /* (safe) */ case PNG_HANDLE_CHUNK_ALWAYS: break; } else flags |= chunk_info[chunk].flag; } } return flags; } #else /* SAVE_UNKNOWN_CHUNKS */ static png_uint_32 get_unknown(display *d, png_infop info_ptr, int after_IDAT) /* Otherwise this will return the cached values set by any user callback */ { UNUSED(info_ptr); if (after_IDAT) return d->after_IDAT; else return d->before_IDAT; } # ifndef PNG_READ_USER_CHUNKS_SUPPORTED /* The #defines above should mean this is never reached, it's just here as * a check to ensure the logic is correct. */ # error No store support and no user chunk support, this will not work # endif /* READ_USER_CHUNKS */ #endif /* SAVE_UNKNOWN_CHUNKS */ static int check(FILE *fp, int argc, const char **argv, png_uint_32p flags/*out*/, display *d, int set_callback) { int i, npasses, ipass; png_uint_32 height; d->keep = PNG_HANDLE_CHUNK_AS_DEFAULT; d->before_IDAT = 0; d->after_IDAT = 0; /* Some of these errors are permanently fatal and cause an exit here, others * are per-test and cause an error return. */ d->png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, d, error, warning); if (d->png_ptr == NULL) { fprintf(stderr, "%s(%s): could not allocate png struct\n", d->file, d->test); /* Terminate here, this error is not test specific. */ exit(1); } d->info_ptr = png_create_info_struct(d->png_ptr); d->end_ptr = png_create_info_struct(d->png_ptr); if (d->info_ptr == NULL || d->end_ptr == NULL) { fprintf(stderr, "%s(%s): could not allocate png info\n", d->file, d->test); clean_display(d); exit(1); } png_init_io(d->png_ptr, fp); # ifdef PNG_READ_USER_CHUNKS_SUPPORTED /* This is only done if requested by the caller; it interferes with the * standard store/save mechanism. */ if (set_callback) png_set_read_user_chunk_fn(d->png_ptr, d, read_callback); # else UNUSED(set_callback) # endif /* Handle each argument in turn; multiple settings are possible for the same * chunk and multiple calls will occur (the last one should override all * preceding ones). */ for (i=0; i= 10700 &&\ !defined(PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED) if (option < PNG_HANDLE_CHUNK_IF_SAFE) # endif /* 1.7+ SAVE_UNKNOWN_CHUNKS */ { png_byte name[5]; memcpy(name, chunk_info[chunk].name, 5); png_set_keep_unknown_chunks(d->png_ptr, option, name, 1); chunk_info[chunk].keep = option; } continue; } break; case 7: /* default */ if (memcmp(argv[i], "default", 7) == 0) { # if PNG_LIBPNG_VER >= 10700 &&\ !defined(PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED) if (option < PNG_HANDLE_CHUNK_IF_SAFE) # endif /* 1.7+ SAVE_UNKNOWN_CHUNKS */ png_set_keep_unknown_chunks(d->png_ptr, option, NULL, 0); d->keep = option; continue; } break; case 3: /* all */ if (memcmp(argv[i], "all", 3) == 0) { # if PNG_LIBPNG_VER >= 10700 &&\ !defined(PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED) if (option < PNG_HANDLE_CHUNK_IF_SAFE) # endif /* 1.7+ SAVE_UNKNOWN_CHUNKS */ png_set_keep_unknown_chunks(d->png_ptr, option, NULL, -1); d->keep = option; for (chunk = 0; chunk < NINFO; ++chunk) if (chunk_info[chunk].all) chunk_info[chunk].keep = option; continue; } break; default: /* some misplaced = */ break; } } fprintf(stderr, "%s(%s): %s: unrecognized chunk argument\n", d->file, d->test, argv[i]); display_exit(d); } png_read_info(d->png_ptr, d->info_ptr); switch (png_get_interlace_type(d->png_ptr, d->info_ptr)) { case PNG_INTERLACE_NONE: npasses = 1; break; case PNG_INTERLACE_ADAM7: npasses = PNG_INTERLACE_ADAM7_PASSES; break; default: /* Hard error because it is not test specific */ fprintf(stderr, "%s(%s): invalid interlace type\n", d->file, d->test); clean_display(d); exit(1); } /* Skip the image data, if IDAT is not being handled then don't do this * because it will cause a CRC error. */ if (chunk_info[0/*IDAT*/].keep == PNG_HANDLE_CHUNK_AS_DEFAULT) { png_start_read_image(d->png_ptr); height = png_get_image_height(d->png_ptr, d->info_ptr); if (npasses > 1) { png_uint_32 width = png_get_image_width(d->png_ptr, d->info_ptr); for (ipass=0; ipass 0) { png_uint_32 y; for (y=0; ypng_ptr, NULL, NULL); } } } /* interlaced */ else /* not interlaced */ { png_uint_32 y; for (y=0; ypng_ptr, NULL, NULL); } } png_read_end(d->png_ptr, d->end_ptr); flags[0] = get_valid(d, d->info_ptr); flags[1] = get_unknown(d, d->info_ptr, 0/*before IDAT*/); /* Only png_read_png sets PNG_INFO_IDAT! */ flags[chunk_info[0/*IDAT*/].keep != PNG_HANDLE_CHUNK_AS_DEFAULT] |= PNG_INFO_IDAT; flags[2] = get_valid(d, d->end_ptr); flags[3] = get_unknown(d, d->end_ptr, 1/*after IDAT*/); clean_display(d); return d->keep; } static void check_error(display *d, png_uint_32 flags, const char *message) { while (flags) { png_uint_32 flag = flags & -(png_int_32)flags; int i = find_by_flag(flag); fprintf(stderr, "%s(%s): chunk %s: %s\n", d->file, d->test, chunk_info[i].name, message); ++(d->error_count); flags &= ~flag; } } static void check_handling(display *d, int def, png_uint_32 chunks, png_uint_32 known, png_uint_32 unknown, const char *position, int set_callback) { while (chunks) { png_uint_32 flag = chunks & -(png_int_32)chunks; int i = find_by_flag(flag); int keep = chunk_info[i].keep; const char *type; const char *errorx = NULL; if (chunk_info[i].unknown) { if (keep == PNG_HANDLE_CHUNK_AS_DEFAULT) { type = "UNKNOWN (default)"; keep = def; } else type = "UNKNOWN (specified)"; if (flag & known) errorx = "chunk processed"; else switch (keep) { case PNG_HANDLE_CHUNK_AS_DEFAULT: if (flag & unknown) errorx = "DEFAULT: unknown chunk saved"; break; case PNG_HANDLE_CHUNK_NEVER: if (flag & unknown) errorx = "DISCARD: unknown chunk saved"; break; case PNG_HANDLE_CHUNK_IF_SAFE: if (ancillary(chunk_info[i].name)) { if (!(flag & unknown)) errorx = "IF-SAFE: unknown ancillary chunk lost"; } else if (flag & unknown) errorx = "IF-SAFE: unknown critical chunk saved"; break; case PNG_HANDLE_CHUNK_ALWAYS: if (!(flag & unknown)) errorx = "SAVE: unknown chunk lost"; break; default: errorx = "internal error: bad keep"; break; } } /* unknown chunk */ else /* known chunk */ { type = "KNOWN"; if (flag & known) { /* chunk was processed, it won't have been saved because that is * caught below when checking for inconsistent processing. */ if (keep != PNG_HANDLE_CHUNK_AS_DEFAULT) errorx = "!DEFAULT: known chunk processed"; } else /* not processed */ switch (keep) { case PNG_HANDLE_CHUNK_AS_DEFAULT: errorx = "DEFAULT: known chunk not processed"; break; case PNG_HANDLE_CHUNK_NEVER: if (flag & unknown) errorx = "DISCARD: known chunk saved"; break; case PNG_HANDLE_CHUNK_IF_SAFE: if (ancillary(chunk_info[i].name)) { if (!(flag & unknown)) errorx = "IF-SAFE: known ancillary chunk lost"; } else if (flag & unknown) errorx = "IF-SAFE: known critical chunk saved"; break; case PNG_HANDLE_CHUNK_ALWAYS: if (!(flag & unknown)) errorx = "SAVE: known chunk lost"; break; default: errorx = "internal error: bad keep (2)"; break; } } if (errorx != NULL) { ++(d->error_count); fprintf(stderr, "%s(%s%s): %s %s %s: %s\n", d->file, d->test, set_callback ? ",callback" : "", type, chunk_info[i].name, position, errorx); } chunks &= ~flag; } } static void perform_one_test(FILE *fp, int argc, const char **argv, png_uint_32 *default_flags, display *d, int set_callback) { int def; png_uint_32 flags[2][4]; rewind(fp); clear_keep(); memcpy(flags[0], default_flags, sizeof flags[0]); def = check(fp, argc, argv, flags[1], d, set_callback); /* If IDAT is being handled as unknown the image read is skipped and all the * IDATs after the first end up in the end info struct, so in this case add * IDAT to the list of unknowns. (Do this after 'check' above sets the * chunk_info 'keep' fields.) * * Note that the flag setting has to be in the 'known' field to avoid * triggering the consistency check below and the flag must only be set if * there are multiple IDATs, so if the check above did find an unknown IDAT * after IDAT. */ if (chunk_info[0/*IDAT*/].keep != PNG_HANDLE_CHUNK_AS_DEFAULT && (flags[1][3] & PNG_INFO_IDAT) != 0) flags[0][2] |= PNG_INFO_IDAT; /* Chunks should either be known or unknown, never both and this should apply * whether the chunk is before or after the IDAT (actually, the app can * probably change this by swapping the handling after the image, but this * test does not do that.) */ check_error(d, (flags[0][0]|flags[0][2]) & (flags[0][1]|flags[0][3]), "chunk handled inconsistently in count tests"); check_error(d, (flags[1][0]|flags[1][2]) & (flags[1][1]|flags[1][3]), "chunk handled inconsistently in option tests"); /* Now find out what happened to each chunk before and after the IDAT and * determine if the behavior was correct. First some basic sanity checks, * any known chunk should be known in the original count, any unknown chunk * should be either known or unknown in the original. */ { png_uint_32 test; test = flags[1][0] & ~flags[0][0]; check_error(d, test, "new known chunk before IDAT"); test = flags[1][1] & ~(flags[0][0] | flags[0][1]); check_error(d, test, "new unknown chunk before IDAT"); test = flags[1][2] & ~flags[0][2]; check_error(d, test, "new known chunk after IDAT"); test = flags[1][3] & ~(flags[0][2] | flags[0][3]); check_error(d, test, "new unknown chunk after IDAT"); } /* Now each chunk in the original list should have been handled according to * the options set for that chunk, regardless of whether libpng knows about * it or not. */ check_handling(d, def, flags[0][0] | flags[0][1], flags[1][0], flags[1][1], "before IDAT", set_callback); check_handling(d, def, flags[0][2] | flags[0][3], flags[1][2], flags[1][3], "after IDAT", set_callback); } static void perform_one_test_safe(FILE *fp, int argc, const char **argv, png_uint_32 *default_flags, display *d, const char *test) { if (setjmp(d->error_return) == 0) { d->test = test; /* allow use of d->error_return */ # ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED perform_one_test(fp, argc, argv, default_flags, d, 0); # endif # ifdef PNG_READ_USER_CHUNKS_SUPPORTED perform_one_test(fp, argc, argv, default_flags, d, 1); # endif d->test = init; /* prevent use of d->error_return */ } } static const char *standard_tests[] = { "discard", "default=discard", NULL, "save", "default=save", NULL, "if-safe", "default=if-safe", NULL, "vpAg", "vpAg=if-safe", NULL, "sTER", "sTER=if-safe", NULL, "IDAT", "default=discard", "IDAT=save", NULL, "sAPI", "bKGD=save", "cHRM=save", "gAMA=save", "all=discard", "iCCP=save", "sBIT=save", "sRGB=save", "eXIf=save", NULL, NULL /*end*/ }; static PNG_NORETURN void usage(const char *program, const char *reason) { fprintf(stderr, "pngunknown: %s: usage:\n %s [--strict] " "--default|{(CHNK|default|all)=(default|discard|if-safe|save)} " "testfile.png\n", reason, program); exit(99); } int main(int argc, const char **argv) { FILE *fp; png_uint_32 default_flags[4]; /*valid,unknown{before,after}*/ int strict = 0, default_tests = 0; const char *count_argv = "default=save"; const char *touch_file = NULL; display d; init_display(&d, argv[0]); while (++argv, --argc > 0) { if (strcmp(*argv, "--strict") == 0) strict = 1; else if (strcmp(*argv, "--default") == 0) default_tests = 1; else if (strcmp(*argv, "--touch") == 0) { if (argc > 1) touch_file = *++argv, --argc; else usage(d.program, "--touch: missing file name"); } else break; } /* A file name is required, but there should be no other arguments if * --default was specified. */ if (argc <= 0) usage(d.program, "missing test file"); /* GCC BUG: if (default_tests && argc != 1) triggers some weird GCC argc * optimization which causes warnings with -Wstrict-overflow! */ else if (default_tests) if (argc != 1) usage(d.program, "extra arguments"); /* The name of the test file is the last argument; remove it. */ d.file = argv[--argc]; fp = fopen(d.file, "rb"); if (fp == NULL) { perror(d.file); exit(99); } /* First find all the chunks, known and unknown, in the test file, a failure * here aborts the whole test. * * If 'save' is supported then the normal saving method should happen, * otherwise if 'read' is supported then the read callback will do the * same thing. If both are supported the 'read' callback won't be * instantiated by default. If 'save' is *not* supported then a user * callback is required even though we can call png_get_unknown_chunks. */ if (check(fp, 1, &count_argv, default_flags, &d, # ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED 0 # else 1 # endif ) != PNG_HANDLE_CHUNK_ALWAYS) { fprintf(stderr, "%s: %s: internal error\n", d.program, d.file); exit(99); } /* Now find what the various supplied options cause to change: */ if (!default_tests) { d.test = cmd; /* acts as a flag to say exit, do not longjmp */ # ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED perform_one_test(fp, argc, argv, default_flags, &d, 0); # endif # ifdef PNG_READ_USER_CHUNKS_SUPPORTED perform_one_test(fp, argc, argv, default_flags, &d, 1); # endif d.test = init; } else { const char **test = standard_tests; /* Set the exit_test pointer here so we can continue after a libpng error. * NOTE: this leaks memory because the png_struct data from the failing * test is never freed. */ while (*test) { const char *this_test = *test++; const char **next = test; int count = display_rc(&d, strict), new_count; const char *result; int arg_count = 0; while (*next != NULL) { ++next; ++arg_count; } perform_one_test_safe(fp, arg_count, test, default_flags, &d, this_test); new_count = display_rc(&d, strict); if (new_count == count) result = "PASS"; else result = "FAIL"; printf("%s: %s %s\n", result, d.program, this_test); test = next+1; } } fclose(fp); if (display_rc(&d, strict) == 0) { /* Success, touch the success file if appropriate */ if (touch_file != NULL) { FILE *fsuccess = fopen(touch_file, "wt"); if (fsuccess != NULL) { int err = 0; fprintf(fsuccess, "PNG unknown tests succeeded\n"); fflush(fsuccess); err = ferror(fsuccess); if (fclose(fsuccess) || err) { fprintf(stderr, "%s: write failed\n", touch_file); exit(99); } } else { fprintf(stderr, "%s: open failed\n", touch_file); exit(99); } } return 0; } return 1; } #else /* !(READ_USER_CHUNKS || SAVE_UNKNOWN_CHUNKS) */ int main(void) { fprintf(stderr, " test ignored: no support to find out about unknown chunks\n"); /* So the test is skipped: */ return SKIP; } #endif /* READ_USER_CHUNKS || SAVE_UNKNOWN_CHUNKS */ #else /* !(SET_UNKNOWN_CHUNKS && READ) */ int main(void) { fprintf(stderr, " test ignored: no support to modify unknown chunk handling\n"); /* So the test is skipped: */ return SKIP; } #endif /* SET_UNKNOWN_CHUNKS && READ*/ libpng-1.6.43/contrib/libtests/pngvalid.c000066400000000000000000013633761456606525400203610ustar00rootroot00000000000000 /* pngvalid.c - validate libpng by constructing then reading png files. * * Copyright (c) 2021 Cosmin Truta * Copyright (c) 2014-2017 John Cunningham Bowler * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer * and license in png.h * * NOTES: * This is a C program that is intended to be linked against libpng. It * generates bitmaps internally, stores them as PNG files (using the * sequential write code) then reads them back (using the sequential * read code) and validates that the result has the correct data. * * The program can be modified and extended to test the correctness of * transformations performed by libpng. */ #define _POSIX_SOURCE 1 #define _ISOC99_SOURCE 1 /* For floating point */ #define _GNU_SOURCE 1 /* For the floating point exception extension */ #define _BSD_SOURCE 1 /* For the floating point exception extension */ #define _DEFAULT_SOURCE 1 /* For the floating point exception extension */ #include #include #if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H) # include #endif #ifdef HAVE_FEENABLEEXCEPT /* from config.h, if included */ # include #endif #ifndef FE_DIVBYZERO # define FE_DIVBYZERO 0 #endif #ifndef FE_INVALID # define FE_INVALID 0 #endif #ifndef FE_OVERFLOW # define FE_OVERFLOW 0 #endif /* Define the following to use this test against your installed libpng, rather * than the one being built here: */ #ifdef PNG_FREESTANDING_TESTS # include #else # include "../../png.h" #endif #ifdef PNG_ZLIB_HEADER # include PNG_ZLIB_HEADER #else # include /* For crc32 */ #endif /* 1.6.1 added support for the configure test harness, which uses 77 to indicate * a skipped test, in earlier versions we need to succeed on a skipped test, so: */ #if PNG_LIBPNG_VER >= 10601 && defined(HAVE_CONFIG_H) # define SKIP 77 #else # define SKIP 0 #endif /* pngvalid requires write support and one of the fixed or floating point APIs. * progressive read is also required currently as the progressive read pointer * is used to record the 'display' structure. */ #if defined PNG_WRITE_SUPPORTED &&\ (defined PNG_PROGRESSIVE_READ_SUPPORTED) &&\ (defined PNG_FIXED_POINT_SUPPORTED || defined PNG_FLOATING_POINT_SUPPORTED) #if PNG_LIBPNG_VER < 10500 /* This deliberately lacks the const. */ typedef png_byte *png_const_bytep; /* This is copied from 1.5.1 png.h: */ #define PNG_INTERLACE_ADAM7_PASSES 7 #define PNG_PASS_START_ROW(pass) (((1U&~(pass))<<(3-((pass)>>1)))&7) #define PNG_PASS_START_COL(pass) (((1U& (pass))<<(3-(((pass)+1)>>1)))&7) #define PNG_PASS_ROW_SHIFT(pass) ((pass)>2?(8-(pass))>>1:3) #define PNG_PASS_COL_SHIFT(pass) ((pass)>1?(7-(pass))>>1:3) #define PNG_PASS_ROWS(height, pass) (((height)+(((1<>PNG_PASS_ROW_SHIFT(pass)) #define PNG_PASS_COLS(width, pass) (((width)+(((1<>PNG_PASS_COL_SHIFT(pass)) #define PNG_ROW_FROM_PASS_ROW(yIn, pass) \ (((yIn)<>(((7-(off))-(pass))<<2)) & 0xFU) | \ ((0x01145AF0U>>(((7-(off))-(pass))<<2)) & 0xF0U)) #define PNG_ROW_IN_INTERLACE_PASS(y, pass) \ ((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1) #define PNG_COL_IN_INTERLACE_PASS(x, pass) \ ((PNG_PASS_MASK(pass,1) >> ((x)&7)) & 1) /* These are needed too for the default build: */ #define PNG_WRITE_16BIT_SUPPORTED #define PNG_READ_16BIT_SUPPORTED /* This comes from pnglibconf.h after 1.5: */ #define PNG_FP_1 100000 #define PNG_GAMMA_THRESHOLD_FIXED\ ((png_fixed_point)(PNG_GAMMA_THRESHOLD * PNG_FP_1)) #endif #if PNG_LIBPNG_VER < 10600 /* 1.6.0 constifies many APIs, the following exists to allow pngvalid to be * compiled against earlier versions. */ # define png_const_structp png_structp #endif #ifndef RELEASE_BUILD /* RELEASE_BUILD is true for releases and release candidates: */ # define RELEASE_BUILD (PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC) #endif #if RELEASE_BUILD # define debugonly(something) #else /* !RELEASE_BUILD */ # define debugonly(something) something #endif /* !RELEASE_BUILD */ #include /* For floating point constants */ #include /* For malloc */ #include /* For memcpy, memset */ #include /* For floor */ /* Convenience macros. */ #define CHUNK(a,b,c,d) (((a)<<24)+((b)<<16)+((c)<<8)+(d)) #define CHUNK_IHDR CHUNK(73,72,68,82) #define CHUNK_PLTE CHUNK(80,76,84,69) #define CHUNK_IDAT CHUNK(73,68,65,84) #define CHUNK_IEND CHUNK(73,69,78,68) #define CHUNK_cHRM CHUNK(99,72,82,77) #define CHUNK_gAMA CHUNK(103,65,77,65) #define CHUNK_sBIT CHUNK(115,66,73,84) #define CHUNK_sRGB CHUNK(115,82,71,66) /* Unused formal parameter errors are removed using the following macro which is * expected to have no bad effects on performance. */ #ifndef UNUSED # if defined(__GNUC__) || defined(_MSC_VER) # define UNUSED(param) (void)param; # else # define UNUSED(param) # endif #endif /***************************** EXCEPTION HANDLING *****************************/ #ifdef PNG_FREESTANDING_TESTS # include #else # include "../visupng/cexcept.h" #endif #ifdef __cplusplus # define this not_the_cpp_this # define new not_the_cpp_new # define voidcast(type, value) static_cast(value) #else # define voidcast(type, value) (value) #endif /* __cplusplus */ struct png_store; define_exception_type(struct png_store*); /* The following are macros to reduce typing everywhere where the well known * name 'the_exception_context' must be defined. */ #define anon_context(ps) struct exception_context *the_exception_context = \ &(ps)->exception_context #define context(ps,fault) anon_context(ps); png_store *fault /* This macro returns the number of elements in an array as an (unsigned int), * it is necessary to avoid the inability of certain versions of GCC to use * the value of a compile-time constant when performing range checks. It must * be passed an array name. */ #define ARRAY_SIZE(a) ((unsigned int)((sizeof (a))/(sizeof (a)[0]))) /* GCC BUG 66447 (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66447) requires * some broken GCC versions to be fixed up to avoid invalid whining about auto * variables that are *not* changed within the scope of a setjmp being changed. * * Feel free to extend the list of broken versions. */ #define is_gnu(major,minor)\ (defined __GNUC__) && __GNUC__ == (major) && __GNUC_MINOR__ == (minor) #define is_gnu_patch(major,minor,patch)\ is_gnu(major,minor) && __GNUC_PATCHLEVEL__ == 0 /* For the moment just do it always; all versions of GCC seem to be broken: */ #ifdef __GNUC__ const void * volatile make_volatile_for_gnu; # define gnu_volatile(x) make_volatile_for_gnu = &x; #else /* !GNUC broken versions */ # define gnu_volatile(x) #endif /* !GNUC broken versions */ /******************************* UTILITIES ************************************/ /* Error handling is particularly problematic in production code - error * handlers often themselves have bugs which lead to programs that detect * minor errors crashing. The following functions deal with one very * common class of errors in error handlers - attempting to format error or * warning messages into buffers that are too small. */ static size_t safecat(char *buffer, size_t bufsize, size_t pos, const char *cat) { while (pos < bufsize && cat != NULL && *cat != 0) buffer[pos++] = *cat++; if (pos >= bufsize) pos = bufsize-1; buffer[pos] = 0; return pos; } static size_t safecatn(char *buffer, size_t bufsize, size_t pos, int n) { char number[64]; sprintf(number, "%d", n); return safecat(buffer, bufsize, pos, number); } #ifdef PNG_READ_TRANSFORMS_SUPPORTED static size_t safecatd(char *buffer, size_t bufsize, size_t pos, double d, int precision) { char number[64]; sprintf(number, "%.*f", precision, d); return safecat(buffer, bufsize, pos, number); } #endif static const char invalid[] = "invalid"; static const char sep[] = ": "; static const char *colour_types[8] = { "grayscale", invalid, "truecolour", "indexed-colour", "grayscale with alpha", invalid, "truecolour with alpha", invalid }; #ifdef PNG_READ_TRANSFORMS_SUPPORTED /* Convert a double precision value to fixed point. */ static png_fixed_point fix(double d) { d = floor(d * PNG_FP_1 + .5); return (png_fixed_point)d; } #endif /* PNG_READ_SUPPORTED */ /* Generate random bytes. This uses a boring repeatable algorithm and it * is implemented here so that it gives the same set of numbers on every * architecture. It's a linear congruential generator (Knuth or Sedgewick * "Algorithms") but it comes from the 'feedback taps' table in Horowitz and * Hill, "The Art of Electronics" (Pseudo-Random Bit Sequences and Noise * Generation.) */ static void make_random_bytes(png_uint_32* seed, void* pv, size_t size) { png_uint_32 u0 = seed[0], u1 = seed[1]; png_bytep bytes = voidcast(png_bytep, pv); /* There are thirty three bits, the next bit in the sequence is bit-33 XOR * bit-20. The top 1 bit is in u1, the bottom 32 are in u0. */ size_t i; for (i=0; i> (20-8)) ^ ((u1 << 7) | (u0 >> (32-7)))) & 0xff; u1 <<= 8; u1 |= u0 >> 24; u0 <<= 8; u0 |= u; *bytes++ = (png_byte)u; } seed[0] = u0; seed[1] = u1; } static void make_four_random_bytes(png_uint_32* seed, png_bytep bytes) { make_random_bytes(seed, bytes, 4); } #if defined PNG_READ_SUPPORTED || defined PNG_WRITE_tRNS_SUPPORTED ||\ defined PNG_WRITE_FILTER_SUPPORTED static void randomize(void *pv, size_t size) { static png_uint_32 random_seed[2] = {0x56789abc, 0xd}; make_random_bytes(random_seed, pv, size); } #define R8(this) randomize(&(this), sizeof (this)) #ifdef PNG_READ_SUPPORTED static png_byte random_byte(void) { unsigned char b1[1]; randomize(b1, sizeof b1); return b1[0]; } #endif /* READ */ static png_uint_16 random_u16(void) { unsigned char b2[2]; randomize(b2, sizeof b2); return png_get_uint_16(b2); } #if defined PNG_READ_RGB_TO_GRAY_SUPPORTED ||\ defined PNG_READ_FILLER_SUPPORTED static png_uint_32 random_u32(void) { unsigned char b4[4]; randomize(b4, sizeof b4); return png_get_uint_32(b4); } #endif /* READ_FILLER || READ_RGB_TO_GRAY */ #endif /* READ || WRITE_tRNS || WRITE_FILTER */ #if defined PNG_READ_TRANSFORMS_SUPPORTED ||\ defined PNG_WRITE_FILTER_SUPPORTED static unsigned int random_mod(unsigned int max) { return random_u16() % max; /* 0 .. max-1 */ } #endif /* READ_TRANSFORMS || WRITE_FILTER */ #if (defined PNG_READ_RGB_TO_GRAY_SUPPORTED) ||\ (defined PNG_READ_FILLER_SUPPORTED) static int random_choice(void) { return random_byte() & 1; } #endif /* READ_RGB_TO_GRAY || READ_FILLER */ /* A numeric ID based on PNG file characteristics. The 'do_interlace' field * simply records whether pngvalid did the interlace itself or whether it * was done by libpng. Width and height must be less than 256. 'palette' is an * index of the palette to use for formats with a palette otherwise a boolean * indicating if a tRNS chunk was generated. */ #define FILEID(col, depth, palette, interlace, width, height, do_interlace) \ ((png_uint_32)((col) + ((depth)<<3) + ((palette)<<8) + ((interlace)<<13) + \ (((do_interlace)!=0)<<15) + ((width)<<16) + ((height)<<24))) #define COL_FROM_ID(id) ((png_byte)((id)& 0x7U)) #define DEPTH_FROM_ID(id) ((png_byte)(((id) >> 3) & 0x1fU)) #define PALETTE_FROM_ID(id) (((id) >> 8) & 0x1f) #define INTERLACE_FROM_ID(id) ((png_byte)(((id) >> 13) & 0x3)) #define DO_INTERLACE_FROM_ID(id) ((int)(((id)>>15) & 1)) #define WIDTH_FROM_ID(id) (((id)>>16) & 0xff) #define HEIGHT_FROM_ID(id) (((id)>>24) & 0xff) /* Utility to construct a standard name for a standard image. */ static size_t standard_name(char *buffer, size_t bufsize, size_t pos, png_byte colour_type, int bit_depth, unsigned int npalette, int interlace_type, png_uint_32 w, png_uint_32 h, int do_interlace) { pos = safecat(buffer, bufsize, pos, colour_types[colour_type]); if (colour_type == 3) /* must have a palette */ { pos = safecat(buffer, bufsize, pos, "["); pos = safecatn(buffer, bufsize, pos, npalette); pos = safecat(buffer, bufsize, pos, "]"); } else if (npalette != 0) pos = safecat(buffer, bufsize, pos, "+tRNS"); pos = safecat(buffer, bufsize, pos, " "); pos = safecatn(buffer, bufsize, pos, bit_depth); pos = safecat(buffer, bufsize, pos, " bit"); if (interlace_type != PNG_INTERLACE_NONE) { pos = safecat(buffer, bufsize, pos, " interlaced"); if (do_interlace) pos = safecat(buffer, bufsize, pos, "(pngvalid)"); else pos = safecat(buffer, bufsize, pos, "(libpng)"); } if (w > 0 || h > 0) { pos = safecat(buffer, bufsize, pos, " "); pos = safecatn(buffer, bufsize, pos, w); pos = safecat(buffer, bufsize, pos, "x"); pos = safecatn(buffer, bufsize, pos, h); } return pos; } static size_t standard_name_from_id(char *buffer, size_t bufsize, size_t pos, png_uint_32 id) { return standard_name(buffer, bufsize, pos, COL_FROM_ID(id), DEPTH_FROM_ID(id), PALETTE_FROM_ID(id), INTERLACE_FROM_ID(id), WIDTH_FROM_ID(id), HEIGHT_FROM_ID(id), DO_INTERLACE_FROM_ID(id)); } /* Convenience API and defines to list valid formats. Note that 16 bit read and * write support is required to do 16 bit read tests (we must be able to make a * 16 bit image to test!) */ #ifdef PNG_WRITE_16BIT_SUPPORTED # define WRITE_BDHI 4 # ifdef PNG_READ_16BIT_SUPPORTED # define READ_BDHI 4 # define DO_16BIT # endif #else # define WRITE_BDHI 3 #endif #ifndef DO_16BIT # define READ_BDHI 3 #endif /* The following defines the number of different palettes to generate for * each log bit depth of a colour type 3 standard image. */ #define PALETTE_COUNT(bit_depth) ((bit_depth) > 4 ? 1U : 16U) static int next_format(png_bytep colour_type, png_bytep bit_depth, unsigned int* palette_number, int low_depth_gray, int tRNS) { if (*bit_depth == 0) { *colour_type = 0; if (low_depth_gray) *bit_depth = 1; else *bit_depth = 8; *palette_number = 0; return 1; } if (*colour_type < 4/*no alpha channel*/) { /* Add multiple palettes for colour type 3, one image with tRNS * and one without for other non-alpha formats: */ unsigned int pn = ++*palette_number; png_byte ct = *colour_type; if (((ct == 0/*GRAY*/ || ct/*RGB*/ == 2) && tRNS && pn < 2) || (ct == 3/*PALETTE*/ && pn < PALETTE_COUNT(*bit_depth))) return 1; /* No: next bit depth */ *palette_number = 0; } *bit_depth = (png_byte)(*bit_depth << 1); /* Palette images are restricted to 8 bit depth */ if (*bit_depth <= 8 #ifdef DO_16BIT || (*colour_type != 3 && *bit_depth <= 16) #endif ) return 1; /* Move to the next color type, or return 0 at the end. */ switch (*colour_type) { case 0: *colour_type = 2; *bit_depth = 8; return 1; case 2: *colour_type = 3; *bit_depth = 1; return 1; case 3: *colour_type = 4; *bit_depth = 8; return 1; case 4: *colour_type = 6; *bit_depth = 8; return 1; default: return 0; } } #ifdef PNG_READ_TRANSFORMS_SUPPORTED static unsigned int sample(png_const_bytep row, png_byte colour_type, png_byte bit_depth, png_uint_32 x, unsigned int sample_index, int swap16, int littleendian) { png_uint_32 bit_index, result; /* Find a sample index for the desired sample: */ x *= bit_depth; bit_index = x; if ((colour_type & 1) == 0) /* !palette */ { if (colour_type & 2) bit_index *= 3; if (colour_type & 4) bit_index += x; /* Alpha channel */ /* Multiple channels; select one: */ if (colour_type & (2+4)) bit_index += sample_index * bit_depth; } /* Return the sample from the row as an integer. */ row += bit_index >> 3; result = *row; if (bit_depth == 8) return result; else if (bit_depth > 8) { if (swap16) return (*++row << 8) + result; else return (result << 8) + *++row; } /* Less than 8 bits per sample. By default PNG has the big end of * the egg on the left of the screen, but if littleendian is set * then the big end is on the right. */ bit_index &= 7; if (!littleendian) bit_index = 8-bit_index-bit_depth; return (result >> bit_index) & ((1U<> 3] & ~destMask; unsigned int sourceByte = fromBuffer[fromIndex >> 3]; /* Don't rely on << or >> supporting '0' here, just in case: */ fromIndex &= 7; if (littleendian) { if (fromIndex > 0) sourceByte >>= fromIndex; if ((toIndex & 7) > 0) sourceByte <<= toIndex & 7; } else { if (fromIndex > 0) sourceByte <<= fromIndex; if ((toIndex & 7) > 0) sourceByte >>= toIndex & 7; } toBuffer[toIndex >> 3] = (png_byte)(destByte | (sourceByte & destMask)); } else /* One or more bytes */ memmove(toBuffer+(toIndex>>3), fromBuffer+(fromIndex>>3), pixelSize>>3); } #ifdef PNG_READ_SUPPORTED /* Copy a complete row of pixels, taking into account potential partial * bytes at the end. */ static void row_copy(png_bytep toBuffer, png_const_bytep fromBuffer, unsigned int bitWidth, int littleendian) { memcpy(toBuffer, fromBuffer, bitWidth >> 3); if ((bitWidth & 7) != 0) { unsigned int mask; toBuffer += bitWidth >> 3; fromBuffer += bitWidth >> 3; if (littleendian) mask = 0xff << (bitWidth & 7); else mask = 0xff >> (bitWidth & 7); *toBuffer = (png_byte)((*toBuffer & mask) | (*fromBuffer & ~mask)); } } /* Compare pixels - they are assumed to start at the first byte in the * given buffers. */ static int pixel_cmp(png_const_bytep pa, png_const_bytep pb, png_uint_32 bit_width) { #if PNG_LIBPNG_VER < 10506 if (memcmp(pa, pb, bit_width>>3) == 0) { png_uint_32 p; if ((bit_width & 7) == 0) return 0; /* Ok, any differences? */ p = pa[bit_width >> 3]; p ^= pb[bit_width >> 3]; if (p == 0) return 0; /* There are, but they may not be significant, remove the bits * after the end (the low order bits in PNG.) */ bit_width &= 7; p >>= 8-bit_width; if (p == 0) return 0; } #else /* From libpng-1.5.6 the overwrite should be fixed, so compare the trailing * bits too: */ if (memcmp(pa, pb, (bit_width+7)>>3) == 0) return 0; #endif /* Return the index of the changed byte. */ { png_uint_32 where = 0; while (pa[where] == pb[where]) ++where; return 1+where; } } #endif /* PNG_READ_SUPPORTED */ /*************************** BASIC PNG FILE WRITING ***************************/ /* A png_store takes data from the sequential writer or provides data * to the sequential reader. It can also store the result of a PNG * write for later retrieval. */ #define STORE_BUFFER_SIZE 500 /* arbitrary */ typedef struct png_store_buffer { struct png_store_buffer* prev; /* NOTE: stored in reverse order */ png_byte buffer[STORE_BUFFER_SIZE]; } png_store_buffer; #define FILE_NAME_SIZE 64 typedef struct store_palette_entry /* record of a single palette entry */ { png_byte red; png_byte green; png_byte blue; png_byte alpha; } store_palette_entry, store_palette[256]; typedef struct png_store_file { struct png_store_file* next; /* as many as you like... */ char name[FILE_NAME_SIZE]; unsigned int IDAT_bits; /* Number of bits in IDAT size */ png_uint_32 IDAT_size; /* Total size of IDAT data */ png_uint_32 id; /* must be correct (see FILEID) */ size_t datacount; /* In this (the last) buffer */ png_store_buffer data; /* Last buffer in file */ int npalette; /* Number of entries in palette */ store_palette_entry* palette; /* May be NULL */ } png_store_file; /* The following is a pool of memory allocated by a single libpng read or write * operation. */ typedef struct store_pool { struct png_store *store; /* Back pointer */ struct store_memory *list; /* List of allocated memory */ png_byte mark[4]; /* Before and after data */ /* Statistics for this run. */ png_alloc_size_t max; /* Maximum single allocation */ png_alloc_size_t current; /* Current allocation */ png_alloc_size_t limit; /* Highest current allocation */ png_alloc_size_t total; /* Total allocation */ /* Overall statistics (retained across successive runs). */ png_alloc_size_t max_max; png_alloc_size_t max_limit; png_alloc_size_t max_total; } store_pool; typedef struct png_store { /* For cexcept.h exception handling - simply store one of these; * the context is a self pointer but it may point to a different * png_store (in fact it never does in this program.) */ struct exception_context exception_context; unsigned int verbose :1; unsigned int treat_warnings_as_errors :1; unsigned int expect_error :1; unsigned int expect_warning :1; unsigned int saw_warning :1; unsigned int speed :1; unsigned int progressive :1; /* use progressive read */ unsigned int validated :1; /* used as a temporary flag */ int nerrors; int nwarnings; int noptions; /* number of options below: */ struct { unsigned char option; /* option number, 0..30 */ unsigned char setting; /* setting (unset,invalid,on,off) */ } options[16]; char test[128]; /* Name of test */ char error[256]; /* Share fields */ png_uint_32 chunklen; /* Length of chunk+overhead (chunkpos >= 8) */ png_uint_32 chunktype;/* Type of chunk (valid if chunkpos >= 4) */ png_uint_32 chunkpos; /* Position in chunk */ png_uint_32 IDAT_size;/* Accumulated IDAT size in .new */ unsigned int IDAT_bits;/* Cache of the file store value */ /* Read fields */ png_structp pread; /* Used to read a saved file */ png_infop piread; png_store_file* current; /* Set when reading */ png_store_buffer* next; /* Set when reading */ size_t readpos; /* Position in *next */ png_byte* image; /* Buffer for reading interlaced images */ size_t cb_image; /* Size of this buffer */ size_t cb_row; /* Row size of the image(s) */ uLong IDAT_crc; png_uint_32 IDAT_len; /* Used when re-chunking IDAT chunks */ png_uint_32 IDAT_pos; /* Used when re-chunking IDAT chunks */ png_uint_32 image_h; /* Number of rows in a single image */ store_pool read_memory_pool; /* Write fields */ png_store_file* saved; png_structp pwrite; /* Used when writing a new file */ png_infop piwrite; size_t writepos; /* Position in .new */ char wname[FILE_NAME_SIZE]; png_store_buffer new; /* The end of the new PNG file being written. */ store_pool write_memory_pool; store_palette_entry* palette; int npalette; } png_store; /* Initialization and cleanup */ static void store_pool_mark(png_bytep mark) { static png_uint_32 store_seed[2] = { 0x12345678, 1}; make_four_random_bytes(store_seed, mark); } #ifdef PNG_READ_TRANSFORMS_SUPPORTED /* Use this for random 32 bit values; this function makes sure the result is * non-zero. */ static png_uint_32 random_32(void) { for (;;) { png_byte mark[4]; png_uint_32 result; store_pool_mark(mark); result = png_get_uint_32(mark); if (result != 0) return result; } } #endif /* PNG_READ_SUPPORTED */ static void store_pool_init(png_store *ps, store_pool *pool) { memset(pool, 0, sizeof *pool); pool->store = ps; pool->list = NULL; pool->max = pool->current = pool->limit = pool->total = 0; pool->max_max = pool->max_limit = pool->max_total = 0; store_pool_mark(pool->mark); } static void store_init(png_store* ps) { memset(ps, 0, sizeof *ps); init_exception_context(&ps->exception_context); store_pool_init(ps, &ps->read_memory_pool); store_pool_init(ps, &ps->write_memory_pool); ps->verbose = 0; ps->treat_warnings_as_errors = 0; ps->expect_error = 0; ps->expect_warning = 0; ps->saw_warning = 0; ps->speed = 0; ps->progressive = 0; ps->validated = 0; ps->nerrors = ps->nwarnings = 0; ps->pread = NULL; ps->piread = NULL; ps->saved = ps->current = NULL; ps->next = NULL; ps->readpos = 0; ps->image = NULL; ps->cb_image = 0; ps->cb_row = 0; ps->image_h = 0; ps->pwrite = NULL; ps->piwrite = NULL; ps->writepos = 0; ps->chunkpos = 8; ps->chunktype = 0; ps->chunklen = 16; ps->IDAT_size = 0; ps->IDAT_bits = 0; ps->new.prev = NULL; ps->palette = NULL; ps->npalette = 0; ps->noptions = 0; } static void store_freebuffer(png_store_buffer* psb) { if (psb->prev) { store_freebuffer(psb->prev); free(psb->prev); psb->prev = NULL; } } static void store_freenew(png_store *ps) { store_freebuffer(&ps->new); ps->writepos = 0; ps->chunkpos = 8; ps->chunktype = 0; ps->chunklen = 16; ps->IDAT_size = 0; ps->IDAT_bits = 0; if (ps->palette != NULL) { free(ps->palette); ps->palette = NULL; ps->npalette = 0; } } static void store_storenew(png_store *ps) { png_store_buffer *pb; pb = voidcast(png_store_buffer*, malloc(sizeof *pb)); if (pb == NULL) png_error(ps->pwrite, "store new: OOM"); *pb = ps->new; ps->new.prev = pb; ps->writepos = 0; } static void store_freefile(png_store_file **ppf) { if (*ppf != NULL) { store_freefile(&(*ppf)->next); store_freebuffer(&(*ppf)->data); (*ppf)->datacount = 0; if ((*ppf)->palette != NULL) { free((*ppf)->palette); (*ppf)->palette = NULL; (*ppf)->npalette = 0; } free(*ppf); *ppf = NULL; } } static unsigned int bits_of(png_uint_32 num) { /* Return the number of bits in 'num' */ unsigned int b = 0; if (num & 0xffff0000U) b += 16U, num >>= 16; if (num & 0xff00U) b += 8U, num >>= 8; if (num & 0xf0U) b += 4U, num >>= 4; if (num & 0xcU) b += 2U, num >>= 2; if (num & 0x2U) ++b, num >>= 1; if (num) ++b; return b; /* 0..32 */ } /* Main interface to file storage, after writing a new PNG file (see the API * below) call store_storefile to store the result with the given name and id. */ static void store_storefile(png_store *ps, png_uint_32 id) { png_store_file *pf; if (ps->chunkpos != 0U || ps->chunktype != 0U || ps->chunklen != 0U || ps->IDAT_size == 0) png_error(ps->pwrite, "storefile: incomplete write"); pf = voidcast(png_store_file*, malloc(sizeof *pf)); if (pf == NULL) png_error(ps->pwrite, "storefile: OOM"); safecat(pf->name, sizeof pf->name, 0, ps->wname); pf->id = id; pf->data = ps->new; pf->datacount = ps->writepos; pf->IDAT_size = ps->IDAT_size; pf->IDAT_bits = bits_of(ps->IDAT_size); /* Because the IDAT always has zlib header stuff this must be true: */ if (pf->IDAT_bits == 0U) png_error(ps->pwrite, "storefile: 0 sized IDAT"); ps->new.prev = NULL; ps->writepos = 0; ps->chunkpos = 8; ps->chunktype = 0; ps->chunklen = 16; ps->IDAT_size = 0; pf->palette = ps->palette; pf->npalette = ps->npalette; ps->palette = 0; ps->npalette = 0; /* And save it. */ pf->next = ps->saved; ps->saved = pf; } /* Generate an error message (in the given buffer) */ static size_t store_message(png_store *ps, png_const_structp pp, char *buffer, size_t bufsize, size_t pos, const char *msg) { if (pp != NULL && pp == ps->pread) { /* Reading a file */ pos = safecat(buffer, bufsize, pos, "read: "); if (ps->current != NULL) { pos = safecat(buffer, bufsize, pos, ps->current->name); pos = safecat(buffer, bufsize, pos, sep); } } else if (pp != NULL && pp == ps->pwrite) { /* Writing a file */ pos = safecat(buffer, bufsize, pos, "write: "); pos = safecat(buffer, bufsize, pos, ps->wname); pos = safecat(buffer, bufsize, pos, sep); } else { /* Neither reading nor writing (or a memory error in struct delete) */ pos = safecat(buffer, bufsize, pos, "pngvalid: "); } if (ps->test[0] != 0) { pos = safecat(buffer, bufsize, pos, ps->test); pos = safecat(buffer, bufsize, pos, sep); } pos = safecat(buffer, bufsize, pos, msg); return pos; } /* Verbose output to the error stream: */ static void store_verbose(png_store *ps, png_const_structp pp, png_const_charp prefix, png_const_charp message) { char buffer[512]; if (prefix) fputs(prefix, stderr); (void)store_message(ps, pp, buffer, sizeof buffer, 0, message); fputs(buffer, stderr); fputc('\n', stderr); } /* Log an error or warning - the relevant count is always incremented. */ static void store_log(png_store* ps, png_const_structp pp, png_const_charp message, int is_error) { /* The warning is copied to the error buffer if there are no errors and it is * the first warning. The error is copied to the error buffer if it is the * first error (overwriting any prior warnings). */ if (is_error ? (ps->nerrors)++ == 0 : (ps->nwarnings)++ == 0 && ps->nerrors == 0) store_message(ps, pp, ps->error, sizeof ps->error, 0, message); if (ps->verbose) store_verbose(ps, pp, is_error ? "error: " : "warning: ", message); } #ifdef PNG_READ_SUPPORTED /* Internal error function, called with a png_store but no libpng stuff. */ static void internal_error(png_store *ps, png_const_charp message) { store_log(ps, NULL, message, 1 /* error */); /* And finally throw an exception. */ { struct exception_context *the_exception_context = &ps->exception_context; Throw ps; } } #endif /* PNG_READ_SUPPORTED */ /* Functions to use as PNG callbacks. */ static void PNGCBAPI store_error(png_structp ppIn, png_const_charp message) /* PNG_NORETURN */ { png_const_structp pp = ppIn; png_store *ps = voidcast(png_store*, png_get_error_ptr(pp)); if (!ps->expect_error) store_log(ps, pp, message, 1 /* error */); /* And finally throw an exception. */ { struct exception_context *the_exception_context = &ps->exception_context; Throw ps; } } static void PNGCBAPI store_warning(png_structp ppIn, png_const_charp message) { png_const_structp pp = ppIn; png_store *ps = voidcast(png_store*, png_get_error_ptr(pp)); if (!ps->expect_warning) store_log(ps, pp, message, 0 /* warning */); else ps->saw_warning = 1; } /* These somewhat odd functions are used when reading an image to ensure that * the buffer is big enough, the png_structp is for errors. */ /* Return a single row from the correct image. */ static png_bytep store_image_row(const png_store* ps, png_const_structp pp, int nImage, png_uint_32 y) { size_t coffset = (nImage * ps->image_h + y) * (ps->cb_row + 5) + 2; if (ps->image == NULL) png_error(pp, "no allocated image"); if (coffset + ps->cb_row + 3 > ps->cb_image) png_error(pp, "image too small"); return ps->image + coffset; } static void store_image_free(png_store *ps, png_const_structp pp) { if (ps->image != NULL) { png_bytep image = ps->image; if (image[-1] != 0xed || image[ps->cb_image] != 0xfe) { if (pp != NULL) png_error(pp, "png_store image overwrite (1)"); else store_log(ps, NULL, "png_store image overwrite (2)", 1); } ps->image = NULL; ps->cb_image = 0; --image; free(image); } } static void store_ensure_image(png_store *ps, png_const_structp pp, int nImages, size_t cbRow, png_uint_32 cRows) { size_t cb = nImages * cRows * (cbRow + 5); if (ps->cb_image < cb) { png_bytep image; store_image_free(ps, pp); /* The buffer is deliberately mis-aligned. */ image = voidcast(png_bytep, malloc(cb+2)); if (image == NULL) { /* Called from the startup - ignore the error for the moment. */ if (pp == NULL) return; png_error(pp, "OOM allocating image buffer"); } /* These magic tags are used to detect overwrites above. */ ++image; image[-1] = 0xed; image[cb] = 0xfe; ps->image = image; ps->cb_image = cb; } /* We have an adequate sized image; lay out the rows. There are 2 bytes at * the start and three at the end of each (this ensures that the row * alignment starts out odd - 2+1 and changes for larger images on each row.) */ ps->cb_row = cbRow; ps->image_h = cRows; /* For error checking, the whole buffer is set to 10110010 (0xb2 - 178). * This deliberately doesn't match the bits in the size test image which are * outside the image; these are set to 0xff (all 1). To make the row * comparison work in the 'size' test case the size rows are pre-initialized * to the same value prior to calling 'standard_row'. */ memset(ps->image, 178, cb); /* Then put in the marks. */ while (--nImages >= 0) { png_uint_32 y; for (y=0; yimage; if (image[-1] != 0xed || image[ps->cb_image] != 0xfe) png_error(pp, "image overwrite"); else { size_t cbRow = ps->cb_row; png_uint_32 rows = ps->image_h; image += iImage * (cbRow+5) * ps->image_h; image += 2; /* skip image first row markers */ for (; rows > 0; --rows) { if (image[-2] != 190 || image[-1] != 239) png_error(pp, "row start overwritten"); if (image[cbRow] != 222 || image[cbRow+1] != 173 || image[cbRow+2] != 17) png_error(pp, "row end overwritten"); image += cbRow+5; } } } #endif /* PNG_READ_SUPPORTED */ static int valid_chunktype(png_uint_32 chunktype) { /* Each byte in the chunk type must be in one of the ranges 65..90, 97..122 * (both inclusive), so: */ unsigned int i; for (i=0; i<4; ++i) { unsigned int c = chunktype & 0xffU; if (!((c >= 65U && c <= 90U) || (c >= 97U && c <= 122U))) return 0; chunktype >>= 8; } return 1; /* It's valid */ } static void PNGCBAPI store_write(png_structp ppIn, png_bytep pb, size_t st) { png_const_structp pp = ppIn; png_store *ps = voidcast(png_store*, png_get_io_ptr(pp)); size_t writepos = ps->writepos; png_uint_32 chunkpos = ps->chunkpos; png_uint_32 chunktype = ps->chunktype; png_uint_32 chunklen = ps->chunklen; if (ps->pwrite != pp) png_error(pp, "store state damaged"); /* Technically this is legal, but in practice libpng never writes more than * the maximum chunk size at once so if it happens something weird has * changed inside libpng (probably). */ if (st > 0x7fffffffU) png_error(pp, "unexpected write size"); /* Now process the bytes to be written. Do this in units of the space in the * output (write) buffer or, at the start 4 bytes for the chunk type and * length limited in any case by the amount of data. */ while (st > 0) { if (writepos >= STORE_BUFFER_SIZE) store_storenew(ps), writepos = 0; if (chunkpos < 4) { png_byte b = *pb++; --st; chunklen = (chunklen << 8) + b; ps->new.buffer[writepos++] = b; ++chunkpos; } else if (chunkpos < 8) { png_byte b = *pb++; --st; chunktype = (chunktype << 8) + b; ps->new.buffer[writepos++] = b; if (++chunkpos == 8) { chunklen &= 0xffffffffU; if (chunklen > 0x7fffffffU) png_error(pp, "chunk length too great"); chunktype &= 0xffffffffU; if (chunktype == CHUNK_IDAT) { if (chunklen > ~ps->IDAT_size) png_error(pp, "pngvalid internal image too large"); ps->IDAT_size += chunklen; } else if (!valid_chunktype(chunktype)) png_error(pp, "invalid chunk type"); chunklen += 12; /* for header and CRC */ } } else /* chunkpos >= 8 */ { size_t cb = st; if (cb > STORE_BUFFER_SIZE - writepos) cb = STORE_BUFFER_SIZE - writepos; if (cb > chunklen - chunkpos/* bytes left in chunk*/) cb = (size_t)/*SAFE*/(chunklen - chunkpos); memcpy(ps->new.buffer + writepos, pb, cb); chunkpos += (png_uint_32)/*SAFE*/cb; pb += cb; writepos += cb; st -= cb; if (chunkpos >= chunklen) /* must be equal */ chunkpos = chunktype = chunklen = 0; } } /* while (st > 0) */ ps->writepos = writepos; ps->chunkpos = chunkpos; ps->chunktype = chunktype; ps->chunklen = chunklen; } static void PNGCBAPI store_flush(png_structp ppIn) { UNUSED(ppIn) /*DOES NOTHING*/ } #ifdef PNG_READ_SUPPORTED static size_t store_read_buffer_size(png_store *ps) { /* Return the bytes available for read in the current buffer. */ if (ps->next != &ps->current->data) return STORE_BUFFER_SIZE; return ps->current->datacount; } /* Return total bytes available for read. */ static size_t store_read_buffer_avail(png_store *ps) { if (ps->current != NULL && ps->next != NULL) { png_store_buffer *next = &ps->current->data; size_t cbAvail = ps->current->datacount; while (next != ps->next && next != NULL) { next = next->prev; cbAvail += STORE_BUFFER_SIZE; } if (next != ps->next) png_error(ps->pread, "buffer read error"); if (cbAvail > ps->readpos) return cbAvail - ps->readpos; } return 0; } static int store_read_buffer_next(png_store *ps) { png_store_buffer *pbOld = ps->next; png_store_buffer *pbNew = &ps->current->data; if (pbOld != pbNew) { while (pbNew != NULL && pbNew->prev != pbOld) pbNew = pbNew->prev; if (pbNew != NULL) { ps->next = pbNew; ps->readpos = 0; return 1; } png_error(ps->pread, "buffer lost"); } return 0; /* EOF or error */ } /* Need separate implementation and callback to allow use of the same code * during progressive read, where the io_ptr is set internally by libpng. */ static void store_read_imp(png_store *ps, png_bytep pb, size_t st) { if (ps->current == NULL || ps->next == NULL) png_error(ps->pread, "store state damaged"); while (st > 0) { size_t cbAvail = store_read_buffer_size(ps) - ps->readpos; if (cbAvail > 0) { if (cbAvail > st) cbAvail = st; memcpy(pb, ps->next->buffer + ps->readpos, cbAvail); st -= cbAvail; pb += cbAvail; ps->readpos += cbAvail; } else if (!store_read_buffer_next(ps)) png_error(ps->pread, "read beyond end of file"); } } static size_t store_read_chunk(png_store *ps, png_bytep pb, size_t max, size_t min) { png_uint_32 chunklen = ps->chunklen; png_uint_32 chunktype = ps->chunktype; png_uint_32 chunkpos = ps->chunkpos; size_t st = max; if (st > 0) do { if (chunkpos >= chunklen) /* end of last chunk */ { png_byte buffer[8]; /* Read the header of the next chunk: */ store_read_imp(ps, buffer, 8U); chunklen = png_get_uint_32(buffer) + 12U; chunktype = png_get_uint_32(buffer+4U); chunkpos = 0U; /* Position read so far */ } if (chunktype == CHUNK_IDAT) { png_uint_32 IDAT_pos = ps->IDAT_pos; png_uint_32 IDAT_len = ps->IDAT_len; png_uint_32 IDAT_size = ps->IDAT_size; /* The IDAT headers are constructed here; skip the input header. */ if (chunkpos < 8U) chunkpos = 8U; if (IDAT_pos == IDAT_len) { png_byte random = random_byte(); /* Make a new IDAT chunk, if IDAT_len is 0 this is the first IDAT, * if IDAT_size is 0 this is the end. At present this is set up * using a random number so that there is a 25% chance before * the start of the first IDAT chunk being 0 length. */ if (IDAT_len == 0U) /* First IDAT */ { switch (random & 3U) { case 0U: IDAT_len = 12U; break; /* 0 bytes */ case 1U: IDAT_len = 13U; break; /* 1 byte */ default: IDAT_len = random_u32(); IDAT_len %= IDAT_size; IDAT_len += 13U; /* 1..IDAT_size bytes */ break; } } else if (IDAT_size == 0U) /* all IDAT data read */ { /* The last (IDAT) chunk should be positioned at the CRC now: */ if (chunkpos != chunklen-4U) png_error(ps->pread, "internal: IDAT size mismatch"); /* The only option here is to add a zero length IDAT, this * happens 25% of the time. Because of the check above * chunklen-4U-chunkpos must be zero, we just need to skip the * CRC now. */ if ((random & 3U) == 0U) IDAT_len = 12U; /* Output another 0 length IDAT */ else { /* End of IDATs, skip the CRC to make the code above load the * next chunk header next time round. */ png_byte buffer[4]; store_read_imp(ps, buffer, 4U); chunkpos += 4U; ps->IDAT_pos = IDAT_pos; ps->IDAT_len = IDAT_len; ps->IDAT_size = 0U; continue; /* Read the next chunk */ } } else { /* Middle of IDATs, use 'random' to determine the number of bits * to use in the IDAT length. */ IDAT_len = random_u32(); IDAT_len &= (1U << (1U + random % ps->IDAT_bits)) - 1U; if (IDAT_len > IDAT_size) IDAT_len = IDAT_size; IDAT_len += 12U; /* zero bytes may occur */ } IDAT_pos = 0U; ps->IDAT_crc = 0x35af061e; /* Ie: crc32(0UL, "IDAT", 4) */ } /* IDAT_pos == IDAT_len */ if (IDAT_pos < 8U) /* Return the header */ do { png_uint_32 b; unsigned int shift; if (IDAT_pos < 4U) b = IDAT_len - 12U; else b = CHUNK_IDAT; shift = 3U & IDAT_pos; ++IDAT_pos; if (shift < 3U) b >>= 8U*(3U-shift); *pb++ = 0xffU & b; } while (--st > 0 && IDAT_pos < 8); else if (IDAT_pos < IDAT_len - 4U) /* I.e not the CRC */ { if (chunkpos < chunklen-4U) { uInt avail = (uInt)-1; if (avail > (IDAT_len-4U) - IDAT_pos) avail = (uInt)/*SAFE*/((IDAT_len-4U) - IDAT_pos); if (avail > st) avail = (uInt)/*SAFE*/st; if (avail > (chunklen-4U) - chunkpos) avail = (uInt)/*SAFE*/((chunklen-4U) - chunkpos); store_read_imp(ps, pb, avail); ps->IDAT_crc = crc32(ps->IDAT_crc, pb, avail); pb += (size_t)/*SAFE*/avail; st -= (size_t)/*SAFE*/avail; chunkpos += (png_uint_32)/*SAFE*/avail; IDAT_size -= (png_uint_32)/*SAFE*/avail; IDAT_pos += (png_uint_32)/*SAFE*/avail; } else /* skip the input CRC */ { png_byte buffer[4]; store_read_imp(ps, buffer, 4U); chunkpos += 4U; } } else /* IDAT crc */ do { uLong b = ps->IDAT_crc; unsigned int shift = (IDAT_len - IDAT_pos); /* 4..1 */ ++IDAT_pos; if (shift > 1U) b >>= 8U*(shift-1U); *pb++ = 0xffU & b; } while (--st > 0 && IDAT_pos < IDAT_len); ps->IDAT_pos = IDAT_pos; ps->IDAT_len = IDAT_len; ps->IDAT_size = IDAT_size; } else /* !IDAT */ { /* If there is still some pending IDAT data after the IDAT chunks have * been processed there is a problem: */ if (ps->IDAT_len > 0 && ps->IDAT_size > 0) png_error(ps->pread, "internal: missing IDAT data"); if (chunktype == CHUNK_IEND && ps->IDAT_len == 0U) png_error(ps->pread, "internal: missing IDAT"); if (chunkpos < 8U) /* Return the header */ do { png_uint_32 b; unsigned int shift; if (chunkpos < 4U) b = chunklen - 12U; else b = chunktype; shift = 3U & chunkpos; ++chunkpos; if (shift < 3U) b >>= 8U*(3U-shift); *pb++ = 0xffU & b; } while (--st > 0 && chunkpos < 8); else /* Return chunk bytes, including the CRC */ { size_t avail = st; if (avail > chunklen - chunkpos) avail = (size_t)/*SAFE*/(chunklen - chunkpos); store_read_imp(ps, pb, avail); pb += avail; st -= avail; chunkpos += (png_uint_32)/*SAFE*/avail; /* Check for end of chunk and end-of-file; don't try to read a new * chunk header at this point unless instructed to do so by 'min'. */ if (chunkpos >= chunklen && max-st >= min && store_read_buffer_avail(ps) == 0) break; } } /* !IDAT */ } while (st > 0); ps->chunklen = chunklen; ps->chunktype = chunktype; ps->chunkpos = chunkpos; return st; /* space left */ } static void PNGCBAPI store_read(png_structp ppIn, png_bytep pb, size_t st) { png_const_structp pp = ppIn; png_store *ps = voidcast(png_store*, png_get_io_ptr(pp)); if (ps == NULL || ps->pread != pp) png_error(pp, "bad store read call"); store_read_chunk(ps, pb, st, st); } static void store_progressive_read(png_store *ps, png_structp pp, png_infop pi) { if (ps->pread != pp || ps->current == NULL || ps->next == NULL) png_error(pp, "store state damaged (progressive)"); /* This is another Horowitz and Hill random noise generator. In this case * the aim is to stress the progressive reader with truly horrible variable * buffer sizes in the range 1..500, so a sequence of 9 bit random numbers * is generated. We could probably just count from 1 to 32767 and get as * good a result. */ while (store_read_buffer_avail(ps) > 0) { static png_uint_32 noise = 2; size_t cb; png_byte buffer[512]; /* Generate 15 more bits of stuff: */ noise = (noise << 9) | ((noise ^ (noise >> (9-5))) & 0x1ff); cb = noise & 0x1ff; cb -= store_read_chunk(ps, buffer, cb, 1); png_process_data(pp, pi, buffer, cb); } } #endif /* PNG_READ_SUPPORTED */ /* The caller must fill this in: */ static store_palette_entry * store_write_palette(png_store *ps, int npalette) { if (ps->pwrite == NULL) store_log(ps, NULL, "attempt to write palette without write stream", 1); if (ps->palette != NULL) png_error(ps->pwrite, "multiple store_write_palette calls"); /* This function can only return NULL if called with '0'! */ if (npalette > 0) { ps->palette = voidcast(store_palette_entry*, malloc(npalette * sizeof *ps->palette)); if (ps->palette == NULL) png_error(ps->pwrite, "store new palette: OOM"); ps->npalette = npalette; } return ps->palette; } #ifdef PNG_READ_SUPPORTED static store_palette_entry * store_current_palette(png_store *ps, int *npalette) { /* This is an internal error (the call has been made outside a read * operation.) */ if (ps->current == NULL) { store_log(ps, ps->pread, "no current stream for palette", 1); return NULL; } /* The result may be null if there is no palette. */ *npalette = ps->current->npalette; return ps->current->palette; } #endif /* PNG_READ_SUPPORTED */ /***************************** MEMORY MANAGEMENT*** ***************************/ #ifdef PNG_USER_MEM_SUPPORTED /* A store_memory is simply the header for an allocated block of memory. The * pointer returned to libpng is just after the end of the header block, the * allocated memory is followed by a second copy of the 'mark'. */ typedef struct store_memory { store_pool *pool; /* Originating pool */ struct store_memory *next; /* Singly linked list */ png_alloc_size_t size; /* Size of memory allocated */ png_byte mark[4]; /* ID marker */ } store_memory; /* Handle a fatal error in memory allocation. This calls png_error if the * libpng struct is non-NULL, else it outputs a message and returns. This means * that a memory problem while libpng is running will abort (png_error) the * handling of particular file while one in cleanup (after the destroy of the * struct has returned) will simply keep going and free (or attempt to free) * all the memory. */ static void store_pool_error(png_store *ps, png_const_structp pp, const char *msg) { if (pp != NULL) png_error(pp, msg); /* Else we have to do it ourselves. png_error eventually calls store_log, * above. store_log accepts a NULL png_structp - it just changes what gets * output by store_message. */ store_log(ps, pp, msg, 1 /* error */); } static void store_memory_free(png_const_structp pp, store_pool *pool, store_memory *memory) { /* Note that pp may be NULL (see store_pool_delete below), the caller has * found 'memory' in pool->list *and* unlinked this entry, so this is a valid * pointer (for sure), but the contents may have been trashed. */ if (memory->pool != pool) store_pool_error(pool->store, pp, "memory corrupted (pool)"); else if (memcmp(memory->mark, pool->mark, sizeof memory->mark) != 0) store_pool_error(pool->store, pp, "memory corrupted (start)"); /* It should be safe to read the size field now. */ else { png_alloc_size_t cb = memory->size; if (cb > pool->max) store_pool_error(pool->store, pp, "memory corrupted (size)"); else if (memcmp((png_bytep)(memory+1)+cb, pool->mark, sizeof pool->mark) != 0) store_pool_error(pool->store, pp, "memory corrupted (end)"); /* Finally give the library a chance to find problems too: */ else { pool->current -= cb; free(memory); } } } static void store_pool_delete(png_store *ps, store_pool *pool) { if (pool->list != NULL) { fprintf(stderr, "%s: %s %s: memory lost (list follows):\n", ps->test, pool == &ps->read_memory_pool ? "read" : "write", pool == &ps->read_memory_pool ? (ps->current != NULL ? ps->current->name : "unknown file") : ps->wname); ++ps->nerrors; do { store_memory *next = pool->list; pool->list = next->next; next->next = NULL; fprintf(stderr, "\t%lu bytes @ %p\n", (unsigned long)next->size, (const void*)(next+1)); /* The NULL means this will always return, even if the memory is * corrupted. */ store_memory_free(NULL, pool, next); } while (pool->list != NULL); } /* And reset the other fields too for the next time. */ if (pool->max > pool->max_max) pool->max_max = pool->max; pool->max = 0; if (pool->current != 0) /* unexpected internal error */ fprintf(stderr, "%s: %s %s: memory counter mismatch (internal error)\n", ps->test, pool == &ps->read_memory_pool ? "read" : "write", pool == &ps->read_memory_pool ? (ps->current != NULL ? ps->current->name : "unknown file") : ps->wname); pool->current = 0; if (pool->limit > pool->max_limit) pool->max_limit = pool->limit; pool->limit = 0; if (pool->total > pool->max_total) pool->max_total = pool->total; pool->total = 0; /* Get a new mark too. */ store_pool_mark(pool->mark); } /* The memory callbacks: */ static png_voidp PNGCBAPI store_malloc(png_structp ppIn, png_alloc_size_t cb) { png_const_structp pp = ppIn; store_pool *pool = voidcast(store_pool*, png_get_mem_ptr(pp)); store_memory *new = voidcast(store_memory*, malloc(cb + (sizeof *new) + (sizeof pool->mark))); if (new != NULL) { if (cb > pool->max) pool->max = cb; pool->current += cb; if (pool->current > pool->limit) pool->limit = pool->current; pool->total += cb; new->size = cb; memcpy(new->mark, pool->mark, sizeof new->mark); memcpy((png_byte*)(new+1) + cb, pool->mark, sizeof pool->mark); new->pool = pool; new->next = pool->list; pool->list = new; ++new; } else { /* NOTE: the PNG user malloc function cannot use the png_ptr it is passed * other than to retrieve the allocation pointer! libpng calls the * store_malloc callback in two basic cases: * * 1) From png_malloc; png_malloc will do a png_error itself if NULL is * returned. * 2) From png_struct or png_info structure creation; png_malloc is * to return so cleanup can be performed. * * To handle this store_malloc can log a message, but can't do anything * else. */ store_log(pool->store, pp, "out of memory", 1 /* is_error */); } return new; } static void PNGCBAPI store_free(png_structp ppIn, png_voidp memory) { png_const_structp pp = ppIn; store_pool *pool = voidcast(store_pool*, png_get_mem_ptr(pp)); store_memory *this = voidcast(store_memory*, memory), **test; /* Because libpng calls store_free with a dummy png_struct when deleting * png_struct or png_info via png_destroy_struct_2 it is necessary to check * the passed in png_structp to ensure it is valid, and not pass it to * png_error if it is not. */ if (pp != pool->store->pread && pp != pool->store->pwrite) pp = NULL; /* First check that this 'memory' really is valid memory - it must be in the * pool list. If it is, use the shared memory_free function to free it. */ --this; for (test = &pool->list; *test != this; test = &(*test)->next) { if (*test == NULL) { store_pool_error(pool->store, pp, "bad pointer to free"); return; } } /* Unlink this entry, *test == this. */ *test = this->next; this->next = NULL; store_memory_free(pp, pool, this); } #endif /* PNG_USER_MEM_SUPPORTED */ /* Setup functions. */ /* Cleanup when aborting a write or after storing the new file. */ static void store_write_reset(png_store *ps) { if (ps->pwrite != NULL) { anon_context(ps); Try png_destroy_write_struct(&ps->pwrite, &ps->piwrite); Catch_anonymous { /* memory corruption: continue. */ } ps->pwrite = NULL; ps->piwrite = NULL; } /* And make sure that all the memory has been freed - this will output * spurious errors in the case of memory corruption above, but this is safe. */ # ifdef PNG_USER_MEM_SUPPORTED store_pool_delete(ps, &ps->write_memory_pool); # endif store_freenew(ps); } /* The following is the main write function, it returns a png_struct and, * optionally, a png_info suitable for writiing a new PNG file. Use * store_storefile above to record this file after it has been written. The * returned libpng structures as destroyed by store_write_reset above. */ static png_structp set_store_for_write(png_store *ps, png_infopp ppi, const char *name) { anon_context(ps); Try { if (ps->pwrite != NULL) png_error(ps->pwrite, "write store already in use"); store_write_reset(ps); safecat(ps->wname, sizeof ps->wname, 0, name); /* Don't do the slow memory checks if doing a speed test, also if user * memory is not supported we can't do it anyway. */ # ifdef PNG_USER_MEM_SUPPORTED if (!ps->speed) ps->pwrite = png_create_write_struct_2(PNG_LIBPNG_VER_STRING, ps, store_error, store_warning, &ps->write_memory_pool, store_malloc, store_free); else # endif ps->pwrite = png_create_write_struct(PNG_LIBPNG_VER_STRING, ps, store_error, store_warning); png_set_write_fn(ps->pwrite, ps, store_write, store_flush); # ifdef PNG_SET_OPTION_SUPPORTED { int opt; for (opt=0; optnoptions; ++opt) if (png_set_option(ps->pwrite, ps->options[opt].option, ps->options[opt].setting) == PNG_OPTION_INVALID) png_error(ps->pwrite, "png option invalid"); } # endif if (ppi != NULL) *ppi = ps->piwrite = png_create_info_struct(ps->pwrite); } Catch_anonymous return NULL; return ps->pwrite; } /* Cleanup when finished reading (either due to error or in the success case). * This routine exists even when there is no read support to make the code * tidier (avoid a mass of ifdefs) and so easier to maintain. */ static void store_read_reset(png_store *ps) { # ifdef PNG_READ_SUPPORTED if (ps->pread != NULL) { anon_context(ps); Try png_destroy_read_struct(&ps->pread, &ps->piread, NULL); Catch_anonymous { /* error already output: continue */ } ps->pread = NULL; ps->piread = NULL; } # endif # ifdef PNG_USER_MEM_SUPPORTED /* Always do this to be safe. */ store_pool_delete(ps, &ps->read_memory_pool); # endif ps->current = NULL; ps->next = NULL; ps->readpos = 0; ps->validated = 0; ps->chunkpos = 8; ps->chunktype = 0; ps->chunklen = 16; ps->IDAT_size = 0; } #ifdef PNG_READ_SUPPORTED static void store_read_set(png_store *ps, png_uint_32 id) { png_store_file *pf = ps->saved; while (pf != NULL) { if (pf->id == id) { ps->current = pf; ps->next = NULL; ps->IDAT_size = pf->IDAT_size; ps->IDAT_bits = pf->IDAT_bits; /* just a cache */ ps->IDAT_len = 0; ps->IDAT_pos = 0; ps->IDAT_crc = 0UL; store_read_buffer_next(ps); return; } pf = pf->next; } { size_t pos; char msg[FILE_NAME_SIZE+64]; pos = standard_name_from_id(msg, sizeof msg, 0, id); pos = safecat(msg, sizeof msg, pos, ": file not found"); png_error(ps->pread, msg); } } /* The main interface for reading a saved file - pass the id number of the file * to retrieve. Ids must be unique or the earlier file will be hidden. The API * returns a png_struct and, optionally, a png_info. Both of these will be * destroyed by store_read_reset above. */ static png_structp set_store_for_read(png_store *ps, png_infopp ppi, png_uint_32 id, const char *name) { /* Set the name for png_error */ safecat(ps->test, sizeof ps->test, 0, name); if (ps->pread != NULL) png_error(ps->pread, "read store already in use"); store_read_reset(ps); /* Both the create APIs can return NULL if used in their default mode * (because there is no other way of handling an error because the jmp_buf * by default is stored in png_struct and that has not been allocated!) * However, given that store_error works correctly in these circumstances * we don't ever expect NULL in this program. */ # ifdef PNG_USER_MEM_SUPPORTED if (!ps->speed) ps->pread = png_create_read_struct_2(PNG_LIBPNG_VER_STRING, ps, store_error, store_warning, &ps->read_memory_pool, store_malloc, store_free); else # endif ps->pread = png_create_read_struct(PNG_LIBPNG_VER_STRING, ps, store_error, store_warning); if (ps->pread == NULL) { struct exception_context *the_exception_context = &ps->exception_context; store_log(ps, NULL, "png_create_read_struct returned NULL (unexpected)", 1 /*error*/); Throw ps; } # ifdef PNG_SET_OPTION_SUPPORTED { int opt; for (opt=0; optnoptions; ++opt) if (png_set_option(ps->pread, ps->options[opt].option, ps->options[opt].setting) == PNG_OPTION_INVALID) png_error(ps->pread, "png option invalid"); } # endif store_read_set(ps, id); if (ppi != NULL) *ppi = ps->piread = png_create_info_struct(ps->pread); return ps->pread; } #endif /* PNG_READ_SUPPORTED */ /* The overall cleanup of a store simply calls the above then removes all the * saved files. This does not delete the store itself. */ static void store_delete(png_store *ps) { store_write_reset(ps); store_read_reset(ps); store_freefile(&ps->saved); store_image_free(ps, NULL); } /*********************** PNG FILE MODIFICATION ON READ ************************/ /* Files may be modified on read. The following structure contains a complete * png_store together with extra members to handle modification and a special * read callback for libpng. To use this the 'modifications' field must be set * to a list of png_modification structures that actually perform the * modification, otherwise a png_modifier is functionally equivalent to a * png_store. There is a special read function, set_modifier_for_read, which * replaces set_store_for_read. */ typedef enum modifier_state { modifier_start, /* Initial value */ modifier_signature, /* Have a signature */ modifier_IHDR /* Have an IHDR */ } modifier_state; typedef struct CIE_color { /* A single CIE tristimulus value, representing the unique response of a * standard observer to a variety of light spectra. The observer recognizes * all spectra that produce this response as the same color, therefore this * is effectively a description of a color. */ double X, Y, Z; } CIE_color; typedef struct color_encoding { /* A description of an (R,G,B) encoding of color (as defined above); this * includes the actual colors of the (R,G,B) triples (1,0,0), (0,1,0) and * (0,0,1) plus an encoding value that is used to encode the linear * components R, G and B to give the actual values R^gamma, G^gamma and * B^gamma that are stored. */ double gamma; /* Encoding (file) gamma of space */ CIE_color red, green, blue; /* End points */ } color_encoding; #ifdef PNG_READ_SUPPORTED #if defined PNG_READ_TRANSFORMS_SUPPORTED && defined PNG_READ_cHRM_SUPPORTED static double chromaticity_x(CIE_color c) { return c.X / (c.X + c.Y + c.Z); } static double chromaticity_y(CIE_color c) { return c.Y / (c.X + c.Y + c.Z); } static CIE_color white_point(const color_encoding *encoding) { CIE_color white; white.X = encoding->red.X + encoding->green.X + encoding->blue.X; white.Y = encoding->red.Y + encoding->green.Y + encoding->blue.Y; white.Z = encoding->red.Z + encoding->green.Z + encoding->blue.Z; return white; } #endif /* READ_TRANSFORMS && READ_cHRM */ #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED static void normalize_color_encoding(color_encoding *encoding) { const double whiteY = encoding->red.Y + encoding->green.Y + encoding->blue.Y; if (whiteY != 1) { encoding->red.X /= whiteY; encoding->red.Y /= whiteY; encoding->red.Z /= whiteY; encoding->green.X /= whiteY; encoding->green.Y /= whiteY; encoding->green.Z /= whiteY; encoding->blue.X /= whiteY; encoding->blue.Y /= whiteY; encoding->blue.Z /= whiteY; } } #endif #ifdef PNG_READ_TRANSFORMS_SUPPORTED static size_t safecat_color_encoding(char *buffer, size_t bufsize, size_t pos, const color_encoding *e, double encoding_gamma) { if (e != 0) { if (encoding_gamma != 0) pos = safecat(buffer, bufsize, pos, "("); pos = safecat(buffer, bufsize, pos, "R("); pos = safecatd(buffer, bufsize, pos, e->red.X, 4); pos = safecat(buffer, bufsize, pos, ","); pos = safecatd(buffer, bufsize, pos, e->red.Y, 4); pos = safecat(buffer, bufsize, pos, ","); pos = safecatd(buffer, bufsize, pos, e->red.Z, 4); pos = safecat(buffer, bufsize, pos, "),G("); pos = safecatd(buffer, bufsize, pos, e->green.X, 4); pos = safecat(buffer, bufsize, pos, ","); pos = safecatd(buffer, bufsize, pos, e->green.Y, 4); pos = safecat(buffer, bufsize, pos, ","); pos = safecatd(buffer, bufsize, pos, e->green.Z, 4); pos = safecat(buffer, bufsize, pos, "),B("); pos = safecatd(buffer, bufsize, pos, e->blue.X, 4); pos = safecat(buffer, bufsize, pos, ","); pos = safecatd(buffer, bufsize, pos, e->blue.Y, 4); pos = safecat(buffer, bufsize, pos, ","); pos = safecatd(buffer, bufsize, pos, e->blue.Z, 4); pos = safecat(buffer, bufsize, pos, ")"); if (encoding_gamma != 0) pos = safecat(buffer, bufsize, pos, ")"); } if (encoding_gamma != 0) { pos = safecat(buffer, bufsize, pos, "^"); pos = safecatd(buffer, bufsize, pos, encoding_gamma, 5); } return pos; } #endif /* READ_TRANSFORMS */ #endif /* PNG_READ_SUPPORTED */ typedef struct png_modifier { png_store this; /* I am a png_store */ struct png_modification *modifications; /* Changes to make */ modifier_state state; /* My state */ /* Information from IHDR: */ png_byte bit_depth; /* From IHDR */ png_byte colour_type; /* From IHDR */ /* While handling PLTE, IDAT and IEND these chunks may be pended to allow * other chunks to be inserted. */ png_uint_32 pending_len; png_uint_32 pending_chunk; /* Test values */ double *gammas; unsigned int ngammas; unsigned int ngamma_tests; /* Number of gamma tests to run*/ double current_gamma; /* 0 if not set */ const color_encoding *encodings; unsigned int nencodings; const color_encoding *current_encoding; /* If an encoding has been set */ unsigned int encoding_counter; /* For iteration */ int encoding_ignored; /* Something overwrote it */ /* Control variables used to iterate through possible encodings, the * following must be set to 0 and tested by the function that uses the * png_modifier because the modifier only sets it to 1 (true.) */ unsigned int repeat :1; /* Repeat this transform test. */ unsigned int test_uses_encoding :1; /* Lowest sbit to test (pre-1.7 libpng fails for sbit < 8) */ png_byte sbitlow; /* Error control - these are the limits on errors accepted by the gamma tests * below. */ double maxout8; /* Maximum output value error */ double maxabs8; /* Absolute sample error 0..1 */ double maxcalc8; /* Absolute sample error 0..1 */ double maxpc8; /* Percentage sample error 0..100% */ double maxout16; /* Maximum output value error */ double maxabs16; /* Absolute sample error 0..1 */ double maxcalc16;/* Absolute sample error 0..1 */ double maxcalcG; /* Absolute sample error 0..1 */ double maxpc16; /* Percentage sample error 0..100% */ /* This is set by transforms that need to allow a higher limit, it is an * internal check on pngvalid to ensure that the calculated error limits are * not ridiculous; without this it is too easy to make a mistake in pngvalid * that allows any value through. * * NOTE: this is not checked in release builds. */ double limit; /* limit on error values, normally 4E-3 */ /* Log limits - values above this are logged, but not necessarily * warned. */ double log8; /* Absolute error in 8 bits to log */ double log16; /* Absolute error in 16 bits to log */ /* Logged 8 and 16 bit errors ('output' values): */ double error_gray_2; double error_gray_4; double error_gray_8; double error_gray_16; double error_color_8; double error_color_16; double error_indexed; /* Flags: */ /* Whether to call png_read_update_info, not png_read_start_image, and how * many times to call it. */ int use_update_info; /* Whether or not to interlace. */ int interlace_type :9; /* int, but must store '1' */ /* Run the standard tests? */ unsigned int test_standard :1; /* Run the odd-sized image and interlace read/write tests? */ unsigned int test_size :1; /* Run tests on reading with a combination of transforms, */ unsigned int test_transform :1; unsigned int test_tRNS :1; /* Includes tRNS images */ /* When to use the use_input_precision option, this controls the gamma * validation code checks. If set any value that is within the transformed * range input-.5 to input+.5 will be accepted, otherwise the value must be * within the normal limits. It should not be necessary to set this; the * result should always be exact within the permitted error limits. */ unsigned int use_input_precision :1; unsigned int use_input_precision_sbit :1; unsigned int use_input_precision_16to8 :1; /* If set assume that the calculation bit depth is set by the input * precision, not the output precision. */ unsigned int calculations_use_input_precision :1; /* If set assume that the calculations are done in 16 bits even if the sample * depth is 8 bits. */ unsigned int assume_16_bit_calculations :1; /* Which gamma tests to run: */ unsigned int test_gamma_threshold :1; unsigned int test_gamma_transform :1; /* main tests */ unsigned int test_gamma_sbit :1; unsigned int test_gamma_scale16 :1; unsigned int test_gamma_background :1; unsigned int test_gamma_alpha_mode :1; unsigned int test_gamma_expand16 :1; unsigned int test_exhaustive :1; /* Whether or not to run the low-bit-depth grayscale tests. This fails on * gamma images in some cases because of gross inaccuracies in the grayscale * gamma handling for low bit depth. */ unsigned int test_lbg :1; unsigned int test_lbg_gamma_threshold :1; unsigned int test_lbg_gamma_transform :1; unsigned int test_lbg_gamma_sbit :1; unsigned int test_lbg_gamma_composition :1; unsigned int log :1; /* Log max error */ /* Buffer information, the buffer size limits the size of the chunks that can * be modified - they must fit (including header and CRC) into the buffer! */ size_t flush; /* Count of bytes to flush */ size_t buffer_count; /* Bytes in buffer */ size_t buffer_position; /* Position in buffer */ png_byte buffer[1024]; } png_modifier; /* This returns true if the test should be stopped now because it has already * failed and it is running silently. */ static int fail(png_modifier *pm) { return !pm->log && !pm->this.verbose && (pm->this.nerrors > 0 || (pm->this.treat_warnings_as_errors && pm->this.nwarnings > 0)); } static void modifier_init(png_modifier *pm) { memset(pm, 0, sizeof *pm); store_init(&pm->this); pm->modifications = NULL; pm->state = modifier_start; pm->sbitlow = 1U; pm->ngammas = 0; pm->ngamma_tests = 0; pm->gammas = 0; pm->current_gamma = 0; pm->encodings = 0; pm->nencodings = 0; pm->current_encoding = 0; pm->encoding_counter = 0; pm->encoding_ignored = 0; pm->repeat = 0; pm->test_uses_encoding = 0; pm->maxout8 = pm->maxpc8 = pm->maxabs8 = pm->maxcalc8 = 0; pm->maxout16 = pm->maxpc16 = pm->maxabs16 = pm->maxcalc16 = 0; pm->maxcalcG = 0; pm->limit = 4E-3; pm->log8 = pm->log16 = 0; /* Means 'off' */ pm->error_gray_2 = pm->error_gray_4 = pm->error_gray_8 = 0; pm->error_gray_16 = pm->error_color_8 = pm->error_color_16 = 0; pm->error_indexed = 0; pm->use_update_info = 0; pm->interlace_type = PNG_INTERLACE_NONE; pm->test_standard = 0; pm->test_size = 0; pm->test_transform = 0; # ifdef PNG_WRITE_tRNS_SUPPORTED pm->test_tRNS = 1; # else pm->test_tRNS = 0; # endif pm->use_input_precision = 0; pm->use_input_precision_sbit = 0; pm->use_input_precision_16to8 = 0; pm->calculations_use_input_precision = 0; pm->assume_16_bit_calculations = 0; pm->test_gamma_threshold = 0; pm->test_gamma_transform = 0; pm->test_gamma_sbit = 0; pm->test_gamma_scale16 = 0; pm->test_gamma_background = 0; pm->test_gamma_alpha_mode = 0; pm->test_gamma_expand16 = 0; pm->test_lbg = 1; pm->test_lbg_gamma_threshold = 1; pm->test_lbg_gamma_transform = 1; pm->test_lbg_gamma_sbit = 1; pm->test_lbg_gamma_composition = 1; pm->test_exhaustive = 0; pm->log = 0; /* Rely on the memset for all the other fields - there are no pointers */ } #ifdef PNG_READ_TRANSFORMS_SUPPORTED /* This controls use of checks that explicitly know how libpng digitizes the * samples in calculations; setting this circumvents simple error limit checking * in the rgb_to_gray check, replacing it with an exact copy of the libpng 1.5 * algorithm. */ #define DIGITIZE PNG_LIBPNG_VER < 10700 /* If pm->calculations_use_input_precision is set then operations will happen * with the precision of the input, not the precision of the output depth. * * If pm->assume_16_bit_calculations is set then even 8 bit calculations use 16 * bit precision. This only affects those of the following limits that pertain * to a calculation - not a digitization operation - unless the following API is * called directly. */ #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED #if DIGITIZE static double digitize(double value, int depth, int do_round) { /* 'value' is in the range 0 to 1, the result is the same value rounded to a * multiple of the digitization factor - 8 or 16 bits depending on both the * sample depth and the 'assume' setting. Digitization is normally by * rounding and 'do_round' should be 1, if it is 0 the digitized value will * be truncated. */ unsigned int digitization_factor = (1U << depth) - 1; /* Limiting the range is done as a convenience to the caller - it's easier to * do it once here than every time at the call site. */ if (value <= 0) value = 0; else if (value >= 1) value = 1; value *= digitization_factor; if (do_round) value += .5; return floor(value)/digitization_factor; } #endif #endif /* RGB_TO_GRAY */ #ifdef PNG_READ_GAMMA_SUPPORTED static double abserr(const png_modifier *pm, int in_depth, int out_depth) { /* Absolute error permitted in linear values - affected by the bit depth of * the calculations. */ if (pm->assume_16_bit_calculations || (pm->calculations_use_input_precision ? in_depth : out_depth) == 16) return pm->maxabs16; else return pm->maxabs8; } static double calcerr(const png_modifier *pm, int in_depth, int out_depth) { /* Error in the linear composition arithmetic - only relevant when * composition actually happens (0 < alpha < 1). */ if ((pm->calculations_use_input_precision ? in_depth : out_depth) == 16) return pm->maxcalc16; else if (pm->assume_16_bit_calculations) return pm->maxcalcG; else return pm->maxcalc8; } static double pcerr(const png_modifier *pm, int in_depth, int out_depth) { /* Percentage error permitted in the linear values. Note that the specified * value is a percentage but this routine returns a simple number. */ if (pm->assume_16_bit_calculations || (pm->calculations_use_input_precision ? in_depth : out_depth) == 16) return pm->maxpc16 * .01; else return pm->maxpc8 * .01; } /* Output error - the error in the encoded value. This is determined by the * digitization of the output so can be +/-0.5 in the actual output value. In * the expand_16 case with the current code in libpng the expand happens after * all the calculations are done in 8 bit arithmetic, so even though the output * depth is 16 the output error is determined by the 8 bit calculation. * * This limit is not determined by the bit depth of internal calculations. * * The specified parameter does *not* include the base .5 digitization error but * it is added here. */ static double outerr(const png_modifier *pm, int in_depth, int out_depth) { /* There is a serious error in the 2 and 4 bit grayscale transform because * the gamma table value (8 bits) is simply shifted, not rounded, so the * error in 4 bit grayscale gamma is up to the value below. This is a hack * to allow pngvalid to succeed: * * TODO: fix this in libpng */ if (out_depth == 2) return .73182-.5; if (out_depth == 4) return .90644-.5; if ((pm->calculations_use_input_precision ? in_depth : out_depth) == 16) return pm->maxout16; /* This is the case where the value was calculated at 8-bit precision then * scaled to 16 bits. */ else if (out_depth == 16) return pm->maxout8 * 257; else return pm->maxout8; } /* This does the same thing as the above however it returns the value to log, * rather than raising a warning. This is useful for debugging to track down * exactly what set of parameters cause high error values. */ static double outlog(const png_modifier *pm, int in_depth, int out_depth) { /* The command line parameters are either 8 bit (0..255) or 16 bit (0..65535) * and so must be adjusted for low bit depth grayscale: */ if (out_depth <= 8) { if (pm->log8 == 0) /* switched off */ return 256; if (out_depth < 8) return pm->log8 / 255 * ((1<log8; } if ((pm->calculations_use_input_precision ? in_depth : out_depth) == 16) { if (pm->log16 == 0) return 65536; return pm->log16; } /* This is the case where the value was calculated at 8-bit precision then * scaled to 16 bits. */ if (pm->log8 == 0) return 65536; return pm->log8 * 257; } /* This complements the above by providing the appropriate quantization for the * final value. Normally this would just be quantization to an integral value, * but in the 8 bit calculation case it's actually quantization to a multiple of * 257! */ static int output_quantization_factor(const png_modifier *pm, int in_depth, int out_depth) { if (out_depth == 16 && in_depth != 16 && pm->calculations_use_input_precision) return 257; else return 1; } #endif /* PNG_READ_GAMMA_SUPPORTED */ /* One modification structure must be provided for each chunk to be modified (in * fact more than one can be provided if multiple separate changes are desired * for a single chunk.) Modifications include adding a new chunk when a * suitable chunk does not exist. * * The caller of modify_fn will reset the CRC of the chunk and record 'modified' * or 'added' as appropriate if the modify_fn returns 1 (true). If the * modify_fn is NULL the chunk is simply removed. */ typedef struct png_modification { struct png_modification *next; png_uint_32 chunk; /* If the following is NULL all matching chunks will be removed: */ int (*modify_fn)(struct png_modifier *pm, struct png_modification *me, int add); /* If the following is set to PLTE, IDAT or IEND and the chunk has not been * found and modified (and there is a modify_fn) the modify_fn will be called * to add the chunk before the relevant chunk. */ png_uint_32 add; unsigned int modified :1; /* Chunk was modified */ unsigned int added :1; /* Chunk was added */ unsigned int removed :1; /* Chunk was removed */ } png_modification; static void modification_reset(png_modification *pmm) { if (pmm != NULL) { pmm->modified = 0; pmm->added = 0; pmm->removed = 0; modification_reset(pmm->next); } } static void modification_init(png_modification *pmm) { memset(pmm, 0, sizeof *pmm); pmm->next = NULL; pmm->chunk = 0; pmm->modify_fn = NULL; pmm->add = 0; modification_reset(pmm); } #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED static void modifier_current_encoding(const png_modifier *pm, color_encoding *ce) { if (pm->current_encoding != 0) *ce = *pm->current_encoding; else memset(ce, 0, sizeof *ce); ce->gamma = pm->current_gamma; } #endif #ifdef PNG_READ_TRANSFORMS_SUPPORTED static size_t safecat_current_encoding(char *buffer, size_t bufsize, size_t pos, const png_modifier *pm) { pos = safecat_color_encoding(buffer, bufsize, pos, pm->current_encoding, pm->current_gamma); if (pm->encoding_ignored) pos = safecat(buffer, bufsize, pos, "[overridden]"); return pos; } #endif /* Iterate through the usefully testable color encodings. An encoding is one * of: * * 1) Nothing (no color space, no gamma). * 2) Just a gamma value from the gamma array (including 1.0) * 3) A color space from the encodings array with the corresponding gamma. * 4) The same, but with gamma 1.0 (only really useful with 16 bit calculations) * * The iterator selects these in turn, the randomizer selects one at random, * which is used depends on the setting of the 'test_exhaustive' flag. Notice * that this function changes the colour space encoding so it must only be * called on completion of the previous test. This is what 'modifier_reset' * does, below. * * After the function has been called the 'repeat' flag will still be set; the * caller of modifier_reset must reset it at the start of each run of the test! */ static unsigned int modifier_total_encodings(const png_modifier *pm) { return 1 + /* (1) nothing */ pm->ngammas + /* (2) gamma values to test */ pm->nencodings + /* (3) total number of encodings */ /* The following test only works after the first time through the * png_modifier code because 'bit_depth' is set when the IHDR is read. * modifier_reset, below, preserves the setting until after it has called * the iterate function (also below.) * * For this reason do not rely on this function outside a call to * modifier_reset. */ ((pm->bit_depth == 16 || pm->assume_16_bit_calculations) ? pm->nencodings : 0); /* (4) encodings with gamma == 1.0 */ } static void modifier_encoding_iterate(png_modifier *pm) { if (!pm->repeat && /* Else something needs the current encoding again. */ pm->test_uses_encoding) /* Some transform is encoding dependent */ { if (pm->test_exhaustive) { if (++pm->encoding_counter >= modifier_total_encodings(pm)) pm->encoding_counter = 0; /* This will stop the repeat */ } else { /* Not exhaustive - choose an encoding at random; generate a number in * the range 1..(max-1), so the result is always non-zero: */ if (pm->encoding_counter == 0) pm->encoding_counter = random_mod(modifier_total_encodings(pm)-1)+1; else pm->encoding_counter = 0; } if (pm->encoding_counter > 0) pm->repeat = 1; } else if (!pm->repeat) pm->encoding_counter = 0; } static void modifier_reset(png_modifier *pm) { store_read_reset(&pm->this); pm->limit = 4E-3; pm->pending_len = pm->pending_chunk = 0; pm->flush = pm->buffer_count = pm->buffer_position = 0; pm->modifications = NULL; pm->state = modifier_start; modifier_encoding_iterate(pm); /* The following must be set in the next run. In particular * test_uses_encodings must be set in the _ini function of each transform * that looks at the encodings. (Not the 'add' function!) */ pm->test_uses_encoding = 0; pm->current_gamma = 0; pm->current_encoding = 0; pm->encoding_ignored = 0; /* These only become value after IHDR is read: */ pm->bit_depth = pm->colour_type = 0; } /* The following must be called before anything else to get the encoding set up * on the modifier. In particular it must be called before the transform init * functions are called. */ static void modifier_set_encoding(png_modifier *pm) { /* Set the encoding to the one specified by the current encoding counter, * first clear out all the settings - this corresponds to an encoding_counter * of 0. */ pm->current_gamma = 0; pm->current_encoding = 0; pm->encoding_ignored = 0; /* not ignored yet - happens in _ini functions. */ /* Now, if required, set the gamma and encoding fields. */ if (pm->encoding_counter > 0) { /* The gammas[] array is an array of screen gammas, not encoding gammas, * so we need the inverse: */ if (pm->encoding_counter <= pm->ngammas) pm->current_gamma = 1/pm->gammas[pm->encoding_counter-1]; else { unsigned int i = pm->encoding_counter - pm->ngammas; if (i >= pm->nencodings) { i %= pm->nencodings; pm->current_gamma = 1; /* Linear, only in the 16 bit case */ } else pm->current_gamma = pm->encodings[i].gamma; pm->current_encoding = pm->encodings + i; } } } /* Enquiry functions to find out what is set. Notice that there is an implicit * assumption below that the first encoding in the list is the one for sRGB. */ static int modifier_color_encoding_is_sRGB(const png_modifier *pm) { return pm->current_encoding != 0 && pm->current_encoding == pm->encodings && pm->current_encoding->gamma == pm->current_gamma; } static int modifier_color_encoding_is_set(const png_modifier *pm) { return pm->current_gamma != 0; } /* The guts of modification are performed during a read. */ static void modifier_crc(png_bytep buffer) { /* Recalculate the chunk CRC - a complete chunk must be in * the buffer, at the start. */ uInt datalen = png_get_uint_32(buffer); uLong crc = crc32(0, buffer+4, datalen+4); /* The cast to png_uint_32 is safe because a crc32 is always a 32 bit value. */ png_save_uint_32(buffer+datalen+8, (png_uint_32)crc); } static void modifier_setbuffer(png_modifier *pm) { modifier_crc(pm->buffer); pm->buffer_count = png_get_uint_32(pm->buffer)+12; pm->buffer_position = 0; } /* Separate the callback into the actual implementation (which is passed the * png_modifier explicitly) and the callback, which gets the modifier from the * png_struct. */ static void modifier_read_imp(png_modifier *pm, png_bytep pb, size_t st) { while (st > 0) { size_t cb; png_uint_32 len, chunk; png_modification *mod; if (pm->buffer_position >= pm->buffer_count) switch (pm->state) { static png_byte sign[8] = { 137, 80, 78, 71, 13, 10, 26, 10 }; case modifier_start: store_read_chunk(&pm->this, pm->buffer, 8, 8); /* signature. */ pm->buffer_count = 8; pm->buffer_position = 0; if (memcmp(pm->buffer, sign, 8) != 0) png_error(pm->this.pread, "invalid PNG file signature"); pm->state = modifier_signature; break; case modifier_signature: store_read_chunk(&pm->this, pm->buffer, 13+12, 13+12); /* IHDR */ pm->buffer_count = 13+12; pm->buffer_position = 0; if (png_get_uint_32(pm->buffer) != 13 || png_get_uint_32(pm->buffer+4) != CHUNK_IHDR) png_error(pm->this.pread, "invalid IHDR"); /* Check the list of modifiers for modifications to the IHDR. */ mod = pm->modifications; while (mod != NULL) { if (mod->chunk == CHUNK_IHDR && mod->modify_fn && (*mod->modify_fn)(pm, mod, 0)) { mod->modified = 1; modifier_setbuffer(pm); } /* Ignore removal or add if IHDR! */ mod = mod->next; } /* Cache information from the IHDR (the modified one.) */ pm->bit_depth = pm->buffer[8+8]; pm->colour_type = pm->buffer[8+8+1]; pm->state = modifier_IHDR; pm->flush = 0; break; case modifier_IHDR: default: /* Read a new chunk and process it until we see PLTE, IDAT or * IEND. 'flush' indicates that there is still some data to * output from the preceding chunk. */ if ((cb = pm->flush) > 0) { if (cb > st) cb = st; pm->flush -= cb; store_read_chunk(&pm->this, pb, cb, cb); pb += cb; st -= cb; if (st == 0) return; } /* No more bytes to flush, read a header, or handle a pending * chunk. */ if (pm->pending_chunk != 0) { png_save_uint_32(pm->buffer, pm->pending_len); png_save_uint_32(pm->buffer+4, pm->pending_chunk); pm->pending_len = 0; pm->pending_chunk = 0; } else store_read_chunk(&pm->this, pm->buffer, 8, 8); pm->buffer_count = 8; pm->buffer_position = 0; /* Check for something to modify or a terminator chunk. */ len = png_get_uint_32(pm->buffer); chunk = png_get_uint_32(pm->buffer+4); /* Terminators first, they may have to be delayed for added * chunks */ if (chunk == CHUNK_PLTE || chunk == CHUNK_IDAT || chunk == CHUNK_IEND) { mod = pm->modifications; while (mod != NULL) { if ((mod->add == chunk || (mod->add == CHUNK_PLTE && chunk == CHUNK_IDAT)) && mod->modify_fn != NULL && !mod->modified && !mod->added) { /* Regardless of what the modify function does do not run * this again. */ mod->added = 1; if ((*mod->modify_fn)(pm, mod, 1 /*add*/)) { /* Reset the CRC on a new chunk */ if (pm->buffer_count > 0) modifier_setbuffer(pm); else { pm->buffer_position = 0; mod->removed = 1; } /* The buffer has been filled with something (we assume) * so output this. Pend the current chunk. */ pm->pending_len = len; pm->pending_chunk = chunk; break; /* out of while */ } } mod = mod->next; } /* Don't do any further processing if the buffer was modified - * otherwise the code will end up modifying a chunk that was * just added. */ if (mod != NULL) break; /* out of switch */ } /* If we get to here then this chunk may need to be modified. To * do this it must be less than 1024 bytes in total size, otherwise * it just gets flushed. */ if (len+12 <= sizeof pm->buffer) { size_t s = len+12-pm->buffer_count; store_read_chunk(&pm->this, pm->buffer+pm->buffer_count, s, s); pm->buffer_count = len+12; /* Check for a modification, else leave it be. */ mod = pm->modifications; while (mod != NULL) { if (mod->chunk == chunk) { if (mod->modify_fn == NULL) { /* Remove this chunk */ pm->buffer_count = pm->buffer_position = 0; mod->removed = 1; break; /* Terminate the while loop */ } else if ((*mod->modify_fn)(pm, mod, 0)) { mod->modified = 1; /* The chunk may have been removed: */ if (pm->buffer_count == 0) { pm->buffer_position = 0; break; } modifier_setbuffer(pm); } } mod = mod->next; } } else pm->flush = len+12 - pm->buffer_count; /* data + crc */ /* Take the data from the buffer (if there is any). */ break; } /* Here to read from the modifier buffer (not directly from * the store, as in the flush case above.) */ cb = pm->buffer_count - pm->buffer_position; if (cb > st) cb = st; memcpy(pb, pm->buffer + pm->buffer_position, cb); st -= cb; pb += cb; pm->buffer_position += cb; } } /* The callback: */ static void PNGCBAPI modifier_read(png_structp ppIn, png_bytep pb, size_t st) { png_const_structp pp = ppIn; png_modifier *pm = voidcast(png_modifier*, png_get_io_ptr(pp)); if (pm == NULL || pm->this.pread != pp) png_error(pp, "bad modifier_read call"); modifier_read_imp(pm, pb, st); } /* Like store_progressive_read but the data is getting changed as we go so we * need a local buffer. */ static void modifier_progressive_read(png_modifier *pm, png_structp pp, png_infop pi) { if (pm->this.pread != pp || pm->this.current == NULL || pm->this.next == NULL) png_error(pp, "store state damaged (progressive)"); /* This is another Horowitz and Hill random noise generator. In this case * the aim is to stress the progressive reader with truly horrible variable * buffer sizes in the range 1..500, so a sequence of 9 bit random numbers * is generated. We could probably just count from 1 to 32767 and get as * good a result. */ for (;;) { static png_uint_32 noise = 1; size_t cb, cbAvail; png_byte buffer[512]; /* Generate 15 more bits of stuff: */ noise = (noise << 9) | ((noise ^ (noise >> (9-5))) & 0x1ff); cb = noise & 0x1ff; /* Check that this number of bytes are available (in the current buffer.) * (This doesn't quite work - the modifier might delete a chunk; unlikely * but possible, it doesn't happen at present because the modifier only * adds chunks to standard images.) */ cbAvail = store_read_buffer_avail(&pm->this); if (pm->buffer_count > pm->buffer_position) cbAvail += pm->buffer_count - pm->buffer_position; if (cb > cbAvail) { /* Check for EOF: */ if (cbAvail == 0) break; cb = cbAvail; } modifier_read_imp(pm, buffer, cb); png_process_data(pp, pi, buffer, cb); } /* Check the invariants at the end (if this fails it's a problem in this * file!) */ if (pm->buffer_count > pm->buffer_position || pm->this.next != &pm->this.current->data || pm->this.readpos < pm->this.current->datacount) png_error(pp, "progressive read implementation error"); } /* Set up a modifier. */ static png_structp set_modifier_for_read(png_modifier *pm, png_infopp ppi, png_uint_32 id, const char *name) { /* Do this first so that the modifier fields are cleared even if an error * happens allocating the png_struct. No allocation is done here so no * cleanup is required. */ pm->state = modifier_start; pm->bit_depth = 0; pm->colour_type = 255; pm->pending_len = 0; pm->pending_chunk = 0; pm->flush = 0; pm->buffer_count = 0; pm->buffer_position = 0; return set_store_for_read(&pm->this, ppi, id, name); } /******************************** MODIFICATIONS *******************************/ /* Standard modifications to add chunks. These do not require the _SUPPORTED * macros because the chunks can be there regardless of whether this specific * libpng supports them. */ typedef struct gama_modification { png_modification this; png_fixed_point gamma; } gama_modification; static int gama_modify(png_modifier *pm, png_modification *me, int add) { UNUSED(add) /* This simply dumps the given gamma value into the buffer. */ png_save_uint_32(pm->buffer, 4); png_save_uint_32(pm->buffer+4, CHUNK_gAMA); png_save_uint_32(pm->buffer+8, ((gama_modification*)me)->gamma); return 1; } static void gama_modification_init(gama_modification *me, png_modifier *pm, double gammad) { double g; modification_init(&me->this); me->this.chunk = CHUNK_gAMA; me->this.modify_fn = gama_modify; me->this.add = CHUNK_PLTE; g = fix(gammad); me->gamma = (png_fixed_point)g; me->this.next = pm->modifications; pm->modifications = &me->this; } typedef struct chrm_modification { png_modification this; const color_encoding *encoding; png_fixed_point wx, wy, rx, ry, gx, gy, bx, by; } chrm_modification; static int chrm_modify(png_modifier *pm, png_modification *me, int add) { UNUSED(add) /* As with gAMA this just adds the required cHRM chunk to the buffer. */ png_save_uint_32(pm->buffer , 32); png_save_uint_32(pm->buffer+ 4, CHUNK_cHRM); png_save_uint_32(pm->buffer+ 8, ((chrm_modification*)me)->wx); png_save_uint_32(pm->buffer+12, ((chrm_modification*)me)->wy); png_save_uint_32(pm->buffer+16, ((chrm_modification*)me)->rx); png_save_uint_32(pm->buffer+20, ((chrm_modification*)me)->ry); png_save_uint_32(pm->buffer+24, ((chrm_modification*)me)->gx); png_save_uint_32(pm->buffer+28, ((chrm_modification*)me)->gy); png_save_uint_32(pm->buffer+32, ((chrm_modification*)me)->bx); png_save_uint_32(pm->buffer+36, ((chrm_modification*)me)->by); return 1; } static void chrm_modification_init(chrm_modification *me, png_modifier *pm, const color_encoding *encoding) { CIE_color white = white_point(encoding); /* Original end points: */ me->encoding = encoding; /* Chromaticities (in fixed point): */ me->wx = fix(chromaticity_x(white)); me->wy = fix(chromaticity_y(white)); me->rx = fix(chromaticity_x(encoding->red)); me->ry = fix(chromaticity_y(encoding->red)); me->gx = fix(chromaticity_x(encoding->green)); me->gy = fix(chromaticity_y(encoding->green)); me->bx = fix(chromaticity_x(encoding->blue)); me->by = fix(chromaticity_y(encoding->blue)); modification_init(&me->this); me->this.chunk = CHUNK_cHRM; me->this.modify_fn = chrm_modify; me->this.add = CHUNK_PLTE; me->this.next = pm->modifications; pm->modifications = &me->this; } typedef struct srgb_modification { png_modification this; png_byte intent; } srgb_modification; static int srgb_modify(png_modifier *pm, png_modification *me, int add) { UNUSED(add) /* As above, ignore add and just make a new chunk */ png_save_uint_32(pm->buffer, 1); png_save_uint_32(pm->buffer+4, CHUNK_sRGB); pm->buffer[8] = ((srgb_modification*)me)->intent; return 1; } static void srgb_modification_init(srgb_modification *me, png_modifier *pm, png_byte intent) { modification_init(&me->this); me->this.chunk = CHUNK_sBIT; if (intent <= 3) /* if valid, else *delete* sRGB chunks */ { me->this.modify_fn = srgb_modify; me->this.add = CHUNK_PLTE; me->intent = intent; } else { me->this.modify_fn = 0; me->this.add = 0; me->intent = 0; } me->this.next = pm->modifications; pm->modifications = &me->this; } #ifdef PNG_READ_GAMMA_SUPPORTED typedef struct sbit_modification { png_modification this; png_byte sbit; } sbit_modification; static int sbit_modify(png_modifier *pm, png_modification *me, int add) { png_byte sbit = ((sbit_modification*)me)->sbit; if (pm->bit_depth > sbit) { int cb = 0; switch (pm->colour_type) { case 0: cb = 1; break; case 2: case 3: cb = 3; break; case 4: cb = 2; break; case 6: cb = 4; break; default: png_error(pm->this.pread, "unexpected colour type in sBIT modification"); } png_save_uint_32(pm->buffer, cb); png_save_uint_32(pm->buffer+4, CHUNK_sBIT); while (cb > 0) (pm->buffer+8)[--cb] = sbit; return 1; } else if (!add) { /* Remove the sBIT chunk */ pm->buffer_count = pm->buffer_position = 0; return 1; } else return 0; /* do nothing */ } static void sbit_modification_init(sbit_modification *me, png_modifier *pm, png_byte sbit) { modification_init(&me->this); me->this.chunk = CHUNK_sBIT; me->this.modify_fn = sbit_modify; me->this.add = CHUNK_PLTE; me->sbit = sbit; me->this.next = pm->modifications; pm->modifications = &me->this; } #endif /* PNG_READ_GAMMA_SUPPORTED */ #endif /* PNG_READ_TRANSFORMS_SUPPORTED */ /***************************** STANDARD PNG FILES *****************************/ /* Standard files - write and save standard files. */ /* There are two basic forms of standard images. Those which attempt to have * all the possible pixel values (not possible for 16bpp images, but a range of * values are produced) and those which have a range of image sizes. The former * are used for testing transforms, in particular gamma correction and bit * reduction and increase. The latter are reserved for testing the behavior of * libpng with respect to 'odd' image sizes - particularly small images where * rows become 1 byte and interlace passes disappear. * * The first, most useful, set are the 'transform' images, the second set of * small images are the 'size' images. * * The transform files are constructed with rows which fit into a 1024 byte row * buffer. This makes allocation easier below. Further regardless of the file * format every row has 128 pixels (giving 1024 bytes for 64bpp formats). * * Files are stored with no gAMA or sBIT chunks, with a PLTE only when needed * and with an ID derived from the colour type, bit depth and interlace type * as above (FILEID). The width (128) and height (variable) are not stored in * the FILEID - instead the fields are set to 0, indicating a transform file. * * The size files ar constructed with rows a maximum of 128 bytes wide, allowing * a maximum width of 16 pixels (for the 64bpp case.) They also have a maximum * height of 16 rows. The width and height are stored in the FILEID and, being * non-zero, indicate a size file. * * Because the PNG filter code is typically the largest CPU consumer within * libpng itself there is a tendency to attempt to optimize it. This results in * special case code which needs to be validated. To cause this to happen the * 'size' images are made to use each possible filter, in so far as this is * possible for smaller images. * * For palette image (colour type 3) multiple transform images are stored with * the same bit depth to allow testing of more colour combinations - * particularly important for testing the gamma code because libpng uses a * different code path for palette images. For size images a single palette is * used. */ /* Make a 'standard' palette. Because there are only 256 entries in a palette * (maximum) this actually makes a random palette in the hope that enough tests * will catch enough errors. (Note that the same palette isn't produced every * time for the same test - it depends on what previous tests have been run - * but a given set of arguments to pngvalid will always produce the same palette * at the same test! This is why pseudo-random number generators are useful for * testing.) * * The store must be open for write when this is called, otherwise an internal * error will occur. This routine contains its own magic number seed, so the * palettes generated don't change if there are intervening errors (changing the * calls to the store_mark seed.) */ static store_palette_entry * make_standard_palette(png_store* ps, int npalette, int do_tRNS) { static png_uint_32 palette_seed[2] = { 0x87654321, 9 }; int i = 0; png_byte values[256][4]; /* Always put in black and white plus the six primary and secondary colors. */ for (; i<8; ++i) { values[i][1] = (png_byte)((i&1) ? 255U : 0U); values[i][2] = (png_byte)((i&2) ? 255U : 0U); values[i][3] = (png_byte)((i&4) ? 255U : 0U); } /* Then add 62 grays (one quarter of the remaining 256 slots). */ { int j = 0; png_byte random_bytes[4]; png_byte need[256]; need[0] = 0; /*got black*/ memset(need+1, 1, (sizeof need)-2); /*need these*/ need[255] = 0; /*but not white*/ while (i<70) { png_byte b; if (j==0) { make_four_random_bytes(palette_seed, random_bytes); j = 4; } b = random_bytes[--j]; if (need[b]) { values[i][1] = b; values[i][2] = b; values[i++][3] = b; } } } /* Finally add 192 colors at random - don't worry about matches to things we * already have, chance is less than 1/65536. Don't worry about grays, * chance is the same, so we get a duplicate or extra gray less than 1 time * in 170. */ for (; i<256; ++i) make_four_random_bytes(palette_seed, values[i]); /* Fill in the alpha values in the first byte. Just use all possible values * (0..255) in an apparently random order: */ { store_palette_entry *palette; png_byte selector[4]; make_four_random_bytes(palette_seed, selector); if (do_tRNS) for (i=0; i<256; ++i) values[i][0] = (png_byte)(i ^ selector[0]); else for (i=0; i<256; ++i) values[i][0] = 255; /* no transparency/tRNS chunk */ /* 'values' contains 256 ARGB values, but we only need 'npalette'. * 'npalette' will always be a power of 2: 2, 4, 16 or 256. In the low * bit depth cases select colors at random, else it is difficult to have * a set of low bit depth palette test with any chance of a reasonable * range of colors. Do this by randomly permuting values into the low * 'npalette' entries using an XOR mask generated here. This also * permutes the npalette == 256 case in a potentially useful way (there is * no relationship between palette index and the color value therein!) */ palette = store_write_palette(ps, npalette); for (i=0; i 0) png_set_tRNS(pp, pi, tRNS, j, 0/*color*/); #endif } } #ifdef PNG_WRITE_tRNS_SUPPORTED static void set_random_tRNS(png_structp pp, png_infop pi, png_byte colour_type, int bit_depth) { /* To make this useful the tRNS color needs to match at least one pixel. * Random values are fine for gray, including the 16-bit case where we know * that the test image contains all the gray values. For RGB we need more * method as only 65536 different RGB values are generated. */ png_color_16 tRNS; png_uint_16 mask = (png_uint_16)((1U << bit_depth)-1); R8(tRNS); /* makes unset fields random */ if (colour_type & 2/*RGB*/) { if (bit_depth == 8) { tRNS.red = random_u16(); tRNS.green = random_u16(); tRNS.blue = tRNS.red ^ tRNS.green; tRNS.red &= mask; tRNS.green &= mask; tRNS.blue &= mask; } else /* bit_depth == 16 */ { tRNS.red = random_u16(); tRNS.green = (png_uint_16)(tRNS.red * 257); tRNS.blue = (png_uint_16)(tRNS.green * 17); } } else { tRNS.gray = random_u16(); tRNS.gray &= mask; } png_set_tRNS(pp, pi, NULL, 0, &tRNS); } #endif /* The number of passes is related to the interlace type. There was no libpng * API to determine this prior to 1.5, so we need an inquiry function: */ static int npasses_from_interlace_type(png_const_structp pp, int interlace_type) { switch (interlace_type) { default: png_error(pp, "invalid interlace type"); case PNG_INTERLACE_NONE: return 1; case PNG_INTERLACE_ADAM7: return PNG_INTERLACE_ADAM7_PASSES; } } static unsigned int bit_size(png_const_structp pp, png_byte colour_type, png_byte bit_depth) { switch (colour_type) { default: png_error(pp, "invalid color type"); case 0: return bit_depth; case 2: return 3*bit_depth; case 3: return bit_depth; case 4: return 2*bit_depth; case 6: return 4*bit_depth; } } #define TRANSFORM_WIDTH 128U #define TRANSFORM_ROWMAX (TRANSFORM_WIDTH*8U) #define SIZE_ROWMAX (16*8U) /* 16 pixels, max 8 bytes each - 128 bytes */ #define STANDARD_ROWMAX TRANSFORM_ROWMAX /* The larger of the two */ #define SIZE_HEIGHTMAX 16 /* Maximum range of size images */ static size_t transform_rowsize(png_const_structp pp, png_byte colour_type, png_byte bit_depth) { return (TRANSFORM_WIDTH * bit_size(pp, colour_type, bit_depth)) / 8; } /* transform_width(pp, colour_type, bit_depth) current returns the same number * every time, so just use a macro: */ #define transform_width(pp, colour_type, bit_depth) TRANSFORM_WIDTH static png_uint_32 transform_height(png_const_structp pp, png_byte colour_type, png_byte bit_depth) { switch (bit_size(pp, colour_type, bit_depth)) { case 1: case 2: case 4: return 1; /* Total of 128 pixels */ case 8: return 2; /* Total of 256 pixels/bytes */ case 16: return 512; /* Total of 65536 pixels */ case 24: case 32: return 512; /* 65536 pixels */ case 48: case 64: return 2048;/* 4 x 65536 pixels. */ # define TRANSFORM_HEIGHTMAX 2048 default: return 0; /* Error, will be caught later */ } } #ifdef PNG_READ_SUPPORTED /* The following can only be defined here, now we have the definitions * of the transform image sizes. */ static png_uint_32 standard_width(png_const_structp pp, png_uint_32 id) { png_uint_32 width = WIDTH_FROM_ID(id); UNUSED(pp) if (width == 0) width = transform_width(pp, COL_FROM_ID(id), DEPTH_FROM_ID(id)); return width; } static png_uint_32 standard_height(png_const_structp pp, png_uint_32 id) { png_uint_32 height = HEIGHT_FROM_ID(id); if (height == 0) height = transform_height(pp, COL_FROM_ID(id), DEPTH_FROM_ID(id)); return height; } static png_uint_32 standard_rowsize(png_const_structp pp, png_uint_32 id) { png_uint_32 width = standard_width(pp, id); /* This won't overflow: */ width *= bit_size(pp, COL_FROM_ID(id), DEPTH_FROM_ID(id)); return (width + 7) / 8; } #endif /* PNG_READ_SUPPORTED */ static void transform_row(png_const_structp pp, png_byte buffer[TRANSFORM_ROWMAX], png_byte colour_type, png_byte bit_depth, png_uint_32 y) { png_uint_32 v = y << 7; png_uint_32 i = 0; switch (bit_size(pp, colour_type, bit_depth)) { case 1: while (i<128/8) buffer[i] = (png_byte)(v & 0xff), v += 17, ++i; return; case 2: while (i<128/4) buffer[i] = (png_byte)(v & 0xff), v += 33, ++i; return; case 4: while (i<128/2) buffer[i] = (png_byte)(v & 0xff), v += 65, ++i; return; case 8: /* 256 bytes total, 128 bytes in each row set as follows: */ while (i<128) buffer[i] = (png_byte)(v & 0xff), ++v, ++i; return; case 16: /* Generate all 65536 pixel values in order, which includes the 8 bit * GA case as well as the 16 bit G case. */ while (i<128) { buffer[2*i] = (png_byte)((v>>8) & 0xff); buffer[2*i+1] = (png_byte)(v & 0xff); ++v; ++i; } return; case 24: /* 65535 pixels, but rotate the values. */ while (i<128) { /* Three bytes per pixel, r, g, b, make b by r^g */ buffer[3*i+0] = (png_byte)((v >> 8) & 0xff); buffer[3*i+1] = (png_byte)(v & 0xff); buffer[3*i+2] = (png_byte)(((v >> 8) ^ v) & 0xff); ++v; ++i; } return; case 32: /* 65535 pixels, r, g, b, a; just replicate */ while (i<128) { buffer[4*i+0] = (png_byte)((v >> 8) & 0xff); buffer[4*i+1] = (png_byte)(v & 0xff); buffer[4*i+2] = (png_byte)((v >> 8) & 0xff); buffer[4*i+3] = (png_byte)(v & 0xff); ++v; ++i; } return; case 48: /* y is maximum 2047, giving 4x65536 pixels, make 'r' increase by 1 at * each pixel, g increase by 257 (0x101) and 'b' by 0x1111: */ while (i<128) { png_uint_32 t = v++; buffer[6*i+0] = (png_byte)((t >> 8) & 0xff); buffer[6*i+1] = (png_byte)(t & 0xff); t *= 257; buffer[6*i+2] = (png_byte)((t >> 8) & 0xff); buffer[6*i+3] = (png_byte)(t & 0xff); t *= 17; buffer[6*i+4] = (png_byte)((t >> 8) & 0xff); buffer[6*i+5] = (png_byte)(t & 0xff); ++i; } return; case 64: /* As above in the 32 bit case. */ while (i<128) { png_uint_32 t = v++; buffer[8*i+0] = (png_byte)((t >> 8) & 0xff); buffer[8*i+1] = (png_byte)(t & 0xff); buffer[8*i+4] = (png_byte)((t >> 8) & 0xff); buffer[8*i+5] = (png_byte)(t & 0xff); t *= 257; buffer[8*i+2] = (png_byte)((t >> 8) & 0xff); buffer[8*i+3] = (png_byte)(t & 0xff); buffer[8*i+6] = (png_byte)((t >> 8) & 0xff); buffer[8*i+7] = (png_byte)(t & 0xff); ++i; } return; default: break; } png_error(pp, "internal error"); } /* This is just to do the right cast - could be changed to a function to check * 'bd' but there isn't much point. */ #define DEPTH(bd) ((png_byte)(1U << (bd))) /* This is just a helper for compiling on minimal systems with no write * interlacing support. If there is no write interlacing we can't generate test * cases with interlace: */ #ifdef PNG_WRITE_INTERLACING_SUPPORTED # define INTERLACE_LAST PNG_INTERLACE_LAST # define check_interlace_type(type) ((void)(type)) # define set_write_interlace_handling(pp,type) png_set_interlace_handling(pp) # define do_own_interlace 0 #elif PNG_LIBPNG_VER < 10700 # define set_write_interlace_handling(pp,type) (1) static void check_interlace_type(int const interlace_type) { /* Prior to 1.7.0 libpng does not support the write of an interlaced image * unless PNG_WRITE_INTERLACING_SUPPORTED, even with do_interlace so the * code here does the pixel interlace itself, so: */ if (interlace_type != PNG_INTERLACE_NONE) { /* This is an internal error - --interlace tests should be skipped, not * attempted. */ fprintf(stderr, "pngvalid: no interlace support\n"); exit(99); } } # define INTERLACE_LAST (PNG_INTERLACE_NONE+1) # define do_own_interlace 0 #else /* libpng 1.7+ */ # define set_write_interlace_handling(pp,type)\ npasses_from_interlace_type(pp,type) # define check_interlace_type(type) ((void)(type)) # define INTERLACE_LAST PNG_INTERLACE_LAST # define do_own_interlace 1 #endif /* WRITE_INTERLACING tests */ #if PNG_LIBPNG_VER >= 10700 || defined PNG_WRITE_INTERLACING_SUPPORTED # define CAN_WRITE_INTERLACE 1 #else # define CAN_WRITE_INTERLACE 0 #endif /* Do the same thing for read interlacing; this controls whether read tests do * their own de-interlace or use libpng. */ #ifdef PNG_READ_INTERLACING_SUPPORTED # define do_read_interlace 0 #else /* no libpng read interlace support */ # define do_read_interlace 1 #endif /* The following two routines use the PNG interlace support macros from * png.h to interlace or deinterlace rows. */ static void interlace_row(png_bytep buffer, png_const_bytep imageRow, unsigned int pixel_size, png_uint_32 w, int pass, int littleendian) { png_uint_32 xin, xout, xstep; /* Note that this can, trivially, be optimized to a memcpy on pass 7, the * code is presented this way to make it easier to understand. In practice * consult the code in the libpng source to see other ways of doing this. * * It is OK for buffer and imageRow to be identical, because 'xin' moves * faster than 'xout' and we copy up. */ xin = PNG_PASS_START_COL(pass); xstep = 1U<wname); text.text = copy; text.text_length = pos; text.itxt_length = 0; text.lang = 0; text.lang_key = 0; png_set_text(pp, pi, &text, 1); } #endif if (colour_type == 3) /* palette */ init_standard_palette(ps, pp, pi, 1U << bit_depth, 1/*do tRNS*/); # ifdef PNG_WRITE_tRNS_SUPPORTED else if (palette_number) set_random_tRNS(pp, pi, colour_type, bit_depth); # endif png_write_info(pp, pi); if (png_get_rowbytes(pp, pi) != transform_rowsize(pp, colour_type, bit_depth)) png_error(pp, "transform row size incorrect"); else { /* Somewhat confusingly this must be called *after* png_write_info * because if it is called before, the information in *pp has not been * updated to reflect the interlaced image. */ int npasses = set_write_interlace_handling(pp, interlace_type); int pass; if (npasses != npasses_from_interlace_type(pp, interlace_type)) png_error(pp, "write: png_set_interlace_handling failed"); for (pass=0; pass 0) interlace_row(buffer, buffer, bit_size(pp, colour_type, bit_depth), w, pass, 0/*data always bigendian*/); else continue; } # endif /* do_own_interlace */ choose_random_filter(pp, pass == 0 && y == 0); png_write_row(pp, buffer); } } } #ifdef PNG_TEXT_SUPPORTED { static char key[] = "end marker"; static char comment[] = "end"; png_text text; /* Use a compressed text string to test the correct interaction of text * compression and IDAT compression. */ text.compression = TEXT_COMPRESSION; text.key = key; text.text = comment; text.text_length = (sizeof comment)-1; text.itxt_length = 0; text.lang = 0; text.lang_key = 0; png_set_text(pp, pi, &text, 1); } #endif png_write_end(pp, pi); /* And store this under the appropriate id, then clean up. */ store_storefile(ps, FILEID(colour_type, bit_depth, palette_number, interlace_type, 0, 0, 0)); store_write_reset(ps); } Catch(fault) { /* Use the png_store returned by the exception. This may help the compiler * because 'ps' is not used in this branch of the setjmp. Note that fault * and ps will always be the same value. */ store_write_reset(fault); } } static void make_transform_images(png_modifier *pm) { png_byte colour_type = 0; png_byte bit_depth = 0; unsigned int palette_number = 0; /* This is in case of errors. */ safecat(pm->this.test, sizeof pm->this.test, 0, "make standard images"); /* Use next_format to enumerate all the combinations we test, including * generating multiple low bit depth palette images. Non-A images (palette * and direct) are created with and without tRNS chunks. */ while (next_format(&colour_type, &bit_depth, &palette_number, 1, 1)) { int interlace_type; for (interlace_type = PNG_INTERLACE_NONE; interlace_type < INTERLACE_LAST; ++interlace_type) { char name[FILE_NAME_SIZE]; standard_name(name, sizeof name, 0, colour_type, bit_depth, palette_number, interlace_type, 0, 0, do_own_interlace); make_transform_image(&pm->this, colour_type, bit_depth, palette_number, interlace_type, name); } } } /* Build a single row for the 'size' test images; this fills in only the * first bit_width bits of the sample row. */ static void size_row(png_byte buffer[SIZE_ROWMAX], png_uint_32 bit_width, png_uint_32 y) { /* height is in the range 1 to 16, so: */ y = ((y & 1) << 7) + ((y & 2) << 6) + ((y & 4) << 5) + ((y & 8) << 4); /* the following ensures bits are set in small images: */ y ^= 0xA5; while (bit_width >= 8) *buffer++ = (png_byte)y++, bit_width -= 8; /* There may be up to 7 remaining bits, these go in the most significant * bits of the byte. */ if (bit_width > 0) { png_uint_32 mask = (1U<<(8-bit_width))-1; *buffer = (png_byte)((*buffer & mask) | (y & ~mask)); } } static void make_size_image(png_store* const ps, png_byte const colour_type, png_byte const bit_depth, int const interlace_type, png_uint_32 const w, png_uint_32 const h, int const do_interlace) { context(ps, fault); check_interlace_type(interlace_type); Try { png_infop pi; png_structp pp; unsigned int pixel_size; /* Make a name and get an appropriate id for the store: */ char name[FILE_NAME_SIZE]; png_uint_32 id = FILEID(colour_type, bit_depth, 0/*palette*/, interlace_type, w, h, do_interlace); standard_name_from_id(name, sizeof name, 0, id); pp = set_store_for_write(ps, &pi, name); /* In the event of a problem return control to the Catch statement below * to do the clean up - it is not possible to 'return' directly from a Try * block. */ if (pp == NULL) Throw ps; png_set_IHDR(pp, pi, w, h, bit_depth, colour_type, interlace_type, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); #ifdef PNG_TEXT_SUPPORTED { static char key[] = "image name"; /* must be writeable */ size_t pos; png_text text; char copy[FILE_NAME_SIZE]; /* Use a compressed text string to test the correct interaction of text * compression and IDAT compression. */ text.compression = TEXT_COMPRESSION; text.key = key; /* Yuck: the text must be writable! */ pos = safecat(copy, sizeof copy, 0, ps->wname); text.text = copy; text.text_length = pos; text.itxt_length = 0; text.lang = 0; text.lang_key = 0; png_set_text(pp, pi, &text, 1); } #endif if (colour_type == 3) /* palette */ init_standard_palette(ps, pp, pi, 1U << bit_depth, 0/*do tRNS*/); png_write_info(pp, pi); /* Calculate the bit size, divide by 8 to get the byte size - this won't * overflow because we know the w values are all small enough even for * a system where 'unsigned int' is only 16 bits. */ pixel_size = bit_size(pp, colour_type, bit_depth); if (png_get_rowbytes(pp, pi) != ((w * pixel_size) + 7) / 8) png_error(pp, "size row size incorrect"); else { int npasses = npasses_from_interlace_type(pp, interlace_type); png_uint_32 y; int pass; png_byte image[16][SIZE_ROWMAX]; /* To help consistent error detection make the parts of this buffer * that aren't set below all '1': */ memset(image, 0xff, sizeof image); if (!do_interlace && npasses != set_write_interlace_handling(pp, interlace_type)) png_error(pp, "write: png_set_interlace_handling failed"); /* Prepare the whole image first to avoid making it 7 times: */ for (y=0; y 0) { /* Set to all 1's for error detection (libpng tends to * set unset things to 0). */ memset(tempRow, 0xff, sizeof tempRow); interlace_row(tempRow, row, pixel_size, w, pass, 0/*data always bigendian*/); row = tempRow; } else continue; } # ifdef PNG_WRITE_FILTER_SUPPORTED /* Only get to here if the row has some pixels in it, set the * filters to 'all' for the very first row and thereafter to a * single filter. It isn't well documented, but png_set_filter * does accept a filter number (per the spec) as well as a bit * mask. * * The code now uses filters at random, except that on the first * row of an image it ensures that a previous row filter is in * the set so that libpng allocates the row buffer. */ { int filters = 8 << random_mod(PNG_FILTER_VALUE_LAST); if (pass == 0 && y == 0 && (filters < PNG_FILTER_UP || w == 1U)) filters |= PNG_FILTER_UP; png_set_filter(pp, 0/*method*/, filters); } # endif png_write_row(pp, row); } } } #ifdef PNG_TEXT_SUPPORTED { static char key[] = "end marker"; static char comment[] = "end"; png_text text; /* Use a compressed text string to test the correct interaction of text * compression and IDAT compression. */ text.compression = TEXT_COMPRESSION; text.key = key; text.text = comment; text.text_length = (sizeof comment)-1; text.itxt_length = 0; text.lang = 0; text.lang_key = 0; png_set_text(pp, pi, &text, 1); } #endif png_write_end(pp, pi); /* And store this under the appropriate id, then clean up. */ store_storefile(ps, id); store_write_reset(ps); } Catch(fault) { /* Use the png_store returned by the exception. This may help the compiler * because 'ps' is not used in this branch of the setjmp. Note that fault * and ps will always be the same value. */ store_write_reset(fault); } } static void make_size(png_store* const ps, png_byte const colour_type, int bdlo, int const bdhi) { for (; bdlo <= bdhi; ++bdlo) { png_uint_32 width; for (width = 1; width <= 16; ++width) { png_uint_32 height; for (height = 1; height <= 16; ++height) { /* The four combinations of DIY interlace and interlace or not - * no interlace + DIY should be identical to no interlace with * libpng doing it. */ make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_NONE, width, height, 0); make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_NONE, width, height, 1); # ifdef PNG_WRITE_INTERLACING_SUPPORTED make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_ADAM7, width, height, 0); # endif # if CAN_WRITE_INTERLACE /* 1.7.0 removes the hack that prevented app write of an interlaced * image if WRITE_INTERLACE was not supported */ make_size_image(ps, colour_type, DEPTH(bdlo), PNG_INTERLACE_ADAM7, width, height, 1); # endif } } } } static void make_size_images(png_store *ps) { /* This is in case of errors. */ safecat(ps->test, sizeof ps->test, 0, "make size images"); /* Arguments are colour_type, low bit depth, high bit depth */ make_size(ps, 0, 0, WRITE_BDHI); make_size(ps, 2, 3, WRITE_BDHI); make_size(ps, 3, 0, 3 /*palette: max 8 bits*/); make_size(ps, 4, 3, WRITE_BDHI); make_size(ps, 6, 3, WRITE_BDHI); } #ifdef PNG_READ_SUPPORTED /* Return a row based on image id and 'y' for checking: */ static void standard_row(png_const_structp pp, png_byte std[STANDARD_ROWMAX], png_uint_32 id, png_uint_32 y) { if (WIDTH_FROM_ID(id) == 0) transform_row(pp, std, COL_FROM_ID(id), DEPTH_FROM_ID(id), y); else size_row(std, WIDTH_FROM_ID(id) * bit_size(pp, COL_FROM_ID(id), DEPTH_FROM_ID(id)), y); } #endif /* PNG_READ_SUPPORTED */ /* Tests - individual test cases */ /* Like 'make_standard' but errors are deliberately introduced into the calls * to ensure that they get detected - it should not be possible to write an * invalid image with libpng! */ /* TODO: the 'set' functions can probably all be made to take a * png_const_structp rather than a modifiable one. */ #ifdef PNG_WARNINGS_SUPPORTED static void sBIT0_error_fn(png_structp pp, png_infop pi) { /* 0 is invalid... */ png_color_8 bad; bad.red = bad.green = bad.blue = bad.gray = bad.alpha = 0; png_set_sBIT(pp, pi, &bad); } static void sBIT_error_fn(png_structp pp, png_infop pi) { png_byte bit_depth; png_color_8 bad; if (png_get_color_type(pp, pi) == PNG_COLOR_TYPE_PALETTE) bit_depth = 8; else bit_depth = png_get_bit_depth(pp, pi); /* Now we know the bit depth we can easily generate an invalid sBIT entry */ bad.red = bad.green = bad.blue = bad.gray = bad.alpha = (png_byte)(bit_depth+1); png_set_sBIT(pp, pi, &bad); } static const struct { void (*fn)(png_structp, png_infop); const char *msg; unsigned int warning :1; /* the error is a warning... */ } error_test[] = { /* no warnings makes these errors undetectable prior to 1.7.0 */ { sBIT0_error_fn, "sBIT(0): failed to detect error", PNG_LIBPNG_VER < 10700 }, { sBIT_error_fn, "sBIT(too big): failed to detect error", PNG_LIBPNG_VER < 10700 }, }; static void make_error(png_store* const ps, png_byte const colour_type, png_byte bit_depth, int interlace_type, int test, png_const_charp name) { context(ps, fault); check_interlace_type(interlace_type); Try { png_infop pi; png_structp pp = set_store_for_write(ps, &pi, name); png_uint_32 w, h; gnu_volatile(pp) if (pp == NULL) Throw ps; w = transform_width(pp, colour_type, bit_depth); gnu_volatile(w) h = transform_height(pp, colour_type, bit_depth); gnu_volatile(h) png_set_IHDR(pp, pi, w, h, bit_depth, colour_type, interlace_type, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); if (colour_type == 3) /* palette */ init_standard_palette(ps, pp, pi, 1U << bit_depth, 0/*do tRNS*/); /* Time for a few errors; these are in various optional chunks, the * standard tests test the standard chunks pretty well. */ # define exception__prev exception_prev_1 # define exception__env exception_env_1 Try { gnu_volatile(exception__prev) /* Expect this to throw: */ ps->expect_error = !error_test[test].warning; ps->expect_warning = error_test[test].warning; ps->saw_warning = 0; error_test[test].fn(pp, pi); /* Normally the error is only detected here: */ png_write_info(pp, pi); /* And handle the case where it was only a warning: */ if (ps->expect_warning && ps->saw_warning) Throw ps; /* If we get here there is a problem, we have success - no error or * no warning - when we shouldn't have success. Log an error. */ store_log(ps, pp, error_test[test].msg, 1 /*error*/); } Catch (fault) { /* expected exit */ } #undef exception__prev #undef exception__env /* And clear these flags */ ps->expect_warning = 0; if (ps->expect_error) ps->expect_error = 0; else { /* Now write the whole image, just to make sure that the detected, or * undetected, error has not created problems inside libpng. This * doesn't work if there was a png_error in png_write_info because that * can abort before PLTE was written. */ if (png_get_rowbytes(pp, pi) != transform_rowsize(pp, colour_type, bit_depth)) png_error(pp, "row size incorrect"); else { int npasses = set_write_interlace_handling(pp, interlace_type); int pass; if (npasses != npasses_from_interlace_type(pp, interlace_type)) png_error(pp, "write: png_set_interlace_handling failed"); for (pass=0; pass 0) interlace_row(buffer, buffer, bit_size(pp, colour_type, bit_depth), w, pass, 0/*data always bigendian*/); else continue; } # endif /* do_own_interlace */ png_write_row(pp, buffer); } } } /* image writing */ png_write_end(pp, pi); } /* The following deletes the file that was just written. */ store_write_reset(ps); } Catch(fault) { store_write_reset(fault); } } static int make_errors(png_modifier* const pm, png_byte const colour_type, int bdlo, int const bdhi) { for (; bdlo <= bdhi; ++bdlo) { int interlace_type; for (interlace_type = PNG_INTERLACE_NONE; interlace_type < INTERLACE_LAST; ++interlace_type) { unsigned int test; char name[FILE_NAME_SIZE]; standard_name(name, sizeof name, 0, colour_type, 1<this, colour_type, DEPTH(bdlo), interlace_type, test, name); if (fail(pm)) return 0; } } } return 1; /* keep going */ } #endif /* PNG_WARNINGS_SUPPORTED */ static void perform_error_test(png_modifier *pm) { #ifdef PNG_WARNINGS_SUPPORTED /* else there are no cases that work! */ /* Need to do this here because we just write in this test. */ safecat(pm->this.test, sizeof pm->this.test, 0, "error test"); if (!make_errors(pm, 0, 0, WRITE_BDHI)) return; if (!make_errors(pm, 2, 3, WRITE_BDHI)) return; if (!make_errors(pm, 3, 0, 3)) return; if (!make_errors(pm, 4, 3, WRITE_BDHI)) return; if (!make_errors(pm, 6, 3, WRITE_BDHI)) return; #else UNUSED(pm) #endif } /* This is just to validate the internal PNG formatting code - if this fails * then the warning messages the library outputs will probably be garbage. */ static void perform_formatting_test(png_store *ps) { #ifdef PNG_TIME_RFC1123_SUPPORTED /* The handle into the formatting code is the RFC1123 support; this test does * nothing if that is compiled out. */ context(ps, fault); Try { png_const_charp correct = "29 Aug 2079 13:53:60 +0000"; png_const_charp result; # if PNG_LIBPNG_VER >= 10600 char timestring[29]; # endif png_structp pp; png_time pt; pp = set_store_for_write(ps, NULL, "libpng formatting test"); if (pp == NULL) Throw ps; /* Arbitrary settings: */ pt.year = 2079; pt.month = 8; pt.day = 29; pt.hour = 13; pt.minute = 53; pt.second = 60; /* a leap second */ # if PNG_LIBPNG_VER < 10600 result = png_convert_to_rfc1123(pp, &pt); # else if (png_convert_to_rfc1123_buffer(timestring, &pt)) result = timestring; else result = NULL; # endif if (result == NULL) png_error(pp, "png_convert_to_rfc1123 failed"); if (strcmp(result, correct) != 0) { size_t pos = 0; char msg[128]; pos = safecat(msg, sizeof msg, pos, "png_convert_to_rfc1123("); pos = safecat(msg, sizeof msg, pos, correct); pos = safecat(msg, sizeof msg, pos, ") returned: '"); pos = safecat(msg, sizeof msg, pos, result); pos = safecat(msg, sizeof msg, pos, "'"); png_error(pp, msg); } store_write_reset(ps); } Catch(fault) { store_write_reset(fault); } #else UNUSED(ps) #endif } #ifdef PNG_READ_SUPPORTED /* Because we want to use the same code in both the progressive reader and the * sequential reader it is necessary to deal with the fact that the progressive * reader callbacks only have one parameter (png_get_progressive_ptr()), so this * must contain all the test parameters and all the local variables directly * accessible to the sequential reader implementation. * * The technique adopted is to reinvent part of what Dijkstra termed a * 'display'; an array of pointers to the stack frames of enclosing functions so * that a nested function definition can access the local (C auto) variables of * the functions that contain its definition. In fact C provides the first * pointer (the local variables - the stack frame pointer) and the last (the * global variables - the BCPL global vector typically implemented as global * addresses), this code requires one more pointer to make the display - the * local variables (and function call parameters) of the function that actually * invokes either the progressive or sequential reader. * * Perhaps confusingly this technique is confounded with classes - the * 'standard_display' defined here is sub-classed as the 'gamma_display' below. * A gamma_display is a standard_display, taking advantage of the ANSI-C * requirement that the pointer to the first member of a structure must be the * same as the pointer to the structure. This allows us to reuse standard_ * functions in the gamma test code; something that could not be done with * nested functions! */ typedef struct standard_display { png_store* ps; /* Test parameters (passed to the function) */ png_byte colour_type; png_byte bit_depth; png_byte red_sBIT; /* Input data sBIT values. */ png_byte green_sBIT; png_byte blue_sBIT; png_byte alpha_sBIT; png_byte interlace_type; png_byte filler; /* Output has a filler */ png_uint_32 id; /* Calculated file ID */ png_uint_32 w; /* Width of image */ png_uint_32 h; /* Height of image */ int npasses; /* Number of interlaced passes */ png_uint_32 pixel_size; /* Width of one pixel in bits */ png_uint_32 bit_width; /* Width of output row in bits */ size_t cbRow; /* Bytes in a row of the output image */ int do_interlace; /* Do interlacing internally */ int littleendian; /* App (row) data is little endian */ int is_transparent; /* Transparency information was present. */ int has_tRNS; /* color type GRAY or RGB with a tRNS chunk. */ int speed; /* Doing a speed test */ int use_update_info;/* Call update_info, not start_image */ struct { png_uint_16 red; png_uint_16 green; png_uint_16 blue; } transparent; /* The transparent color, if set. */ int npalette; /* Number of entries in the palette. */ store_palette palette; } standard_display; static void standard_display_init(standard_display *dp, png_store* ps, png_uint_32 id, int do_interlace, int use_update_info) { memset(dp, 0, sizeof *dp); dp->ps = ps; dp->colour_type = COL_FROM_ID(id); dp->bit_depth = DEPTH_FROM_ID(id); if (dp->bit_depth < 1 || dp->bit_depth > 16) internal_error(ps, "internal: bad bit depth"); if (dp->colour_type == 3) dp->red_sBIT = dp->blue_sBIT = dp->green_sBIT = dp->alpha_sBIT = 8; else dp->red_sBIT = dp->blue_sBIT = dp->green_sBIT = dp->alpha_sBIT = dp->bit_depth; dp->interlace_type = INTERLACE_FROM_ID(id); check_interlace_type(dp->interlace_type); dp->id = id; /* All the rest are filled in after the read_info: */ dp->w = 0; dp->h = 0; dp->npasses = 0; dp->pixel_size = 0; dp->bit_width = 0; dp->cbRow = 0; dp->do_interlace = do_interlace; dp->littleendian = 0; dp->is_transparent = 0; dp->speed = ps->speed; dp->use_update_info = use_update_info; dp->npalette = 0; /* Preset the transparent color to black: */ memset(&dp->transparent, 0, sizeof dp->transparent); /* Preset the palette to full intensity/opaque throughout: */ memset(dp->palette, 0xff, sizeof dp->palette); } /* Initialize the palette fields - this must be done later because the palette * comes from the particular png_store_file that is selected. */ static void standard_palette_init(standard_display *dp) { store_palette_entry *palette = store_current_palette(dp->ps, &dp->npalette); /* The remaining entries remain white/opaque. */ if (dp->npalette > 0) { int i = dp->npalette; memcpy(dp->palette, palette, i * sizeof *palette); /* Check for a non-opaque palette entry: */ while (--i >= 0) if (palette[i].alpha < 255) break; # ifdef __GNUC__ /* GCC can't handle the more obviously optimizable version. */ if (i >= 0) dp->is_transparent = 1; else dp->is_transparent = 0; # else dp->is_transparent = (i >= 0); # endif } } /* Utility to read the palette from the PNG file and convert it into * store_palette format. This returns 1 if there is any transparency in the * palette (it does not check for a transparent colour in the non-palette case.) */ static int read_palette(store_palette palette, int *npalette, png_const_structp pp, png_infop pi) { png_colorp pal; png_bytep trans_alpha; int num; pal = 0; *npalette = -1; if (png_get_PLTE(pp, pi, &pal, npalette) & PNG_INFO_PLTE) { int i = *npalette; if (i <= 0 || i > 256) png_error(pp, "validate: invalid PLTE count"); while (--i >= 0) { palette[i].red = pal[i].red; palette[i].green = pal[i].green; palette[i].blue = pal[i].blue; } /* Mark the remainder of the entries with a flag value (other than * white/opaque which is the flag value stored above.) */ memset(palette + *npalette, 126, (256-*npalette) * sizeof *palette); } else /* !png_get_PLTE */ { if (*npalette != (-1)) png_error(pp, "validate: invalid PLTE result"); /* But there is no palette, so record this: */ *npalette = 0; memset(palette, 113, sizeof (store_palette)); } trans_alpha = 0; num = 2; /* force error below */ if ((png_get_tRNS(pp, pi, &trans_alpha, &num, 0) & PNG_INFO_tRNS) != 0 && (trans_alpha != NULL || num != 1/*returns 1 for a transparent color*/) && /* Oops, if a palette tRNS gets expanded png_read_update_info (at least so * far as 1.5.4) does not remove the trans_alpha pointer, only num_trans, * so in the above call we get a success, we get a pointer (who knows what * to) and we get num_trans == 0: */ !(trans_alpha != NULL && num == 0)) /* TODO: fix this in libpng. */ { int i; /* Any of these are crash-worthy - given the implementation of * png_get_tRNS up to 1.5 an app won't crash if it just checks the * result above and fails to check that the variables it passed have * actually been filled in! Note that if the app were to pass the * last, png_color_16p, variable too it couldn't rely on this. */ if (trans_alpha == NULL || num <= 0 || num > 256 || num > *npalette) png_error(pp, "validate: unexpected png_get_tRNS (palette) result"); for (i=0; iis_transparent) png_error(pp, "validate: palette transparency changed"); if (npalette != dp->npalette) { size_t pos = 0; char msg[64]; pos = safecat(msg, sizeof msg, pos, "validate: palette size changed: "); pos = safecatn(msg, sizeof msg, pos, dp->npalette); pos = safecat(msg, sizeof msg, pos, " -> "); pos = safecatn(msg, sizeof msg, pos, npalette); png_error(pp, msg); } { int i = npalette; /* npalette is aliased */ while (--i >= 0) if (palette[i].red != dp->palette[i].red || palette[i].green != dp->palette[i].green || palette[i].blue != dp->palette[i].blue || palette[i].alpha != dp->palette[i].alpha) png_error(pp, "validate: PLTE or tRNS chunk changed"); } } /* By passing a 'standard_display' the progressive callbacks can be used * directly by the sequential code, the functions suffixed "_imp" are the * implementations, the functions without the suffix are the callbacks. * * The code for the info callback is split into two because this callback calls * png_read_update_info or png_start_read_image and what gets called depends on * whether the info needs updating (we want to test both calls in pngvalid.) */ static void standard_info_part1(standard_display *dp, png_structp pp, png_infop pi) { if (png_get_bit_depth(pp, pi) != dp->bit_depth) png_error(pp, "validate: bit depth changed"); if (png_get_color_type(pp, pi) != dp->colour_type) png_error(pp, "validate: color type changed"); if (png_get_filter_type(pp, pi) != PNG_FILTER_TYPE_BASE) png_error(pp, "validate: filter type changed"); if (png_get_interlace_type(pp, pi) != dp->interlace_type) png_error(pp, "validate: interlacing changed"); if (png_get_compression_type(pp, pi) != PNG_COMPRESSION_TYPE_BASE) png_error(pp, "validate: compression type changed"); dp->w = png_get_image_width(pp, pi); if (dp->w != standard_width(pp, dp->id)) png_error(pp, "validate: image width changed"); dp->h = png_get_image_height(pp, pi); if (dp->h != standard_height(pp, dp->id)) png_error(pp, "validate: image height changed"); /* Record (but don't check at present) the input sBIT according to the colour * type information. */ { png_color_8p sBIT = 0; if (png_get_sBIT(pp, pi, &sBIT) & PNG_INFO_sBIT) { int sBIT_invalid = 0; if (sBIT == 0) png_error(pp, "validate: unexpected png_get_sBIT result"); if (dp->colour_type & PNG_COLOR_MASK_COLOR) { if (sBIT->red == 0 || sBIT->red > dp->bit_depth) sBIT_invalid = 1; else dp->red_sBIT = sBIT->red; if (sBIT->green == 0 || sBIT->green > dp->bit_depth) sBIT_invalid = 1; else dp->green_sBIT = sBIT->green; if (sBIT->blue == 0 || sBIT->blue > dp->bit_depth) sBIT_invalid = 1; else dp->blue_sBIT = sBIT->blue; } else /* !COLOR */ { if (sBIT->gray == 0 || sBIT->gray > dp->bit_depth) sBIT_invalid = 1; else dp->blue_sBIT = dp->green_sBIT = dp->red_sBIT = sBIT->gray; } /* All 8 bits in tRNS for a palette image are significant - see the * spec. */ if (dp->colour_type & PNG_COLOR_MASK_ALPHA) { if (sBIT->alpha == 0 || sBIT->alpha > dp->bit_depth) sBIT_invalid = 1; else dp->alpha_sBIT = sBIT->alpha; } if (sBIT_invalid) png_error(pp, "validate: sBIT value out of range"); } } /* Important: this is validating the value *before* any transforms have been * put in place. It doesn't matter for the standard tests, where there are * no transforms, but it does for other tests where rowbytes may change after * png_read_update_info. */ if (png_get_rowbytes(pp, pi) != standard_rowsize(pp, dp->id)) png_error(pp, "validate: row size changed"); /* Validate the colour type 3 palette (this can be present on other color * types.) */ standard_palette_validate(dp, pp, pi); /* In any case always check for a transparent color (notice that the * colour type 3 case must not give a successful return on the get_tRNS call * with these arguments!) */ { png_color_16p trans_color = 0; if (png_get_tRNS(pp, pi, 0, 0, &trans_color) & PNG_INFO_tRNS) { if (trans_color == 0) png_error(pp, "validate: unexpected png_get_tRNS (color) result"); switch (dp->colour_type) { case 0: dp->transparent.red = dp->transparent.green = dp->transparent.blue = trans_color->gray; dp->has_tRNS = 1; break; case 2: dp->transparent.red = trans_color->red; dp->transparent.green = trans_color->green; dp->transparent.blue = trans_color->blue; dp->has_tRNS = 1; break; case 3: /* Not expected because it should result in the array case * above. */ png_error(pp, "validate: unexpected png_get_tRNS result"); break; default: png_error(pp, "validate: invalid tRNS chunk with alpha image"); } } } /* Read the number of passes - expected to match the value used when * creating the image (interlaced or not). This has the side effect of * turning on interlace handling (if do_interlace is not set.) */ dp->npasses = npasses_from_interlace_type(pp, dp->interlace_type); if (!dp->do_interlace) { # ifdef PNG_READ_INTERLACING_SUPPORTED if (dp->npasses != png_set_interlace_handling(pp)) png_error(pp, "validate: file changed interlace type"); # else /* !READ_INTERLACING */ /* This should never happen: the relevant tests (!do_interlace) should * not be run. */ if (dp->npasses > 1) png_error(pp, "validate: no libpng interlace support"); # endif /* !READ_INTERLACING */ } /* Caller calls png_read_update_info or png_start_read_image now, then calls * part2. */ } /* This must be called *after* the png_read_update_info call to get the correct * 'rowbytes' value, otherwise png_get_rowbytes will refer to the untransformed * image. */ static void standard_info_part2(standard_display *dp, png_const_structp pp, png_const_infop pi, int nImages) { /* Record cbRow now that it can be found. */ { png_byte ct = png_get_color_type(pp, pi); png_byte bd = png_get_bit_depth(pp, pi); if (bd >= 8 && (ct == PNG_COLOR_TYPE_RGB || ct == PNG_COLOR_TYPE_GRAY) && dp->filler) ct |= 4; /* handle filler as faked alpha channel */ dp->pixel_size = bit_size(pp, ct, bd); } dp->bit_width = png_get_image_width(pp, pi) * dp->pixel_size; dp->cbRow = png_get_rowbytes(pp, pi); /* Validate the rowbytes here again. */ if (dp->cbRow != (dp->bit_width+7)/8) png_error(pp, "bad png_get_rowbytes calculation"); /* Then ensure there is enough space for the output image(s). */ store_ensure_image(dp->ps, pp, nImages, dp->cbRow, dp->h); } static void standard_info_imp(standard_display *dp, png_structp pp, png_infop pi, int nImages) { /* Note that the validation routine has the side effect of turning on * interlace handling in the subsequent code. */ standard_info_part1(dp, pp, pi); /* And the info callback has to call this (or png_read_update_info - see * below in the png_modifier code for that variant. */ if (dp->use_update_info) { /* For debugging the effect of multiple calls: */ int i = dp->use_update_info; while (i-- > 0) png_read_update_info(pp, pi); } else png_start_read_image(pp); /* Validate the height, width and rowbytes plus ensure that sufficient buffer * exists for decoding the image. */ standard_info_part2(dp, pp, pi, nImages); } static void PNGCBAPI standard_info(png_structp pp, png_infop pi) { standard_display *dp = voidcast(standard_display*, png_get_progressive_ptr(pp)); /* Call with nImages==1 because the progressive reader can only produce one * image. */ standard_info_imp(dp, pp, pi, 1 /*only one image*/); } static void PNGCBAPI progressive_row(png_structp ppIn, png_bytep new_row, png_uint_32 y, int pass) { png_const_structp pp = ppIn; const standard_display *dp = voidcast(standard_display*, png_get_progressive_ptr(pp)); /* When handling interlacing some rows will be absent in each pass, the * callback still gets called, but with a NULL pointer. This is checked * in the 'else' clause below. We need our own 'cbRow', but we can't call * png_get_rowbytes because we got no info structure. */ if (new_row != NULL) { png_bytep row; /* In the case where the reader doesn't do the interlace it gives * us the y in the sub-image: */ if (dp->do_interlace && dp->interlace_type == PNG_INTERLACE_ADAM7) { #ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED /* Use this opportunity to validate the png 'current' APIs: */ if (y != png_get_current_row_number(pp)) png_error(pp, "png_get_current_row_number is broken"); if (pass != png_get_current_pass_number(pp)) png_error(pp, "png_get_current_pass_number is broken"); #endif /* USER_TRANSFORM_INFO */ y = PNG_ROW_FROM_PASS_ROW(y, pass); } /* Validate this just in case. */ if (y >= dp->h) png_error(pp, "invalid y to progressive row callback"); row = store_image_row(dp->ps, pp, 0, y); /* Combine the new row into the old: */ #ifdef PNG_READ_INTERLACING_SUPPORTED if (dp->do_interlace) #endif /* READ_INTERLACING */ { if (dp->interlace_type == PNG_INTERLACE_ADAM7) deinterlace_row(row, new_row, dp->pixel_size, dp->w, pass, dp->littleendian); else row_copy(row, new_row, dp->pixel_size * dp->w, dp->littleendian); } #ifdef PNG_READ_INTERLACING_SUPPORTED else png_progressive_combine_row(pp, row, new_row); #endif /* PNG_READ_INTERLACING_SUPPORTED */ } else if (dp->interlace_type == PNG_INTERLACE_ADAM7 && PNG_ROW_IN_INTERLACE_PASS(y, pass) && PNG_PASS_COLS(dp->w, pass) > 0) png_error(pp, "missing row in progressive de-interlacing"); } static void sequential_row(standard_display *dp, png_structp pp, png_infop pi, int iImage, int iDisplay) { int npasses = dp->npasses; int do_interlace = dp->do_interlace && dp->interlace_type == PNG_INTERLACE_ADAM7; png_uint_32 height = standard_height(pp, dp->id); png_uint_32 width = standard_width(pp, dp->id); const png_store* ps = dp->ps; int pass; for (pass=0; pass 0 && PNG_ROW_IN_INTERLACE_PASS(y, pass)) { /* Read the row into a pair of temporary buffers, then do the * merge here into the output rows. */ png_byte row[STANDARD_ROWMAX], display[STANDARD_ROWMAX]; /* The following aids (to some extent) error detection - we can * see where png_read_row wrote. Use opposite values in row and * display to make this easier. Don't use 0xff (which is used in * the image write code to fill unused bits) or 0 (which is a * likely value to overwrite unused bits with). */ memset(row, 0xc5, sizeof row); memset(display, 0x5c, sizeof display); png_read_row(pp, row, display); if (iImage >= 0) deinterlace_row(store_image_row(ps, pp, iImage, y), row, dp->pixel_size, dp->w, pass, dp->littleendian); if (iDisplay >= 0) deinterlace_row(store_image_row(ps, pp, iDisplay, y), display, dp->pixel_size, dp->w, pass, dp->littleendian); } } else png_read_row(pp, iImage >= 0 ? store_image_row(ps, pp, iImage, y) : NULL, iDisplay >= 0 ? store_image_row(ps, pp, iDisplay, y) : NULL); } } /* And finish the read operation (only really necessary if the caller wants * to find additional data in png_info from chunks after the last IDAT.) */ png_read_end(pp, pi); } #ifdef PNG_TEXT_SUPPORTED static void standard_check_text(png_const_structp pp, png_const_textp tp, png_const_charp keyword, png_const_charp text) { char msg[1024]; size_t pos = safecat(msg, sizeof msg, 0, "text: "); size_t ok; pos = safecat(msg, sizeof msg, pos, keyword); pos = safecat(msg, sizeof msg, pos, ": "); ok = pos; if (tp->compression != TEXT_COMPRESSION) { char buf[64]; sprintf(buf, "compression [%d->%d], ", TEXT_COMPRESSION, tp->compression); pos = safecat(msg, sizeof msg, pos, buf); } if (tp->key == NULL || strcmp(tp->key, keyword) != 0) { pos = safecat(msg, sizeof msg, pos, "keyword \""); if (tp->key != NULL) { pos = safecat(msg, sizeof msg, pos, tp->key); pos = safecat(msg, sizeof msg, pos, "\", "); } else pos = safecat(msg, sizeof msg, pos, "null, "); } if (tp->text == NULL) pos = safecat(msg, sizeof msg, pos, "text lost, "); else { if (tp->text_length != strlen(text)) { char buf[64]; sprintf(buf, "text length changed[%lu->%lu], ", (unsigned long)strlen(text), (unsigned long)tp->text_length); pos = safecat(msg, sizeof msg, pos, buf); } if (strcmp(tp->text, text) != 0) { pos = safecat(msg, sizeof msg, pos, "text becomes \""); pos = safecat(msg, sizeof msg, pos, tp->text); pos = safecat(msg, sizeof msg, pos, "\" (was \""); pos = safecat(msg, sizeof msg, pos, text); pos = safecat(msg, sizeof msg, pos, "\"), "); } } if (tp->itxt_length != 0) pos = safecat(msg, sizeof msg, pos, "iTXt length set, "); if (tp->lang != NULL) { pos = safecat(msg, sizeof msg, pos, "iTXt language \""); pos = safecat(msg, sizeof msg, pos, tp->lang); pos = safecat(msg, sizeof msg, pos, "\", "); } if (tp->lang_key != NULL) { pos = safecat(msg, sizeof msg, pos, "iTXt keyword \""); pos = safecat(msg, sizeof msg, pos, tp->lang_key); pos = safecat(msg, sizeof msg, pos, "\", "); } if (pos > ok) { msg[pos-2] = '\0'; /* Remove the ", " at the end */ png_error(pp, msg); } } static void standard_text_validate(standard_display *dp, png_const_structp pp, png_infop pi, int check_end) { png_textp tp = NULL; png_uint_32 num_text = png_get_text(pp, pi, &tp, NULL); if (num_text == 2 && tp != NULL) { standard_check_text(pp, tp, "image name", dp->ps->current->name); /* This exists because prior to 1.5.18 the progressive reader left the * png_struct z_stream unreset at the end of the image, so subsequent * attempts to use it simply returns Z_STREAM_END. */ if (check_end) standard_check_text(pp, tp+1, "end marker", "end"); } else { char msg[64]; sprintf(msg, "expected two text items, got %lu", (unsigned long)num_text); png_error(pp, msg); } } #else # define standard_text_validate(dp,pp,pi,check_end) ((void)0) #endif static void standard_row_validate(standard_display *dp, png_const_structp pp, int iImage, int iDisplay, png_uint_32 y) { int where; png_byte std[STANDARD_ROWMAX]; /* The row must be pre-initialized to the magic number here for the size * tests to pass: */ memset(std, 178, sizeof std); standard_row(pp, std, dp->id, y); /* At the end both the 'row' and 'display' arrays should end up identical. * In earlier passes 'row' will be partially filled in, with only the pixels * that have been read so far, but 'display' will have those pixels * replicated to fill the unread pixels while reading an interlaced image. */ if (iImage >= 0 && (where = pixel_cmp(std, store_image_row(dp->ps, pp, iImage, y), dp->bit_width)) != 0) { char msg[64]; sprintf(msg, "PNG image row[%lu][%d] changed from %.2x to %.2x", (unsigned long)y, where-1, std[where-1], store_image_row(dp->ps, pp, iImage, y)[where-1]); png_error(pp, msg); } if (iDisplay >= 0 && (where = pixel_cmp(std, store_image_row(dp->ps, pp, iDisplay, y), dp->bit_width)) != 0) { char msg[64]; sprintf(msg, "display row[%lu][%d] changed from %.2x to %.2x", (unsigned long)y, where-1, std[where-1], store_image_row(dp->ps, pp, iDisplay, y)[where-1]); png_error(pp, msg); } } static void standard_image_validate(standard_display *dp, png_const_structp pp, int iImage, int iDisplay) { png_uint_32 y; if (iImage >= 0) store_image_check(dp->ps, pp, iImage); if (iDisplay >= 0) store_image_check(dp->ps, pp, iDisplay); for (y=0; yh; ++y) standard_row_validate(dp, pp, iImage, iDisplay, y); /* This avoids false positives if the validation code is never called! */ dp->ps->validated = 1; } static void PNGCBAPI standard_end(png_structp ppIn, png_infop pi) { png_const_structp pp = ppIn; standard_display *dp = voidcast(standard_display*, png_get_progressive_ptr(pp)); UNUSED(pi) /* Validate the image - progressive reading only produces one variant for * interlaced images. */ standard_text_validate(dp, pp, pi, PNG_LIBPNG_VER >= 10518/*check_end: see comments above*/); standard_image_validate(dp, pp, 0, -1); } /* A single test run checking the standard image to ensure it is not damaged. */ static void standard_test(png_store* const psIn, png_uint_32 const id, int do_interlace, int use_update_info) { standard_display d; context(psIn, fault); /* Set up the display (stack frame) variables from the arguments to the * function and initialize the locals that are filled in later. */ standard_display_init(&d, psIn, id, do_interlace, use_update_info); /* Everything is protected by a Try/Catch. The functions called also * typically have local Try/Catch blocks. */ Try { png_structp pp; png_infop pi; /* Get a png_struct for reading the image. This will throw an error if it * fails, so we don't need to check the result. */ pp = set_store_for_read(d.ps, &pi, d.id, d.do_interlace ? (d.ps->progressive ? "pngvalid progressive deinterlacer" : "pngvalid sequential deinterlacer") : (d.ps->progressive ? "progressive reader" : "sequential reader")); /* Initialize the palette correctly from the png_store_file. */ standard_palette_init(&d); /* Introduce the correct read function. */ if (d.ps->progressive) { png_set_progressive_read_fn(pp, &d, standard_info, progressive_row, standard_end); /* Now feed data into the reader until we reach the end: */ store_progressive_read(d.ps, pp, pi); } else { /* Note that this takes the store, not the display. */ png_set_read_fn(pp, d.ps, store_read); /* Check the header values: */ png_read_info(pp, pi); /* The code tests both versions of the images that the sequential * reader can produce. */ standard_info_imp(&d, pp, pi, 2 /*images*/); /* Need the total bytes in the image below; we can't get to this point * unless the PNG file values have been checked against the expected * values. */ { sequential_row(&d, pp, pi, 0, 1); /* After the last pass loop over the rows again to check that the * image is correct. */ if (!d.speed) { standard_text_validate(&d, pp, pi, 1/*check_end*/); standard_image_validate(&d, pp, 0, 1); } else d.ps->validated = 1; } } /* Check for validation. */ if (!d.ps->validated) png_error(pp, "image read failed silently"); /* Successful completion. */ } Catch(fault) d.ps = fault; /* make sure this hasn't been clobbered. */ /* In either case clean up the store. */ store_read_reset(d.ps); } static int test_standard(png_modifier* const pm, png_byte const colour_type, int bdlo, int const bdhi) { for (; bdlo <= bdhi; ++bdlo) { int interlace_type; for (interlace_type = PNG_INTERLACE_NONE; interlace_type < INTERLACE_LAST; ++interlace_type) { standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/, interlace_type, 0, 0, 0), do_read_interlace, pm->use_update_info); if (fail(pm)) return 0; } } return 1; /* keep going */ } static void perform_standard_test(png_modifier *pm) { /* Test each colour type over the valid range of bit depths (expressed as * log2(bit_depth) in turn, stop as soon as any error is detected. */ if (!test_standard(pm, 0, 0, READ_BDHI)) return; if (!test_standard(pm, 2, 3, READ_BDHI)) return; if (!test_standard(pm, 3, 0, 3)) return; if (!test_standard(pm, 4, 3, READ_BDHI)) return; if (!test_standard(pm, 6, 3, READ_BDHI)) return; } /********************************** SIZE TESTS ********************************/ static int test_size(png_modifier* const pm, png_byte const colour_type, int bdlo, int const bdhi) { /* Run the tests on each combination. * * NOTE: on my 32 bit x86 each of the following blocks takes * a total of 3.5 seconds if done across every combo of bit depth * width and height. This is a waste of time in practice, hence the * hinc and winc stuff: */ static const png_byte hinc[] = {1, 3, 11, 1, 5}; static const png_byte winc[] = {1, 9, 5, 7, 1}; int save_bdlo = bdlo; for (; bdlo <= bdhi; ++bdlo) { png_uint_32 h, w; for (h=1; h<=16; h+=hinc[bdlo]) { for (w=1; w<=16; w+=winc[bdlo]) { /* First test all the 'size' images against the sequential * reader using libpng to deinterlace (where required.) This * validates the write side of libpng. There are four possibilities * to validate. */ standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/, PNG_INTERLACE_NONE, w, h, 0), 0/*do_interlace*/, pm->use_update_info); if (fail(pm)) return 0; standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/, PNG_INTERLACE_NONE, w, h, 1), 0/*do_interlace*/, pm->use_update_info); if (fail(pm)) return 0; /* Now validate the interlaced read side - do_interlace true, * in the progressive case this does actually make a difference * to the code used in the non-interlaced case too. */ standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/, PNG_INTERLACE_NONE, w, h, 0), 1/*do_interlace*/, pm->use_update_info); if (fail(pm)) return 0; # if CAN_WRITE_INTERLACE /* Validate the pngvalid code itself: */ standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/, PNG_INTERLACE_ADAM7, w, h, 1), 1/*do_interlace*/, pm->use_update_info); if (fail(pm)) return 0; # endif } } } /* Now do the tests of libpng interlace handling, after we have made sure * that the pngvalid version works: */ for (bdlo = save_bdlo; bdlo <= bdhi; ++bdlo) { png_uint_32 h, w; for (h=1; h<=16; h+=hinc[bdlo]) { for (w=1; w<=16; w+=winc[bdlo]) { # ifdef PNG_READ_INTERLACING_SUPPORTED /* Test with pngvalid generated interlaced images first; we have * already verify these are ok (unless pngvalid has self-consistent * read/write errors, which is unlikely), so this detects errors in * the read side first: */ # if CAN_WRITE_INTERLACE standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/, PNG_INTERLACE_ADAM7, w, h, 1), 0/*do_interlace*/, pm->use_update_info); if (fail(pm)) return 0; # endif # endif /* READ_INTERLACING */ # ifdef PNG_WRITE_INTERLACING_SUPPORTED /* Test the libpng write side against the pngvalid read side: */ standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/, PNG_INTERLACE_ADAM7, w, h, 0), 1/*do_interlace*/, pm->use_update_info); if (fail(pm)) return 0; # endif # ifdef PNG_READ_INTERLACING_SUPPORTED # ifdef PNG_WRITE_INTERLACING_SUPPORTED /* Test both together: */ standard_test(&pm->this, FILEID(colour_type, DEPTH(bdlo), 0/*palette*/, PNG_INTERLACE_ADAM7, w, h, 0), 0/*do_interlace*/, pm->use_update_info); if (fail(pm)) return 0; # endif # endif /* READ_INTERLACING */ } } } return 1; /* keep going */ } static void perform_size_test(png_modifier *pm) { /* Test each colour type over the valid range of bit depths (expressed as * log2(bit_depth) in turn, stop as soon as any error is detected. */ if (!test_size(pm, 0, 0, READ_BDHI)) return; if (!test_size(pm, 2, 3, READ_BDHI)) return; /* For the moment don't do the palette test - it's a waste of time when * compared to the grayscale test. */ #if 0 if (!test_size(pm, 3, 0, 3)) return; #endif if (!test_size(pm, 4, 3, READ_BDHI)) return; if (!test_size(pm, 6, 3, READ_BDHI)) return; } /******************************* TRANSFORM TESTS ******************************/ #ifdef PNG_READ_TRANSFORMS_SUPPORTED /* A set of tests to validate libpng image transforms. The possibilities here * are legion because the transforms can be combined in a combinatorial * fashion. To deal with this some measure of restraint is required, otherwise * the tests would take forever. */ typedef struct image_pixel { /* A local (pngvalid) representation of a PNG pixel, in all its * various forms. */ unsigned int red, green, blue, alpha; /* For non-palette images. */ unsigned int palette_index; /* For a palette image. */ png_byte colour_type; /* As in the spec. */ png_byte bit_depth; /* Defines bit size in row */ png_byte sample_depth; /* Scale of samples */ unsigned int have_tRNS :1; /* tRNS chunk may need processing */ unsigned int swap_rgb :1; /* RGB swapped to BGR */ unsigned int alpha_first :1; /* Alpha at start, not end */ unsigned int alpha_inverted :1; /* Alpha channel inverted */ unsigned int mono_inverted :1; /* Gray channel inverted */ unsigned int swap16 :1; /* Byte swap 16-bit components */ unsigned int littleendian :1; /* High bits on right */ unsigned int sig_bits :1; /* Pixel shifted (sig bits only) */ /* For checking the code calculates double precision floating point values * along with an error value, accumulated from the transforms. Because an * sBIT setting allows larger error bounds (indeed, by the spec, apparently * up to just less than +/-1 in the scaled value) the *lowest* sBIT for each * channel is stored. This sBIT value is folded in to the stored error value * at the end of the application of the transforms to the pixel. * * If sig_bits is set above the red, green, blue and alpha values have been * scaled so they only contain the significant bits of the component values. */ double redf, greenf, bluef, alphaf; double rede, greene, bluee, alphae; png_byte red_sBIT, green_sBIT, blue_sBIT, alpha_sBIT; } image_pixel; /* Shared utility function, see below. */ static void image_pixel_setf(image_pixel *this, unsigned int rMax, unsigned int gMax, unsigned int bMax, unsigned int aMax) { this->redf = this->red / (double)rMax; this->greenf = this->green / (double)gMax; this->bluef = this->blue / (double)bMax; this->alphaf = this->alpha / (double)aMax; if (this->red < rMax) this->rede = this->redf * DBL_EPSILON; else this->rede = 0; if (this->green < gMax) this->greene = this->greenf * DBL_EPSILON; else this->greene = 0; if (this->blue < bMax) this->bluee = this->bluef * DBL_EPSILON; else this->bluee = 0; if (this->alpha < aMax) this->alphae = this->alphaf * DBL_EPSILON; else this->alphae = 0; } /* Initialize the structure for the next pixel - call this before doing any * transforms and call it for each pixel since all the fields may need to be * reset. */ static void image_pixel_init(image_pixel *this, png_const_bytep row, png_byte colour_type, png_byte bit_depth, png_uint_32 x, store_palette palette, const image_pixel *format /*from pngvalid transform of input*/) { png_byte sample_depth = (png_byte)(colour_type == PNG_COLOR_TYPE_PALETTE ? 8 : bit_depth); unsigned int max = (1U<swap16); int littleendian = (format != 0 && format->littleendian); int sig_bits = (format != 0 && format->sig_bits); /* Initially just set everything to the same number and the alpha to opaque. * Note that this currently assumes a simple palette where entry x has colour * rgb(x,x,x)! */ this->palette_index = this->red = this->green = this->blue = sample(row, colour_type, bit_depth, x, 0, swap16, littleendian); this->alpha = max; this->red_sBIT = this->green_sBIT = this->blue_sBIT = this->alpha_sBIT = sample_depth; /* Then override as appropriate: */ if (colour_type == 3) /* palette */ { /* This permits the caller to default to the sample value. */ if (palette != 0) { unsigned int i = this->palette_index; this->red = palette[i].red; this->green = palette[i].green; this->blue = palette[i].blue; this->alpha = palette[i].alpha; } } else /* not palette */ { unsigned int i = 0; if ((colour_type & 4) != 0 && format != 0 && format->alpha_first) { this->alpha = this->red; /* This handles the gray case for 'AG' pixels */ this->palette_index = this->red = this->green = this->blue = sample(row, colour_type, bit_depth, x, 1, swap16, littleendian); i = 1; } if (colour_type & 2) { /* Green is second for both BGR and RGB: */ this->green = sample(row, colour_type, bit_depth, x, ++i, swap16, littleendian); if (format != 0 && format->swap_rgb) /* BGR */ this->red = sample(row, colour_type, bit_depth, x, ++i, swap16, littleendian); else this->blue = sample(row, colour_type, bit_depth, x, ++i, swap16, littleendian); } else /* grayscale */ if (format != 0 && format->mono_inverted) this->red = this->green = this->blue = this->red ^ max; if ((colour_type & 4) != 0) /* alpha */ { if (format == 0 || !format->alpha_first) this->alpha = sample(row, colour_type, bit_depth, x, ++i, swap16, littleendian); if (format != 0 && format->alpha_inverted) this->alpha ^= max; } } /* Calculate the scaled values, these are simply the values divided by * 'max' and the error is initialized to the double precision epsilon value * from the header file. */ image_pixel_setf(this, sig_bits ? (1U << format->red_sBIT)-1 : max, sig_bits ? (1U << format->green_sBIT)-1 : max, sig_bits ? (1U << format->blue_sBIT)-1 : max, sig_bits ? (1U << format->alpha_sBIT)-1 : max); /* Store the input information for use in the transforms - these will * modify the information. */ this->colour_type = colour_type; this->bit_depth = bit_depth; this->sample_depth = sample_depth; this->have_tRNS = 0; this->swap_rgb = 0; this->alpha_first = 0; this->alpha_inverted = 0; this->mono_inverted = 0; this->swap16 = 0; this->littleendian = 0; this->sig_bits = 0; } #if defined PNG_READ_EXPAND_SUPPORTED || defined PNG_READ_GRAY_TO_RGB_SUPPORTED\ || defined PNG_READ_EXPAND_SUPPORTED || defined PNG_READ_EXPAND_16_SUPPORTED\ || defined PNG_READ_BACKGROUND_SUPPORTED /* Convert a palette image to an rgb image. This necessarily converts the tRNS * chunk at the same time, because the tRNS will be in palette form. The way * palette validation works means that the original palette is never updated, * instead the image_pixel value from the row contains the RGB of the * corresponding palette entry and *this* is updated. Consequently this routine * only needs to change the colour type information. */ static void image_pixel_convert_PLTE(image_pixel *this) { if (this->colour_type == PNG_COLOR_TYPE_PALETTE) { if (this->have_tRNS) { this->colour_type = PNG_COLOR_TYPE_RGB_ALPHA; this->have_tRNS = 0; } else this->colour_type = PNG_COLOR_TYPE_RGB; /* The bit depth of the row changes at this point too (notice that this is * the row format, not the sample depth, which is separate.) */ this->bit_depth = 8; } } /* Add an alpha channel; this will import the tRNS information because tRNS is * not valid in an alpha image. The bit depth will invariably be set to at * least 8 prior to 1.7.0. Palette images will be converted to alpha (using * the above API). With png_set_background the alpha channel is never expanded * but this routine is used by pngvalid to simplify code; 'for_background' * records this. */ static void image_pixel_add_alpha(image_pixel *this, const standard_display *display, int for_background) { if (this->colour_type == PNG_COLOR_TYPE_PALETTE) image_pixel_convert_PLTE(this); if ((this->colour_type & PNG_COLOR_MASK_ALPHA) == 0) { if (this->colour_type == PNG_COLOR_TYPE_GRAY) { # if PNG_LIBPNG_VER < 10700 if (!for_background && this->bit_depth < 8) this->bit_depth = this->sample_depth = 8; # endif if (this->have_tRNS) { /* After 1.7 the expansion of bit depth only happens if there is a * tRNS chunk to expand at this point. */ # if PNG_LIBPNG_VER >= 10700 if (!for_background && this->bit_depth < 8) this->bit_depth = this->sample_depth = 8; # endif this->have_tRNS = 0; /* Check the input, original, channel value here against the * original tRNS gray chunk valie. */ if (this->red == display->transparent.red) this->alphaf = 0; else this->alphaf = 1; } else this->alphaf = 1; this->colour_type = PNG_COLOR_TYPE_GRAY_ALPHA; } else if (this->colour_type == PNG_COLOR_TYPE_RGB) { if (this->have_tRNS) { this->have_tRNS = 0; /* Again, check the exact input values, not the current transformed * value! */ if (this->red == display->transparent.red && this->green == display->transparent.green && this->blue == display->transparent.blue) this->alphaf = 0; else this->alphaf = 1; } else this->alphaf = 1; this->colour_type = PNG_COLOR_TYPE_RGB_ALPHA; } /* The error in the alpha is zero and the sBIT value comes from the * original sBIT data (actually it will always be the original bit depth). */ this->alphae = 0; this->alpha_sBIT = display->alpha_sBIT; } } #endif /* transforms that need image_pixel_add_alpha */ struct transform_display; typedef struct image_transform { /* The name of this transform: a string. */ const char *name; /* Each transform can be disabled from the command line: */ int enable; /* The global list of transforms; read only. */ struct image_transform *const list; /* The global count of the number of times this transform has been set on an * image. */ unsigned int global_use; /* The local count of the number of times this transform has been set. */ unsigned int local_use; /* The next transform in the list, each transform must call its own next * transform after it has processed the pixel successfully. */ const struct image_transform *next; /* A single transform for the image, expressed as a series of function * callbacks and some space for values. * * First a callback to add any required modifications to the png_modifier; * this gets called just before the modifier is set up for read. */ void (*ini)(const struct image_transform *this, struct transform_display *that); /* And a callback to set the transform on the current png_read_struct: */ void (*set)(const struct image_transform *this, struct transform_display *that, png_structp pp, png_infop pi); /* Then a transform that takes an input pixel in one PNG format or another * and modifies it by a pngvalid implementation of the transform (thus * duplicating the libpng intent without, we hope, duplicating the bugs * in the libpng implementation!) The png_structp is solely to allow error * reporting via png_error and png_warning. */ void (*mod)(const struct image_transform *this, image_pixel *that, png_const_structp pp, const struct transform_display *display); /* Add this transform to the list and return true if the transform is * meaningful for this colour type and bit depth - if false then the * transform should have no effect on the image so there's not a lot of * point running it. */ int (*add)(struct image_transform *this, const struct image_transform **that, png_byte colour_type, png_byte bit_depth); } image_transform; typedef struct transform_display { standard_display this; /* Parameters */ png_modifier* pm; const image_transform* transform_list; unsigned int max_gamma_8; /* Local variables */ png_byte output_colour_type; png_byte output_bit_depth; png_byte unpacked; /* Modifications (not necessarily used.) */ gama_modification gama_mod; chrm_modification chrm_mod; srgb_modification srgb_mod; } transform_display; /* Set sRGB, cHRM and gAMA transforms as required by the current encoding. */ static void transform_set_encoding(transform_display *this) { /* Set up the png_modifier '_current' fields then use these to determine how * to add appropriate chunks. */ png_modifier *pm = this->pm; modifier_set_encoding(pm); if (modifier_color_encoding_is_set(pm)) { if (modifier_color_encoding_is_sRGB(pm)) srgb_modification_init(&this->srgb_mod, pm, PNG_sRGB_INTENT_ABSOLUTE); else { /* Set gAMA and cHRM separately. */ gama_modification_init(&this->gama_mod, pm, pm->current_gamma); if (pm->current_encoding != 0) chrm_modification_init(&this->chrm_mod, pm, pm->current_encoding); } } } /* Three functions to end the list: */ static void image_transform_ini_end(const image_transform *this, transform_display *that) { UNUSED(this) UNUSED(that) } static void image_transform_set_end(const image_transform *this, transform_display *that, png_structp pp, png_infop pi) { UNUSED(this) UNUSED(that) UNUSED(pp) UNUSED(pi) } /* At the end of the list recalculate the output image pixel value from the * double precision values set up by the preceding 'mod' calls: */ static unsigned int sample_scale(double sample_value, unsigned int scale) { sample_value = floor(sample_value * scale + .5); /* Return NaN as 0: */ if (!(sample_value > 0)) sample_value = 0; else if (sample_value > scale) sample_value = scale; return (unsigned int)sample_value; } static void image_transform_mod_end(const image_transform *this, image_pixel *that, png_const_structp pp, const transform_display *display) { unsigned int scale = (1U<sample_depth)-1; int sig_bits = that->sig_bits; UNUSED(this) UNUSED(pp) UNUSED(display) /* At the end recalculate the digitized red green and blue values according * to the current sample_depth of the pixel. * * The sample value is simply scaled to the maximum, checking for over * and underflow (which can both happen for some image transforms, * including simple size scaling, though libpng doesn't do that at present. */ that->red = sample_scale(that->redf, scale); /* This is a bit bogus; really the above calculation should use the red_sBIT * value, not sample_depth, but because libpng does png_set_shift by just * shifting the bits we get errors if we don't do it the same way. */ if (sig_bits && that->red_sBIT < that->sample_depth) that->red >>= that->sample_depth - that->red_sBIT; /* The error value is increased, at the end, according to the lowest sBIT * value seen. Common sense tells us that the intermediate integer * representations are no more accurate than +/- 0.5 in the integral values, * the sBIT allows the implementation to be worse than this. In addition the * PNG specification actually permits any error within the range (-1..+1), * but that is ignored here. Instead the final digitized value is compared, * below to the digitized value of the error limits - this has the net effect * of allowing (almost) +/-1 in the output value. It's difficult to see how * any algorithm that digitizes intermediate results can be more accurate. */ that->rede += 1./(2*((1U<red_sBIT)-1)); if (that->colour_type & PNG_COLOR_MASK_COLOR) { that->green = sample_scale(that->greenf, scale); if (sig_bits && that->green_sBIT < that->sample_depth) that->green >>= that->sample_depth - that->green_sBIT; that->blue = sample_scale(that->bluef, scale); if (sig_bits && that->blue_sBIT < that->sample_depth) that->blue >>= that->sample_depth - that->blue_sBIT; that->greene += 1./(2*((1U<green_sBIT)-1)); that->bluee += 1./(2*((1U<blue_sBIT)-1)); } else { that->blue = that->green = that->red; that->bluef = that->greenf = that->redf; that->bluee = that->greene = that->rede; } if ((that->colour_type & PNG_COLOR_MASK_ALPHA) || that->colour_type == PNG_COLOR_TYPE_PALETTE) { that->alpha = sample_scale(that->alphaf, scale); that->alphae += 1./(2*((1U<alpha_sBIT)-1)); } else { that->alpha = scale; /* opaque */ that->alphaf = 1; /* Override this. */ that->alphae = 0; /* It's exact ;-) */ } if (sig_bits && that->alpha_sBIT < that->sample_depth) that->alpha >>= that->sample_depth - that->alpha_sBIT; } /* Static 'end' structure: */ static image_transform image_transform_end = { "(end)", /* name */ 1, /* enable */ 0, /* list */ 0, /* global_use */ 0, /* local_use */ 0, /* next */ image_transform_ini_end, image_transform_set_end, image_transform_mod_end, 0 /* never called, I want it to crash if it is! */ }; /* Reader callbacks and implementations, where they differ from the standard * ones. */ static void transform_display_init(transform_display *dp, png_modifier *pm, png_uint_32 id, const image_transform *transform_list) { memset(dp, 0, sizeof *dp); /* Standard fields */ standard_display_init(&dp->this, &pm->this, id, do_read_interlace, pm->use_update_info); /* Parameter fields */ dp->pm = pm; dp->transform_list = transform_list; dp->max_gamma_8 = 16; /* Local variable fields */ dp->output_colour_type = 255; /* invalid */ dp->output_bit_depth = 255; /* invalid */ dp->unpacked = 0; /* not unpacked */ } static void transform_info_imp(transform_display *dp, png_structp pp, png_infop pi) { /* Reuse the standard stuff as appropriate. */ standard_info_part1(&dp->this, pp, pi); /* Now set the list of transforms. */ dp->transform_list->set(dp->transform_list, dp, pp, pi); /* Update the info structure for these transforms: */ { int i = dp->this.use_update_info; /* Always do one call, even if use_update_info is 0. */ do png_read_update_info(pp, pi); while (--i > 0); } /* And get the output information into the standard_display */ standard_info_part2(&dp->this, pp, pi, 1/*images*/); /* Plus the extra stuff we need for the transform tests: */ dp->output_colour_type = png_get_color_type(pp, pi); dp->output_bit_depth = png_get_bit_depth(pp, pi); /* If png_set_filler is in action then fake the output color type to include * an alpha channel where appropriate. */ if (dp->output_bit_depth >= 8 && (dp->output_colour_type == PNG_COLOR_TYPE_RGB || dp->output_colour_type == PNG_COLOR_TYPE_GRAY) && dp->this.filler) dp->output_colour_type |= 4; /* Validate the combination of colour type and bit depth that we are getting * out of libpng; the semantics of something not in the PNG spec are, at * best, unclear. */ switch (dp->output_colour_type) { case PNG_COLOR_TYPE_PALETTE: if (dp->output_bit_depth > 8) goto error; /* FALLTHROUGH */ case PNG_COLOR_TYPE_GRAY: if (dp->output_bit_depth == 1 || dp->output_bit_depth == 2 || dp->output_bit_depth == 4) break; /* FALLTHROUGH */ default: if (dp->output_bit_depth == 8 || dp->output_bit_depth == 16) break; /* FALLTHROUGH */ error: { char message[128]; size_t pos; pos = safecat(message, sizeof message, 0, "invalid final bit depth: colour type("); pos = safecatn(message, sizeof message, pos, dp->output_colour_type); pos = safecat(message, sizeof message, pos, ") with bit depth: "); pos = safecatn(message, sizeof message, pos, dp->output_bit_depth); png_error(pp, message); } } /* Use a test pixel to check that the output agrees with what we expect - * this avoids running the whole test if the output is unexpected. This also * checks for internal errors. */ { image_pixel test_pixel; memset(&test_pixel, 0, sizeof test_pixel); test_pixel.colour_type = dp->this.colour_type; /* input */ test_pixel.bit_depth = dp->this.bit_depth; if (test_pixel.colour_type == PNG_COLOR_TYPE_PALETTE) test_pixel.sample_depth = 8; else test_pixel.sample_depth = test_pixel.bit_depth; /* Don't need sBIT here, but it must be set to non-zero to avoid * arithmetic overflows. */ test_pixel.have_tRNS = dp->this.is_transparent != 0; test_pixel.red_sBIT = test_pixel.green_sBIT = test_pixel.blue_sBIT = test_pixel.alpha_sBIT = test_pixel.sample_depth; dp->transform_list->mod(dp->transform_list, &test_pixel, pp, dp); if (test_pixel.colour_type != dp->output_colour_type) { char message[128]; size_t pos = safecat(message, sizeof message, 0, "colour type "); pos = safecatn(message, sizeof message, pos, dp->output_colour_type); pos = safecat(message, sizeof message, pos, " expected "); pos = safecatn(message, sizeof message, pos, test_pixel.colour_type); png_error(pp, message); } if (test_pixel.bit_depth != dp->output_bit_depth) { char message[128]; size_t pos = safecat(message, sizeof message, 0, "bit depth "); pos = safecatn(message, sizeof message, pos, dp->output_bit_depth); pos = safecat(message, sizeof message, pos, " expected "); pos = safecatn(message, sizeof message, pos, test_pixel.bit_depth); png_error(pp, message); } /* If both bit depth and colour type are correct check the sample depth. */ if (test_pixel.colour_type == PNG_COLOR_TYPE_PALETTE && test_pixel.sample_depth != 8) /* oops - internal error! */ png_error(pp, "pngvalid: internal: palette sample depth not 8"); else if (dp->unpacked && test_pixel.bit_depth != 8) png_error(pp, "pngvalid: internal: bad unpacked pixel depth"); else if (!dp->unpacked && test_pixel.colour_type != PNG_COLOR_TYPE_PALETTE && test_pixel.bit_depth != test_pixel.sample_depth) { char message[128]; size_t pos = safecat(message, sizeof message, 0, "internal: sample depth "); /* Because unless something has set 'unpacked' or the image is palette * mapped we expect the transform to keep sample depth and bit depth * the same. */ pos = safecatn(message, sizeof message, pos, test_pixel.sample_depth); pos = safecat(message, sizeof message, pos, " expected "); pos = safecatn(message, sizeof message, pos, test_pixel.bit_depth); png_error(pp, message); } else if (test_pixel.bit_depth != dp->output_bit_depth) { /* This could be a libpng error too; libpng has not produced what we * expect for the output bit depth. */ char message[128]; size_t pos = safecat(message, sizeof message, 0, "internal: bit depth "); pos = safecatn(message, sizeof message, pos, dp->output_bit_depth); pos = safecat(message, sizeof message, pos, " expected "); pos = safecatn(message, sizeof message, pos, test_pixel.bit_depth); png_error(pp, message); } } } static void PNGCBAPI transform_info(png_structp pp, png_infop pi) { transform_info_imp(voidcast(transform_display*, png_get_progressive_ptr(pp)), pp, pi); } static void transform_range_check(png_const_structp pp, unsigned int r, unsigned int g, unsigned int b, unsigned int a, unsigned int in_digitized, double in, unsigned int out, png_byte sample_depth, double err, double limit, const char *name, double digitization_error) { /* Compare the scaled, digitized, values of our local calculation (in+-err) * with the digitized values libpng produced; 'sample_depth' is the actual * digitization depth of the libpng output colors (the bit depth except for * palette images where it is always 8.) The check on 'err' is to detect * internal errors in pngvalid itself. */ unsigned int max = (1U< limit ||) !(out >= in_min && out <= in_max)) { char message[256]; size_t pos; pos = safecat(message, sizeof message, 0, name); pos = safecat(message, sizeof message, pos, " output value error: rgba("); pos = safecatn(message, sizeof message, pos, r); pos = safecat(message, sizeof message, pos, ","); pos = safecatn(message, sizeof message, pos, g); pos = safecat(message, sizeof message, pos, ","); pos = safecatn(message, sizeof message, pos, b); pos = safecat(message, sizeof message, pos, ","); pos = safecatn(message, sizeof message, pos, a); pos = safecat(message, sizeof message, pos, "): "); pos = safecatn(message, sizeof message, pos, out); pos = safecat(message, sizeof message, pos, " expected: "); pos = safecatn(message, sizeof message, pos, in_digitized); pos = safecat(message, sizeof message, pos, " ("); pos = safecatd(message, sizeof message, pos, (in-err)*max, 3); pos = safecat(message, sizeof message, pos, ".."); pos = safecatd(message, sizeof message, pos, (in+err)*max, 3); pos = safecat(message, sizeof message, pos, ")"); png_error(pp, message); } UNUSED(limit) } static void transform_image_validate(transform_display *dp, png_const_structp pp, png_infop pi) { /* Constants for the loop below: */ const png_store* const ps = dp->this.ps; png_byte in_ct = dp->this.colour_type; png_byte in_bd = dp->this.bit_depth; png_uint_32 w = dp->this.w; png_uint_32 h = dp->this.h; png_byte out_ct = dp->output_colour_type; png_byte out_bd = dp->output_bit_depth; png_byte sample_depth = (png_byte)(out_ct == PNG_COLOR_TYPE_PALETTE ? 8 : out_bd); png_byte red_sBIT = dp->this.red_sBIT; png_byte green_sBIT = dp->this.green_sBIT; png_byte blue_sBIT = dp->this.blue_sBIT; png_byte alpha_sBIT = dp->this.alpha_sBIT; int have_tRNS = dp->this.is_transparent; double digitization_error; store_palette out_palette; png_uint_32 y; UNUSED(pi) /* Check for row overwrite errors */ store_image_check(dp->this.ps, pp, 0); /* Read the palette corresponding to the output if the output colour type * indicates a palette, otherwise set out_palette to garbage. */ if (out_ct == PNG_COLOR_TYPE_PALETTE) { /* Validate that the palette count itself has not changed - this is not * expected. */ int npalette = (-1); (void)read_palette(out_palette, &npalette, pp, pi); if (npalette != dp->this.npalette) png_error(pp, "unexpected change in palette size"); digitization_error = .5; } else { png_byte in_sample_depth; memset(out_palette, 0x5e, sizeof out_palette); /* use-input-precision means assume that if the input has 8 bit (or less) * samples and the output has 16 bit samples the calculations will be done * with 8 bit precision, not 16. */ if (in_ct == PNG_COLOR_TYPE_PALETTE || in_bd < 16) in_sample_depth = 8; else in_sample_depth = in_bd; if (sample_depth != 16 || in_sample_depth > 8 || !dp->pm->calculations_use_input_precision) digitization_error = .5; /* Else calculations are at 8 bit precision, and the output actually * consists of scaled 8-bit values, so scale .5 in 8 bits to the 16 bits: */ else digitization_error = .5 * 257; } for (y=0; ythis.palette, NULL); in_pixel.red_sBIT = red_sBIT; in_pixel.green_sBIT = green_sBIT; in_pixel.blue_sBIT = blue_sBIT; in_pixel.alpha_sBIT = alpha_sBIT; in_pixel.have_tRNS = have_tRNS != 0; /* For error detection, below. */ r = in_pixel.red; g = in_pixel.green; b = in_pixel.blue; a = in_pixel.alpha; /* This applies the transforms to the input data, including output * format operations which must be used when reading the output * pixel that libpng produces. */ dp->transform_list->mod(dp->transform_list, &in_pixel, pp, dp); /* Read the output pixel and compare it to what we got, we don't * use the error field here, so no need to update sBIT. in_pixel * says whether we expect libpng to change the output format. */ image_pixel_init(&out_pixel, pRow, out_ct, out_bd, x, out_palette, &in_pixel); /* We don't expect changes to the index here even if the bit depth is * changed. */ if (in_ct == PNG_COLOR_TYPE_PALETTE && out_ct == PNG_COLOR_TYPE_PALETTE) { if (in_pixel.palette_index != out_pixel.palette_index) png_error(pp, "unexpected transformed palette index"); } /* Check the colours for palette images too - in fact the palette could * be separately verified itself in most cases. */ if (in_pixel.red != out_pixel.red) transform_range_check(pp, r, g, b, a, in_pixel.red, in_pixel.redf, out_pixel.red, sample_depth, in_pixel.rede, dp->pm->limit + 1./(2*((1U<pm->limit + 1./(2*((1U<pm->limit + 1./(2*((1U<pm->limit + 1./(2*((1U<this.ps->validated = 1; } static void PNGCBAPI transform_end(png_structp ppIn, png_infop pi) { png_const_structp pp = ppIn; transform_display *dp = voidcast(transform_display*, png_get_progressive_ptr(pp)); if (!dp->this.speed) transform_image_validate(dp, pp, pi); else dp->this.ps->validated = 1; } /* A single test run. */ static void transform_test(png_modifier *pmIn, png_uint_32 idIn, const image_transform* transform_listIn, const char * const name) { transform_display d; context(&pmIn->this, fault); transform_display_init(&d, pmIn, idIn, transform_listIn); Try { size_t pos = 0; png_structp pp; png_infop pi; char full_name[256]; /* Make sure the encoding fields are correct and enter the required * modifications. */ transform_set_encoding(&d); /* Add any modifications required by the transform list. */ d.transform_list->ini(d.transform_list, &d); /* Add the color space information, if any, to the name. */ pos = safecat(full_name, sizeof full_name, pos, name); pos = safecat_current_encoding(full_name, sizeof full_name, pos, d.pm); /* Get a png_struct for reading the image. */ pp = set_modifier_for_read(d.pm, &pi, d.this.id, full_name); standard_palette_init(&d.this); # if 0 /* Logging (debugging only) */ { char buffer[256]; (void)store_message(&d.pm->this, pp, buffer, sizeof buffer, 0, "running test"); fprintf(stderr, "%s\n", buffer); } # endif /* Introduce the correct read function. */ if (d.pm->this.progressive) { /* Share the row function with the standard implementation. */ png_set_progressive_read_fn(pp, &d, transform_info, progressive_row, transform_end); /* Now feed data into the reader until we reach the end: */ modifier_progressive_read(d.pm, pp, pi); } else { /* modifier_read expects a png_modifier* */ png_set_read_fn(pp, d.pm, modifier_read); /* Check the header values: */ png_read_info(pp, pi); /* Process the 'info' requirements. Only one image is generated */ transform_info_imp(&d, pp, pi); sequential_row(&d.this, pp, pi, -1, 0); if (!d.this.speed) transform_image_validate(&d, pp, pi); else d.this.ps->validated = 1; } modifier_reset(d.pm); } Catch(fault) { modifier_reset(voidcast(png_modifier*,(void*)fault)); } } /* The transforms: */ #define ITSTRUCT(name) image_transform_##name #define ITDATA(name) image_transform_data_##name #define image_transform_ini image_transform_default_ini #define IT(name)\ static image_transform ITSTRUCT(name) =\ {\ #name,\ 1, /*enable*/\ &PT, /*list*/\ 0, /*global_use*/\ 0, /*local_use*/\ 0, /*next*/\ image_transform_ini,\ image_transform_png_set_##name##_set,\ image_transform_png_set_##name##_mod,\ image_transform_png_set_##name##_add\ } #define PT ITSTRUCT(end) /* stores the previous transform */ /* To save code: */ extern void image_transform_default_ini(const image_transform *this, transform_display *that); /* silence GCC warnings */ void /* private, but almost always needed */ image_transform_default_ini(const image_transform *this, transform_display *that) { this->next->ini(this->next, that); } #ifdef PNG_READ_BACKGROUND_SUPPORTED static int image_transform_default_add(image_transform *this, const image_transform **that, png_byte colour_type, png_byte bit_depth) { UNUSED(colour_type) UNUSED(bit_depth) this->next = *that; *that = this; return 1; } #endif #ifdef PNG_READ_EXPAND_SUPPORTED /* png_set_palette_to_rgb */ static void image_transform_png_set_palette_to_rgb_set(const image_transform *this, transform_display *that, png_structp pp, png_infop pi) { png_set_palette_to_rgb(pp); this->next->set(this->next, that, pp, pi); } static void image_transform_png_set_palette_to_rgb_mod(const image_transform *this, image_pixel *that, png_const_structp pp, const transform_display *display) { if (that->colour_type == PNG_COLOR_TYPE_PALETTE) image_pixel_convert_PLTE(that); this->next->mod(this->next, that, pp, display); } static int image_transform_png_set_palette_to_rgb_add(image_transform *this, const image_transform **that, png_byte colour_type, png_byte bit_depth) { UNUSED(bit_depth) this->next = *that; *that = this; return colour_type == PNG_COLOR_TYPE_PALETTE; } IT(palette_to_rgb); #undef PT #define PT ITSTRUCT(palette_to_rgb) #endif /* PNG_READ_EXPAND_SUPPORTED */ #ifdef PNG_READ_EXPAND_SUPPORTED /* png_set_tRNS_to_alpha */ static void image_transform_png_set_tRNS_to_alpha_set(const image_transform *this, transform_display *that, png_structp pp, png_infop pi) { png_set_tRNS_to_alpha(pp); /* If there was a tRNS chunk that would get expanded and add an alpha * channel is_transparent must be updated: */ if (that->this.has_tRNS) that->this.is_transparent = 1; this->next->set(this->next, that, pp, pi); } static void image_transform_png_set_tRNS_to_alpha_mod(const image_transform *this, image_pixel *that, png_const_structp pp, const transform_display *display) { #if PNG_LIBPNG_VER < 10700 /* LIBPNG BUG: this always forces palette images to RGB. */ if (that->colour_type == PNG_COLOR_TYPE_PALETTE) image_pixel_convert_PLTE(that); #endif /* This effectively does an 'expand' only if there is some transparency to * convert to an alpha channel. */ if (that->have_tRNS) # if PNG_LIBPNG_VER >= 10700 if (that->colour_type != PNG_COLOR_TYPE_PALETTE && (that->colour_type & PNG_COLOR_MASK_ALPHA) == 0) # endif image_pixel_add_alpha(that, &display->this, 0/*!for background*/); #if PNG_LIBPNG_VER < 10700 /* LIBPNG BUG: otherwise libpng still expands to 8 bits! */ else { if (that->bit_depth < 8) that->bit_depth =8; if (that->sample_depth < 8) that->sample_depth = 8; } #endif this->next->mod(this->next, that, pp, display); } static int image_transform_png_set_tRNS_to_alpha_add(image_transform *this, const image_transform **that, png_byte colour_type, png_byte bit_depth) { UNUSED(bit_depth) this->next = *that; *that = this; /* We don't know yet whether there will be a tRNS chunk, but we know that * this transformation should do nothing if there already is an alpha * channel. In addition, after the bug fix in 1.7.0, there is no longer * any action on a palette image. */ return # if PNG_LIBPNG_VER >= 10700 colour_type != PNG_COLOR_TYPE_PALETTE && # endif (colour_type & PNG_COLOR_MASK_ALPHA) == 0; } IT(tRNS_to_alpha); #undef PT #define PT ITSTRUCT(tRNS_to_alpha) #endif /* PNG_READ_EXPAND_SUPPORTED */ #ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED /* png_set_gray_to_rgb */ static void image_transform_png_set_gray_to_rgb_set(const image_transform *this, transform_display *that, png_structp pp, png_infop pi) { png_set_gray_to_rgb(pp); /* NOTE: this doesn't result in tRNS expansion. */ this->next->set(this->next, that, pp, pi); } static void image_transform_png_set_gray_to_rgb_mod(const image_transform *this, image_pixel *that, png_const_structp pp, const transform_display *display) { /* NOTE: we can actually pend the tRNS processing at this point because we * can correctly recognize the original pixel value even though we have * mapped the one gray channel to the three RGB ones, but in fact libpng * doesn't do this, so we don't either. */ if ((that->colour_type & PNG_COLOR_MASK_COLOR) == 0 && that->have_tRNS) image_pixel_add_alpha(that, &display->this, 0/*!for background*/); /* Simply expand the bit depth and alter the colour type as required. */ if (that->colour_type == PNG_COLOR_TYPE_GRAY) { /* RGB images have a bit depth at least equal to '8' */ if (that->bit_depth < 8) that->sample_depth = that->bit_depth = 8; /* And just changing the colour type works here because the green and blue * channels are being maintained in lock-step with the red/gray: */ that->colour_type = PNG_COLOR_TYPE_RGB; } else if (that->colour_type == PNG_COLOR_TYPE_GRAY_ALPHA) that->colour_type = PNG_COLOR_TYPE_RGB_ALPHA; this->next->mod(this->next, that, pp, display); } static int image_transform_png_set_gray_to_rgb_add(image_transform *this, const image_transform **that, png_byte colour_type, png_byte bit_depth) { UNUSED(bit_depth) this->next = *that; *that = this; return (colour_type & PNG_COLOR_MASK_COLOR) == 0; } IT(gray_to_rgb); #undef PT #define PT ITSTRUCT(gray_to_rgb) #endif /* PNG_READ_GRAY_TO_RGB_SUPPORTED */ #ifdef PNG_READ_EXPAND_SUPPORTED /* png_set_expand */ static void image_transform_png_set_expand_set(const image_transform *this, transform_display *that, png_structp pp, png_infop pi) { png_set_expand(pp); if (that->this.has_tRNS) that->this.is_transparent = 1; this->next->set(this->next, that, pp, pi); } static void image_transform_png_set_expand_mod(const image_transform *this, image_pixel *that, png_const_structp pp, const transform_display *display) { /* The general expand case depends on what the colour type is: */ if (that->colour_type == PNG_COLOR_TYPE_PALETTE) image_pixel_convert_PLTE(that); else if (that->bit_depth < 8) /* grayscale */ that->sample_depth = that->bit_depth = 8; if (that->have_tRNS) image_pixel_add_alpha(that, &display->this, 0/*!for background*/); this->next->mod(this->next, that, pp, display); } static int image_transform_png_set_expand_add(image_transform *this, const image_transform **that, png_byte colour_type, png_byte bit_depth) { UNUSED(bit_depth) this->next = *that; *that = this; /* 'expand' should do nothing for RGBA or GA input - no tRNS and the bit * depth is at least 8 already. */ return (colour_type & PNG_COLOR_MASK_ALPHA) == 0; } IT(expand); #undef PT #define PT ITSTRUCT(expand) #endif /* PNG_READ_EXPAND_SUPPORTED */ #ifdef PNG_READ_EXPAND_SUPPORTED /* png_set_expand_gray_1_2_4_to_8 * Pre 1.7.0 LIBPNG BUG: this just does an 'expand' */ static void image_transform_png_set_expand_gray_1_2_4_to_8_set( const image_transform *this, transform_display *that, png_structp pp, png_infop pi) { png_set_expand_gray_1_2_4_to_8(pp); /* NOTE: don't expect this to expand tRNS */ this->next->set(this->next, that, pp, pi); } static void image_transform_png_set_expand_gray_1_2_4_to_8_mod( const image_transform *this, image_pixel *that, png_const_structp pp, const transform_display *display) { #if PNG_LIBPNG_VER < 10700 image_transform_png_set_expand_mod(this, that, pp, display); #else /* Only expand grayscale of bit depth less than 8: */ if (that->colour_type == PNG_COLOR_TYPE_GRAY && that->bit_depth < 8) that->sample_depth = that->bit_depth = 8; this->next->mod(this->next, that, pp, display); #endif /* 1.7 or later */ } static int image_transform_png_set_expand_gray_1_2_4_to_8_add(image_transform *this, const image_transform **that, png_byte colour_type, png_byte bit_depth) { #if PNG_LIBPNG_VER < 10700 return image_transform_png_set_expand_add(this, that, colour_type, bit_depth); #else UNUSED(bit_depth) this->next = *that; *that = this; /* This should do nothing unless the color type is gray and the bit depth is * less than 8: */ return colour_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8; #endif /* 1.7 or later */ } IT(expand_gray_1_2_4_to_8); #undef PT #define PT ITSTRUCT(expand_gray_1_2_4_to_8) #endif /* PNG_READ_EXPAND_SUPPORTED */ #ifdef PNG_READ_EXPAND_16_SUPPORTED /* png_set_expand_16 */ static void image_transform_png_set_expand_16_set(const image_transform *this, transform_display *that, png_structp pp, png_infop pi) { png_set_expand_16(pp); /* NOTE: prior to 1.7 libpng does SET_EXPAND as well, so tRNS is expanded. */ # if PNG_LIBPNG_VER < 10700 if (that->this.has_tRNS) that->this.is_transparent = 1; # endif this->next->set(this->next, that, pp, pi); } static void image_transform_png_set_expand_16_mod(const image_transform *this, image_pixel *that, png_const_structp pp, const transform_display *display) { /* Expect expand_16 to expand everything to 16 bits as a result of also * causing 'expand' to happen. */ if (that->colour_type == PNG_COLOR_TYPE_PALETTE) image_pixel_convert_PLTE(that); if (that->have_tRNS) image_pixel_add_alpha(that, &display->this, 0/*!for background*/); if (that->bit_depth < 16) that->sample_depth = that->bit_depth = 16; this->next->mod(this->next, that, pp, display); } static int image_transform_png_set_expand_16_add(image_transform *this, const image_transform **that, png_byte colour_type, png_byte bit_depth) { UNUSED(colour_type) this->next = *that; *that = this; /* expand_16 does something unless the bit depth is already 16. */ return bit_depth < 16; } IT(expand_16); #undef PT #define PT ITSTRUCT(expand_16) #endif /* PNG_READ_EXPAND_16_SUPPORTED */ #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED /* API added in 1.5.4 */ /* png_set_scale_16 */ static void image_transform_png_set_scale_16_set(const image_transform *this, transform_display *that, png_structp pp, png_infop pi) { png_set_scale_16(pp); # if PNG_LIBPNG_VER < 10700 /* libpng will limit the gamma table size: */ that->max_gamma_8 = PNG_MAX_GAMMA_8; # endif this->next->set(this->next, that, pp, pi); } static void image_transform_png_set_scale_16_mod(const image_transform *this, image_pixel *that, png_const_structp pp, const transform_display *display) { if (that->bit_depth == 16) { that->sample_depth = that->bit_depth = 8; if (that->red_sBIT > 8) that->red_sBIT = 8; if (that->green_sBIT > 8) that->green_sBIT = 8; if (that->blue_sBIT > 8) that->blue_sBIT = 8; if (that->alpha_sBIT > 8) that->alpha_sBIT = 8; } this->next->mod(this->next, that, pp, display); } static int image_transform_png_set_scale_16_add(image_transform *this, const image_transform **that, png_byte colour_type, png_byte bit_depth) { UNUSED(colour_type) this->next = *that; *that = this; return bit_depth > 8; } IT(scale_16); #undef PT #define PT ITSTRUCT(scale_16) #endif /* PNG_READ_SCALE_16_TO_8_SUPPORTED (1.5.4 on) */ #ifdef PNG_READ_16_TO_8_SUPPORTED /* the default before 1.5.4 */ /* png_set_strip_16 */ static void image_transform_png_set_strip_16_set(const image_transform *this, transform_display *that, png_structp pp, png_infop pi) { png_set_strip_16(pp); # if PNG_LIBPNG_VER < 10700 /* libpng will limit the gamma table size: */ that->max_gamma_8 = PNG_MAX_GAMMA_8; # endif this->next->set(this->next, that, pp, pi); } static void image_transform_png_set_strip_16_mod(const image_transform *this, image_pixel *that, png_const_structp pp, const transform_display *display) { if (that->bit_depth == 16) { that->sample_depth = that->bit_depth = 8; if (that->red_sBIT > 8) that->red_sBIT = 8; if (that->green_sBIT > 8) that->green_sBIT = 8; if (that->blue_sBIT > 8) that->blue_sBIT = 8; if (that->alpha_sBIT > 8) that->alpha_sBIT = 8; /* Prior to 1.5.4 png_set_strip_16 would use an 'accurate' method if this * configuration option is set. From 1.5.4 the flag is never set and the * 'scale' API (above) must be used. */ # ifdef PNG_READ_ACCURATE_SCALE_SUPPORTED # if PNG_LIBPNG_VER >= 10504 # error PNG_READ_ACCURATE_SCALE should not be set # endif /* The strip 16 algorithm drops the low 8 bits rather than calculating * 1/257, so we need to adjust the permitted errors appropriately: * Notice that this is only relevant prior to the addition of the * png_set_scale_16 API in 1.5.4 (but 1.5.4+ always defines the above!) */ { const double d = (255-128.5)/65535; that->rede += d; that->greene += d; that->bluee += d; that->alphae += d; } # endif } this->next->mod(this->next, that, pp, display); } static int image_transform_png_set_strip_16_add(image_transform *this, const image_transform **that, png_byte colour_type, png_byte bit_depth) { UNUSED(colour_type) this->next = *that; *that = this; return bit_depth > 8; } IT(strip_16); #undef PT #define PT ITSTRUCT(strip_16) #endif /* PNG_READ_16_TO_8_SUPPORTED */ #ifdef PNG_READ_STRIP_ALPHA_SUPPORTED /* png_set_strip_alpha */ static void image_transform_png_set_strip_alpha_set(const image_transform *this, transform_display *that, png_structp pp, png_infop pi) { png_set_strip_alpha(pp); this->next->set(this->next, that, pp, pi); } static void image_transform_png_set_strip_alpha_mod(const image_transform *this, image_pixel *that, png_const_structp pp, const transform_display *display) { if (that->colour_type == PNG_COLOR_TYPE_GRAY_ALPHA) that->colour_type = PNG_COLOR_TYPE_GRAY; else if (that->colour_type == PNG_COLOR_TYPE_RGB_ALPHA) that->colour_type = PNG_COLOR_TYPE_RGB; that->have_tRNS = 0; that->alphaf = 1; this->next->mod(this->next, that, pp, display); } static int image_transform_png_set_strip_alpha_add(image_transform *this, const image_transform **that, png_byte colour_type, png_byte bit_depth) { UNUSED(bit_depth) this->next = *that; *that = this; return (colour_type & PNG_COLOR_MASK_ALPHA) != 0; } IT(strip_alpha); #undef PT #define PT ITSTRUCT(strip_alpha) #endif /* PNG_READ_STRIP_ALPHA_SUPPORTED */ #ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED /* png_set_rgb_to_gray(png_structp, int err_action, double red, double green) * png_set_rgb_to_gray_fixed(png_structp, int err_action, png_fixed_point red, * png_fixed_point green) * png_get_rgb_to_gray_status * * The 'default' test here uses values known to be used inside libpng prior to * 1.7.0: * * red: 6968 * green: 23434 * blue: 2366 * * These values are being retained for compatibility, along with the somewhat * broken truncation calculation in the fast-and-inaccurate code path. Older * versions of libpng will fail the accuracy tests below because they use the * truncation algorithm everywhere. */ #define data ITDATA(rgb_to_gray) static struct { double gamma; /* File gamma to use in processing */ /* The following are the parameters for png_set_rgb_to_gray: */ # ifdef PNG_FLOATING_POINT_SUPPORTED double red_to_set; double green_to_set; # else png_fixed_point red_to_set; png_fixed_point green_to_set; # endif /* The actual coefficients: */ double red_coefficient; double green_coefficient; double blue_coefficient; /* Set if the coeefficients have been overridden. */ int coefficients_overridden; } data; #undef image_transform_ini #define image_transform_ini image_transform_png_set_rgb_to_gray_ini static void image_transform_png_set_rgb_to_gray_ini(const image_transform *this, transform_display *that) { png_modifier *pm = that->pm; const color_encoding *e = pm->current_encoding; UNUSED(this) /* Since we check the encoding this flag must be set: */ pm->test_uses_encoding = 1; /* If 'e' is not NULL chromaticity information is present and either a cHRM * or an sRGB chunk will be inserted. */ if (e != 0) { /* Coefficients come from the encoding, but may need to be normalized to a * white point Y of 1.0 */ const double whiteY = e->red.Y + e->green.Y + e->blue.Y; data.red_coefficient = e->red.Y; data.green_coefficient = e->green.Y; data.blue_coefficient = e->blue.Y; if (whiteY != 1) { data.red_coefficient /= whiteY; data.green_coefficient /= whiteY; data.blue_coefficient /= whiteY; } } else { /* The default (built in) coefficients, as above: */ # if PNG_LIBPNG_VER < 10700 data.red_coefficient = 6968 / 32768.; data.green_coefficient = 23434 / 32768.; data.blue_coefficient = 2366 / 32768.; # else data.red_coefficient = .2126; data.green_coefficient = .7152; data.blue_coefficient = .0722; # endif } data.gamma = pm->current_gamma; /* If not set then the calculations assume linear encoding (implicitly): */ if (data.gamma == 0) data.gamma = 1; /* The arguments to png_set_rgb_to_gray can override the coefficients implied * by the color space encoding. If doing exhaustive checks do the override * in each case, otherwise do it randomly. */ if (pm->test_exhaustive) { /* First time in coefficients_overridden is 0, the following sets it to 1, * so repeat if it is set. If a test fails this may mean we subsequently * skip a non-override test, ignore that. */ data.coefficients_overridden = !data.coefficients_overridden; pm->repeat = data.coefficients_overridden != 0; } else data.coefficients_overridden = random_choice(); if (data.coefficients_overridden) { /* These values override the color encoding defaults, simply use random * numbers. */ png_uint_32 ru; double total; ru = random_u32(); data.green_coefficient = total = (ru & 0xffff) / 65535.; ru >>= 16; data.red_coefficient = (1 - total) * (ru & 0xffff) / 65535.; total += data.red_coefficient; data.blue_coefficient = 1 - total; # ifdef PNG_FLOATING_POINT_SUPPORTED data.red_to_set = data.red_coefficient; data.green_to_set = data.green_coefficient; # else data.red_to_set = fix(data.red_coefficient); data.green_to_set = fix(data.green_coefficient); # endif /* The following just changes the error messages: */ pm->encoding_ignored = 1; } else { data.red_to_set = -1; data.green_to_set = -1; } /* Adjust the error limit in the png_modifier because of the larger errors * produced in the digitization during the gamma handling. */ if (data.gamma != 1) /* Use gamma tables */ { if (that->this.bit_depth == 16 || pm->assume_16_bit_calculations) { /* The computations have the form: * * r * rc + g * gc + b * bc * * Each component of which is +/-1/65535 from the gamma_to_1 table * lookup, resulting in a base error of +/-6. The gamma_from_1 * conversion adds another +/-2 in the 16-bit case and * +/-(1<<(15-PNG_MAX_GAMMA_8)) in the 8-bit case. */ # if PNG_LIBPNG_VER < 10700 if (that->this.bit_depth < 16) that->max_gamma_8 = PNG_MAX_GAMMA_8; # endif that->pm->limit += pow( (that->this.bit_depth == 16 || that->max_gamma_8 > 14 ? 8. : 6. + (1<<(15-that->max_gamma_8)) )/65535, data.gamma); } else { /* Rounding to 8 bits in the linear space causes massive errors which * will trigger the error check in transform_range_check. Fix that * here by taking the gamma encoding into account. * * When DIGITIZE is set because a pre-1.7 version of libpng is being * tested allow a bigger slack. * * NOTE: this number only affects the internal limit check in pngvalid, * it has no effect on the limits applied to the libpng values. */ #if DIGITIZE that->pm->limit += pow( 2.0/255, data.gamma); #else that->pm->limit += pow( 1.0/255, data.gamma); #endif } } else { /* With no gamma correction a large error comes from the truncation of the * calculation in the 8 bit case, allow for that here. */ if (that->this.bit_depth != 16 && !pm->assume_16_bit_calculations) that->pm->limit += 4E-3; } } static void image_transform_png_set_rgb_to_gray_set(const image_transform *this, transform_display *that, png_structp pp, png_infop pi) { int error_action = 1; /* no error, no defines in png.h */ # ifdef PNG_FLOATING_POINT_SUPPORTED png_set_rgb_to_gray(pp, error_action, data.red_to_set, data.green_to_set); # else png_set_rgb_to_gray_fixed(pp, error_action, data.red_to_set, data.green_to_set); # endif # ifdef PNG_READ_cHRM_SUPPORTED if (that->pm->current_encoding != 0) { /* We have an encoding so a cHRM chunk may have been set; if so then * check that the libpng APIs give the correct (X,Y,Z) values within * some margin of error for the round trip through the chromaticity * form. */ # ifdef PNG_FLOATING_POINT_SUPPORTED # define API_function png_get_cHRM_XYZ # define API_form "FP" # define API_type double # define API_cvt(x) (x) # else # define API_function png_get_cHRM_XYZ_fixed # define API_form "fixed" # define API_type png_fixed_point # define API_cvt(x) ((double)(x)/PNG_FP_1) # endif API_type rX, gX, bX; API_type rY, gY, bY; API_type rZ, gZ, bZ; if ((API_function(pp, pi, &rX, &rY, &rZ, &gX, &gY, &gZ, &bX, &bY, &bZ) & PNG_INFO_cHRM) != 0) { double maxe; const char *el; color_encoding e, o; /* Expect libpng to return a normalized result, but the original * color space encoding may not be normalized. */ modifier_current_encoding(that->pm, &o); normalize_color_encoding(&o); /* Sanity check the pngvalid code - the coefficients should match * the normalized Y values of the encoding unless they were * overridden. */ if (data.red_to_set == -1 && data.green_to_set == -1 && (fabs(o.red.Y - data.red_coefficient) > DBL_EPSILON || fabs(o.green.Y - data.green_coefficient) > DBL_EPSILON || fabs(o.blue.Y - data.blue_coefficient) > DBL_EPSILON)) png_error(pp, "internal pngvalid cHRM coefficient error"); /* Generate a colour space encoding. */ e.gamma = o.gamma; /* not used */ e.red.X = API_cvt(rX); e.red.Y = API_cvt(rY); e.red.Z = API_cvt(rZ); e.green.X = API_cvt(gX); e.green.Y = API_cvt(gY); e.green.Z = API_cvt(gZ); e.blue.X = API_cvt(bX); e.blue.Y = API_cvt(bY); e.blue.Z = API_cvt(bZ); /* This should match the original one from the png_modifier, within * the range permitted by the libpng fixed point representation. */ maxe = 0; el = "-"; /* Set to element name with error */ # define CHECK(col,x)\ {\ double err = fabs(o.col.x - e.col.x);\ if (err > maxe)\ {\ maxe = err;\ el = #col "(" #x ")";\ }\ } CHECK(red,X) CHECK(red,Y) CHECK(red,Z) CHECK(green,X) CHECK(green,Y) CHECK(green,Z) CHECK(blue,X) CHECK(blue,Y) CHECK(blue,Z) /* Here in both fixed and floating cases to check the values read * from the cHRm chunk. PNG uses fixed point in the cHRM chunk, so * we can't expect better than +/-.5E-5 on the result, allow 1E-5. */ if (maxe >= 1E-5) { size_t pos = 0; char buffer[256]; pos = safecat(buffer, sizeof buffer, pos, API_form); pos = safecat(buffer, sizeof buffer, pos, " cHRM "); pos = safecat(buffer, sizeof buffer, pos, el); pos = safecat(buffer, sizeof buffer, pos, " error: "); pos = safecatd(buffer, sizeof buffer, pos, maxe, 7); pos = safecat(buffer, sizeof buffer, pos, " "); /* Print the color space without the gamma value: */ pos = safecat_color_encoding(buffer, sizeof buffer, pos, &o, 0); pos = safecat(buffer, sizeof buffer, pos, " -> "); pos = safecat_color_encoding(buffer, sizeof buffer, pos, &e, 0); png_error(pp, buffer); } } } # endif /* READ_cHRM */ this->next->set(this->next, that, pp, pi); } static void image_transform_png_set_rgb_to_gray_mod(const image_transform *this, image_pixel *that, png_const_structp pp, const transform_display *display) { if ((that->colour_type & PNG_COLOR_MASK_COLOR) != 0) { double gray, err; # if PNG_LIBPNG_VER < 10700 if (that->colour_type == PNG_COLOR_TYPE_PALETTE) image_pixel_convert_PLTE(that); # endif /* Image now has RGB channels... */ # if DIGITIZE { png_modifier *pm = display->pm; unsigned int sample_depth = that->sample_depth; unsigned int calc_depth = (pm->assume_16_bit_calculations ? 16 : sample_depth); unsigned int gamma_depth = (sample_depth == 16 ? display->max_gamma_8 : (pm->assume_16_bit_calculations ? display->max_gamma_8 : sample_depth)); int isgray; double r, g, b; double rlo, rhi, glo, ghi, blo, bhi, graylo, grayhi; /* Do this using interval arithmetic, otherwise it is too difficult to * handle the errors correctly. * * To handle the gamma correction work out the upper and lower bounds * of the digitized value. Assume rounding here - normally the values * will be identical after this operation if there is only one * transform, feel free to delete the png_error checks on this below in * the future (this is just me trying to ensure it works!) * * Interval arithmetic is exact, but to implement it it must be * possible to control the floating point implementation rounding mode. * This cannot be done in ANSI-C, so instead I reduce the 'lo' values * by DBL_EPSILON and increase the 'hi' values by the same. */ # define DD(v,d,r) (digitize(v*(1-DBL_EPSILON), d, r) * (1-DBL_EPSILON)) # define DU(v,d,r) (digitize(v*(1+DBL_EPSILON), d, r) * (1+DBL_EPSILON)) r = rlo = rhi = that->redf; rlo -= that->rede; rlo = DD(rlo, calc_depth, 1/*round*/); rhi += that->rede; rhi = DU(rhi, calc_depth, 1/*round*/); g = glo = ghi = that->greenf; glo -= that->greene; glo = DD(glo, calc_depth, 1/*round*/); ghi += that->greene; ghi = DU(ghi, calc_depth, 1/*round*/); b = blo = bhi = that->bluef; blo -= that->bluee; blo = DD(blo, calc_depth, 1/*round*/); bhi += that->bluee; bhi = DU(bhi, calc_depth, 1/*round*/); isgray = r==g && g==b; if (data.gamma != 1) { const double power = 1/data.gamma; const double abse = .5/(sample_depth == 16 ? 65535 : 255); /* If a gamma calculation is done it is done using lookup tables of * precision gamma_depth, so the already digitized value above may * need to be further digitized here. */ if (gamma_depth != calc_depth) { rlo = DD(rlo, gamma_depth, 0/*truncate*/); rhi = DU(rhi, gamma_depth, 0/*truncate*/); glo = DD(glo, gamma_depth, 0/*truncate*/); ghi = DU(ghi, gamma_depth, 0/*truncate*/); blo = DD(blo, gamma_depth, 0/*truncate*/); bhi = DU(bhi, gamma_depth, 0/*truncate*/); } /* 'abse' is the error in the gamma table calculation itself. */ r = pow(r, power); rlo = DD(pow(rlo, power)-abse, calc_depth, 1); rhi = DU(pow(rhi, power)+abse, calc_depth, 1); g = pow(g, power); glo = DD(pow(glo, power)-abse, calc_depth, 1); ghi = DU(pow(ghi, power)+abse, calc_depth, 1); b = pow(b, power); blo = DD(pow(blo, power)-abse, calc_depth, 1); bhi = DU(pow(bhi, power)+abse, calc_depth, 1); } /* Now calculate the actual gray values. Although the error in the * coefficients depends on whether they were specified on the command * line (in which case truncation to 15 bits happened) or not (rounding * was used) the maximum error in an individual coefficient is always * 2/32768, because even in the rounding case the requirement that * coefficients add up to 32768 can cause a larger rounding error. * * The only time when rounding doesn't occur in 1.5.5 and later is when * the non-gamma code path is used for less than 16 bit data. */ gray = r * data.red_coefficient + g * data.green_coefficient + b * data.blue_coefficient; { int do_round = data.gamma != 1 || calc_depth == 16; const double ce = 2. / 32768; graylo = DD(rlo * (data.red_coefficient-ce) + glo * (data.green_coefficient-ce) + blo * (data.blue_coefficient-ce), calc_depth, do_round); if (graylo > gray) /* always accept the right answer */ graylo = gray; grayhi = DU(rhi * (data.red_coefficient+ce) + ghi * (data.green_coefficient+ce) + bhi * (data.blue_coefficient+ce), calc_depth, do_round); if (grayhi < gray) grayhi = gray; } /* And invert the gamma. */ if (data.gamma != 1) { const double power = data.gamma; /* And this happens yet again, shifting the values once more. */ if (gamma_depth != sample_depth) { rlo = DD(rlo, gamma_depth, 0/*truncate*/); rhi = DU(rhi, gamma_depth, 0/*truncate*/); glo = DD(glo, gamma_depth, 0/*truncate*/); ghi = DU(ghi, gamma_depth, 0/*truncate*/); blo = DD(blo, gamma_depth, 0/*truncate*/); bhi = DU(bhi, gamma_depth, 0/*truncate*/); } gray = pow(gray, power); graylo = DD(pow(graylo, power), sample_depth, 1); grayhi = DU(pow(grayhi, power), sample_depth, 1); } # undef DD # undef DU /* Now the error can be calculated. * * If r==g==b because there is no overall gamma correction libpng * currently preserves the original value. */ if (isgray) err = (that->rede + that->greene + that->bluee)/3; else { err = fabs(grayhi-gray); if (fabs(gray - graylo) > err) err = fabs(graylo-gray); #if !RELEASE_BUILD /* Check that this worked: */ if (err > pm->limit) { size_t pos = 0; char buffer[128]; pos = safecat(buffer, sizeof buffer, pos, "rgb_to_gray error "); pos = safecatd(buffer, sizeof buffer, pos, err, 6); pos = safecat(buffer, sizeof buffer, pos, " exceeds limit "); pos = safecatd(buffer, sizeof buffer, pos, pm->limit, 6); png_warning(pp, buffer); pm->limit = err; } #endif /* !RELEASE_BUILD */ } } # else /* !DIGITIZE */ { double r = that->redf; double re = that->rede; double g = that->greenf; double ge = that->greene; double b = that->bluef; double be = that->bluee; # if PNG_LIBPNG_VER < 10700 /* The true gray case involves no math in earlier versions (not * true, there was some if gamma correction was happening too.) */ if (r == g && r == b) { gray = r; err = re; if (err < ge) err = ge; if (err < be) err = be; } else # endif /* before 1.7 */ if (data.gamma == 1) { /* There is no need to do the conversions to and from linear space, * so the calculation should be a lot more accurate. There is a * built in error in the coefficients because they only have 15 bits * and are adjusted to make sure they add up to 32768. This * involves a integer calculation with truncation of the form: * * ((int)(coefficient * 100000) * 32768)/100000 * * This is done to the red and green coefficients (the ones * provided to the API) then blue is calculated from them so the * result adds up to 32768. In the worst case this can result in * a -1 error in red and green and a +2 error in blue. Consequently * the worst case in the calculation below is 2/32768 error. * * TODO: consider fixing this in libpng by rounding the calculation * limiting the error to 1/32768. * * Handling this by adding 2/32768 here avoids needing to increase * the global error limits to take this into account.) */ gray = r * data.red_coefficient + g * data.green_coefficient + b * data.blue_coefficient; err = re * data.red_coefficient + ge * data.green_coefficient + be * data.blue_coefficient + 2./32768 + gray * 5 * DBL_EPSILON; } else { /* The calculation happens in linear space, and this produces much * wider errors in the encoded space. These are handled here by * factoring the errors in to the calculation. There are two table * lookups in the calculation and each introduces a quantization * error defined by the table size. */ png_modifier *pm = display->pm; double in_qe = (that->sample_depth > 8 ? .5/65535 : .5/255); double out_qe = (that->sample_depth > 8 ? .5/65535 : (pm->assume_16_bit_calculations ? .5/(1<max_gamma_8) : .5/255)); double rhi, ghi, bhi, grayhi; double g1 = 1/data.gamma; rhi = r + re + in_qe; if (rhi > 1) rhi = 1; r -= re + in_qe; if (r < 0) r = 0; ghi = g + ge + in_qe; if (ghi > 1) ghi = 1; g -= ge + in_qe; if (g < 0) g = 0; bhi = b + be + in_qe; if (bhi > 1) bhi = 1; b -= be + in_qe; if (b < 0) b = 0; r = pow(r, g1)*(1-DBL_EPSILON); rhi = pow(rhi, g1)*(1+DBL_EPSILON); g = pow(g, g1)*(1-DBL_EPSILON); ghi = pow(ghi, g1)*(1+DBL_EPSILON); b = pow(b, g1)*(1-DBL_EPSILON); bhi = pow(bhi, g1)*(1+DBL_EPSILON); /* Work out the lower and upper bounds for the gray value in the * encoded space, then work out an average and error. Remove the * previously added input quantization error at this point. */ gray = r * data.red_coefficient + g * data.green_coefficient + b * data.blue_coefficient - 2./32768 - out_qe; if (gray <= 0) gray = 0; else { gray *= (1 - 6 * DBL_EPSILON); gray = pow(gray, data.gamma) * (1-DBL_EPSILON); } grayhi = rhi * data.red_coefficient + ghi * data.green_coefficient + bhi * data.blue_coefficient + 2./32768 + out_qe; grayhi *= (1 + 6 * DBL_EPSILON); if (grayhi >= 1) grayhi = 1; else grayhi = pow(grayhi, data.gamma) * (1+DBL_EPSILON); err = (grayhi - gray) / 2; gray = (grayhi + gray) / 2; if (err <= in_qe) err = gray * DBL_EPSILON; else err -= in_qe; #if !RELEASE_BUILD /* Validate that the error is within limits (this has caused * problems before, it's much easier to detect them here.) */ if (err > pm->limit) { size_t pos = 0; char buffer[128]; pos = safecat(buffer, sizeof buffer, pos, "rgb_to_gray error "); pos = safecatd(buffer, sizeof buffer, pos, err, 6); pos = safecat(buffer, sizeof buffer, pos, " exceeds limit "); pos = safecatd(buffer, sizeof buffer, pos, pm->limit, 6); png_warning(pp, buffer); pm->limit = err; } #endif /* !RELEASE_BUILD */ } } # endif /* !DIGITIZE */ that->bluef = that->greenf = that->redf = gray; that->bluee = that->greene = that->rede = err; /* The sBIT is the minimum of the three colour channel sBITs. */ if (that->red_sBIT > that->green_sBIT) that->red_sBIT = that->green_sBIT; if (that->red_sBIT > that->blue_sBIT) that->red_sBIT = that->blue_sBIT; that->blue_sBIT = that->green_sBIT = that->red_sBIT; /* And remove the colour bit in the type: */ if (that->colour_type == PNG_COLOR_TYPE_RGB) that->colour_type = PNG_COLOR_TYPE_GRAY; else if (that->colour_type == PNG_COLOR_TYPE_RGB_ALPHA) that->colour_type = PNG_COLOR_TYPE_GRAY_ALPHA; } this->next->mod(this->next, that, pp, display); } static int image_transform_png_set_rgb_to_gray_add(image_transform *this, const image_transform **that, png_byte colour_type, png_byte bit_depth) { UNUSED(bit_depth) this->next = *that; *that = this; return (colour_type & PNG_COLOR_MASK_COLOR) != 0; } #undef data IT(rgb_to_gray); #undef PT #define PT ITSTRUCT(rgb_to_gray) #undef image_transform_ini #define image_transform_ini image_transform_default_ini #endif /* PNG_READ_RGB_TO_GRAY_SUPPORTED */ #ifdef PNG_READ_BACKGROUND_SUPPORTED /* png_set_background(png_structp, png_const_color_16p background_color, * int background_gamma_code, int need_expand, double background_gamma) * png_set_background_fixed(png_structp, png_const_color_16p background_color, * int background_gamma_code, int need_expand, * png_fixed_point background_gamma) * * This ignores the gamma (at present.) */ #define data ITDATA(background) static image_pixel data; static void image_transform_png_set_background_set(const image_transform *this, transform_display *that, png_structp pp, png_infop pi) { png_byte colour_type, bit_depth; png_byte random_bytes[8]; /* 8 bytes - 64 bits - the biggest pixel */ int expand; png_color_16 back; /* We need a background colour, because we don't know exactly what transforms * have been set we have to supply the colour in the original file format and * so we need to know what that is! The background colour is stored in the * transform_display. */ R8(random_bytes); /* Read the random value, for colour type 3 the background colour is actually * expressed as a 24bit rgb, not an index. */ colour_type = that->this.colour_type; if (colour_type == 3) { colour_type = PNG_COLOR_TYPE_RGB; bit_depth = 8; expand = 0; /* passing in an RGB not a pixel index */ } else { if (that->this.has_tRNS) that->this.is_transparent = 1; bit_depth = that->this.bit_depth; expand = 1; } image_pixel_init(&data, random_bytes, colour_type, bit_depth, 0/*x*/, 0/*unused: palette*/, NULL/*format*/); /* Extract the background colour from this image_pixel, but make sure the * unused fields of 'back' are garbage. */ R8(back); if (colour_type & PNG_COLOR_MASK_COLOR) { back.red = (png_uint_16)data.red; back.green = (png_uint_16)data.green; back.blue = (png_uint_16)data.blue; } else back.gray = (png_uint_16)data.red; #ifdef PNG_FLOATING_POINT_SUPPORTED png_set_background(pp, &back, PNG_BACKGROUND_GAMMA_FILE, expand, 0); #else png_set_background_fixed(pp, &back, PNG_BACKGROUND_GAMMA_FILE, expand, 0); #endif this->next->set(this->next, that, pp, pi); } static void image_transform_png_set_background_mod(const image_transform *this, image_pixel *that, png_const_structp pp, const transform_display *display) { /* Check for tRNS first: */ if (that->have_tRNS && that->colour_type != PNG_COLOR_TYPE_PALETTE) image_pixel_add_alpha(that, &display->this, 1/*for background*/); /* This is only necessary if the alpha value is less than 1. */ if (that->alphaf < 1) { /* Now we do the background calculation without any gamma correction. */ if (that->alphaf <= 0) { that->redf = data.redf; that->greenf = data.greenf; that->bluef = data.bluef; that->rede = data.rede; that->greene = data.greene; that->bluee = data.bluee; that->red_sBIT= data.red_sBIT; that->green_sBIT= data.green_sBIT; that->blue_sBIT= data.blue_sBIT; } else /* 0 < alpha < 1 */ { double alf = 1 - that->alphaf; that->redf = that->redf * that->alphaf + data.redf * alf; that->rede = that->rede * that->alphaf + data.rede * alf + DBL_EPSILON; that->greenf = that->greenf * that->alphaf + data.greenf * alf; that->greene = that->greene * that->alphaf + data.greene * alf + DBL_EPSILON; that->bluef = that->bluef * that->alphaf + data.bluef * alf; that->bluee = that->bluee * that->alphaf + data.bluee * alf + DBL_EPSILON; } /* Remove the alpha type and set the alpha (not in that order.) */ that->alphaf = 1; that->alphae = 0; } if (that->colour_type == PNG_COLOR_TYPE_RGB_ALPHA) that->colour_type = PNG_COLOR_TYPE_RGB; else if (that->colour_type == PNG_COLOR_TYPE_GRAY_ALPHA) that->colour_type = PNG_COLOR_TYPE_GRAY; /* PNG_COLOR_TYPE_PALETTE is not changed */ this->next->mod(this->next, that, pp, display); } #define image_transform_png_set_background_add image_transform_default_add #undef data IT(background); #undef PT #define PT ITSTRUCT(background) #endif /* PNG_READ_BACKGROUND_SUPPORTED */ /* png_set_quantize(png_structp, png_colorp palette, int num_palette, * int maximum_colors, png_const_uint_16p histogram, int full_quantize) * * Very difficult to validate this! */ /*NOTE: TBD NYI */ /* The data layout transforms are handled by swapping our own channel data, * necessarily these need to happen at the end of the transform list because the * semantic of the channels changes after these are executed. Some of these, * like set_shift and set_packing, can't be done at present because they change * the layout of the data at the sub-sample level so sample() won't get the * right answer. */ /* png_set_invert_alpha */ #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED /* Invert the alpha channel * * png_set_invert_alpha(png_structrp png_ptr) */ static void image_transform_png_set_invert_alpha_set(const image_transform *this, transform_display *that, png_structp pp, png_infop pi) { png_set_invert_alpha(pp); this->next->set(this->next, that, pp, pi); } static void image_transform_png_set_invert_alpha_mod(const image_transform *this, image_pixel *that, png_const_structp pp, const transform_display *display) { if (that->colour_type & 4) that->alpha_inverted = 1; this->next->mod(this->next, that, pp, display); } static int image_transform_png_set_invert_alpha_add(image_transform *this, const image_transform **that, png_byte colour_type, png_byte bit_depth) { UNUSED(bit_depth) this->next = *that; *that = this; /* Only has an effect on pixels with alpha: */ return (colour_type & 4) != 0; } IT(invert_alpha); #undef PT #define PT ITSTRUCT(invert_alpha) #endif /* PNG_READ_INVERT_ALPHA_SUPPORTED */ /* png_set_bgr */ #ifdef PNG_READ_BGR_SUPPORTED /* Swap R,G,B channels to order B,G,R. * * png_set_bgr(png_structrp png_ptr) * * This only has an effect on RGB and RGBA pixels. */ static void image_transform_png_set_bgr_set(const image_transform *this, transform_display *that, png_structp pp, png_infop pi) { png_set_bgr(pp); this->next->set(this->next, that, pp, pi); } static void image_transform_png_set_bgr_mod(const image_transform *this, image_pixel *that, png_const_structp pp, const transform_display *display) { if (that->colour_type == PNG_COLOR_TYPE_RGB || that->colour_type == PNG_COLOR_TYPE_RGBA) that->swap_rgb = 1; this->next->mod(this->next, that, pp, display); } static int image_transform_png_set_bgr_add(image_transform *this, const image_transform **that, png_byte colour_type, png_byte bit_depth) { UNUSED(bit_depth) this->next = *that; *that = this; return colour_type == PNG_COLOR_TYPE_RGB || colour_type == PNG_COLOR_TYPE_RGBA; } IT(bgr); #undef PT #define PT ITSTRUCT(bgr) #endif /* PNG_READ_BGR_SUPPORTED */ /* png_set_swap_alpha */ #ifdef PNG_READ_SWAP_ALPHA_SUPPORTED /* Put the alpha channel first. * * png_set_swap_alpha(png_structrp png_ptr) * * This only has an effect on GA and RGBA pixels. */ static void image_transform_png_set_swap_alpha_set(const image_transform *this, transform_display *that, png_structp pp, png_infop pi) { png_set_swap_alpha(pp); this->next->set(this->next, that, pp, pi); } static void image_transform_png_set_swap_alpha_mod(const image_transform *this, image_pixel *that, png_const_structp pp, const transform_display *display) { if (that->colour_type == PNG_COLOR_TYPE_GA || that->colour_type == PNG_COLOR_TYPE_RGBA) that->alpha_first = 1; this->next->mod(this->next, that, pp, display); } static int image_transform_png_set_swap_alpha_add(image_transform *this, const image_transform **that, png_byte colour_type, png_byte bit_depth) { UNUSED(bit_depth) this->next = *that; *that = this; return colour_type == PNG_COLOR_TYPE_GA || colour_type == PNG_COLOR_TYPE_RGBA; } IT(swap_alpha); #undef PT #define PT ITSTRUCT(swap_alpha) #endif /* PNG_READ_SWAP_ALPHA_SUPPORTED */ /* png_set_swap */ #ifdef PNG_READ_SWAP_SUPPORTED /* Byte swap 16-bit components. * * png_set_swap(png_structrp png_ptr) */ static void image_transform_png_set_swap_set(const image_transform *this, transform_display *that, png_structp pp, png_infop pi) { png_set_swap(pp); this->next->set(this->next, that, pp, pi); } static void image_transform_png_set_swap_mod(const image_transform *this, image_pixel *that, png_const_structp pp, const transform_display *display) { if (that->bit_depth == 16) that->swap16 = 1; this->next->mod(this->next, that, pp, display); } static int image_transform_png_set_swap_add(image_transform *this, const image_transform **that, png_byte colour_type, png_byte bit_depth) { UNUSED(colour_type) this->next = *that; *that = this; return bit_depth == 16; } IT(swap); #undef PT #define PT ITSTRUCT(swap) #endif /* PNG_READ_SWAP_SUPPORTED */ #ifdef PNG_READ_FILLER_SUPPORTED /* Add a filler byte to 8-bit Gray or 24-bit RGB images. * * png_set_filler, (png_structp png_ptr, png_uint_32 filler, int flags)); * * Flags: * * PNG_FILLER_BEFORE * PNG_FILLER_AFTER */ #define data ITDATA(filler) static struct { png_uint_32 filler; int flags; } data; static void image_transform_png_set_filler_set(const image_transform *this, transform_display *that, png_structp pp, png_infop pi) { /* Need a random choice for 'before' and 'after' as well as for the * filler. The 'filler' value has all 32 bits set, but only bit_depth * will be used. At this point we don't know bit_depth. */ data.filler = random_u32(); data.flags = random_choice(); png_set_filler(pp, data.filler, data.flags); /* The standard display handling stuff also needs to know that * there is a filler, so set that here. */ that->this.filler = 1; this->next->set(this->next, that, pp, pi); } static void image_transform_png_set_filler_mod(const image_transform *this, image_pixel *that, png_const_structp pp, const transform_display *display) { if (that->bit_depth >= 8 && (that->colour_type == PNG_COLOR_TYPE_RGB || that->colour_type == PNG_COLOR_TYPE_GRAY)) { unsigned int max = (1U << that->bit_depth)-1; that->alpha = data.filler & max; that->alphaf = ((double)that->alpha) / max; that->alphae = 0; /* The filler has been stored in the alpha channel, we must record * that this has been done for the checking later on, the color * type is faked to have an alpha channel, but libpng won't report * this; the app has to know the extra channel is there and this * was recording in standard_display::filler above. */ that->colour_type |= 4; /* alpha added */ that->alpha_first = data.flags == PNG_FILLER_BEFORE; } this->next->mod(this->next, that, pp, display); } static int image_transform_png_set_filler_add(image_transform *this, const image_transform **that, png_byte colour_type, png_byte bit_depth) { this->next = *that; *that = this; return bit_depth >= 8 && (colour_type == PNG_COLOR_TYPE_RGB || colour_type == PNG_COLOR_TYPE_GRAY); } #undef data IT(filler); #undef PT #define PT ITSTRUCT(filler) /* png_set_add_alpha, (png_structp png_ptr, png_uint_32 filler, int flags)); */ /* Add an alpha byte to 8-bit Gray or 24-bit RGB images. */ #define data ITDATA(add_alpha) static struct { png_uint_32 filler; int flags; } data; static void image_transform_png_set_add_alpha_set(const image_transform *this, transform_display *that, png_structp pp, png_infop pi) { /* Need a random choice for 'before' and 'after' as well as for the * filler. The 'filler' value has all 32 bits set, but only bit_depth * will be used. At this point we don't know bit_depth. */ data.filler = random_u32(); data.flags = random_choice(); png_set_add_alpha(pp, data.filler, data.flags); this->next->set(this->next, that, pp, pi); } static void image_transform_png_set_add_alpha_mod(const image_transform *this, image_pixel *that, png_const_structp pp, const transform_display *display) { if (that->bit_depth >= 8 && (that->colour_type == PNG_COLOR_TYPE_RGB || that->colour_type == PNG_COLOR_TYPE_GRAY)) { unsigned int max = (1U << that->bit_depth)-1; that->alpha = data.filler & max; that->alphaf = ((double)that->alpha) / max; that->alphae = 0; that->colour_type |= 4; /* alpha added */ that->alpha_first = data.flags == PNG_FILLER_BEFORE; } this->next->mod(this->next, that, pp, display); } static int image_transform_png_set_add_alpha_add(image_transform *this, const image_transform **that, png_byte colour_type, png_byte bit_depth) { this->next = *that; *that = this; return bit_depth >= 8 && (colour_type == PNG_COLOR_TYPE_RGB || colour_type == PNG_COLOR_TYPE_GRAY); } #undef data IT(add_alpha); #undef PT #define PT ITSTRUCT(add_alpha) #endif /* PNG_READ_FILLER_SUPPORTED */ /* png_set_packing */ #ifdef PNG_READ_PACK_SUPPORTED /* Use 1 byte per pixel in 1, 2, or 4-bit depth files. * * png_set_packing(png_structrp png_ptr) * * This should only affect grayscale and palette images with less than 8 bits * per pixel. */ static void image_transform_png_set_packing_set(const image_transform *this, transform_display *that, png_structp pp, png_infop pi) { png_set_packing(pp); that->unpacked = 1; this->next->set(this->next, that, pp, pi); } static void image_transform_png_set_packing_mod(const image_transform *this, image_pixel *that, png_const_structp pp, const transform_display *display) { /* The general expand case depends on what the colour type is, * low bit-depth pixel values are unpacked into bytes without * scaling, so sample_depth is not changed. */ if (that->bit_depth < 8) /* grayscale or palette */ that->bit_depth = 8; this->next->mod(this->next, that, pp, display); } static int image_transform_png_set_packing_add(image_transform *this, const image_transform **that, png_byte colour_type, png_byte bit_depth) { UNUSED(colour_type) this->next = *that; *that = this; /* Nothing should happen unless the bit depth is less than 8: */ return bit_depth < 8; } IT(packing); #undef PT #define PT ITSTRUCT(packing) #endif /* PNG_READ_PACK_SUPPORTED */ /* png_set_packswap */ #ifdef PNG_READ_PACKSWAP_SUPPORTED /* Swap pixels packed into bytes; reverses the order on screen so that * the high order bits correspond to the rightmost pixels. * * png_set_packswap(png_structrp png_ptr) */ static void image_transform_png_set_packswap_set(const image_transform *this, transform_display *that, png_structp pp, png_infop pi) { png_set_packswap(pp); that->this.littleendian = 1; this->next->set(this->next, that, pp, pi); } static void image_transform_png_set_packswap_mod(const image_transform *this, image_pixel *that, png_const_structp pp, const transform_display *display) { if (that->bit_depth < 8) that->littleendian = 1; this->next->mod(this->next, that, pp, display); } static int image_transform_png_set_packswap_add(image_transform *this, const image_transform **that, png_byte colour_type, png_byte bit_depth) { UNUSED(colour_type) this->next = *that; *that = this; return bit_depth < 8; } IT(packswap); #undef PT #define PT ITSTRUCT(packswap) #endif /* PNG_READ_PACKSWAP_SUPPORTED */ /* png_set_invert_mono */ #ifdef PNG_READ_INVERT_MONO_SUPPORTED /* Invert the gray channel * * png_set_invert_mono(png_structrp png_ptr) */ static void image_transform_png_set_invert_mono_set(const image_transform *this, transform_display *that, png_structp pp, png_infop pi) { png_set_invert_mono(pp); this->next->set(this->next, that, pp, pi); } static void image_transform_png_set_invert_mono_mod(const image_transform *this, image_pixel *that, png_const_structp pp, const transform_display *display) { if (that->colour_type & 4) that->mono_inverted = 1; this->next->mod(this->next, that, pp, display); } static int image_transform_png_set_invert_mono_add(image_transform *this, const image_transform **that, png_byte colour_type, png_byte bit_depth) { UNUSED(bit_depth) this->next = *that; *that = this; /* Only has an effect on pixels with no colour: */ return (colour_type & 2) == 0; } IT(invert_mono); #undef PT #define PT ITSTRUCT(invert_mono) #endif /* PNG_READ_INVERT_MONO_SUPPORTED */ #ifdef PNG_READ_SHIFT_SUPPORTED /* png_set_shift(png_structp, png_const_color_8p true_bits) * * The output pixels will be shifted by the given true_bits * values. */ #define data ITDATA(shift) static png_color_8 data; static void image_transform_png_set_shift_set(const image_transform *this, transform_display *that, png_structp pp, png_infop pi) { /* Get a random set of shifts. The shifts need to do something * to test the transform, so they are limited to the bit depth * of the input image. Notice that in the following the 'gray' * field is randomized independently. This acts as a check that * libpng does use the correct field. */ unsigned int depth = that->this.bit_depth; data.red = (png_byte)/*SAFE*/(random_mod(depth)+1); data.green = (png_byte)/*SAFE*/(random_mod(depth)+1); data.blue = (png_byte)/*SAFE*/(random_mod(depth)+1); data.gray = (png_byte)/*SAFE*/(random_mod(depth)+1); data.alpha = (png_byte)/*SAFE*/(random_mod(depth)+1); png_set_shift(pp, &data); this->next->set(this->next, that, pp, pi); } static void image_transform_png_set_shift_mod(const image_transform *this, image_pixel *that, png_const_structp pp, const transform_display *display) { /* Copy the correct values into the sBIT fields, libpng does not do * anything to palette data: */ if (that->colour_type != PNG_COLOR_TYPE_PALETTE) { that->sig_bits = 1; /* The sBIT fields are reset to the values previously sent to * png_set_shift according to the colour type. * does. */ if (that->colour_type & 2) /* RGB channels */ { that->red_sBIT = data.red; that->green_sBIT = data.green; that->blue_sBIT = data.blue; } else /* One grey channel */ that->red_sBIT = that->green_sBIT = that->blue_sBIT = data.gray; that->alpha_sBIT = data.alpha; } this->next->mod(this->next, that, pp, display); } static int image_transform_png_set_shift_add(image_transform *this, const image_transform **that, png_byte colour_type, png_byte bit_depth) { UNUSED(bit_depth) this->next = *that; *that = this; return colour_type != PNG_COLOR_TYPE_PALETTE; } IT(shift); #undef PT #define PT ITSTRUCT(shift) #endif /* PNG_READ_SHIFT_SUPPORTED */ #ifdef THIS_IS_THE_PROFORMA static void image_transform_png_set_@_set(const image_transform *this, transform_display *that, png_structp pp, png_infop pi) { png_set_@(pp); this->next->set(this->next, that, pp, pi); } static void image_transform_png_set_@_mod(const image_transform *this, image_pixel *that, png_const_structp pp, const transform_display *display) { this->next->mod(this->next, that, pp, display); } static int image_transform_png_set_@_add(image_transform *this, const image_transform **that, png_byte colour_type, png_byte bit_depth) { this->next = *that; *that = this; return 1; } IT(@); #endif /* This may just be 'end' if all the transforms are disabled! */ static image_transform *const image_transform_first = &PT; static void transform_enable(const char *name) { /* Everything starts out enabled, so if we see an 'enable' disabled * everything else the first time round. */ static int all_disabled = 0; int found_it = 0; image_transform *list = image_transform_first; while (list != &image_transform_end) { if (strcmp(list->name, name) == 0) { list->enable = 1; found_it = 1; } else if (!all_disabled) list->enable = 0; list = list->list; } all_disabled = 1; if (!found_it) { fprintf(stderr, "pngvalid: --transform-enable=%s: unknown transform\n", name); exit(99); } } static void transform_disable(const char *name) { image_transform *list = image_transform_first; while (list != &image_transform_end) { if (strcmp(list->name, name) == 0) { list->enable = 0; return; } list = list->list; } fprintf(stderr, "pngvalid: --transform-disable=%s: unknown transform\n", name); exit(99); } static void image_transform_reset_count(void) { image_transform *next = image_transform_first; int count = 0; while (next != &image_transform_end) { next->local_use = 0; next->next = 0; next = next->list; ++count; } /* This can only happen if we every have more than 32 transforms (excluding * the end) in the list. */ if (count > 32) abort(); } static int image_transform_test_counter(png_uint_32 counter, unsigned int max) { /* Test the list to see if there is any point continuing, given a current * counter and a 'max' value. */ image_transform *next = image_transform_first; while (next != &image_transform_end) { /* For max 0 or 1 continue until the counter overflows: */ counter >>= 1; /* Continue if any entry hasn't reacked the max. */ if (max > 1 && next->local_use < max) return 1; next = next->list; } return max <= 1 && counter == 0; } static png_uint_32 image_transform_add(const image_transform **this, unsigned int max, png_uint_32 counter, char *name, size_t sizeof_name, size_t *pos, png_byte colour_type, png_byte bit_depth) { for (;;) /* until we manage to add something */ { png_uint_32 mask; image_transform *list; /* Find the next counter value, if the counter is zero this is the start * of the list. This routine always returns the current counter (not the * next) so it returns 0 at the end and expects 0 at the beginning. */ if (counter == 0) /* first time */ { image_transform_reset_count(); if (max <= 1) counter = 1; else counter = random_32(); } else /* advance the counter */ { switch (max) { case 0: ++counter; break; case 1: counter <<= 1; break; default: counter = random_32(); break; } } /* Now add all these items, if possible */ *this = &image_transform_end; list = image_transform_first; mask = 1; /* Go through the whole list adding anything that the counter selects: */ while (list != &image_transform_end) { if ((counter & mask) != 0 && list->enable && (max == 0 || list->local_use < max)) { /* Candidate to add: */ if (list->add(list, this, colour_type, bit_depth) || max == 0) { /* Added, so add to the name too. */ *pos = safecat(name, sizeof_name, *pos, " +"); *pos = safecat(name, sizeof_name, *pos, list->name); } else { /* Not useful and max>0, so remove it from *this: */ *this = list->next; list->next = 0; /* And, since we know it isn't useful, stop it being added again * in this run: */ list->local_use = max; } } mask <<= 1; list = list->list; } /* Now if anything was added we have something to do. */ if (*this != &image_transform_end) return counter; /* Nothing added, but was there anything in there to add? */ if (!image_transform_test_counter(counter, max)) return 0; } } static void perform_transform_test(png_modifier *pm) { png_byte colour_type = 0; png_byte bit_depth = 0; unsigned int palette_number = 0; while (next_format(&colour_type, &bit_depth, &palette_number, pm->test_lbg, pm->test_tRNS)) { png_uint_32 counter = 0; size_t base_pos; char name[64]; base_pos = safecat(name, sizeof name, 0, "transform:"); for (;;) { size_t pos = base_pos; const image_transform *list = 0; /* 'max' is currently hardwired to '1'; this should be settable on the * command line. */ counter = image_transform_add(&list, 1/*max*/, counter, name, sizeof name, &pos, colour_type, bit_depth); if (counter == 0) break; /* The command line can change this to checking interlaced images. */ do { pm->repeat = 0; transform_test(pm, FILEID(colour_type, bit_depth, palette_number, pm->interlace_type, 0, 0, 0), list, name); if (fail(pm)) return; } while (pm->repeat); } } } #endif /* PNG_READ_TRANSFORMS_SUPPORTED */ /********************************* GAMMA TESTS ********************************/ #ifdef PNG_READ_GAMMA_SUPPORTED /* Reader callbacks and implementations, where they differ from the standard * ones. */ typedef struct gamma_display { standard_display this; /* Parameters */ png_modifier* pm; double file_gamma; double screen_gamma; double background_gamma; png_byte sbit; int threshold_test; int use_input_precision; int scale16; int expand16; int do_background; png_color_16 background_color; /* Local variables */ double maxerrout; double maxerrpc; double maxerrabs; } gamma_display; #define ALPHA_MODE_OFFSET 4 static void gamma_display_init(gamma_display *dp, png_modifier *pm, png_uint_32 id, double file_gamma, double screen_gamma, png_byte sbit, int threshold_test, int use_input_precision, int scale16, int expand16, int do_background, const png_color_16 *pointer_to_the_background_color, double background_gamma) { /* Standard fields */ standard_display_init(&dp->this, &pm->this, id, do_read_interlace, pm->use_update_info); /* Parameter fields */ dp->pm = pm; dp->file_gamma = file_gamma; dp->screen_gamma = screen_gamma; dp->background_gamma = background_gamma; dp->sbit = sbit; dp->threshold_test = threshold_test; dp->use_input_precision = use_input_precision; dp->scale16 = scale16; dp->expand16 = expand16; dp->do_background = do_background; if (do_background && pointer_to_the_background_color != 0) dp->background_color = *pointer_to_the_background_color; else memset(&dp->background_color, 0, sizeof dp->background_color); /* Local variable fields */ dp->maxerrout = dp->maxerrpc = dp->maxerrabs = 0; } static void gamma_info_imp(gamma_display *dp, png_structp pp, png_infop pi) { /* Reuse the standard stuff as appropriate. */ standard_info_part1(&dp->this, pp, pi); /* If requested strip 16 to 8 bits - this is handled automagically below * because the output bit depth is read from the library. Note that there * are interactions with sBIT but, internally, libpng makes sbit at most * PNG_MAX_GAMMA_8 prior to 1.7 when doing the following. */ if (dp->scale16) # ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED png_set_scale_16(pp); # else /* The following works both in 1.5.4 and earlier versions: */ # ifdef PNG_READ_16_TO_8_SUPPORTED png_set_strip_16(pp); # else png_error(pp, "scale16 (16 to 8 bit conversion) not supported"); # endif # endif if (dp->expand16) # ifdef PNG_READ_EXPAND_16_SUPPORTED png_set_expand_16(pp); # else png_error(pp, "expand16 (8 to 16 bit conversion) not supported"); # endif if (dp->do_background >= ALPHA_MODE_OFFSET) { # ifdef PNG_READ_ALPHA_MODE_SUPPORTED { /* This tests the alpha mode handling, if supported. */ int mode = dp->do_background - ALPHA_MODE_OFFSET; /* The gamma value is the output gamma, and is in the standard, * non-inverted, representation. It provides a default for the PNG file * gamma, but since the file has a gAMA chunk this does not matter. */ const double sg = dp->screen_gamma; # ifndef PNG_FLOATING_POINT_SUPPORTED png_fixed_point g = fix(sg); # endif # ifdef PNG_FLOATING_POINT_SUPPORTED png_set_alpha_mode(pp, mode, sg); # else png_set_alpha_mode_fixed(pp, mode, g); # endif /* However, for the standard Porter-Duff algorithm the output defaults * to be linear, so if the test requires non-linear output it must be * corrected here. */ if (mode == PNG_ALPHA_STANDARD && sg != 1) { # ifdef PNG_FLOATING_POINT_SUPPORTED png_set_gamma(pp, sg, dp->file_gamma); # else png_fixed_point f = fix(dp->file_gamma); png_set_gamma_fixed(pp, g, f); # endif } } # else png_error(pp, "alpha mode handling not supported"); # endif } else { /* Set up gamma processing. */ # ifdef PNG_FLOATING_POINT_SUPPORTED png_set_gamma(pp, dp->screen_gamma, dp->file_gamma); # else { png_fixed_point s = fix(dp->screen_gamma); png_fixed_point f = fix(dp->file_gamma); png_set_gamma_fixed(pp, s, f); } # endif if (dp->do_background) { # ifdef PNG_READ_BACKGROUND_SUPPORTED /* NOTE: this assumes the caller provided the correct background gamma! */ const double bg = dp->background_gamma; # ifndef PNG_FLOATING_POINT_SUPPORTED png_fixed_point g = fix(bg); # endif # ifdef PNG_FLOATING_POINT_SUPPORTED png_set_background(pp, &dp->background_color, dp->do_background, 0/*need_expand*/, bg); # else png_set_background_fixed(pp, &dp->background_color, dp->do_background, 0/*need_expand*/, g); # endif # else png_error(pp, "png_set_background not supported"); # endif } } { int i = dp->this.use_update_info; /* Always do one call, even if use_update_info is 0. */ do png_read_update_info(pp, pi); while (--i > 0); } /* Now we may get a different cbRow: */ standard_info_part2(&dp->this, pp, pi, 1 /*images*/); } static void PNGCBAPI gamma_info(png_structp pp, png_infop pi) { gamma_info_imp(voidcast(gamma_display*, png_get_progressive_ptr(pp)), pp, pi); } /* Validate a single component value - the routine gets the input and output * sample values as unscaled PNG component values along with a cache of all the * information required to validate the values. */ typedef struct validate_info { png_const_structp pp; gamma_display *dp; png_byte sbit; int use_input_precision; int do_background; int scale16; unsigned int sbit_max; unsigned int isbit_shift; unsigned int outmax; double gamma_correction; /* Overall correction required. */ double file_inverse; /* Inverse of file gamma. */ double screen_gamma; double screen_inverse; /* Inverse of screen gamma. */ double background_red; /* Linear background value, red or gray. */ double background_green; double background_blue; double maxabs; double maxpc; double maxcalc; double maxout; double maxout_total; /* Total including quantization error */ double outlog; int outquant; } validate_info; static void init_validate_info(validate_info *vi, gamma_display *dp, png_const_structp pp, int in_depth, int out_depth) { unsigned int outmax = (1U<pp = pp; vi->dp = dp; if (dp->sbit > 0 && dp->sbit < in_depth) { vi->sbit = dp->sbit; vi->isbit_shift = in_depth - dp->sbit; } else { vi->sbit = (png_byte)in_depth; vi->isbit_shift = 0; } vi->sbit_max = (1U << vi->sbit)-1; /* This mimics the libpng threshold test, '0' is used to prevent gamma * correction in the validation test. */ vi->screen_gamma = dp->screen_gamma; if (fabs(vi->screen_gamma-1) < PNG_GAMMA_THRESHOLD) vi->screen_gamma = vi->screen_inverse = 0; else vi->screen_inverse = 1/vi->screen_gamma; vi->use_input_precision = dp->use_input_precision; vi->outmax = outmax; vi->maxabs = abserr(dp->pm, in_depth, out_depth); vi->maxpc = pcerr(dp->pm, in_depth, out_depth); vi->maxcalc = calcerr(dp->pm, in_depth, out_depth); vi->maxout = outerr(dp->pm, in_depth, out_depth); vi->outquant = output_quantization_factor(dp->pm, in_depth, out_depth); vi->maxout_total = vi->maxout + vi->outquant * .5; vi->outlog = outlog(dp->pm, in_depth, out_depth); if ((dp->this.colour_type & PNG_COLOR_MASK_ALPHA) != 0 || (dp->this.colour_type == 3 && dp->this.is_transparent) || ((dp->this.colour_type == 0 || dp->this.colour_type == 2) && dp->this.has_tRNS)) { vi->do_background = dp->do_background; if (vi->do_background != 0) { const double bg_inverse = 1/dp->background_gamma; double r, g, b; /* Caller must at least put the gray value into the red channel */ r = dp->background_color.red; r /= outmax; g = dp->background_color.green; g /= outmax; b = dp->background_color.blue; b /= outmax; # if 0 /* libpng doesn't do this optimization, if we do pngvalid will fail. */ if (fabs(bg_inverse-1) >= PNG_GAMMA_THRESHOLD) # endif { r = pow(r, bg_inverse); g = pow(g, bg_inverse); b = pow(b, bg_inverse); } vi->background_red = r; vi->background_green = g; vi->background_blue = b; } } else /* Do not expect any background processing */ vi->do_background = 0; if (vi->do_background == 0) vi->background_red = vi->background_green = vi->background_blue = 0; vi->gamma_correction = 1/(dp->file_gamma*dp->screen_gamma); if (fabs(vi->gamma_correction-1) < PNG_GAMMA_THRESHOLD) vi->gamma_correction = 0; vi->file_inverse = 1/dp->file_gamma; if (fabs(vi->file_inverse-1) < PNG_GAMMA_THRESHOLD) vi->file_inverse = 0; vi->scale16 = dp->scale16; } /* This function handles composition of a single non-alpha component. The * argument is the input sample value, in the range 0..1, and the alpha value. * The result is the composed, linear, input sample. If alpha is less than zero * this is the alpha component and the function should not be called! */ static double gamma_component_compose(int do_background, double input_sample, double alpha, double background, int *compose) { switch (do_background) { #ifdef PNG_READ_BACKGROUND_SUPPORTED case PNG_BACKGROUND_GAMMA_SCREEN: case PNG_BACKGROUND_GAMMA_FILE: case PNG_BACKGROUND_GAMMA_UNIQUE: /* Standard PNG background processing. */ if (alpha < 1) { if (alpha > 0) { input_sample = input_sample * alpha + background * (1-alpha); if (compose != NULL) *compose = 1; } else input_sample = background; } break; #endif #ifdef PNG_READ_ALPHA_MODE_SUPPORTED case ALPHA_MODE_OFFSET + PNG_ALPHA_STANDARD: case ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN: /* The components are premultiplied in either case and the output is * gamma encoded (to get standard Porter-Duff we expect the output * gamma to be set to 1.0!) */ case ALPHA_MODE_OFFSET + PNG_ALPHA_OPTIMIZED: /* The optimization is that the partial-alpha entries are linear * while the opaque pixels are gamma encoded, but this only affects the * output encoding. */ if (alpha < 1) { if (alpha > 0) { input_sample *= alpha; if (compose != NULL) *compose = 1; } else input_sample = 0; } break; #endif default: /* Standard cases where no compositing is done (so the component * value is already correct.) */ UNUSED(alpha) UNUSED(background) UNUSED(compose) break; } return input_sample; } /* This API returns the encoded *input* component, in the range 0..1 */ static double gamma_component_validate(const char *name, const validate_info *vi, unsigned int id, unsigned int od, const double alpha /* <0 for the alpha channel itself */, const double background /* component background value */) { unsigned int isbit = id >> vi->isbit_shift; unsigned int sbit_max = vi->sbit_max; unsigned int outmax = vi->outmax; int do_background = vi->do_background; double i; /* First check on the 'perfect' result obtained from the digitized input * value, id, and compare this against the actual digitized result, 'od'. * 'i' is the input result in the range 0..1: */ i = isbit; i /= sbit_max; /* Check for the fast route: if we don't do any background composition or if * this is the alpha channel ('alpha' < 0) or if the pixel is opaque then * just use the gamma_correction field to correct to the final output gamma. */ if (alpha == 1 /* opaque pixel component */ || !do_background #ifdef PNG_READ_ALPHA_MODE_SUPPORTED || do_background == ALPHA_MODE_OFFSET + PNG_ALPHA_PNG #endif || (alpha < 0 /* alpha channel */ #ifdef PNG_READ_ALPHA_MODE_SUPPORTED && do_background != ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN #endif )) { /* Then get the gamma corrected version of 'i' and compare to 'od', any * error less than .5 is insignificant - just quantization of the output * value to the nearest digital value (nevertheless the error is still * recorded - it's interesting ;-) */ double encoded_sample = i; double encoded_error; /* alpha less than 0 indicates the alpha channel, which is always linear */ if (alpha >= 0 && vi->gamma_correction > 0) encoded_sample = pow(encoded_sample, vi->gamma_correction); encoded_sample *= outmax; encoded_error = fabs(od-encoded_sample); if (encoded_error > vi->dp->maxerrout) vi->dp->maxerrout = encoded_error; if (encoded_error < vi->maxout_total && encoded_error < vi->outlog) return i; } /* The slow route - attempt to do linear calculations. */ /* There may be an error, or background processing is required, so calculate * the actual sample values - unencoded light intensity values. Note that in * practice these are not completely unencoded because they include a * 'viewing correction' to decrease or (normally) increase the perceptual * contrast of the image. There's nothing we can do about this - we don't * know what it is - so assume the unencoded value is perceptually linear. */ { double input_sample = i; /* In range 0..1 */ double output, error, encoded_sample, encoded_error; double es_lo, es_hi; int compose = 0; /* Set to one if composition done */ int output_is_encoded; /* Set if encoded to screen gamma */ int log_max_error = 1; /* Check maximum error values */ png_const_charp pass = 0; /* Reason test passes (or 0 for fail) */ /* Convert to linear light (with the above caveat.) The alpha channel is * already linear. */ if (alpha >= 0) { int tcompose; if (vi->file_inverse > 0) input_sample = pow(input_sample, vi->file_inverse); /* Handle the compose processing: */ tcompose = 0; input_sample = gamma_component_compose(do_background, input_sample, alpha, background, &tcompose); if (tcompose) compose = 1; } /* And similarly for the output value, but we need to check the background * handling to linearize it correctly. */ output = od; output /= outmax; output_is_encoded = vi->screen_gamma > 0; if (alpha < 0) /* The alpha channel */ { #ifdef PNG_READ_ALPHA_MODE_SUPPORTED if (do_background != ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN) #endif { /* In all other cases the output alpha channel is linear already, * don't log errors here, they are much larger in linear data. */ output_is_encoded = 0; log_max_error = 0; } } #ifdef PNG_READ_ALPHA_MODE_SUPPORTED else /* A component */ { if (do_background == ALPHA_MODE_OFFSET + PNG_ALPHA_OPTIMIZED && alpha < 1) /* the optimized case - linear output */ { if (alpha > 0) log_max_error = 0; output_is_encoded = 0; } } #endif if (output_is_encoded) output = pow(output, vi->screen_gamma); /* Calculate (or recalculate) the encoded_sample value and repeat the * check above (unnecessary if we took the fast route, but harmless.) */ encoded_sample = input_sample; if (output_is_encoded) encoded_sample = pow(encoded_sample, vi->screen_inverse); encoded_sample *= outmax; encoded_error = fabs(od-encoded_sample); /* Don't log errors in the alpha channel, or the 'optimized' case, * neither are significant to the overall perception. */ if (log_max_error && encoded_error > vi->dp->maxerrout) vi->dp->maxerrout = encoded_error; if (encoded_error < vi->maxout_total) { if (encoded_error < vi->outlog) return i; /* Test passed but error is bigger than the log limit, record why the * test passed: */ pass = "less than maxout:\n"; } /* i: the original input value in the range 0..1 * * pngvalid calculations: * input_sample: linear result; i linearized and composed, range 0..1 * encoded_sample: encoded result; input_sample scaled to output bit depth * * libpng calculations: * output: linear result; od scaled to 0..1 and linearized * od: encoded result from libpng */ /* Now we have the numbers for real errors, both absolute values as as a * percentage of the correct value (output): */ error = fabs(input_sample-output); if (log_max_error && error > vi->dp->maxerrabs) vi->dp->maxerrabs = error; /* The following is an attempt to ignore the tendency of quantization to * dominate the percentage errors for lower result values: */ if (log_max_error && input_sample > .5) { double percentage_error = error/input_sample; if (percentage_error > vi->dp->maxerrpc) vi->dp->maxerrpc = percentage_error; } /* Now calculate the digitization limits for 'encoded_sample' using the * 'max' values. Note that maxout is in the encoded space but maxpc and * maxabs are in linear light space. * * First find the maximum error in linear light space, range 0..1: */ { double tmp = input_sample * vi->maxpc; if (tmp < vi->maxabs) tmp = vi->maxabs; /* If 'compose' is true the composition was done in linear space using * integer arithmetic. This introduces an extra error of +/- 0.5 (at * least) in the integer space used. 'maxcalc' records this, taking * into account the possibility that even for 16 bit output 8 bit space * may have been used. */ if (compose && tmp < vi->maxcalc) tmp = vi->maxcalc; /* The 'maxout' value refers to the encoded result, to compare with * this encode input_sample adjusted by the maximum error (tmp) above. */ es_lo = encoded_sample - vi->maxout; if (es_lo > 0 && input_sample-tmp > 0) { double low_value = input_sample-tmp; if (output_is_encoded) low_value = pow(low_value, vi->screen_inverse); low_value *= outmax; if (low_value < es_lo) es_lo = low_value; /* Quantize this appropriately: */ es_lo = ceil(es_lo / vi->outquant - .5) * vi->outquant; } else es_lo = 0; es_hi = encoded_sample + vi->maxout; if (es_hi < outmax && input_sample+tmp < 1) { double high_value = input_sample+tmp; if (output_is_encoded) high_value = pow(high_value, vi->screen_inverse); high_value *= outmax; if (high_value > es_hi) es_hi = high_value; es_hi = floor(es_hi / vi->outquant + .5) * vi->outquant; } else es_hi = outmax; } /* The primary test is that the final encoded value returned by the * library should be between the two limits (inclusive) that were * calculated above. */ if (od >= es_lo && od <= es_hi) { /* The value passes, but we may need to log the information anyway. */ if (encoded_error < vi->outlog) return i; if (pass == 0) pass = "within digitization limits:\n"; } { /* There has been an error in processing, or we need to log this * value. */ double is_lo, is_hi; /* pass is set at this point if either of the tests above would have * passed. Don't do these additional tests here - just log the * original [es_lo..es_hi] values. */ if (pass == 0 && vi->use_input_precision && vi->dp->sbit) { /* Ok, something is wrong - this actually happens in current libpng * 16-to-8 processing. Assume that the input value (id, adjusted * for sbit) can be anywhere between value-.5 and value+.5 - quite a * large range if sbit is low. * * NOTE: at present because the libpng gamma table stuff has been * changed to use a rounding algorithm to correct errors in 8-bit * calculations the precise sbit calculation (a shift) has been * lost. This can result in up to a +/-1 error in the presence of * an sbit less than the bit depth. */ # if PNG_LIBPNG_VER < 10700 # define SBIT_ERROR .5 # else # define SBIT_ERROR 1. # endif double tmp = (isbit - SBIT_ERROR)/sbit_max; if (tmp <= 0) tmp = 0; else if (alpha >= 0 && vi->file_inverse > 0 && tmp < 1) tmp = pow(tmp, vi->file_inverse); tmp = gamma_component_compose(do_background, tmp, alpha, background, NULL); if (output_is_encoded && tmp > 0 && tmp < 1) tmp = pow(tmp, vi->screen_inverse); is_lo = ceil(outmax * tmp - vi->maxout_total); if (is_lo < 0) is_lo = 0; tmp = (isbit + SBIT_ERROR)/sbit_max; if (tmp >= 1) tmp = 1; else if (alpha >= 0 && vi->file_inverse > 0 && tmp < 1) tmp = pow(tmp, vi->file_inverse); tmp = gamma_component_compose(do_background, tmp, alpha, background, NULL); if (output_is_encoded && tmp > 0 && tmp < 1) tmp = pow(tmp, vi->screen_inverse); is_hi = floor(outmax * tmp + vi->maxout_total); if (is_hi > outmax) is_hi = outmax; if (!(od < is_lo || od > is_hi)) { if (encoded_error < vi->outlog) return i; pass = "within input precision limits:\n"; } /* One last chance. If this is an alpha channel and the 16to8 * option has been used and 'inaccurate' scaling is used then the * bit reduction is obtained by simply using the top 8 bits of the * value. * * This is only done for older libpng versions when the 'inaccurate' * (chop) method of scaling was used. */ # ifndef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED # if PNG_LIBPNG_VER < 10504 /* This may be required for other components in the future, * but at present the presence of gamma correction effectively * prevents the errors in the component scaling (I don't quite * understand why, but since it's better this way I care not * to ask, JB 20110419.) */ if (pass == 0 && alpha < 0 && vi->scale16 && vi->sbit > 8 && vi->sbit + vi->isbit_shift == 16) { tmp = ((id >> 8) - .5)/255; if (tmp > 0) { is_lo = ceil(outmax * tmp - vi->maxout_total); if (is_lo < 0) is_lo = 0; } else is_lo = 0; tmp = ((id >> 8) + .5)/255; if (tmp < 1) { is_hi = floor(outmax * tmp + vi->maxout_total); if (is_hi > outmax) is_hi = outmax; } else is_hi = outmax; if (!(od < is_lo || od > is_hi)) { if (encoded_error < vi->outlog) return i; pass = "within 8 bit limits:\n"; } } # endif # endif } else /* !use_input_precision */ is_lo = es_lo, is_hi = es_hi; /* Attempt to output a meaningful error/warning message: the message * output depends on the background/composite operation being performed * because this changes what parameters were actually used above. */ { size_t pos = 0; /* Need either 1/255 or 1/65535 precision here; 3 or 6 decimal * places. Just use outmax to work out which. */ int precision = (outmax >= 1000 ? 6 : 3); int use_input=1, use_background=0, do_compose=0; char msg[256]; if (pass != 0) pos = safecat(msg, sizeof msg, pos, "\n\t"); /* Set up the various flags, the output_is_encoded flag above * is also used below. do_compose is just a double check. */ switch (do_background) { # ifdef PNG_READ_BACKGROUND_SUPPORTED case PNG_BACKGROUND_GAMMA_SCREEN: case PNG_BACKGROUND_GAMMA_FILE: case PNG_BACKGROUND_GAMMA_UNIQUE: use_background = (alpha >= 0 && alpha < 1); # endif # ifdef PNG_READ_ALPHA_MODE_SUPPORTED /* FALLTHROUGH */ case ALPHA_MODE_OFFSET + PNG_ALPHA_STANDARD: case ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN: case ALPHA_MODE_OFFSET + PNG_ALPHA_OPTIMIZED: # endif /* ALPHA_MODE_SUPPORTED */ # if (defined PNG_READ_BACKGROUND_SUPPORTED) ||\ (defined PNG_READ_ALPHA_MODE_SUPPORTED) do_compose = (alpha > 0 && alpha < 1); use_input = (alpha != 0); break; # endif default: break; } /* Check the 'compose' flag */ if (compose != do_compose) png_error(vi->pp, "internal error (compose)"); /* 'name' is the component name */ pos = safecat(msg, sizeof msg, pos, name); pos = safecat(msg, sizeof msg, pos, "("); pos = safecatn(msg, sizeof msg, pos, id); if (use_input || pass != 0/*logging*/) { if (isbit != id) { /* sBIT has reduced the precision of the input: */ pos = safecat(msg, sizeof msg, pos, ", sbit("); pos = safecatn(msg, sizeof msg, pos, vi->sbit); pos = safecat(msg, sizeof msg, pos, "): "); pos = safecatn(msg, sizeof msg, pos, isbit); } pos = safecat(msg, sizeof msg, pos, "/"); /* The output is either "id/max" or "id sbit(sbit): isbit/max" */ pos = safecatn(msg, sizeof msg, pos, vi->sbit_max); } pos = safecat(msg, sizeof msg, pos, ")"); /* A component may have been multiplied (in linear space) by the * alpha value, 'compose' says whether this is relevant. */ if (compose || pass != 0) { /* If any form of composition is being done report our * calculated linear value here (the code above doesn't record * the input value before composition is performed, so what * gets reported is the value after composition.) */ if (use_input || pass != 0) { if (vi->file_inverse > 0) { pos = safecat(msg, sizeof msg, pos, "^"); pos = safecatd(msg, sizeof msg, pos, vi->file_inverse, 2); } else pos = safecat(msg, sizeof msg, pos, "[linear]"); pos = safecat(msg, sizeof msg, pos, "*(alpha)"); pos = safecatd(msg, sizeof msg, pos, alpha, precision); } /* Now record the *linear* background value if it was used * (this function is not passed the original, non-linear, * value but it is contained in the test name.) */ if (use_background) { pos = safecat(msg, sizeof msg, pos, use_input ? "+" : " "); pos = safecat(msg, sizeof msg, pos, "(background)"); pos = safecatd(msg, sizeof msg, pos, background, precision); pos = safecat(msg, sizeof msg, pos, "*"); pos = safecatd(msg, sizeof msg, pos, 1-alpha, precision); } } /* Report the calculated value (input_sample) and the linearized * libpng value (output) unless this is just a component gamma * correction. */ if (compose || alpha < 0 || pass != 0) { pos = safecat(msg, sizeof msg, pos, pass != 0 ? " =\n\t" : " = "); pos = safecatd(msg, sizeof msg, pos, input_sample, precision); pos = safecat(msg, sizeof msg, pos, " (libpng: "); pos = safecatd(msg, sizeof msg, pos, output, precision); pos = safecat(msg, sizeof msg, pos, ")"); /* Finally report the output gamma encoding, if any. */ if (output_is_encoded) { pos = safecat(msg, sizeof msg, pos, " ^"); pos = safecatd(msg, sizeof msg, pos, vi->screen_inverse, 2); pos = safecat(msg, sizeof msg, pos, "(to screen) ="); } else pos = safecat(msg, sizeof msg, pos, " [screen is linear] ="); } if ((!compose && alpha >= 0) || pass != 0) { if (pass != 0) /* logging */ pos = safecat(msg, sizeof msg, pos, "\n\t[overall:"); /* This is the non-composition case, the internal linear * values are irrelevant (though the log below will reveal * them.) Output a much shorter warning/error message and report * the overall gamma correction. */ if (vi->gamma_correction > 0) { pos = safecat(msg, sizeof msg, pos, " ^"); pos = safecatd(msg, sizeof msg, pos, vi->gamma_correction, 2); pos = safecat(msg, sizeof msg, pos, "(gamma correction) ="); } else pos = safecat(msg, sizeof msg, pos, " [no gamma correction] ="); if (pass != 0) pos = safecat(msg, sizeof msg, pos, "]"); } /* This is our calculated encoded_sample which should (but does * not) match od: */ pos = safecat(msg, sizeof msg, pos, pass != 0 ? "\n\t" : " "); pos = safecatd(msg, sizeof msg, pos, is_lo, 1); pos = safecat(msg, sizeof msg, pos, " < "); pos = safecatd(msg, sizeof msg, pos, encoded_sample, 1); pos = safecat(msg, sizeof msg, pos, " (libpng: "); pos = safecatn(msg, sizeof msg, pos, od); pos = safecat(msg, sizeof msg, pos, ")"); pos = safecat(msg, sizeof msg, pos, "/"); pos = safecatn(msg, sizeof msg, pos, outmax); pos = safecat(msg, sizeof msg, pos, " < "); pos = safecatd(msg, sizeof msg, pos, is_hi, 1); if (pass == 0) /* The error condition */ { # ifdef PNG_WARNINGS_SUPPORTED png_warning(vi->pp, msg); # else store_warning(vi->pp, msg); # endif } else /* logging this value */ store_verbose(&vi->dp->pm->this, vi->pp, pass, msg); } } } return i; } static void gamma_image_validate(gamma_display *dp, png_const_structp pp, png_infop pi) { /* Get some constants derived from the input and output file formats: */ const png_store* const ps = dp->this.ps; png_byte in_ct = dp->this.colour_type; png_byte in_bd = dp->this.bit_depth; png_uint_32 w = dp->this.w; png_uint_32 h = dp->this.h; const size_t cbRow = dp->this.cbRow; png_byte out_ct = png_get_color_type(pp, pi); png_byte out_bd = png_get_bit_depth(pp, pi); /* There are three sources of error, firstly the quantization in the * file encoding, determined by sbit and/or the file depth, secondly * the output (screen) gamma and thirdly the output file encoding. * * Since this API receives the screen and file gamma in double * precision it is possible to calculate an exact answer given an input * pixel value. Therefore we assume that the *input* value is exact - * sample/maxsample - calculate the corresponding gamma corrected * output to the limits of double precision arithmetic and compare with * what libpng returns. * * Since the library must quantize the output to 8 or 16 bits there is * a fundamental limit on the accuracy of the output of +/-.5 - this * quantization limit is included in addition to the other limits * specified by the parameters to the API. (Effectively, add .5 * everywhere.) * * The behavior of the 'sbit' parameter is defined by section 12.5 * (sample depth scaling) of the PNG spec. That section forces the * decoder to assume that the PNG values have been scaled if sBIT is * present: * * png-sample = floor( input-sample * (max-out/max-in) + .5); * * This means that only a subset of the possible PNG values should * appear in the input. However, the spec allows the encoder to use a * variety of approximations to the above and doesn't require any * restriction of the values produced. * * Nevertheless the spec requires that the upper 'sBIT' bits of the * value stored in a PNG file be the original sample bits. * Consequently the code below simply scales the top sbit bits by * (1<this.palette; int in_is_transparent = dp->this.is_transparent; int process_tRNS; int out_npalette = -1; int out_is_transparent = 0; /* Just refers to the palette case */ store_palette out_palette; validate_info vi; /* Check for row overwrite errors */ store_image_check(dp->this.ps, pp, 0); /* Supply the input and output sample depths here - 8 for an indexed image, * otherwise the bit depth. */ init_validate_info(&vi, dp, pp, in_ct==3?8:in_bd, out_ct==3?8:out_bd); processing = (vi.gamma_correction > 0 && !dp->threshold_test) || in_bd != out_bd || in_ct != out_ct || vi.do_background; process_tRNS = dp->this.has_tRNS && vi.do_background; /* TODO: FIX THIS: MAJOR BUG! If the transformations all happen inside * the palette there is no way of finding out, because libpng fails to * update the palette on png_read_update_info. Indeed, libpng doesn't * even do the required work until much later, when it doesn't have any * info pointer. Oops. For the moment 'processing' is turned off if * out_ct is palette. */ if (in_ct == 3 && out_ct == 3) processing = 0; if (processing && out_ct == 3) out_is_transparent = read_palette(out_palette, &out_npalette, pp, pi); for (y=0; ythis.palette[in_index].alpha : sample(std, in_ct, in_bd, x, samples_per_pixel, 0, 0); unsigned int output_alpha = 65536 /* as a flag value */; if (out_ct == 3) { if (out_is_transparent) output_alpha = out_palette[out_index].alpha; } else if ((out_ct & PNG_COLOR_MASK_ALPHA) != 0) output_alpha = sample(pRow, out_ct, out_bd, x, samples_per_pixel, 0, 0); if (output_alpha != 65536) alpha = gamma_component_validate("alpha", &vi, input_alpha, output_alpha, -1/*alpha*/, 0/*background*/); else /* no alpha in output */ { /* This is a copy of the calculation of 'i' above in order to * have the alpha value to use in the background calculation. */ alpha = input_alpha >> vi.isbit_shift; alpha /= vi.sbit_max; } } else if (process_tRNS) { /* alpha needs to be set appropriately for this pixel, it is * currently 1 and needs to be 0 for an input pixel which matches * the values in tRNS. */ switch (in_ct) { case 0: /* gray */ if (sample(std, in_ct, in_bd, x, 0, 0, 0) == dp->this.transparent.red) alpha = 0; break; case 2: /* RGB */ if (sample(std, in_ct, in_bd, x, 0, 0, 0) == dp->this.transparent.red && sample(std, in_ct, in_bd, x, 1, 0, 0) == dp->this.transparent.green && sample(std, in_ct, in_bd, x, 2, 0, 0) == dp->this.transparent.blue) alpha = 0; break; default: break; } } /* Handle grayscale or RGB components. */ if ((in_ct & PNG_COLOR_MASK_COLOR) == 0) /* grayscale */ (void)gamma_component_validate("gray", &vi, sample(std, in_ct, in_bd, x, 0, 0, 0), sample(pRow, out_ct, out_bd, x, 0, 0, 0), alpha/*component*/, vi.background_red); else /* RGB or palette */ { (void)gamma_component_validate("red", &vi, in_ct == 3 ? in_palette[in_index].red : sample(std, in_ct, in_bd, x, 0, 0, 0), out_ct == 3 ? out_palette[out_index].red : sample(pRow, out_ct, out_bd, x, 0, 0, 0), alpha/*component*/, vi.background_red); (void)gamma_component_validate("green", &vi, in_ct == 3 ? in_palette[in_index].green : sample(std, in_ct, in_bd, x, 1, 0, 0), out_ct == 3 ? out_palette[out_index].green : sample(pRow, out_ct, out_bd, x, 1, 0, 0), alpha/*component*/, vi.background_green); (void)gamma_component_validate("blue", &vi, in_ct == 3 ? in_palette[in_index].blue : sample(std, in_ct, in_bd, x, 2, 0, 0), out_ct == 3 ? out_palette[out_index].blue : sample(pRow, out_ct, out_bd, x, 2, 0, 0), alpha/*component*/, vi.background_blue); } } } else if (memcmp(std, pRow, cbRow) != 0) { char msg[64]; /* No transform is expected on the threshold tests. */ sprintf(msg, "gamma: below threshold row %lu changed", (unsigned long)y); png_error(pp, msg); } } /* row (y) loop */ dp->this.ps->validated = 1; } static void PNGCBAPI gamma_end(png_structp ppIn, png_infop pi) { png_const_structp pp = ppIn; gamma_display *dp = voidcast(gamma_display*, png_get_progressive_ptr(pp)); if (!dp->this.speed) gamma_image_validate(dp, pp, pi); else dp->this.ps->validated = 1; } /* A single test run checking a gamma transformation. * * maxabs: maximum absolute error as a fraction * maxout: maximum output error in the output units * maxpc: maximum percentage error (as a percentage) */ static void gamma_test(png_modifier *pmIn, png_byte colour_typeIn, png_byte bit_depthIn, int palette_numberIn, int interlace_typeIn, const double file_gammaIn, const double screen_gammaIn, png_byte sbitIn, int threshold_testIn, const char *name, int use_input_precisionIn, int scale16In, int expand16In, int do_backgroundIn, const png_color_16 *bkgd_colorIn, double bkgd_gammaIn) { gamma_display d; context(&pmIn->this, fault); gamma_display_init(&d, pmIn, FILEID(colour_typeIn, bit_depthIn, palette_numberIn, interlace_typeIn, 0, 0, 0), file_gammaIn, screen_gammaIn, sbitIn, threshold_testIn, use_input_precisionIn, scale16In, expand16In, do_backgroundIn, bkgd_colorIn, bkgd_gammaIn); Try { png_structp pp; png_infop pi; gama_modification gama_mod; srgb_modification srgb_mod; sbit_modification sbit_mod; /* For the moment don't use the png_modifier support here. */ d.pm->encoding_counter = 0; modifier_set_encoding(d.pm); /* Just resets everything */ d.pm->current_gamma = d.file_gamma; /* Make an appropriate modifier to set the PNG file gamma to the * given gamma value and the sBIT chunk to the given precision. */ d.pm->modifications = NULL; gama_modification_init(&gama_mod, d.pm, d.file_gamma); srgb_modification_init(&srgb_mod, d.pm, 127 /*delete*/); if (d.sbit > 0) sbit_modification_init(&sbit_mod, d.pm, d.sbit); modification_reset(d.pm->modifications); /* Get a png_struct for reading the image. */ pp = set_modifier_for_read(d.pm, &pi, d.this.id, name); standard_palette_init(&d.this); /* Introduce the correct read function. */ if (d.pm->this.progressive) { /* Share the row function with the standard implementation. */ png_set_progressive_read_fn(pp, &d, gamma_info, progressive_row, gamma_end); /* Now feed data into the reader until we reach the end: */ modifier_progressive_read(d.pm, pp, pi); } else { /* modifier_read expects a png_modifier* */ png_set_read_fn(pp, d.pm, modifier_read); /* Check the header values: */ png_read_info(pp, pi); /* Process the 'info' requirements. Only one image is generated */ gamma_info_imp(&d, pp, pi); sequential_row(&d.this, pp, pi, -1, 0); if (!d.this.speed) gamma_image_validate(&d, pp, pi); else d.this.ps->validated = 1; } modifier_reset(d.pm); if (d.pm->log && !d.threshold_test && !d.this.speed) fprintf(stderr, "%d bit %s %s: max error %f (%.2g, %2g%%)\n", d.this.bit_depth, colour_types[d.this.colour_type], name, d.maxerrout, d.maxerrabs, 100*d.maxerrpc); /* Log the summary values too. */ if (d.this.colour_type == 0 || d.this.colour_type == 4) { switch (d.this.bit_depth) { case 1: break; case 2: if (d.maxerrout > d.pm->error_gray_2) d.pm->error_gray_2 = d.maxerrout; break; case 4: if (d.maxerrout > d.pm->error_gray_4) d.pm->error_gray_4 = d.maxerrout; break; case 8: if (d.maxerrout > d.pm->error_gray_8) d.pm->error_gray_8 = d.maxerrout; break; case 16: if (d.maxerrout > d.pm->error_gray_16) d.pm->error_gray_16 = d.maxerrout; break; default: png_error(pp, "bad bit depth (internal: 1)"); } } else if (d.this.colour_type == 2 || d.this.colour_type == 6) { switch (d.this.bit_depth) { case 8: if (d.maxerrout > d.pm->error_color_8) d.pm->error_color_8 = d.maxerrout; break; case 16: if (d.maxerrout > d.pm->error_color_16) d.pm->error_color_16 = d.maxerrout; break; default: png_error(pp, "bad bit depth (internal: 2)"); } } else if (d.this.colour_type == 3) { if (d.maxerrout > d.pm->error_indexed) d.pm->error_indexed = d.maxerrout; } } Catch(fault) modifier_reset(voidcast(png_modifier*,(void*)fault)); } static void gamma_threshold_test(png_modifier *pm, png_byte colour_type, png_byte bit_depth, int interlace_type, double file_gamma, double screen_gamma) { size_t pos = 0; char name[64]; pos = safecat(name, sizeof name, pos, "threshold "); pos = safecatd(name, sizeof name, pos, file_gamma, 3); pos = safecat(name, sizeof name, pos, "/"); pos = safecatd(name, sizeof name, pos, screen_gamma, 3); (void)gamma_test(pm, colour_type, bit_depth, 0/*palette*/, interlace_type, file_gamma, screen_gamma, 0/*sBIT*/, 1/*threshold test*/, name, 0 /*no input precision*/, 0 /*no scale16*/, 0 /*no expand16*/, 0 /*no background*/, 0 /*hence*/, 0 /*no background gamma*/); } static void perform_gamma_threshold_tests(png_modifier *pm) { png_byte colour_type = 0; png_byte bit_depth = 0; unsigned int palette_number = 0; /* Don't test more than one instance of each palette - it's pointless, in * fact this test is somewhat excessive since libpng doesn't make this * decision based on colour type or bit depth! * * CHANGED: now test two palettes and, as a side effect, images with and * without tRNS. */ while (next_format(&colour_type, &bit_depth, &palette_number, pm->test_lbg_gamma_threshold, pm->test_tRNS)) if (palette_number < 2) { double test_gamma = 1.0; while (test_gamma >= .4) { /* There's little point testing the interlacing vs non-interlacing, * but this can be set from the command line. */ gamma_threshold_test(pm, colour_type, bit_depth, pm->interlace_type, test_gamma, 1/test_gamma); test_gamma *= .95; } /* And a special test for sRGB */ gamma_threshold_test(pm, colour_type, bit_depth, pm->interlace_type, .45455, 2.2); if (fail(pm)) return; } } static void gamma_transform_test(png_modifier *pm, png_byte colour_type, png_byte bit_depth, int palette_number, int interlace_type, const double file_gamma, const double screen_gamma, png_byte sbit, int use_input_precision, int scale16) { size_t pos = 0; char name[64]; if (sbit != bit_depth && sbit != 0) { pos = safecat(name, sizeof name, pos, "sbit("); pos = safecatn(name, sizeof name, pos, sbit); pos = safecat(name, sizeof name, pos, ") "); } else pos = safecat(name, sizeof name, pos, "gamma "); if (scale16) pos = safecat(name, sizeof name, pos, "16to8 "); pos = safecatd(name, sizeof name, pos, file_gamma, 3); pos = safecat(name, sizeof name, pos, "->"); pos = safecatd(name, sizeof name, pos, screen_gamma, 3); gamma_test(pm, colour_type, bit_depth, palette_number, interlace_type, file_gamma, screen_gamma, sbit, 0, name, use_input_precision, scale16, pm->test_gamma_expand16, 0 , 0, 0); } static void perform_gamma_transform_tests(png_modifier *pm) { png_byte colour_type = 0; png_byte bit_depth = 0; unsigned int palette_number = 0; while (next_format(&colour_type, &bit_depth, &palette_number, pm->test_lbg_gamma_transform, pm->test_tRNS)) { unsigned int i, j; for (i=0; ingamma_tests; ++i) { for (j=0; jngamma_tests; ++j) { if (i != j) { gamma_transform_test(pm, colour_type, bit_depth, palette_number, pm->interlace_type, 1/pm->gammas[i], pm->gammas[j], 0/*sBIT*/, pm->use_input_precision, 0/*do not scale16*/); if (fail(pm)) return; } } } } } static void perform_gamma_sbit_tests(png_modifier *pm) { png_byte sbit; /* The only interesting cases are colour and grayscale, alpha is ignored here * for overall speed. Only bit depths where sbit is less than the bit depth * are tested. */ for (sbit=pm->sbitlow; sbit<(1<test_lbg_gamma_sbit, pm->test_tRNS)) if ((colour_type & PNG_COLOR_MASK_ALPHA) == 0 && ((colour_type == 3 && sbit < 8) || (colour_type != 3 && sbit < bit_depth))) { unsigned int i; for (i=0; ingamma_tests; ++i) { unsigned int j; for (j=0; jngamma_tests; ++j) { if (i != j) { gamma_transform_test(pm, colour_type, bit_depth, npalette, pm->interlace_type, 1/pm->gammas[i], pm->gammas[j], sbit, pm->use_input_precision_sbit, 0 /*scale16*/); if (fail(pm)) return; } } } } } } /* Note that this requires a 16 bit source image but produces 8 bit output, so * we only need the 16bit write support, but the 16 bit images are only * generated if DO_16BIT is defined. */ #ifdef DO_16BIT static void perform_gamma_scale16_tests(png_modifier *pm) { # ifndef PNG_MAX_GAMMA_8 # define PNG_MAX_GAMMA_8 11 # endif # if defined PNG_MAX_GAMMA_8 || PNG_LIBPNG_VER < 10700 # define SBIT_16_TO_8 PNG_MAX_GAMMA_8 # else # define SBIT_16_TO_8 16 # endif /* Include the alpha cases here. Note that sbit matches the internal value * used by the library - otherwise we will get spurious errors from the * internal sbit style approximation. * * The threshold test is here because otherwise the 16 to 8 conversion will * proceed *without* gamma correction, and the tests above will fail (but not * by much) - this could be fixed, it only appears with the -g option. */ unsigned int i, j; for (i=0; ingamma_tests; ++i) { for (j=0; jngamma_tests; ++j) { if (i != j && fabs(pm->gammas[j]/pm->gammas[i]-1) >= PNG_GAMMA_THRESHOLD) { gamma_transform_test(pm, 0, 16, 0, pm->interlace_type, 1/pm->gammas[i], pm->gammas[j], SBIT_16_TO_8, pm->use_input_precision_16to8, 1 /*scale16*/); if (fail(pm)) return; gamma_transform_test(pm, 2, 16, 0, pm->interlace_type, 1/pm->gammas[i], pm->gammas[j], SBIT_16_TO_8, pm->use_input_precision_16to8, 1 /*scale16*/); if (fail(pm)) return; gamma_transform_test(pm, 4, 16, 0, pm->interlace_type, 1/pm->gammas[i], pm->gammas[j], SBIT_16_TO_8, pm->use_input_precision_16to8, 1 /*scale16*/); if (fail(pm)) return; gamma_transform_test(pm, 6, 16, 0, pm->interlace_type, 1/pm->gammas[i], pm->gammas[j], SBIT_16_TO_8, pm->use_input_precision_16to8, 1 /*scale16*/); if (fail(pm)) return; } } } } #endif /* 16 to 8 bit conversion */ #if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\ defined(PNG_READ_ALPHA_MODE_SUPPORTED) static void gamma_composition_test(png_modifier *pm, png_byte colour_type, png_byte bit_depth, int palette_number, int interlace_type, const double file_gamma, const double screen_gamma, int use_input_precision, int do_background, int expand_16) { size_t pos = 0; png_const_charp base; double bg; char name[128]; png_color_16 background; /* Make up a name and get an appropriate background gamma value. */ switch (do_background) { default: base = ""; bg = 4; /* should not be used */ break; case PNG_BACKGROUND_GAMMA_SCREEN: base = " bckg(Screen):"; bg = 1/screen_gamma; break; case PNG_BACKGROUND_GAMMA_FILE: base = " bckg(File):"; bg = file_gamma; break; case PNG_BACKGROUND_GAMMA_UNIQUE: base = " bckg(Unique):"; /* This tests the handling of a unique value, the math is such that the * value tends to be <1, but is neither screen nor file (even if they * match!) */ bg = (file_gamma + screen_gamma) / 3; break; #ifdef PNG_READ_ALPHA_MODE_SUPPORTED case ALPHA_MODE_OFFSET + PNG_ALPHA_PNG: base = " alpha(PNG)"; bg = 4; /* should not be used */ break; case ALPHA_MODE_OFFSET + PNG_ALPHA_STANDARD: base = " alpha(Porter-Duff)"; bg = 4; /* should not be used */ break; case ALPHA_MODE_OFFSET + PNG_ALPHA_OPTIMIZED: base = " alpha(Optimized)"; bg = 4; /* should not be used */ break; case ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN: base = " alpha(Broken)"; bg = 4; /* should not be used */ break; #endif } /* Use random background values - the background is always presented in the * output space (8 or 16 bit components). */ if (expand_16 || bit_depth == 16) { png_uint_32 r = random_32(); background.red = (png_uint_16)r; background.green = (png_uint_16)(r >> 16); r = random_32(); background.blue = (png_uint_16)r; background.gray = (png_uint_16)(r >> 16); /* In earlier libpng versions, those where DIGITIZE is set, any background * gamma correction in the expand16 case was done using 8-bit gamma * correction tables, resulting in larger errors. To cope with those * cases use a 16-bit background value which will handle this gamma * correction. */ # if DIGITIZE if (expand_16 && (do_background == PNG_BACKGROUND_GAMMA_UNIQUE || do_background == PNG_BACKGROUND_GAMMA_FILE) && fabs(bg*screen_gamma-1) > PNG_GAMMA_THRESHOLD) { /* The background values will be looked up in an 8-bit table to do * the gamma correction, so only select values which are an exact * match for the 8-bit table entries: */ background.red = (png_uint_16)((background.red >> 8) * 257); background.green = (png_uint_16)((background.green >> 8) * 257); background.blue = (png_uint_16)((background.blue >> 8) * 257); background.gray = (png_uint_16)((background.gray >> 8) * 257); } # endif } else /* 8 bit colors */ { png_uint_32 r = random_32(); background.red = (png_byte)r; background.green = (png_byte)(r >> 8); background.blue = (png_byte)(r >> 16); background.gray = (png_byte)(r >> 24); } background.index = 193; /* rgb(193,193,193) to detect errors */ if (!(colour_type & PNG_COLOR_MASK_COLOR)) { /* Because, currently, png_set_background is always called with * 'need_expand' false in this case and because the gamma test itself * doesn't cause an expand to 8-bit for lower bit depths the colour must * be reduced to the correct range. */ if (bit_depth < 8) background.gray &= (png_uint_16)((1U << bit_depth)-1); /* Grayscale input, we do not convert to RGB (TBD), so we must set the * background to gray - else libpng seems to fail. */ background.red = background.green = background.blue = background.gray; } pos = safecat(name, sizeof name, pos, "gamma "); pos = safecatd(name, sizeof name, pos, file_gamma, 3); pos = safecat(name, sizeof name, pos, "->"); pos = safecatd(name, sizeof name, pos, screen_gamma, 3); pos = safecat(name, sizeof name, pos, base); if (do_background < ALPHA_MODE_OFFSET) { /* Include the background color and gamma in the name: */ pos = safecat(name, sizeof name, pos, "("); /* This assumes no expand gray->rgb - the current code won't handle that! */ if (colour_type & PNG_COLOR_MASK_COLOR) { pos = safecatn(name, sizeof name, pos, background.red); pos = safecat(name, sizeof name, pos, ","); pos = safecatn(name, sizeof name, pos, background.green); pos = safecat(name, sizeof name, pos, ","); pos = safecatn(name, sizeof name, pos, background.blue); } else pos = safecatn(name, sizeof name, pos, background.gray); pos = safecat(name, sizeof name, pos, ")^"); pos = safecatd(name, sizeof name, pos, bg, 3); } gamma_test(pm, colour_type, bit_depth, palette_number, interlace_type, file_gamma, screen_gamma, 0/*sBIT*/, 0, name, use_input_precision, 0/*strip 16*/, expand_16, do_background, &background, bg); } static void perform_gamma_composition_tests(png_modifier *pm, int do_background, int expand_16) { png_byte colour_type = 0; png_byte bit_depth = 0; unsigned int palette_number = 0; /* Skip the non-alpha cases - there is no setting of a transparency colour at * present. * * TODO: incorrect; the palette case sets tRNS and, now RGB and gray do, * however the palette case fails miserably so is commented out below. */ while (next_format(&colour_type, &bit_depth, &palette_number, pm->test_lbg_gamma_composition, pm->test_tRNS)) if ((colour_type & PNG_COLOR_MASK_ALPHA) != 0 #if 0 /* TODO: FIXME */ /*TODO: FIXME: this should work */ || colour_type == 3 #endif || (colour_type != 3 && palette_number != 0)) { unsigned int i, j; /* Don't skip the i==j case here - it's relevant. */ for (i=0; ingamma_tests; ++i) { for (j=0; jngamma_tests; ++j) { gamma_composition_test(pm, colour_type, bit_depth, palette_number, pm->interlace_type, 1/pm->gammas[i], pm->gammas[j], pm->use_input_precision, do_background, expand_16); if (fail(pm)) return; } } } } #endif /* READ_BACKGROUND || READ_ALPHA_MODE */ static void init_gamma_errors(png_modifier *pm) { /* Use -1 to catch tests that were not actually run */ pm->error_gray_2 = pm->error_gray_4 = pm->error_gray_8 = -1.; pm->error_color_8 = -1.; pm->error_indexed = -1.; pm->error_gray_16 = pm->error_color_16 = -1.; } static void print_one(const char *leader, double err) { if (err != -1.) printf(" %s %.5f\n", leader, err); } static void summarize_gamma_errors(png_modifier *pm, png_const_charp who, int low_bit_depth, int indexed) { fflush(stderr); if (who) printf("\nGamma correction with %s:\n", who); else printf("\nBasic gamma correction:\n"); if (low_bit_depth) { print_one(" 2 bit gray: ", pm->error_gray_2); print_one(" 4 bit gray: ", pm->error_gray_4); print_one(" 8 bit gray: ", pm->error_gray_8); print_one(" 8 bit color:", pm->error_color_8); if (indexed) print_one(" indexed: ", pm->error_indexed); } print_one("16 bit gray: ", pm->error_gray_16); print_one("16 bit color:", pm->error_color_16); fflush(stdout); } static void perform_gamma_test(png_modifier *pm, int summary) { /*TODO: remove this*/ /* Save certain values for the temporary overrides below. */ unsigned int calculations_use_input_precision = pm->calculations_use_input_precision; # ifdef PNG_READ_BACKGROUND_SUPPORTED double maxout8 = pm->maxout8; # endif /* First some arbitrary no-transform tests: */ if (!pm->this.speed && pm->test_gamma_threshold) { perform_gamma_threshold_tests(pm); if (fail(pm)) return; } /* Now some real transforms. */ if (pm->test_gamma_transform) { if (summary) { fflush(stderr); printf("Gamma correction error summary\n\n"); printf("The printed value is the maximum error in the pixel values\n"); printf("calculated by the libpng gamma correction code. The error\n"); printf("is calculated as the difference between the output pixel\n"); printf("value (always an integer) and the ideal value from the\n"); printf("libpng specification (typically not an integer).\n\n"); printf("Expect this value to be less than .5 for 8 bit formats,\n"); printf("less than 1 for formats with fewer than 8 bits and a small\n"); printf("number (typically less than 5) for the 16 bit formats.\n"); printf("For performance reasons the value for 16 bit formats\n"); printf("increases when the image file includes an sBIT chunk.\n"); fflush(stdout); } init_gamma_errors(pm); /*TODO: remove this. Necessary because the current libpng * implementation works in 8 bits: */ if (pm->test_gamma_expand16) pm->calculations_use_input_precision = 1; perform_gamma_transform_tests(pm); if (!calculations_use_input_precision) pm->calculations_use_input_precision = 0; if (summary) summarize_gamma_errors(pm, NULL/*who*/, 1/*low bit depth*/, 1/*indexed*/); if (fail(pm)) return; } /* The sbit tests produce much larger errors: */ if (pm->test_gamma_sbit) { init_gamma_errors(pm); perform_gamma_sbit_tests(pm); if (summary) summarize_gamma_errors(pm, "sBIT", pm->sbitlow < 8U, 1/*indexed*/); if (fail(pm)) return; } #ifdef DO_16BIT /* Should be READ_16BIT_SUPPORTED */ if (pm->test_gamma_scale16) { /* The 16 to 8 bit strip operations: */ init_gamma_errors(pm); perform_gamma_scale16_tests(pm); if (summary) { fflush(stderr); printf("\nGamma correction with 16 to 8 bit reduction:\n"); printf(" 16 bit gray: %.5f\n", pm->error_gray_16); printf(" 16 bit color: %.5f\n", pm->error_color_16); fflush(stdout); } if (fail(pm)) return; } #endif #ifdef PNG_READ_BACKGROUND_SUPPORTED if (pm->test_gamma_background) { init_gamma_errors(pm); /*TODO: remove this. Necessary because the current libpng * implementation works in 8 bits: */ if (pm->test_gamma_expand16) { pm->calculations_use_input_precision = 1; pm->maxout8 = .499; /* because the 16 bit background is smashed */ } perform_gamma_composition_tests(pm, PNG_BACKGROUND_GAMMA_UNIQUE, pm->test_gamma_expand16); if (!calculations_use_input_precision) pm->calculations_use_input_precision = 0; pm->maxout8 = maxout8; if (summary) summarize_gamma_errors(pm, "background", 1, 0/*indexed*/); if (fail(pm)) return; } #endif #ifdef PNG_READ_ALPHA_MODE_SUPPORTED if (pm->test_gamma_alpha_mode) { int do_background; init_gamma_errors(pm); /*TODO: remove this. Necessary because the current libpng * implementation works in 8 bits: */ if (pm->test_gamma_expand16) pm->calculations_use_input_precision = 1; for (do_background = ALPHA_MODE_OFFSET + PNG_ALPHA_STANDARD; do_background <= ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN && !fail(pm); ++do_background) perform_gamma_composition_tests(pm, do_background, pm->test_gamma_expand16); if (!calculations_use_input_precision) pm->calculations_use_input_precision = 0; if (summary) summarize_gamma_errors(pm, "alpha mode", 1, 0/*indexed*/); if (fail(pm)) return; } #endif } #endif /* PNG_READ_GAMMA_SUPPORTED */ #endif /* PNG_READ_SUPPORTED */ /* INTERLACE MACRO VALIDATION */ /* This is copied verbatim from the specification, it is simply the pass * number in which each pixel in each 8x8 tile appears. The array must * be indexed adam7[y][x] and notice that the pass numbers are based at * 1, not 0 - the base libpng uses. */ static const png_byte adam7[8][8] = { { 1,6,4,6,2,6,4,6 }, { 7,7,7,7,7,7,7,7 }, { 5,6,5,6,5,6,5,6 }, { 7,7,7,7,7,7,7,7 }, { 3,6,4,6,3,6,4,6 }, { 7,7,7,7,7,7,7,7 }, { 5,6,5,6,5,6,5,6 }, { 7,7,7,7,7,7,7,7 } }; /* This routine validates all the interlace support macros in png.h for * a variety of valid PNG widths and heights. It uses a number of similarly * named internal routines that feed off the above array. */ static png_uint_32 png_pass_start_row(int pass) { int x, y; ++pass; for (y=0; y<8; ++y) for (x=0; x<8; ++x) if (adam7[y][x] == pass) return y; return 0xf; } static png_uint_32 png_pass_start_col(int pass) { int x, y; ++pass; for (x=0; x<8; ++x) for (y=0; y<8; ++y) if (adam7[y][x] == pass) return x; return 0xf; } static int png_pass_row_shift(int pass) { int x, y, base=(-1), inc=8; ++pass; for (y=0; y<8; ++y) { for (x=0; x<8; ++x) { if (adam7[y][x] == pass) { if (base == (-1)) base = y; else if (base == y) {} else if (inc == y-base) base=y; else if (inc == 8) inc = y-base, base=y; else if (inc != y-base) return 0xff; /* error - more than one 'inc' value! */ } } } if (base == (-1)) return 0xfe; /* error - no row in pass! */ /* The shift is always 1, 2 or 3 - no pass has all the rows! */ switch (inc) { case 2: return 1; case 4: return 2; case 8: return 3; default: break; } /* error - unrecognized 'inc' */ return (inc << 8) + 0xfd; } static int png_pass_col_shift(int pass) { int x, y, base=(-1), inc=8; ++pass; for (x=0; x<8; ++x) { for (y=0; y<8; ++y) { if (adam7[y][x] == pass) { if (base == (-1)) base = x; else if (base == x) {} else if (inc == x-base) base=x; else if (inc == 8) inc = x-base, base=x; else if (inc != x-base) return 0xff; /* error - more than one 'inc' value! */ } } } if (base == (-1)) return 0xfe; /* error - no row in pass! */ /* The shift is always 1, 2 or 3 - no pass has all the rows! */ switch (inc) { case 1: return 0; /* pass 7 has all the columns */ case 2: return 1; case 4: return 2; case 8: return 3; default: break; } /* error - unrecognized 'inc' */ return (inc << 8) + 0xfd; } static png_uint_32 png_row_from_pass_row(png_uint_32 yIn, int pass) { /* By examination of the array: */ switch (pass) { case 0: return yIn * 8; case 1: return yIn * 8; case 2: return yIn * 8 + 4; case 3: return yIn * 4; case 4: return yIn * 4 + 2; case 5: return yIn * 2; case 6: return yIn * 2 + 1; default: break; } return 0xff; /* bad pass number */ } static png_uint_32 png_col_from_pass_col(png_uint_32 xIn, int pass) { /* By examination of the array: */ switch (pass) { case 0: return xIn * 8; case 1: return xIn * 8 + 4; case 2: return xIn * 4; case 3: return xIn * 4 + 2; case 4: return xIn * 2; case 5: return xIn * 2 + 1; case 6: return xIn; default: break; } return 0xff; /* bad pass number */ } static int png_row_in_interlace_pass(png_uint_32 y, int pass) { /* Is row 'y' in pass 'pass'? */ int x; y &= 7; ++pass; for (x=0; x<8; ++x) if (adam7[y][x] == pass) return 1; return 0; } static int png_col_in_interlace_pass(png_uint_32 x, int pass) { /* Is column 'x' in pass 'pass'? */ int y; x &= 7; ++pass; for (y=0; y<8; ++y) if (adam7[y][x] == pass) return 1; return 0; } static png_uint_32 png_pass_rows(png_uint_32 height, int pass) { png_uint_32 tiles = height>>3; png_uint_32 rows = 0; unsigned int x, y; height &= 7; ++pass; for (y=0; y<8; ++y) { for (x=0; x<8; ++x) { if (adam7[y][x] == pass) { rows += tiles; if (y < height) ++rows; break; /* i.e. break the 'x', column, loop. */ } } } return rows; } static png_uint_32 png_pass_cols(png_uint_32 width, int pass) { png_uint_32 tiles = width>>3; png_uint_32 cols = 0; unsigned int x, y; width &= 7; ++pass; for (x=0; x<8; ++x) { for (y=0; y<8; ++y) { if (adam7[y][x] == pass) { cols += tiles; if (x < width) ++cols; break; /* i.e. break the 'y', row, loop. */ } } } return cols; } static void perform_interlace_macro_validation(void) { /* The macros to validate, first those that depend only on pass: * * PNG_PASS_START_ROW(pass) * PNG_PASS_START_COL(pass) * PNG_PASS_ROW_SHIFT(pass) * PNG_PASS_COL_SHIFT(pass) */ int pass; for (pass=0; pass<7; ++pass) { png_uint_32 m, f, v; m = PNG_PASS_START_ROW(pass); f = png_pass_start_row(pass); if (m != f) { fprintf(stderr, "PNG_PASS_START_ROW(%d) = %u != %x\n", pass, m, f); exit(99); } m = PNG_PASS_START_COL(pass); f = png_pass_start_col(pass); if (m != f) { fprintf(stderr, "PNG_PASS_START_COL(%d) = %u != %x\n", pass, m, f); exit(99); } m = PNG_PASS_ROW_SHIFT(pass); f = png_pass_row_shift(pass); if (m != f) { fprintf(stderr, "PNG_PASS_ROW_SHIFT(%d) = %u != %x\n", pass, m, f); exit(99); } m = PNG_PASS_COL_SHIFT(pass); f = png_pass_col_shift(pass); if (m != f) { fprintf(stderr, "PNG_PASS_COL_SHIFT(%d) = %u != %x\n", pass, m, f); exit(99); } /* Macros that depend on the image or sub-image height too: * * PNG_PASS_ROWS(height, pass) * PNG_PASS_COLS(width, pass) * PNG_ROW_FROM_PASS_ROW(yIn, pass) * PNG_COL_FROM_PASS_COL(xIn, pass) * PNG_ROW_IN_INTERLACE_PASS(y, pass) * PNG_COL_IN_INTERLACE_PASS(x, pass) */ for (v=0;;) { /* The first two tests overflow if the pass row or column is outside * the possible range for a 32-bit result. In fact the values should * never be outside the range for a 31-bit result, but checking for 32 * bits here ensures that if an app uses a bogus pass row or column * (just so long as it fits in a 32 bit integer) it won't get a * possibly dangerous overflow. */ /* First the base 0 stuff: */ if (v < png_pass_rows(0xFFFFFFFFU, pass)) { m = PNG_ROW_FROM_PASS_ROW(v, pass); f = png_row_from_pass_row(v, pass); if (m != f) { fprintf(stderr, "PNG_ROW_FROM_PASS_ROW(%u, %d) = %u != %x\n", v, pass, m, f); exit(99); } } if (v < png_pass_cols(0xFFFFFFFFU, pass)) { m = PNG_COL_FROM_PASS_COL(v, pass); f = png_col_from_pass_col(v, pass); if (m != f) { fprintf(stderr, "PNG_COL_FROM_PASS_COL(%u, %d) = %u != %x\n", v, pass, m, f); exit(99); } } m = PNG_ROW_IN_INTERLACE_PASS(v, pass); f = png_row_in_interlace_pass(v, pass); if (m != f) { fprintf(stderr, "PNG_ROW_IN_INTERLACE_PASS(%u, %d) = %u != %x\n", v, pass, m, f); exit(99); } m = PNG_COL_IN_INTERLACE_PASS(v, pass); f = png_col_in_interlace_pass(v, pass); if (m != f) { fprintf(stderr, "PNG_COL_IN_INTERLACE_PASS(%u, %d) = %u != %x\n", v, pass, m, f); exit(99); } /* Then the base 1 stuff: */ ++v; m = PNG_PASS_ROWS(v, pass); f = png_pass_rows(v, pass); if (m != f) { fprintf(stderr, "PNG_PASS_ROWS(%u, %d) = %u != %x\n", v, pass, m, f); exit(99); } m = PNG_PASS_COLS(v, pass); f = png_pass_cols(v, pass); if (m != f) { fprintf(stderr, "PNG_PASS_COLS(%u, %d) = %u != %x\n", v, pass, m, f); exit(99); } /* Move to the next v - the stepping algorithm starts skipping * values above 1024. */ if (v > 1024) { if (v == PNG_UINT_31_MAX) break; v = (v << 1) ^ v; if (v >= PNG_UINT_31_MAX) v = PNG_UINT_31_MAX-1; } } } } /* Test color encodings. These values are back-calculated from the published * chromaticities. The values are accurate to about 14 decimal places; 15 are * given. These values are much more accurate than the ones given in the spec, * which typically don't exceed 4 decimal places. This allows testing of the * libpng code to its theoretical accuracy of 4 decimal places. (If pngvalid * used the published errors the 'slack' permitted would have to be +/-.5E-4 or * more.) * * The png_modifier code assumes that encodings[0] is sRGB and treats it * specially: do not change the first entry in this list! */ static const color_encoding test_encodings[] = { /* sRGB: must be first in this list! */ /*gamma:*/ { 1/2.2, /*red: */ { 0.412390799265959, 0.212639005871510, 0.019330818715592 }, /*green:*/ { 0.357584339383878, 0.715168678767756, 0.119194779794626 }, /*blue: */ { 0.180480788401834, 0.072192315360734, 0.950532152249660} }, /* Kodak ProPhoto (wide gamut) */ /*gamma:*/ { 1/1.6 /*approximate: uses 1.8 power law compared to sRGB 2.4*/, /*red: */ { 0.797760489672303, 0.288071128229293, 0.000000000000000 }, /*green:*/ { 0.135185837175740, 0.711843217810102, 0.000000000000000 }, /*blue: */ { 0.031349349581525, 0.000085653960605, 0.825104602510460} }, /* Adobe RGB (1998) */ /*gamma:*/ { 1/(2+51./256), /*red: */ { 0.576669042910131, 0.297344975250536, 0.027031361386412 }, /*green:*/ { 0.185558237906546, 0.627363566255466, 0.070688852535827 }, /*blue: */ { 0.188228646234995, 0.075291458493998, 0.991337536837639} }, /* Adobe Wide Gamut RGB */ /*gamma:*/ { 1/(2+51./256), /*red: */ { 0.716500716779386, 0.258728243040113, 0.000000000000000 }, /*green:*/ { 0.101020574397477, 0.724682314948566, 0.051211818965388 }, /*blue: */ { 0.146774385252705, 0.016589442011321, 0.773892783545073} }, /* Fake encoding which selects just the green channel */ /*gamma:*/ { 1.45/2.2, /* the 'Mac' gamma */ /*red: */ { 0.716500716779386, 0.000000000000000, 0.000000000000000 }, /*green:*/ { 0.101020574397477, 1.000000000000000, 0.051211818965388 }, /*blue: */ { 0.146774385252705, 0.000000000000000, 0.773892783545073} }, }; /* signal handler * * This attempts to trap signals and escape without crashing. It needs a * context pointer so that it can throw an exception (call longjmp) to recover * from the condition; this is handled by making the png_modifier used by 'main' * into a global variable. */ static png_modifier pm; static void signal_handler(int signum) { size_t pos = 0; char msg[64]; pos = safecat(msg, sizeof msg, pos, "caught signal: "); switch (signum) { case SIGABRT: pos = safecat(msg, sizeof msg, pos, "abort"); break; case SIGFPE: pos = safecat(msg, sizeof msg, pos, "floating point exception"); break; case SIGILL: pos = safecat(msg, sizeof msg, pos, "illegal instruction"); break; case SIGINT: pos = safecat(msg, sizeof msg, pos, "interrupt"); break; case SIGSEGV: pos = safecat(msg, sizeof msg, pos, "invalid memory access"); break; case SIGTERM: pos = safecat(msg, sizeof msg, pos, "termination request"); break; default: pos = safecat(msg, sizeof msg, pos, "unknown "); pos = safecatn(msg, sizeof msg, pos, signum); break; } store_log(&pm.this, NULL/*png_structp*/, msg, 1/*error*/); /* And finally throw an exception so we can keep going, unless this is * SIGTERM in which case stop now. */ if (signum != SIGTERM) { struct exception_context *the_exception_context = &pm.this.exception_context; Throw &pm.this; } else exit(1); } /* main program */ int main(int argc, char **argv) { int summary = 1; /* Print the error summary at the end */ int memstats = 0; /* Print memory statistics at the end */ /* Create the given output file on success: */ const char *touch = NULL; /* This is an array of standard gamma values (believe it or not I've seen * every one of these mentioned somewhere.) * * In the following list the most useful values are first! */ static double gammas[]={2.2, 1.0, 2.2/1.45, 1.8, 1.5, 2.4, 2.5, 2.62, 2.9}; /* This records the command and arguments: */ size_t cp = 0; char command[1024]; anon_context(&pm.this); gnu_volatile(summary) gnu_volatile(memstats) gnu_volatile(touch) /* Add appropriate signal handlers, just the ANSI specified ones: */ signal(SIGABRT, signal_handler); signal(SIGFPE, signal_handler); signal(SIGILL, signal_handler); signal(SIGINT, signal_handler); signal(SIGSEGV, signal_handler); signal(SIGTERM, signal_handler); #ifdef HAVE_FEENABLEEXCEPT /* Only required to enable FP exceptions on platforms where they start off * disabled; this is not necessary but if it is not done pngvalid will likely * end up ignoring FP conditions that other platforms fault. */ feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW); #endif modifier_init(&pm); /* Preallocate the image buffer, because we know how big it needs to be, * note that, for testing purposes, it is deliberately mis-aligned by tag * bytes either side. All rows have an additional five bytes of padding for * overwrite checking. */ store_ensure_image(&pm.this, NULL, 2, TRANSFORM_ROWMAX, TRANSFORM_HEIGHTMAX); /* Don't give argv[0], it's normally some horrible libtool string: */ cp = safecat(command, sizeof command, cp, "pngvalid"); /* Default to error on warning: */ pm.this.treat_warnings_as_errors = 1; /* Default assume_16_bit_calculations appropriately; this tells the checking * code that 16-bit arithmetic is used for 8-bit samples when it would make a * difference. */ pm.assume_16_bit_calculations = PNG_LIBPNG_VER >= 10700; /* Currently 16 bit expansion happens at the end of the pipeline, so the * calculations are done in the input bit depth not the output. * * TODO: fix this */ pm.calculations_use_input_precision = 1U; /* Store the test gammas */ pm.gammas = gammas; pm.ngammas = ARRAY_SIZE(gammas); pm.ngamma_tests = 0; /* default to off */ /* Low bit depth gray images don't do well in the gamma tests, until * this is fixed turn them off for some gamma cases: */ # ifdef PNG_WRITE_tRNS_SUPPORTED pm.test_tRNS = 1; # endif pm.test_lbg = PNG_LIBPNG_VER >= 10600; pm.test_lbg_gamma_threshold = 1; pm.test_lbg_gamma_transform = PNG_LIBPNG_VER >= 10600; pm.test_lbg_gamma_sbit = 1; pm.test_lbg_gamma_composition = PNG_LIBPNG_VER >= 10700; /* And the test encodings */ pm.encodings = test_encodings; pm.nencodings = ARRAY_SIZE(test_encodings); # if PNG_LIBPNG_VER < 10700 pm.sbitlow = 8U; /* because libpng doesn't do sBIT below 8! */ # else pm.sbitlow = 1U; # endif /* The following allows results to pass if they correspond to anything in the * transformed range [input-.5,input+.5]; this is is required because of the * way libpng treats the 16_TO_8 flag when building the gamma tables in * releases up to 1.6.0. * * TODO: review this */ pm.use_input_precision_16to8 = 1U; pm.use_input_precision_sbit = 1U; /* because libpng now rounds sBIT */ /* Some default values (set the behavior for 'make check' here). * These values simply control the maximum error permitted in the gamma * transformations. The practical limits for human perception are described * below (the setting for maxpc16), however for 8 bit encodings it isn't * possible to meet the accepted capabilities of human vision - i.e. 8 bit * images can never be good enough, regardless of encoding. */ pm.maxout8 = .1; /* Arithmetic error in *encoded* value */ pm.maxabs8 = .00005; /* 1/20000 */ pm.maxcalc8 = 1./255; /* +/-1 in 8 bits for compose errors */ pm.maxpc8 = .499; /* I.e., .499% fractional error */ pm.maxout16 = .499; /* Error in *encoded* value */ pm.maxabs16 = .00005;/* 1/20000 */ pm.maxcalc16 =1./65535;/* +/-1 in 16 bits for compose errors */ # if PNG_LIBPNG_VER < 10700 pm.maxcalcG = 1./((1<38149 by the following: */ pm.maxpc16 = .005; /* I.e., 1/200% - 1/20000 */ /* Now parse the command line options. */ while (--argc >= 1) { int catmore = 0; /* Set if the argument has an argument. */ /* Record each argument for posterity: */ cp = safecat(command, sizeof command, cp, " "); cp = safecat(command, sizeof command, cp, *++argv); if (strcmp(*argv, "-v") == 0) pm.this.verbose = 1; else if (strcmp(*argv, "-l") == 0) pm.log = 1; else if (strcmp(*argv, "-q") == 0) summary = pm.this.verbose = pm.log = 0; else if (strcmp(*argv, "-w") == 0 || strcmp(*argv, "--strict") == 0) pm.this.treat_warnings_as_errors = 1; /* NOTE: this is the default! */ else if (strcmp(*argv, "--nostrict") == 0) pm.this.treat_warnings_as_errors = 0; else if (strcmp(*argv, "--speed") == 0) pm.this.speed = 1, pm.ngamma_tests = pm.ngammas, pm.test_standard = 0, summary = 0; else if (strcmp(*argv, "--memory") == 0) memstats = 1; else if (strcmp(*argv, "--size") == 0) pm.test_size = 1; else if (strcmp(*argv, "--nosize") == 0) pm.test_size = 0; else if (strcmp(*argv, "--standard") == 0) pm.test_standard = 1; else if (strcmp(*argv, "--nostandard") == 0) pm.test_standard = 0; else if (strcmp(*argv, "--transform") == 0) pm.test_transform = 1; else if (strcmp(*argv, "--notransform") == 0) pm.test_transform = 0; #ifdef PNG_READ_TRANSFORMS_SUPPORTED else if (strncmp(*argv, "--transform-disable=", sizeof "--transform-disable") == 0) { pm.test_transform = 1; transform_disable(*argv + sizeof "--transform-disable"); } else if (strncmp(*argv, "--transform-enable=", sizeof "--transform-enable") == 0) { pm.test_transform = 1; transform_enable(*argv + sizeof "--transform-enable"); } #endif /* PNG_READ_TRANSFORMS_SUPPORTED */ else if (strcmp(*argv, "--gamma") == 0) { /* Just do two gamma tests here (2.2 and linear) for speed: */ pm.ngamma_tests = 2U; pm.test_gamma_threshold = 1; pm.test_gamma_transform = 1; pm.test_gamma_sbit = 1; pm.test_gamma_scale16 = 1; pm.test_gamma_background = 1; /* composition */ pm.test_gamma_alpha_mode = 1; } else if (strcmp(*argv, "--nogamma") == 0) pm.ngamma_tests = 0; else if (strcmp(*argv, "--gamma-threshold") == 0) pm.ngamma_tests = 2U, pm.test_gamma_threshold = 1; else if (strcmp(*argv, "--nogamma-threshold") == 0) pm.test_gamma_threshold = 0; else if (strcmp(*argv, "--gamma-transform") == 0) pm.ngamma_tests = 2U, pm.test_gamma_transform = 1; else if (strcmp(*argv, "--nogamma-transform") == 0) pm.test_gamma_transform = 0; else if (strcmp(*argv, "--gamma-sbit") == 0) pm.ngamma_tests = 2U, pm.test_gamma_sbit = 1; else if (strcmp(*argv, "--nogamma-sbit") == 0) pm.test_gamma_sbit = 0; else if (strcmp(*argv, "--gamma-16-to-8") == 0) pm.ngamma_tests = 2U, pm.test_gamma_scale16 = 1; else if (strcmp(*argv, "--nogamma-16-to-8") == 0) pm.test_gamma_scale16 = 0; else if (strcmp(*argv, "--gamma-background") == 0) pm.ngamma_tests = 2U, pm.test_gamma_background = 1; else if (strcmp(*argv, "--nogamma-background") == 0) pm.test_gamma_background = 0; else if (strcmp(*argv, "--gamma-alpha-mode") == 0) pm.ngamma_tests = 2U, pm.test_gamma_alpha_mode = 1; else if (strcmp(*argv, "--nogamma-alpha-mode") == 0) pm.test_gamma_alpha_mode = 0; else if (strcmp(*argv, "--expand16") == 0) { # ifdef PNG_READ_EXPAND_16_SUPPORTED pm.test_gamma_expand16 = 1; # else fprintf(stderr, "pngvalid: --expand16: no read support\n"); return SKIP; # endif } else if (strcmp(*argv, "--noexpand16") == 0) pm.test_gamma_expand16 = 0; else if (strcmp(*argv, "--low-depth-gray") == 0) pm.test_lbg = pm.test_lbg_gamma_threshold = pm.test_lbg_gamma_transform = pm.test_lbg_gamma_sbit = pm.test_lbg_gamma_composition = 1; else if (strcmp(*argv, "--nolow-depth-gray") == 0) pm.test_lbg = pm.test_lbg_gamma_threshold = pm.test_lbg_gamma_transform = pm.test_lbg_gamma_sbit = pm.test_lbg_gamma_composition = 0; else if (strcmp(*argv, "--tRNS") == 0) { # ifdef PNG_WRITE_tRNS_SUPPORTED pm.test_tRNS = 1; # else fprintf(stderr, "pngvalid: --tRNS: no write support\n"); return SKIP; # endif } else if (strcmp(*argv, "--notRNS") == 0) pm.test_tRNS = 0; else if (strcmp(*argv, "--more-gammas") == 0) pm.ngamma_tests = 3U; else if (strcmp(*argv, "--all-gammas") == 0) pm.ngamma_tests = pm.ngammas; else if (strcmp(*argv, "--progressive-read") == 0) pm.this.progressive = 1; else if (strcmp(*argv, "--use-update-info") == 0) ++pm.use_update_info; /* Can call multiple times */ else if (strcmp(*argv, "--interlace") == 0) { # if CAN_WRITE_INTERLACE pm.interlace_type = PNG_INTERLACE_ADAM7; # else /* !CAN_WRITE_INTERLACE */ fprintf(stderr, "pngvalid: no write interlace support\n"); return SKIP; # endif /* !CAN_WRITE_INTERLACE */ } else if (strcmp(*argv, "--use-input-precision") == 0) pm.use_input_precision = 1U; else if (strcmp(*argv, "--use-calculation-precision") == 0) pm.use_input_precision = 0; else if (strcmp(*argv, "--calculations-use-input-precision") == 0) pm.calculations_use_input_precision = 1U; else if (strcmp(*argv, "--assume-16-bit-calculations") == 0) pm.assume_16_bit_calculations = 1U; else if (strcmp(*argv, "--calculations-follow-bit-depth") == 0) pm.calculations_use_input_precision = pm.assume_16_bit_calculations = 0; else if (strcmp(*argv, "--exhaustive") == 0) pm.test_exhaustive = 1; else if (argc > 1 && strcmp(*argv, "--sbitlow") == 0) --argc, pm.sbitlow = (png_byte)atoi(*++argv), catmore = 1; else if (argc > 1 && strcmp(*argv, "--touch") == 0) --argc, touch = *++argv, catmore = 1; else if (argc > 1 && strncmp(*argv, "--max", 5) == 0) { --argc; if (strcmp(5+*argv, "abs8") == 0) pm.maxabs8 = atof(*++argv); else if (strcmp(5+*argv, "abs16") == 0) pm.maxabs16 = atof(*++argv); else if (strcmp(5+*argv, "calc8") == 0) pm.maxcalc8 = atof(*++argv); else if (strcmp(5+*argv, "calc16") == 0) pm.maxcalc16 = atof(*++argv); else if (strcmp(5+*argv, "out8") == 0) pm.maxout8 = atof(*++argv); else if (strcmp(5+*argv, "out16") == 0) pm.maxout16 = atof(*++argv); else if (strcmp(5+*argv, "pc8") == 0) pm.maxpc8 = atof(*++argv); else if (strcmp(5+*argv, "pc16") == 0) pm.maxpc16 = atof(*++argv); else { fprintf(stderr, "pngvalid: %s: unknown 'max' option\n", *argv); exit(99); } catmore = 1; } else if (strcmp(*argv, "--log8") == 0) --argc, pm.log8 = atof(*++argv), catmore = 1; else if (strcmp(*argv, "--log16") == 0) --argc, pm.log16 = atof(*++argv), catmore = 1; #ifdef PNG_SET_OPTION_SUPPORTED else if (strncmp(*argv, "--option=", 9) == 0) { /* Syntax of the argument is