diff options
author | Akira Kakuto <kakuto@fuk.kindai.ac.jp> | 2024-01-26 03:44:51 +0000 |
---|---|---|
committer | Akira Kakuto <kakuto@fuk.kindai.ac.jp> | 2024-01-26 03:44:51 +0000 |
commit | 3cedc5fd080731a3cd2c47e2f40fc140bba1accb (patch) | |
tree | e0530823f7d1ae5e33f4aeb5b5a6e8f873a1ad68 /Build/source/libs/libpng/libpng-src/contrib | |
parent | c5b2b6fde7be60e4ef155aa1f6bef99621e26efc (diff) |
libpng 1.6.41
git-svn-id: svn://tug.org/texlive/trunk@69596 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs/libpng/libpng-src/contrib')
26 files changed, 607 insertions, 459 deletions
diff --git a/Build/source/libs/libpng/libpng-src/contrib/mips-mmi/linux.c b/Build/source/libs/libpng/libpng-src/contrib/mips-mmi/linux.c new file mode 100644 index 00000000000..31525fde9a1 --- /dev/null +++ b/Build/source/libs/libpng/libpng-src/contrib/mips-mmi/linux.c @@ -0,0 +1,142 @@ + +/* contrib/mips-mmi/linux.c + * + * Copyright (c) 2024 Cosmin Truta + * Written by guxiwei, 2023 + * + * This code is released under the libpng license. + * For conditions of distribution and use, see the disclaimer + * and license in png.h + */ + +#include <stdint.h> +#include <stdio.h> +#include <string.h> +#include <sys/auxv.h> + +/* + * parse_r var, r - Helper assembler macro for parsing register names. + * + * This converts the register name in $n form provided in \r to the + * corresponding register number, which is assigned to the variable \var. It is + * needed to allow explicit encoding of instructions in inline assembly where + * registers are chosen by the compiler in $n form, allowing us to avoid using + * fixed register numbers. + * + * It also allows newer instructions (not implemented by the assembler) to be + * transparently implemented using assembler macros, instead of needing separate + * cases depending on toolchain support. + * + * Simple usage example: + * __asm__ __volatile__("parse_r __rt, %0\n\t" + * ".insn\n\t" + * "# di %0\n\t" + * ".word (0x41606000 | (__rt << 16))" + * : "=r" (status); + */ + +/* Match an individual register number and assign to \var */ +#define _IFC_REG(n) \ + ".ifc \\r, $" #n "\n\t" \ + "\\var = " #n "\n\t" \ + ".endif\n\t" + +__asm__(".macro parse_r var r\n\t" + "\\var = -1\n\t" + _IFC_REG(0) _IFC_REG(1) _IFC_REG(2) _IFC_REG(3) + _IFC_REG(4) _IFC_REG(5) _IFC_REG(6) _IFC_REG(7) + _IFC_REG(8) _IFC_REG(9) _IFC_REG(10) _IFC_REG(11) + _IFC_REG(12) _IFC_REG(13) _IFC_REG(14) _IFC_REG(15) + _IFC_REG(16) _IFC_REG(17) _IFC_REG(18) _IFC_REG(19) + _IFC_REG(20) _IFC_REG(21) _IFC_REG(22) _IFC_REG(23) + _IFC_REG(24) _IFC_REG(25) _IFC_REG(26) _IFC_REG(27) + _IFC_REG(28) _IFC_REG(29) _IFC_REG(30) _IFC_REG(31) + ".iflt \\var\n\t" + ".error \"Unable to parse register name \\r\"\n\t" + ".endif\n\t" + ".endm"); + +#define HWCAP_LOONGSON_CPUCFG (1 << 14) + +static int cpucfg_available(void) +{ + return getauxval(AT_HWCAP) & HWCAP_LOONGSON_CPUCFG; +} + +static int strstart(const char *str, const char *pfx, const char **ptr) +{ + while (*pfx && *pfx == *str) { + pfx++; + str++; + } + if (!*pfx && ptr) + *ptr = str; + return !*pfx; +} + +/* Most toolchains have no CPUCFG support yet */ +static uint32_t read_cpucfg(uint32_t reg) +{ + uint32_t __res; + + __asm__ __volatile__( + "parse_r __res,%0\n\t" + "parse_r reg,%1\n\t" + ".insn \n\t" + ".word (0xc8080118 | (reg << 21) | (__res << 11))\n\t" + :"=r"(__res) + :"r"(reg) + : + ); + return __res; +} + +#define LOONGSON_CFG1 0x1 + +#define LOONGSON_CFG1_MMI (1 << 4) + +static int cpu_flags_cpucfg(void) +{ + int flags = 0; + uint32_t cfg1 = read_cpucfg(LOONGSON_CFG1); + + if (cfg1 & LOONGSON_CFG1_MMI) + flags = 1; + + return flags; +} + +static int cpu_flags_cpuinfo(void) +{ + FILE *f = fopen("/proc/cpuinfo", "r"); + char buf[200]; + int flags = 0; + + if (!f) + return flags; + + while (fgets(buf, sizeof(buf), f)) { + /* Legacy kernel may not export MMI in ASEs implemented */ + if (strstart(buf, "cpu model", NULL)) { + if (strstr(buf, "Loongson-3 ")) + flags = 1; + break; + } + if (strstart(buf, "ASEs implemented", NULL)) { + if (strstr(buf, " loongson-mmi")) + flags = 1; + break; + } + } + fclose(f); + return flags; +} + +static int png_have_mmi() +{ + if (cpucfg_available()) + return cpu_flags_cpucfg(); + else + return cpu_flags_cpuinfo(); + return 0; +} diff --git a/Build/source/libs/libpng/libpng-src/contrib/mips-msa/linux.c b/Build/source/libs/libpng/libpng-src/contrib/mips-msa/linux.c index 3bac6111b79..cae8ca50ffc 100644 --- a/Build/source/libs/libpng/libpng-src/contrib/mips-msa/linux.c +++ b/Build/source/libs/libpng/libpng-src/contrib/mips-msa/linux.c @@ -1,67 +1,55 @@ /* contrib/mips-msa/linux.c * - * Copyright (c) 2020 Cosmin Truta + * Copyright (c) 2020-2023 Cosmin Truta * Copyright (c) 2016 Glenn Randers-Pehrson * Written by Mandar Sahastrabuddhe, 2016. + * Updated by Sui Jingfeng, 2021. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer * and license in png.h * - * SEE contrib/mips-msa/README before reporting bugs + * On Linux, png_have_msa is implemented by reading the pseudo-file + * "/proc/self/auxv". + * + * See contrib/mips-msa/README before reporting bugs. * * STATUS: SUPPORTED * BUG REPORTS: png-mng-implement@sourceforge.net - * - * png_have_msa 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 <stdio.h> and it assumes that /proc/cpuinfo is never localized. */ -#include <stdio.h> -#include <string.h> +#include <elf.h> +#include <fcntl.h> #include <stdlib.h> +#include <unistd.h> static int png_have_msa(png_structp png_ptr) { - FILE *f = fopen("/proc/cpuinfo", "rb"); + Elf64_auxv_t aux; + int fd; + int has_msa = 0; - char *string = "msa"; - char word[10]; - - if (f != NULL) + fd = open("/proc/self/auxv", O_RDONLY); + if (fd >= 0) { - while(!feof(f)) + while (read(fd, &aux, sizeof(Elf64_auxv_t)) == sizeof(Elf64_auxv_t)) { - int ch = fgetc(f); - static int i = 0; - - while(!(ch <= 32)) + if (aux.a_type == AT_HWCAP) { - word[i++] = ch; - ch = fgetc(f); - } - - int val = strcmp(string, word); + uint64_t hwcap = aux.a_un.a_val; - if (val == 0) { - fclose(f); - return 1; + has_msa = (hwcap >> 1) & 1; + break; } - - i = 0; - memset(word, 0, 10); } - - fclose(f); + close(fd); } #ifdef PNG_WARNINGS_SUPPORTED else - png_warning(png_ptr, "/proc/cpuinfo open failed"); + png_warning(png_ptr, "/proc/self/auxv open failed"); #endif - return 0; + + return has_msa; } diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminus/.gitignore b/Build/source/libs/libpng/libpng-src/contrib/pngminus/.gitignore new file mode 100644 index 00000000000..5114c75cdf2 --- /dev/null +++ b/Build/source/libs/libpng/libpng-src/contrib/pngminus/.gitignore @@ -0,0 +1,11 @@ +# Compiled executables +png2pnm +png2pnm.exe +png2pnm-static* +pnm2png +pnm2png.exe +pnm2png-static* + +# Test artifacts +*.png +*.p[abgnp]m diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminus/CHANGES.txt b/Build/source/libs/libpng/libpng-src/contrib/pngminus/CHANGES.txt index 4e64e5ee614..85e590a4a24 100644 --- a/Build/source/libs/libpng/libpng-src/contrib/pngminus/CHANGES.txt +++ b/Build/source/libs/libpng/libpng-src/contrib/pngminus/CHANGES.txt @@ -3,7 +3,7 @@ pnm2png / png2pnm --- conversion from PBM/PGM/PPM-file to PNG-file copyright (C) 1999-2019 by Willem van Schaik <willem at schaik dot com> version 1.0 - 1999.10.15 - First version. - 1.1 - 2015.07.29 - Fixed leaks (Glenn Randers-Pehrson) + 1.1 - 2015.07.29 - Fix memory leaks (Glenn Randers-Pehrson) 1.2 - 2017.04.22 - Add buffer-size check 1.3 - 2017.08.24 - Fix potential overflow in buffer-size check (Glenn Randers-Pehrson) @@ -11,3 +11,4 @@ version 1.0 - 1999.10.15 - First version. 1.5 - 2018.08.05 - Fix buffer overflow in tokenizer (Cosmin Truta) 1.6 - 2018.08.05 - Improve portability and fix style (Cosmin Truta) 1.7 - 2019.01.22 - Change license to MIT (Willem van Schaik) + 1.8 - 2024.01.09 - Fix, improve, modernize (Cosmin Truta) diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminus/CMakeLists.txt b/Build/source/libs/libpng/libpng-src/contrib/pngminus/CMakeLists.txt index 1f815a58251..d7893648a72 100644 --- a/Build/source/libs/libpng/libpng-src/contrib/pngminus/CMakeLists.txt +++ b/Build/source/libs/libpng/libpng-src/contrib/pngminus/CMakeLists.txt @@ -1,24 +1,41 @@ -cmake_minimum_required(VERSION 3.1) -cmake_policy(VERSION 3.1) +# Copyright (c) 2018-2024 Cosmin Truta +# +# This software is released under the MIT license. For conditions of +# distribution and use, see the LICENSE file part of this package. -project(PNGMINUS C) +cmake_minimum_required(VERSION 3.5) -option(PNGMINUS_USE_STATIC_LIBRARIES "Use the static library builds" ON) +project(PNGMINUS C) -# libpng -add_subdirectory(../.. libpng) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../..) -include_directories(${CMAKE_CURRENT_BINARY_DIR}/libpng) -if(PNGMINUS_USE_STATIC_LIBRARIES) - set(PNGMINUS_PNG_LIBRARY png_static) -else() - set(PNGMINUS_PNG_LIBRARY png) -endif() +option(PNGMINUS_USE_SYSTEM_PNG + "Use the libpng build found in the system" OFF) -# png2pnm add_executable(png2pnm png2pnm.c) -target_link_libraries(png2pnm ${PNGMINUS_PNG_LIBRARY}) - -# pnm2png add_executable(pnm2png pnm2png.c) -target_link_libraries(pnm2png ${PNGMINUS_PNG_LIBRARY}) + +if(PNGMINUS_USE_SYSTEM_PNG) + # Use the system libpng. + find_package(PNG REQUIRED) + target_link_libraries(png2pnm PRIVATE PNG::PNG) + target_link_libraries(pnm2png PRIVATE PNG::PNG) +else() + # Build and use the internal libpng. + # Configure libpng for static linking, to produce single-file executables. + set(PNG_STATIC ON + CACHE STRING "Build the internal libpng as a static library" FORCE) + set(PNG_SHARED OFF + CACHE STRING "Build the internal libpng as a shared library" FORCE) + set(PNG_FRAMEWORK OFF + CACHE STRING "Build the internal libpng as a framework bundle" FORCE) + add_subdirectory(../.. libpng) + target_include_directories(png2pnm PRIVATE + "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../..>" + "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/libpng>" + ) + target_include_directories(pnm2png PRIVATE + "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../..>" + "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/libpng>" + ) + target_link_libraries(png2pnm PRIVATE png_static) + target_link_libraries(pnm2png PRIVATE png_static) +endif() diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminus/png2pnm.c b/Build/source/libs/libpng/libpng-src/contrib/pngminus/png2pnm.c index 5fef7ed1425..f9d5138b7eb 100644 --- a/Build/source/libs/libpng/libpng-src/contrib/pngminus/png2pnm.c +++ b/Build/source/libs/libpng/libpng-src/contrib/pngminus/png2pnm.c @@ -14,15 +14,10 @@ #define BOOL unsigned char #endif #ifndef TRUE -#define TRUE (BOOL) 1 +#define TRUE ((BOOL) 1) #endif #ifndef FALSE -#define FALSE (BOOL) 0 -#endif - -/* make png2pnm verbose so we can find problems (needs to be before png.h) */ -#ifndef PNG_DEBUG -#define PNG_DEBUG 0 +#define FALSE ((BOOL) 0) #endif #include "png.h" @@ -33,6 +28,9 @@ int main (int argc, char *argv[]); void usage (); BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file, BOOL raw, BOOL alpha); +BOOL do_png2pnm (png_struct *png_ptr, png_info *info_ptr, + FILE *pnm_file, FILE *alpha_file, + BOOL raw, BOOL alpha); /* * main @@ -43,9 +41,12 @@ int main (int argc, char *argv[]) FILE *fp_rd = stdin; FILE *fp_wr = stdout; FILE *fp_al = NULL; + const char *fname_wr = NULL; + const char *fname_al = NULL; BOOL raw = TRUE; BOOL alpha = FALSE; int argi; + int ret; for (argi = 1; argi < argc; argi++) { @@ -64,6 +65,7 @@ int main (int argc, char *argv[]) argi++; if ((fp_al = fopen (argv[argi], "wb")) == NULL) { + fname_al = argv[argi]; fprintf (stderr, "PNM2PNG\n"); fprintf (stderr, "Error: cannot create alpha-channel file %s\n", argv[argi]); @@ -94,6 +96,7 @@ int main (int argc, char *argv[]) } else if (fp_wr == stdout) { + fname_wr = argv[argi]; if ((fp_wr = fopen (argv[argi], "wb")) == NULL) { fprintf (stderr, "PNG2PNM\n"); @@ -119,12 +122,7 @@ int main (int argc, char *argv[]) #endif /* call the conversion program itself */ - if (png2pnm (fp_rd, fp_wr, fp_al, raw, alpha) == FALSE) - { - fprintf (stderr, "PNG2PNM\n"); - fprintf (stderr, "Error: unsuccessful conversion of PNG-image\n"); - exit (1); - } + ret = png2pnm (fp_rd, fp_wr, fp_al, raw, alpha); /* close input file */ fclose (fp_rd); @@ -134,6 +132,17 @@ int main (int argc, char *argv[]) if (alpha) fclose (fp_al); + if (!ret) + { + fprintf (stderr, "PNG2PNM\n"); + fprintf (stderr, "Error: unsuccessful conversion of PNG-image\n"); + if (fname_wr) + remove (fname_wr); /* no broken output file shall remain behind */ + if (fname_al) + remove (fname_al); /* ditto */ + exit (1); + } + return 0; } @@ -163,35 +172,11 @@ void usage () BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file, BOOL raw, BOOL alpha) { - png_struct *png_ptr = NULL; - png_info *info_ptr = NULL; - png_byte buf[8]; - png_byte *png_pixels = NULL; - png_byte **row_pointers = NULL; - png_byte *pix_ptr = NULL; - png_uint_32 row_bytes; + png_struct *png_ptr; + png_info *info_ptr; + BOOL ret; - png_uint_32 width; - png_uint_32 height; - int bit_depth; - int channels; - int color_type; - int alpha_present; - int row, col; - int ret; - int i; - long dep_16; - - /* read and check signature in PNG file */ - ret = fread (buf, 1, 8, png_file); - if (ret != 8) - return FALSE; - - ret = png_sig_cmp (buf, 0, 8); - if (ret != 0) - return FALSE; - - /* create png and info structures */ + /* initialize the libpng context for reading from png_file */ png_ptr = png_create_read_struct (png_get_libpng_ver(NULL), NULL, NULL, NULL); @@ -208,31 +193,47 @@ BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file, if (setjmp (png_jmpbuf (png_ptr))) { png_destroy_read_struct (&png_ptr, &info_ptr, NULL); - return FALSE; + return FALSE; /* generic libpng error */ } - /* set up the input control for C streams */ png_init_io (png_ptr, png_file); - png_set_sig_bytes (png_ptr, 8); /* we already read the 8 signature bytes */ - /* read the file information */ - png_read_info (png_ptr, info_ptr); + /* do the actual conversion */ + ret = do_png2pnm (png_ptr, info_ptr, pnm_file, alpha_file, raw, alpha); - /* get size and bit-depth of the PNG-image */ - png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, - NULL, NULL, NULL); + /* clean up the libpng structures and their internally-managed data */ + png_destroy_read_struct (&png_ptr, &info_ptr, NULL); - /* set-up the transformations */ + return ret; +} - /* transform paletted images into full-color rgb */ - if (color_type == PNG_COLOR_TYPE_PALETTE) - png_set_expand (png_ptr); - /* expand images to bit-depth 8 (only applicable for grayscale images) */ - if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) - png_set_expand (png_ptr); - /* transform transparency maps into full alpha-channel */ - if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) - png_set_expand (png_ptr); +/* + * do_png2pnm - does the conversion in a fully-initialized libpng context + */ + +BOOL do_png2pnm (png_struct *png_ptr, png_info *info_ptr, + FILE *pnm_file, FILE *alpha_file, + BOOL raw, BOOL alpha) +{ + png_byte **row_pointers; + png_byte *pix_ptr; + png_uint_32 width; + png_uint_32 height; + int bit_depth; + int channels; + int color_type; + int alpha_present; + png_uint_32 row, col, i; + long dep_16; + + /* set up the image transformations that are necessary for the PNM format */ + + /* set up (if applicable) the expansion of paletted images to full-color rgb, + * and the expansion of transparency maps to full alpha-channel */ + png_set_expand (png_ptr); + + /* set up (if applicable) the expansion of grayscale images to bit-depth 8 */ + png_set_expand_gray_1_2_4_to_8 (png_ptr); #ifdef NJET /* downgrade 16-bit images to 8-bit */ @@ -242,30 +243,22 @@ BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file, if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb (png_ptr); - /* only if file has a file gamma, we do a correction */ - if (png_get_gAMA (png_ptr, info_ptr, &file_gamma)) - png_set_gamma (png_ptr, (double) 2.2, file_gamma); + /* if the PNG image has a gAMA chunk then gamma-correct the output image */ + { + double file_gamma; + if (png_get_gAMA (png_ptr, info_ptr, &file_gamma)) + png_set_gamma (png_ptr, (double) 2.2, file_gamma); + } #endif - /* 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); + /* read the image file, with all of the above image transforms applied */ + png_read_png (png_ptr, info_ptr, 0, NULL); - /* get the new color-type and bit-depth (after expansion/stripping) */ + /* get the image size, bit-depth and color-type */ png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL); - /* check for 16-bit files */ - if (bit_depth == 16) - { - raw = FALSE; -#if defined(O_BINARY) && (O_BINARY != 0) - setmode (fileno (pnm_file), O_BINARY); -#endif - } - - /* calculate new number of channels and store alpha-presence */ + /* calculate the number of channels and store alpha-presence */ if (color_type == PNG_COLOR_TYPE_GRAY) channels = 1; else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) @@ -282,47 +275,12 @@ BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file, if (alpha && !alpha_present) { fprintf (stderr, "PNG2PNM\n"); - fprintf (stderr, "Error: PNG-file doesn't contain alpha channel\n"); - exit (1); - } - - /* row_bytes is the width x number of channels x (bit-depth / 8) */ - row_bytes = png_get_rowbytes (png_ptr, info_ptr); - - if ((row_bytes == 0) || - ((size_t) height > (size_t) (-1) / (size_t) row_bytes)) - { - /* too big */ - png_destroy_read_struct (&png_ptr, &info_ptr, NULL); - return FALSE; - } - if ((png_pixels = (png_byte *) - malloc ((size_t) row_bytes * (size_t) height)) == NULL) - { - png_destroy_read_struct (&png_ptr, &info_ptr, NULL); - return FALSE; - } - - if ((row_pointers = (png_byte **) - malloc ((size_t) height * sizeof (png_byte *))) == NULL) - { - png_destroy_read_struct (&png_ptr, &info_ptr, NULL); - free (png_pixels); + fprintf (stderr, "Warning: no alpha channel in PNG file\n"); return FALSE; } - /* set the individual row_pointers to point at the correct offsets */ - for (i = 0; i < ((int) height); i++) - row_pointers[i] = png_pixels + i * row_bytes; - - /* now we can go ahead and just read the whole image */ - png_read_image (png_ptr, row_pointers); - - /* read rest of file, and get additional chunks in info_ptr - REQUIRED */ - png_read_end (png_ptr, info_ptr); - - /* clean up after the read, and free any memory allocated - REQUIRED */ - png_destroy_read_struct (&png_ptr, &info_ptr, NULL); + /* get address of internally-allocated image data */ + row_pointers = png_get_rows (png_ptr, info_ptr); /* write header of PNM file */ @@ -353,24 +311,27 @@ BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file, } /* write data to PNM file */ - pix_ptr = png_pixels; - for (row = 0; row < (int) height; row++) + for (row = 0; row < height; row++) { - for (col = 0; col < (int) width; col++) + pix_ptr = row_pointers[row]; + for (col = 0; col < width; col++) { - for (i = 0; i < (channels - alpha_present); i++) + for (i = 0; i < (png_uint_32) (channels - alpha_present); i++) { if (raw) { fputc ((int) *pix_ptr++, pnm_file); + if (bit_depth == 16) + fputc ((int) *pix_ptr++, pnm_file); } else { if (bit_depth == 16) { - dep_16 = (long) *pix_ptr++; - fprintf (pnm_file, "%ld ", (dep_16 << 8) + ((long) *pix_ptr++)); + dep_16 = ((long) *pix_ptr++) << 8; + dep_16 += ((long) *pix_ptr++); + fprintf (pnm_file, "%ld ", dep_16); } else { @@ -382,22 +343,27 @@ BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file, { if (!alpha) { - pix_ptr++; /* alpha */ + /* skip the alpha-channel */ + pix_ptr++; if (bit_depth == 16) pix_ptr++; } - else /* output alpha-channel as pgm file */ + else { + /* output the alpha-channel as pgm file */ if (raw) { fputc ((int) *pix_ptr++, alpha_file); + if (bit_depth == 16) + fputc ((int) *pix_ptr++, alpha_file); } else { if (bit_depth == 16) { - dep_16 = (long) *pix_ptr++; - fprintf (alpha_file, "%ld ", (dep_16 << 8) + (long) *pix_ptr++); + dep_16 = ((long) *pix_ptr++) << 8; + dep_16 += ((long) *pix_ptr++); + fprintf (alpha_file, "%ld ", dep_16); } else { @@ -417,11 +383,5 @@ BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file, fprintf (pnm_file, "\n"); } /* end for row */ - if (row_pointers != NULL) - free (row_pointers); - if (png_pixels != NULL) - free (png_pixels); - return TRUE; - } /* end of source */ diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminus/pnm2png.c b/Build/source/libs/libpng/libpng-src/contrib/pngminus/pnm2png.c index a2c2551da92..052fd3272c8 100644 --- a/Build/source/libs/libpng/libpng-src/contrib/pngminus/pnm2png.c +++ b/Build/source/libs/libpng/libpng-src/contrib/pngminus/pnm2png.c @@ -6,6 +6,7 @@ * distribution and use, see the LICENSE file part of this package. */ +#include <limits.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> @@ -14,15 +15,10 @@ #define BOOL unsigned char #endif #ifndef TRUE -#define TRUE (BOOL) 1 +#define TRUE ((BOOL) 1) #endif #ifndef FALSE -#define FALSE (BOOL) 0 -#endif - -/* make pnm2png verbose so we can find problems (needs to be before png.h) */ -#ifndef PNG_DEBUG -#define PNG_DEBUG 0 +#define FALSE ((BOOL) 0) #endif #include "png.h" @@ -33,9 +29,14 @@ int main (int argc, char *argv[]); void usage (); BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace, BOOL alpha); -void get_token (FILE *pnm_file, char *token_buf, size_t token_buf_size); -png_uint_32 get_data (FILE *pnm_file, int depth); -png_uint_32 get_value (FILE *pnm_file, int depth); +BOOL do_pnm2png (png_struct *png_ptr, png_info *info_ptr, + FILE *pnm_file, FILE *alpha_file, + BOOL interlace, BOOL alpha); +int fscan_pnm_magic (FILE *pnm_file, char *magic_buf, size_t magic_buf_size); +int fscan_pnm_token (FILE *pnm_file, char *token_buf, size_t token_buf_size); +int fscan_pnm_uint_32 (FILE *pnm_file, png_uint_32 *num_ptr); +png_uint_32 get_pnm_data (FILE *pnm_file, int depth); +png_uint_32 get_pnm_value (FILE *pnm_file, int depth); /* * main @@ -46,9 +47,11 @@ int main (int argc, char *argv[]) FILE *fp_rd = stdin; FILE *fp_al = NULL; FILE *fp_wr = stdout; + const char *fname_wr = NULL; BOOL interlace = FALSE; BOOL alpha = FALSE; int argi; + int ret; for (argi = 1; argi < argc; argi++) { @@ -94,6 +97,7 @@ int main (int argc, char *argv[]) } else if (fp_wr == stdout) { + fname_wr = argv[argi]; if ((fp_wr = fopen (argv[argi], "wb")) == NULL) { fprintf (stderr, "PNM2PNG\n"); @@ -121,12 +125,7 @@ int main (int argc, char *argv[]) #endif /* call the conversion program itself */ - if (pnm2png (fp_rd, fp_wr, fp_al, interlace, alpha) == FALSE) - { - fprintf (stderr, "PNM2PNG\n"); - fprintf (stderr, "Error: unsuccessful converting to PNG-image\n"); - exit (1); - } + ret = pnm2png (fp_rd, fp_wr, fp_al, interlace, alpha); /* close input file */ fclose (fp_rd); @@ -136,6 +135,15 @@ int main (int argc, char *argv[]) if (alpha) fclose (fp_al); + if (!ret) + { + fprintf (stderr, "PNM2PNG\n"); + fprintf (stderr, "Error: unsuccessful converting to PNG-image\n"); + if (fname_wr) + remove (fname_wr); /* no broken output file shall remain behind */ + exit (1); + } + return 0; } @@ -163,77 +171,98 @@ void usage () BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace, BOOL alpha) { - png_struct *png_ptr = NULL; - png_info *info_ptr = NULL; - png_byte *png_pixels = NULL; - png_byte **row_pointers = NULL; - png_byte *pix_ptr = NULL; - volatile png_uint_32 row_bytes; - - char type_token[16]; - char width_token[16]; - char height_token[16]; - char maxval_token[16]; - volatile int color_type = 1; - unsigned long ul_width = 0, ul_alpha_width = 0; - unsigned long ul_height = 0, ul_alpha_height = 0; - unsigned long ul_maxval = 0; - volatile png_uint_32 width = 0, height = 0; - volatile png_uint_32 alpha_width = 0, alpha_height = 0; - png_uint_32 maxval; - volatile int bit_depth = 0; - int channels = 0; - int alpha_depth = 0; - int alpha_present = 0; - int row, col; - BOOL raw, alpha_raw = FALSE; -#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) + png_struct *png_ptr; + png_info *info_ptr; + BOOL ret; + + /* initialize the libpng context for writing to png_file */ + + png_ptr = png_create_write_struct (png_get_libpng_ver(NULL), + NULL, NULL, NULL); + if (!png_ptr) + return FALSE; /* out of memory */ + + info_ptr = png_create_info_struct (png_ptr); + if (!info_ptr) + { + png_destroy_write_struct (&png_ptr, NULL); + return FALSE; /* out of memory */ + } + + if (setjmp (png_jmpbuf (png_ptr))) + { + png_destroy_write_struct (&png_ptr, &info_ptr); + return FALSE; /* generic libpng error */ + } + + png_init_io (png_ptr, png_file); + + /* do the actual conversion */ + ret = do_pnm2png (png_ptr, info_ptr, pnm_file, alpha_file, interlace, alpha); + + /* clean up the libpng structures and their internally-managed data */ + png_destroy_write_struct (&png_ptr, &info_ptr); + + return ret; +} + +/* + * do_pnm2png - does the conversion in a fully-initialized libpng context + */ + +BOOL do_pnm2png (png_struct *png_ptr, png_info *info_ptr, + FILE *pnm_file, FILE *alpha_file, + BOOL interlace, BOOL alpha) +{ + png_byte **row_pointers; + png_byte *pix_ptr; + int bit_depth; + int color_type; + int channels; + char magic_token[4]; + BOOL raw; + png_uint_32 width, height, maxval; + png_uint_32 row_bytes; + png_uint_32 row, col; + png_uint_32 val16, i; + png_uint_32 alpha_width = 0, alpha_height = 0; + int alpha_depth = 0, alpha_present = 0; + BOOL alpha_raw = FALSE; BOOL packed_bitmap = FALSE; -#endif - png_uint_32 tmp16; - int i; /* read header of PNM file */ - get_token (pnm_file, type_token, sizeof (type_token)); - if (type_token[0] != 'P') + if (fscan_pnm_magic (pnm_file, magic_token, sizeof (magic_token)) != 1) + return FALSE; /* not a PNM file */ + + if ((magic_token[1] == '1') || (magic_token[1] == '4')) { - return FALSE; + if ((fscan_pnm_uint_32 (pnm_file, &width) != 1) || + (fscan_pnm_uint_32 (pnm_file, &height) != 1)) + return FALSE; /* bad PBM file header */ + } else if ((magic_token[1] == '2') || (magic_token[1] == '5') || + (magic_token[1] == '3') || (magic_token[1] == '6')) + { + if ((fscan_pnm_uint_32 (pnm_file, &width) != 1) || + (fscan_pnm_uint_32 (pnm_file, &height) != 1) || + (fscan_pnm_uint_32 (pnm_file, &maxval) != 1)) + return FALSE; /* bad PGM/PPM file header */ } - else if ((type_token[1] == '1') || (type_token[1] == '4')) + + if ((magic_token[1] == '1') || (magic_token[1] == '4')) { -#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) - raw = (type_token[1] == '4'); - color_type = PNG_COLOR_TYPE_GRAY; - get_token (pnm_file, width_token, sizeof (width_token)); - sscanf (width_token, "%lu", &ul_width); - width = (png_uint_32) ul_width; - get_token (pnm_file, height_token, sizeof (height_token)); - sscanf (height_token, "%lu", &ul_height); - height = (png_uint_32) ul_height; + raw = (magic_token[1] == '4'); bit_depth = 1; + color_type = PNG_COLOR_TYPE_GRAY; packed_bitmap = TRUE; -#else - fprintf (stderr, "PNM2PNG built without PNG_WRITE_INVERT_SUPPORTED and\n"); - fprintf (stderr, "PNG_WRITE_PACK_SUPPORTED can't read PBM (P1,P4) files\n"); - return FALSE; -#endif } - else if ((type_token[1] == '2') || (type_token[1] == '5')) + else if ((magic_token[1] == '2') || (magic_token[1] == '5')) { - raw = (type_token[1] == '5'); + raw = (magic_token[1] == '5'); color_type = PNG_COLOR_TYPE_GRAY; - get_token (pnm_file, width_token, sizeof (width_token)); - sscanf (width_token, "%lu", &ul_width); - width = (png_uint_32) ul_width; - get_token (pnm_file, height_token, sizeof (height_token)); - sscanf (height_token, "%lu", &ul_height); - height = (png_uint_32) ul_height; - get_token (pnm_file, maxval_token, sizeof (maxval_token)); - sscanf (maxval_token, "%lu", &ul_maxval); - maxval = (png_uint_32) ul_maxval; - - if (maxval <= 1) + if (maxval == 0) + return FALSE; + else if (maxval == 1) bit_depth = 1; else if (maxval <= 3) bit_depth = 2; @@ -246,20 +275,13 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, else /* maxval > 65535U */ return FALSE; } - else if ((type_token[1] == '3') || (type_token[1] == '6')) + else if ((magic_token[1] == '3') || (magic_token[1] == '6')) { - raw = (type_token[1] == '6'); + raw = (magic_token[1] == '6'); color_type = PNG_COLOR_TYPE_RGB; - get_token (pnm_file, width_token, sizeof (width_token)); - sscanf (width_token, "%lu", &ul_width); - width = (png_uint_32) ul_width; - get_token (pnm_file, height_token, sizeof (height_token)); - sscanf (height_token, "%lu", &ul_height); - height = (png_uint_32) ul_height; - get_token (pnm_file, maxval_token, sizeof (maxval_token)); - sscanf (maxval_token, "%lu", &ul_maxval); - maxval = (png_uint_32) ul_maxval; - if (maxval <= 1) + if (maxval == 0) + return FALSE; + else if (maxval == 1) bit_depth = 1; else if (maxval <= 3) bit_depth = 2; @@ -272,6 +294,11 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, else /* maxval > 65535U */ return FALSE; } + else if (magic_token[1] == '7') + { + fprintf (stderr, "PNM2PNG can't read PAM (P7) files\n"); + return FALSE; + } else { return FALSE; @@ -281,51 +308,36 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, if (alpha) { - if (color_type == PNG_COLOR_TYPE_GRAY) - color_type = PNG_COLOR_TYPE_GRAY_ALPHA; - if (color_type == PNG_COLOR_TYPE_RGB) - color_type = PNG_COLOR_TYPE_RGB_ALPHA; + if ((fscan_pnm_magic (alpha_file, magic_token, sizeof (magic_token)) != 1) + || ((magic_token[1] != '2') && (magic_token[1] != '5'))) + return FALSE; /* not a PGM file */ - get_token (alpha_file, type_token, sizeof (type_token)); - if (type_token[0] != 'P') - { + if ((fscan_pnm_uint_32 (alpha_file, &alpha_width) != 1) || + (fscan_pnm_uint_32 (alpha_file, &alpha_height) != 1) || + (fscan_pnm_uint_32 (alpha_file, &maxval) != 1)) + return FALSE; /* bad PGM file header */ + + if ((alpha_width != width) || (alpha_height != height)) + return FALSE; /* mismatched PGM dimensions */ + + alpha_raw = (magic_token[1] == '5'); + color_type |= PNG_COLOR_MASK_ALPHA; + if (maxval == 0) return FALSE; - } - else if ((type_token[1] == '2') || (type_token[1] == '5')) - { - alpha_raw = (type_token[1] == '5'); - get_token (alpha_file, width_token, sizeof (width_token)); - sscanf (width_token, "%lu", &ul_alpha_width); - alpha_width = (png_uint_32) ul_alpha_width; - if (alpha_width != width) - return FALSE; - get_token (alpha_file, height_token, sizeof (height_token)); - sscanf (height_token, "%lu", &ul_alpha_height); - alpha_height = (png_uint_32) ul_alpha_height; - if (alpha_height != height) - return FALSE; - get_token (alpha_file, maxval_token, sizeof (maxval_token)); - sscanf (maxval_token, "%lu", &ul_maxval); - maxval = (png_uint_32) ul_maxval; - if (maxval <= 1) - alpha_depth = 1; - else if (maxval <= 3) - alpha_depth = 2; - else if (maxval <= 15) - alpha_depth = 4; - else if (maxval <= 255) - alpha_depth = 8; - else if (maxval <= 65535U) - alpha_depth = 16; - else /* maxval > 65535U */ - return FALSE; - if (alpha_depth != bit_depth) - return FALSE; - } - else - { + else if (maxval == 1) + alpha_depth = 1; + else if (maxval <= 3) + alpha_depth = 2; + else if (maxval <= 15) + alpha_depth = 4; + else if (maxval <= 255) + alpha_depth = 8; + else if (maxval <= 65535U) + alpha_depth = 16; + else /* maxval > 65535U */ + return FALSE; + if (alpha_depth != bit_depth) return FALSE; - } } /* end if alpha */ /* calculate the number of channels and store alpha-presence */ @@ -337,21 +349,17 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, channels = 3; else if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) channels = 4; -#if 0 else - channels = 0; /* cannot happen */ -#endif + return FALSE; /* NOTREACHED */ alpha_present = (channels - 1) % 2; -#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) if (packed_bitmap) { /* row data is as many bytes as can fit width x channels x bit_depth */ row_bytes = (width * channels * bit_depth + 7) / 8; } else -#endif { /* row_bytes is the width x number of channels x (bit-depth / 8) */ row_bytes = width * channels * ((bit_depth <= 8) ? 1 : 2); @@ -363,50 +371,59 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, /* too big */ return FALSE; } - if ((png_pixels = (png_byte *) - malloc ((size_t) row_bytes * (size_t) height)) == NULL) + + /* allocate the rows using the same memory layout as libpng, and transfer + * their ownership to libpng, with the responsibility to clean everything up; + * please note the use of png_calloc instead of png_malloc */ + row_pointers = (png_byte **) + png_calloc (png_ptr, height * sizeof (png_byte *)); + png_set_rows (png_ptr, info_ptr, row_pointers); + png_data_freer (png_ptr, info_ptr, PNG_DESTROY_WILL_FREE_DATA, PNG_FREE_ALL); + for (row = 0; row < height; row++) { - /* out of memory */ - return FALSE; + /* the individual rows should only be allocated after all the previous + * steps completed successfully, because libpng must handle correctly + * any image allocation left incomplete after an out-of-memory error */ + row_pointers[row] = (png_byte *) png_malloc (png_ptr, row_bytes); } - /* read data from PNM file */ - pix_ptr = png_pixels; + /* read the data from PNM file */ - for (row = 0; row < (int) height; row++) + for (row = 0; row < height; row++) { -#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) + pix_ptr = row_pointers[row]; if (packed_bitmap) { - for (i = 0; i < (int) row_bytes; i++) + for (i = 0; i < row_bytes; i++) { /* png supports this format natively so no conversion is needed */ - *pix_ptr++ = get_data (pnm_file, 8); + *pix_ptr++ = get_pnm_data (pnm_file, 8); } } else -#endif { - for (col = 0; col < (int) width; col++) + for (col = 0; col < width; col++) { - for (i = 0; i < (channels - alpha_present); i++) + for (i = 0; i < (png_uint_32) (channels - alpha_present); i++) { if (raw) { - *pix_ptr++ = get_data (pnm_file, bit_depth); + *pix_ptr++ = get_pnm_data (pnm_file, bit_depth); + if (bit_depth == 16) + *pix_ptr++ = get_pnm_data (pnm_file, bit_depth); } else { if (bit_depth <= 8) { - *pix_ptr++ = get_value (pnm_file, bit_depth); + *pix_ptr++ = get_pnm_value (pnm_file, bit_depth); } else { - tmp16 = get_value (pnm_file, bit_depth); - *pix_ptr = (png_byte) ((tmp16 >> 8) & 0xFF); + val16 = get_pnm_value (pnm_file, bit_depth); + *pix_ptr = (png_byte) ((val16 >> 8) & 0xFF); pix_ptr++; - *pix_ptr = (png_byte) (tmp16 & 0xFF); + *pix_ptr = (png_byte) (val16 & 0xFF); pix_ptr++; } } @@ -416,19 +433,21 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, { if (alpha_raw) { - *pix_ptr++ = get_data (alpha_file, alpha_depth); + *pix_ptr++ = get_pnm_data (alpha_file, alpha_depth); + if (alpha_depth == 16) + *pix_ptr++ = get_pnm_data (alpha_file, alpha_depth); } else { if (alpha_depth <= 8) { - *pix_ptr++ = get_value (alpha_file, bit_depth); + *pix_ptr++ = get_pnm_value (alpha_file, bit_depth); } else { - tmp16 = get_value (alpha_file, bit_depth); - *pix_ptr++ = (png_byte) ((tmp16 >> 8) & 0xFF); - *pix_ptr++ = (png_byte) (tmp16 & 0xFF); + val16 = get_pnm_value (alpha_file, bit_depth); + *pix_ptr++ = (png_byte) ((val16 >> 8) & 0xFF); + *pix_ptr++ = (png_byte) (val16 & 0xFF); } } } /* end if alpha */ @@ -436,86 +455,66 @@ BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, } /* end for col */ } /* end for row */ - /* prepare the standard PNG structures */ - png_ptr = png_create_write_struct (png_get_libpng_ver(NULL), - NULL, NULL, NULL); - if (!png_ptr) - { - free (png_pixels); - return FALSE; - } - info_ptr = png_create_info_struct (png_ptr); - if (!info_ptr) - { - png_destroy_write_struct (&png_ptr, NULL); - free (png_pixels); - return FALSE; - } + /* we're going to write more or less the same PNG as the input file */ + png_set_IHDR (png_ptr, info_ptr, width, height, bit_depth, color_type, + (!interlace) ? PNG_INTERLACE_NONE : PNG_INTERLACE_ADAM7, + PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); -#if defined(PNG_WRITE_INVERT_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) if (packed_bitmap == TRUE) { png_set_packing (png_ptr); png_set_invert_mono (png_ptr); } -#endif - - if (setjmp (png_jmpbuf (png_ptr))) - { - png_destroy_write_struct (&png_ptr, &info_ptr); - free (png_pixels); - return FALSE; - } - - /* initialize the png structure */ - png_init_io (png_ptr, png_file); - - /* we're going to write more or less the same PNG as the input file */ - png_set_IHDR (png_ptr, info_ptr, width, height, bit_depth, color_type, - (!interlace) ? PNG_INTERLACE_NONE : PNG_INTERLACE_ADAM7, - PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); /* write the file header information */ png_write_info (png_ptr, info_ptr); - /* if needed we will allocate memory for an new array of row-pointers */ - if (row_pointers == NULL) - { - if ((row_pointers = (png_byte **) - malloc (height * sizeof (png_byte *))) == NULL) - { - png_destroy_write_struct (&png_ptr, &info_ptr); - free (png_pixels); - return FALSE; - } - } - - /* set the individual row_pointers to point at the correct offsets */ - for (i = 0; i < (int) height; i++) - row_pointers[i] = png_pixels + i * row_bytes; - /* write out the entire image data in one call */ png_write_image (png_ptr, row_pointers); /* write the additional chunks to the PNG file (not really needed) */ png_write_end (png_ptr, info_ptr); - /* clean up after the write, and free any memory allocated */ - png_destroy_write_struct (&png_ptr, &info_ptr); - - if (row_pointers != NULL) - free (row_pointers); - if (png_pixels != NULL) - free (png_pixels); - return TRUE; } /* end of pnm2png */ /* - * get_token - gets the first string after whitespace + * fscan_pnm_magic - like fscan_pnm_token below, but expects the magic string + * to start immediately, without any comment or whitespace, + * and to match the regex /^P[1-9]$/ */ -void get_token (FILE *pnm_file, char *token_buf, size_t token_buf_size) +int fscan_pnm_magic (FILE *pnm_file, char *magic_buf, size_t magic_buf_size) +{ + int ret; + + ret = fgetc (pnm_file); + if (ret == EOF) return 0; + ungetc (ret, pnm_file); + if (ret != 'P') return 0; + + /* the string buffer must be at least four bytes long, i.e., the capacity + * required for strings of at least three characters long, i.e., the minimum + * required for ensuring that our magic string is exactly two characters long + */ + if (magic_buf_size < 4) return -1; + + ret = fscan_pnm_token (pnm_file, magic_buf, magic_buf_size); + if (ret < 1) return ret; + + if ((magic_buf[1] < '1') || (magic_buf[1] > '9')) return 0; + if (magic_buf[2] != '\0') return 0; + + return 1; +} + +/* + * fscan_pnm_token - extracts the first string token after whitespace, + * and (like fscanf) returns the number of successful + * extractions, which can be either 0 or 1 + */ + +int fscan_pnm_token (FILE *pnm_file, char *token_buf, size_t token_buf_size) { size_t i = 0; int ret; @@ -543,29 +542,66 @@ void get_token (FILE *pnm_file, char *token_buf, size_t token_buf_size) { ret = fgetc (pnm_file); if (ret == EOF) break; + if (ret == '0') + { + /* avoid storing more than one leading '0' in the token buffer, + * to ensure that all valid (in-range) numeric inputs can fit in. */ + if ((i == 0) && (token_buf[i] == '0')) continue; + } if (++i == token_buf_size - 1) break; token_buf[i] = (char) ret; } while ((ret != '\n') && (ret != '\r') && (ret != ' ')); token_buf[i] = '\0'; + return (i > 0) ? 1 : 0; +} - return; +/* + * fscan_pnm_uint_32 - like fscan_token above, but expects the extracted token + * to be numeric, and converts it to an unsigned 32-bit int + */ + +int fscan_pnm_uint_32 (FILE *pnm_file, png_uint_32 *num_ptr) +{ + char token[16]; + unsigned long token_value; + int ret; + + ret = fscan_pnm_token (pnm_file, token, sizeof (token)); + if (ret < 1) return ret; + + if ((token[0] < '0') && (token[0] > '9')) + return 0; /* the token starts with junk, or a +/- sign, which is invalid */ + + ret = sscanf (token, "%lu%*c", &token_value); + if (ret != 1) + return 0; /* the token ends with junk */ + + *num_ptr = (png_uint_32) token_value; + +#if ULONG_MAX > 0xFFFFFFFFUL + /* saturate the converted number, following the fscanf convention */ + if (token_value > 0xFFFFFFFFUL) + *num_ptr = 0xFFFFFFFFUL; +#endif + + return 1; } /* - * get_data - takes first byte and converts into next pixel value, - * taking as much bits as defined by bit-depth and - * using the bit-depth to fill up a byte (0Ah -> AAh) + * get_pnm_data - takes first byte and converts into next pixel value, + * taking as many bits as defined by bit-depth and + * using the bit-depth to fill up a byte (0x0A -> 0xAA) */ -png_uint_32 get_data (FILE *pnm_file, int depth) +png_uint_32 get_pnm_data (FILE *pnm_file, int depth) { static int bits_left = 0; static int old_value = 0; static int mask = 0; - int i; png_uint_32 ret_value; + int i; if (mask == 0) for (i = 0; i < depth; i++) @@ -573,7 +609,11 @@ png_uint_32 get_data (FILE *pnm_file, int depth) if (bits_left <= 0) { + /* FIXME: + * signal the premature end of file, instead of pretending to read zeroes + */ old_value = fgetc (pnm_file); + if (old_value == EOF) return 0; bits_left = 8; } @@ -588,25 +628,28 @@ png_uint_32 get_data (FILE *pnm_file, int depth) } /* - * get_value - takes first (numeric) string and converts into number, - * using the bit-depth to fill up a byte (0Ah -> AAh) + * get_pnm_value - takes first (numeric) string and converts into number, + * using the bit-depth to fill up a byte (0x0A -> 0xAA) */ -png_uint_32 get_value (FILE *pnm_file, int depth) +png_uint_32 get_pnm_value (FILE *pnm_file, int depth) { static png_uint_32 mask = 0; - char token[16]; - unsigned long ul_ret_value; png_uint_32 ret_value; - int i = 0; + int i; if (mask == 0) for (i = 0; i < depth; i++) mask = (mask << 1) | 0x01; - get_token (pnm_file, token, sizeof (token)); - sscanf (token, "%lu", &ul_ret_value); - ret_value = (png_uint_32) ul_ret_value; + if (fscan_pnm_uint_32 (pnm_file, &ret_value) != 1) + { + /* FIXME: + * signal the invalid numeric tokens or the premature end of file, + * instead of pretending to read zeroes + */ + return 0; + } ret_value &= mask; diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminus/png2pnm.bat b/Build/source/libs/libpng/libpng-src/contrib/pngminus/test_png2pnm.bat index a2798c34032..a2798c34032 100644 --- a/Build/source/libs/libpng/libpng-src/contrib/pngminus/png2pnm.bat +++ b/Build/source/libs/libpng/libpng-src/contrib/pngminus/test_png2pnm.bat diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminus/png2pnm.sh b/Build/source/libs/libpng/libpng-src/contrib/pngminus/test_png2pnm.sh index 756126a53c2..756126a53c2 100755..100644 --- a/Build/source/libs/libpng/libpng-src/contrib/pngminus/png2pnm.sh +++ b/Build/source/libs/libpng/libpng-src/contrib/pngminus/test_png2pnm.sh diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminus/pngminus.bat b/Build/source/libs/libpng/libpng-src/contrib/pngminus/test_pngminus.bat index fa60e7de07f..fa60e7de07f 100644 --- a/Build/source/libs/libpng/libpng-src/contrib/pngminus/pngminus.bat +++ b/Build/source/libs/libpng/libpng-src/contrib/pngminus/test_pngminus.bat diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminus/pngminus.sh b/Build/source/libs/libpng/libpng-src/contrib/pngminus/test_pngminus.sh index cc9b4a56e37..cc9b4a56e37 100755..100644 --- a/Build/source/libs/libpng/libpng-src/contrib/pngminus/pngminus.sh +++ b/Build/source/libs/libpng/libpng-src/contrib/pngminus/test_pngminus.sh diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminus/pnm2png.bat b/Build/source/libs/libpng/libpng-src/contrib/pngminus/test_pnm2png.bat index c02b80beccd..c02b80beccd 100644 --- a/Build/source/libs/libpng/libpng-src/contrib/pngminus/pnm2png.bat +++ b/Build/source/libs/libpng/libpng-src/contrib/pngminus/test_pnm2png.bat diff --git a/Build/source/libs/libpng/libpng-src/contrib/pngminus/pnm2png.sh b/Build/source/libs/libpng/libpng-src/contrib/pngminus/test_pnm2png.sh index 2ad17a608c9..2ad17a608c9 100755..100644 --- a/Build/source/libs/libpng/libpng-src/contrib/pngminus/pnm2png.sh +++ b/Build/source/libs/libpng/libpng-src/contrib/pngminus/test_pnm2png.sh diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/regression-palette-8.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/regression-palette-8.png Binary files differnew file mode 100644 index 00000000000..dcb88b6ec41 --- /dev/null +++ b/Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/regression-palette-8.png diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/small-palette-1.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/small-palette-1.png Binary files differnew file mode 100644 index 00000000000..7e9dbfd095b --- /dev/null +++ b/Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/small-palette-1.png diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/small-palette-2.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/small-palette-2.png Binary files differnew file mode 100644 index 00000000000..6629164d709 --- /dev/null +++ b/Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/small-palette-2.png diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/small-palette-4.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/small-palette-4.png Binary files differnew file mode 100644 index 00000000000..7401dc70b1f --- /dev/null +++ b/Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/small-palette-4.png diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/small-palette-8.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/small-palette-8.png Binary files differnew file mode 100644 index 00000000000..a4533871314 --- /dev/null +++ b/Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/small-palette-8.png diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/test-palette-1.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/test-palette-1.png Binary files differnew file mode 100644 index 00000000000..614fd97bba7 --- /dev/null +++ b/Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/test-palette-1.png diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/test-palette-2.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/test-palette-2.png Binary files differnew file mode 100644 index 00000000000..a7e996464bf --- /dev/null +++ b/Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/test-palette-2.png diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/test-palette-4.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/test-palette-4.png Binary files differnew file mode 100644 index 00000000000..39853bfce9a --- /dev/null +++ b/Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/test-palette-4.png diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/test-palette-8.png b/Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/test-palette-8.png Binary files differnew file mode 100644 index 00000000000..46d0993544e --- /dev/null +++ b/Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/test-palette-8.png diff --git a/Build/source/libs/libpng/libpng-src/contrib/testpngs/makepngs.sh b/Build/source/libs/libpng/libpng-src/contrib/testpngs/makepngs.sh index 270f0630aaf..f0238c3b53d 100755 --- a/Build/source/libs/libpng/libpng-src/contrib/testpngs/makepngs.sh +++ b/Build/source/libs/libpng/libpng-src/contrib/testpngs/makepngs.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/usr/bin/env bash # Make a set of test PNG files, MAKEPNG is the name of the makepng executable # built from contrib/libtests/makepng.c diff --git a/Build/source/libs/libpng/libpng-src/contrib/tools/intgamma.sh b/Build/source/libs/libpng/libpng-src/contrib/tools/intgamma.sh index 3198cb2415d..aaed68a09ee 100755 --- a/Build/source/libs/libpng/libpng-src/contrib/tools/intgamma.sh +++ b/Build/source/libs/libpng/libpng-src/contrib/tools/intgamma.sh @@ -19,7 +19,7 @@ # Function to print out a list of numbers as integers; the function truncates # the integers which must be one-per-line. -function print(){ +print(){ awk 'BEGIN{ str = "" } diff --git a/Build/source/libs/libpng/libpng-src/contrib/tools/pngcp.c b/Build/source/libs/libpng/libpng-src/contrib/tools/pngcp.c index 579e28d2b8a..cf621fa5bf5 100644 --- a/Build/source/libs/libpng/libpng-src/contrib/tools/pngcp.c +++ b/Build/source/libs/libpng/libpng-src/contrib/tools/pngcp.c @@ -1,6 +1,6 @@ /* pngcp.c * - * Copyright (c) 2016,2022 John Cunningham Bowler + * Copyright (c) 2016,2022,2024 John Cunningham Bowler * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -88,16 +88,6 @@ # define voidcast(type, value) (value) #endif /* __cplusplus */ -#ifdef __GNUC__ - /* Many versions of GCC erroneously report that local variables unmodified - * within the scope of a setjmp may be clobbered. This hacks round the - * problem (sometimes) without harming other compilers. - */ -# define gv volatile -#else -# define gv -#endif - /* 'CLOCK_PROCESS_CPUTIME_ID' is one of the clock timers for clock_gettime. It * need not be supported even when clock_gettime is available. It returns the * 'CPU' time the process has consumed. 'CPU' time is assumed to include time @@ -395,6 +385,7 @@ struct display { jmp_buf error_return; /* Where to go to on error */ unsigned int errset; /* error_return is set */ + int errlevel; /* error level from longjmp */ const char *operation; /* What is happening */ const char *filename; /* The name of the original file */ @@ -634,7 +625,10 @@ display_log(struct display *dp, error_level level, const char *fmt, ...) if (level > APP_FAIL || (level > ERRORS && !(dp->options & CONTINUE))) { if (dp->errset) + { + dp->errlevel = level; longjmp(dp->error_return, level); + } else exit(99); @@ -2318,14 +2312,9 @@ cp_one_file(struct display *dp, const char *filename, const char *destname) } static int -cppng(struct display *dp, const char *file, const char *gv dest) - /* Exists solely to isolate the setjmp clobbers which some versions of GCC - * erroneously generate. - */ +cppng(struct display *dp, const char *file, const char *dest) { - int ret = setjmp(dp->error_return); - - if (ret == 0) + if (setjmp(dp->error_return) == 0) { dp->errset = 1; cp_one_file(dp, file, dest); @@ -2337,10 +2326,11 @@ cppng(struct display *dp, const char *file, const char *gv dest) { dp->errset = 0; - if (ret < ERRORS) /* shouldn't longjmp on warnings */ - display_log(dp, INTERNAL_ERROR, "unexpected return code %d", ret); + if (dp->errlevel < ERRORS) /* shouldn't longjmp on warnings */ + display_log(dp, INTERNAL_ERROR, "unexpected return code %d", + dp->errlevel); - return ret; + return dp->errlevel; } } diff --git a/Build/source/libs/libpng/libpng-src/contrib/tools/pngfix.c b/Build/source/libs/libpng/libpng-src/contrib/tools/pngfix.c index cdf3f1cb4a1..025e68790e2 100644 --- a/Build/source/libs/libpng/libpng-src/contrib/tools/pngfix.c +++ b/Build/source/libs/libpng/libpng-src/contrib/tools/pngfix.c @@ -1,6 +1,6 @@ /* pngfix.c * - * Copyright (c) 2014-2017 John Cunningham Bowler + * Copyright (c) 2014-2017,2024 John Cunningham Bowler * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -20,19 +20,6 @@ #define implies(x,y) assert(!(x) || (y)) -#ifdef __GNUC__ - /* This is used to fix the error: - * - * pngfix.c: - * In function 'zlib_advance': - * pngfix.c:181:13: error: assuming signed overflow does not - * occur when simplifying conditional to constant [-Werror=strict-overflow] - */ -# define FIX_GCC volatile -#else -# define FIX_GCC -#endif - #define PROGRAM_NAME "pngfix" /* Define the following to use this program against your installed libpng, @@ -218,7 +205,7 @@ uarb_inc(uarb num, int in_digits, png_int_32 add) * in_digits+1 if add is known to be in the range -65535..65535. */ { - FIX_GCC int out_digits = 0; + int out_digits = 0; while (out_digits < in_digits) { @@ -263,7 +250,7 @@ uarb_add32(uarb num, int in_digits, png_uint_32 add) } static int -uarb_mult_digit(uarb acc, int a_digits, uarb num, FIX_GCC int n_digits, +uarb_mult_digit(uarb acc, int a_digits, uarb num, int n_digits, png_uint_16 val) /* Primitive one-digit multiply - 'val' must be 0..65535. Note that this * primitive is a multiply and accumulate - the result of *num * val is added @@ -336,7 +323,7 @@ uarb_shift(uarb inout, int ndigits, unsigned int right_shift) * 1..15 */ { - FIX_GCC int i = ndigits; + int i = ndigits; png_uint_16 carry = 0; assert(right_shift >= 1 && right_shift <= 15); @@ -351,7 +338,7 @@ uarb_shift(uarb inout, int ndigits, unsigned int right_shift) inout[i] = temp; /* The shift may reduce ndigits */ - if (i == ndigits-1 && temp == 0) + if (i+1 == ndigits && temp == 0) ndigits = i; } @@ -1005,10 +992,18 @@ file_end(struct file *file) if (file->out != NULL) { - /* NOTE: this is bitwise |, all the following functions must execute and - * must succeed. + /* On some systems 'fclose' deletes the FILE struct (making it + * inaccessbile). There is no guarantee that fclose returns an error + * code from fflush or, indeed, from the FILE error indicator. There is + * also no explicit (or clear) guarantee in the standard that anything + * other than a read or write operation sets the error indicator; fflush + * is not a read or write operation, so both conditions must be checked + * to ensure the close succeeded and in ANSI-C conformant code they must + * be checked before the fclose call. */ - if (ferror(file->out) | fflush(file->out) | fclose(file->out)) + const int err = fflush(file->out) || ferror(file->out); + + if (fclose(file->out) || err) { perror(file->out_name); emit_error(file, READ_ERROR_CODE, "output write error"); @@ -4054,3 +4049,4 @@ main(void) return 77; } #endif /* PNG_SETJMP_SUPPORTED */ +/* vi: set textwidth=80 shiftwidth=3 softtabstop=-1 expandtab: */ |