summaryrefslogtreecommitdiff
path: root/Build/source/libs/libpng/libpng-src/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/libpng/libpng-src/contrib')
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/mips-mmi/linux.c142
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/mips-msa/linux.c58
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngminus/.gitignore11
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngminus/CHANGES.txt3
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngminus/CMakeLists.txt53
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngminus/png2pnm.c222
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngminus/pnm2png.c503
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngminus/test_png2pnm.bat (renamed from Build/source/libs/libpng/libpng-src/contrib/pngminus/png2pnm.bat)0
-rw-r--r--[-rwxr-xr-x]Build/source/libs/libpng/libpng-src/contrib/pngminus/test_png2pnm.sh (renamed from Build/source/libs/libpng/libpng-src/contrib/pngminus/png2pnm.sh)0
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngminus/test_pngminus.bat (renamed from Build/source/libs/libpng/libpng-src/contrib/pngminus/pngminus.bat)0
-rw-r--r--[-rwxr-xr-x]Build/source/libs/libpng/libpng-src/contrib/pngminus/test_pngminus.sh (renamed from Build/source/libs/libpng/libpng-src/contrib/pngminus/pngminus.sh)0
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/pngminus/test_pnm2png.bat (renamed from Build/source/libs/libpng/libpng-src/contrib/pngminus/pnm2png.bat)0
-rw-r--r--[-rwxr-xr-x]Build/source/libs/libpng/libpng-src/contrib/pngminus/test_pnm2png.sh (renamed from Build/source/libs/libpng/libpng-src/contrib/pngminus/pnm2png.sh)0
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/regression-palette-8.pngbin0 -> 1033 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/small-palette-1.pngbin0 -> 271 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/small-palette-2.pngbin0 -> 277 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/small-palette-4.pngbin0 -> 315 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/small-palette-8.pngbin0 -> 1035 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/test-palette-1.pngbin0 -> 432 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/test-palette-2.pngbin0 -> 499 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/test-palette-4.pngbin0 -> 591 bytes
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/test-palette-8.pngbin0 -> 2728 bytes
-rwxr-xr-xBuild/source/libs/libpng/libpng-src/contrib/testpngs/makepngs.sh2
-rwxr-xr-xBuild/source/libs/libpng/libpng-src/contrib/tools/intgamma.sh2
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/tools/pngcp.c32
-rw-r--r--Build/source/libs/libpng/libpng-src/contrib/tools/pngfix.c38
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
new file mode 100644
index 00000000000..dcb88b6ec41
--- /dev/null
+++ b/Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/regression-palette-8.png
Binary files differ
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
new file mode 100644
index 00000000000..7e9dbfd095b
--- /dev/null
+++ b/Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/small-palette-1.png
Binary files differ
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
new file mode 100644
index 00000000000..6629164d709
--- /dev/null
+++ b/Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/small-palette-2.png
Binary files differ
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
new file mode 100644
index 00000000000..7401dc70b1f
--- /dev/null
+++ b/Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/small-palette-4.png
Binary files differ
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
new file mode 100644
index 00000000000..a4533871314
--- /dev/null
+++ b/Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/small-palette-8.png
Binary files differ
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
new file mode 100644
index 00000000000..614fd97bba7
--- /dev/null
+++ b/Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/test-palette-1.png
Binary files differ
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
new file mode 100644
index 00000000000..a7e996464bf
--- /dev/null
+++ b/Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/test-palette-2.png
Binary files differ
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
new file mode 100644
index 00000000000..39853bfce9a
--- /dev/null
+++ b/Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/test-palette-4.png
Binary files differ
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
new file mode 100644
index 00000000000..46d0993544e
--- /dev/null
+++ b/Build/source/libs/libpng/libpng-src/contrib/testpngs/badpal/test-palette-8.png
Binary files differ
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: */