diff --git a/media/libpng/ANNOUNCE b/media/libpng/ANNOUNCE --- a/media/libpng/ANNOUNCE +++ b/media/libpng/ANNOUNCE @@ -1,45 +1,37 @@ -libpng 1.6.47 - February 18, 2025 -================================= +libpng 1.6.53 - December 5, 2025 +================================ This is a public release of libpng, intended for use in production code. Files available for download ---------------------------- -Source files with LF line endings (for Unix/Linux): - - * libpng-1.6.47.tar.xz (LZMA-compressed, recommended) - * libpng-1.6.47.tar.gz (deflate-compressed) +Source files: -Source files with CRLF line endings (for Windows): - - * lpng1647.7z (LZMA-compressed, recommended) - * lpng1647.zip (deflate-compressed) + * libpng-1.6.53.tar.xz (LZMA-compressed, recommended) + * libpng-1.6.53.tar.gz (deflate-compressed) + * lpng1653.7z (LZMA-compressed) + * lpng1653.zip (deflate-compressed) Other information: * README.md * LICENSE.md * AUTHORS.md * TRADEMARK.md -Changes from version 1.6.46 to version 1.6.47 +Changes from version 1.6.52 to version 1.6.53 --------------------------------------------- - * Modified the behaviour of colorspace chunks in order to adhere - to the new precedence rules formulated in the latest draft of - the PNG Specification. - (Contributed by John Bowler) - * Fixed a latent bug in `png_write_iCCP`. - This would have been a read-beyond-end-of-malloc vulnerability, - introduced early in the libpng-1.6.0 development, yet (fortunately!) - it was inaccessible before the above-mentioned modification of the - colorspace precedence rules, due to pre-existing colorspace checks. - (Reported by Bob Friesenhahn; fixed by John Bowler) + * Fixed a build failure on RISC-V RVV caused by a misspelled intrinsic. + (Contributed by Alexander Smorkalov.) + * Fixed a build failure with CMake 4.1 or newer, on Windows, when using + Visual C++ without MASM installed. + (Reported by Andrew Tribick; fixed by Luis Caro Campos.) Send comments/corrections/commendations to png-mng-implement at lists.sf.net. Subscription is required; visit https://lists.sourceforge.net/lists/listinfo/png-mng-implement diff --git a/media/libpng/AUTHORS b/media/libpng/AUTHORS --- a/media/libpng/AUTHORS +++ b/media/libpng/AUTHORS @@ -3,10 +3,11 @@ This is the list of PNG Reference Library ("libpng") Contributing Authors, for copyright and licensing purposes. * Adam Richter + * Alexander Smorkalov * Andreas Dilger * Chris Blume * Cosmin Truta * Dave Martindale * Eric S. Raymond @@ -18,10 +19,11 @@ * John Bowler * Kevin Bracey * Lucas Chollet * Magnus Holmgren * Mandar Sahastrabuddhe + * Manfred Schlaegl * Mans Rullgard * Matt Sarett * Mike Klein * Pascal Massimino * Paul Schmidt @@ -29,30 +31,36 @@ * Qiang Zhou * Sam Bushell * Samuel Williams * Simon-Pierre Cadieux * Tim Wegner + * Tobias Stoeckmann * Tom Lane * Tom Tanner * Vadim Barkov * Willem van Schaik * Zhijie Liang * Apple Inc. - Zixu Wang (王子旭) * Arm Holdings - Richard Townsend - * Google Inc. + * Google LLC - Dan Field + - Dragoș Tiselice - Leon Scroggins III - Matt Sarett - Mike Klein - Sami Boukortt - Wan-Teh Chang * Loongson Technology Corporation Ltd. - GuXiWei (顾希伟) - JinBo (金波) - ZhangLixia (张利霞) + * Samsung Group + - Filip Wasil + * SpacemiT Hangzhou Technology, Co. + - Liang Junzhao (梁俊钊) The build projects, the build scripts, the test scripts, and other files in the "projects", "scripts" and "tests" directories, have other copyright owners, but are released under the libpng license. diff --git a/media/libpng/CHANGES b/media/libpng/CHANGES --- a/media/libpng/CHANGES +++ b/media/libpng/CHANGES @@ -6249,9 +6249,79 @@ introduced early in the libpng-1.6.0 development, yet (fortunately!) it was inaccessible before the above-mentioned modification of the colorspace precedence rules, due to pre-existing colorspace checks. (Reported by Bob Friesenhahn; fixed by John Bowler) +Version 1.6.48 [April 30, 2025] + Fixed the floating-point version of the mDCv setter `png_set_mDCv`. + (Reported by Mohit Bakshi; fixed by John Bowler) + Added #error directives to discourage the inclusion of private + libpng implementation header files in PNG-supporting applications. + Added the CMake build option `PNG_LIBCONF_HEADER`, to be used as an + alternative to `DFA_XTRA`. + Removed the Travis CI configuration files, with heartfelt thanks for + their generous support of our project over the past five years! + +Version 1.6.49 [June 12, 2025] + Added SIMD-optimized code for the RISC-V Vector Extension (RVV). + (Contributed by Manfred Schlaegl, Dragos Tiselice and Filip Wasil) + Added various fixes and improvements to the build scripts and to + the sample code. + +Version 1.6.50 [July 1, 2025] + Improved the detection of the RVV Extension on the RISC-V platform. + (Contributed by Filip Wasil) + Replaced inline ASM with C intrinsics in the RVV code. + (Contributed by Filip Wasil) + Fixed a decoder defect in which unknown chunks trailing IDAT, set + to go through the unknown chunk handler, incorrectly triggered + out-of-place IEND errors. + (Contributed by John Bowler) + Fixed the CMake file for cross-platform builds that require `libm`. + +Version 1.6.51 [November 21, 2025] + Fixed CVE-2025-64505 (moderate severity): + Heap buffer overflow in `png_do_quantize` via malformed palette index. + (Reported by Samsung; analyzed by Fabio Gritti.) + Fixed CVE-2025-64506 (moderate severity): + Heap buffer over-read in `png_write_image_8bit` with 8-bit input and + `convert_to_8bit` enabled. + (Reported by Samsung and ; + analyzed by Fabio Gritti.) + Fixed CVE-2025-64720 (high severity): + Buffer overflow in `png_image_read_composite` via incorrect palette + premultiplication. + (Reported by Samsung; analyzed by John Bowler.) + Fixed CVE-2025-65018 (high severity): + Heap buffer overflow in `png_combine_row` triggered via + `png_image_finish_read`. + (Reported by .) + Fixed a memory leak in `png_set_quantize`. + (Reported by Samsung; analyzed by Fabio Gritti.) + Removed the experimental and incomplete ERROR_NUMBERS code. + (Contributed by Tobias Stoeckmann.) + Improved the RISC-V vector extension support; required RVV 1.0 or newer. + (Contributed by Filip Wasil.) + Added GitHub Actions workflows for automated testing. + Performed various refactorings and cleanups. + +Version 1.6.52 [December 3, 2025] + Fixed CVE-2025-66293 (high severity): + Out-of-bounds read in `png_image_read_composite`. + (Reported by flyfish101 .) + Fixed the Paeth filter handling in the RISC-V RVV implementation. + (Reported by Filip Wasil; fixed by Liang Junzhao.) + Improved the performance of the RISC-V RVV implementation. + (Contributed by Liang Junzhao.) + Added allocation failure fuzzing to oss-fuzz. + (Contributed by Philippe Antoine.) + +Version 1.6.53 [December 5, 2025] + Fixed a build failure on RISC-V RVV caused by a misspelled intrinsic. + (Contributed by Alexander Smorkalov.) + Fixed a build failure with CMake 4.1 or newer, on Windows, when using + Visual C++ without MASM installed. + Send comments/corrections/commendations to png-mng-implement at lists.sf.net. Subscription is required; visit https://lists.sourceforge.net/lists/listinfo/png-mng-implement to subscribe. diff --git a/media/libpng/README b/media/libpng/README --- a/media/libpng/README +++ b/media/libpng/README @@ -1,6 +1,6 @@ -README for libpng version 1.6.47 +README for libpng version 1.6.53 ================================ See the note about version numbers near the top of `png.h`. See `INSTALL` for instructions on how to install libpng. @@ -145,10 +145,11 @@ arm/ => Optimized code for ARM Neon intel/ => Optimized code for INTEL SSE2 loongarch/ => Optimized code for LoongArch LSX mips/ => Optimized code for MIPS MSA and MIPS MMI powerpc/ => Optimized code for PowerPC VSX + riscv/ => Optimized code for the RISC-V platform ci/ => Scripts for continuous integration contrib/ => External contributions arm-neon/ => Optimized code for the ARM-NEON platform mips-msa/ => Optimized code for the MIPS-MSA platform powerpc-vsx/ => Optimized code for the POWERPC-VSX platform @@ -160,10 +161,11 @@ pngexif/ => Program to inspect the EXIF information in PNG files pngminim/ => Minimal decoder, encoder, and progressive decoder programs demonstrating the use of pngusr.dfa pngminus/ => Simple pnm2png and png2pnm programs pngsuite/ => Test images + riscv-rvv/ => Optimized code for the RISC-V Vector platform testpngs/ => Test images tools/ => Various tools visupng/ => VisualPng, a Windows viewer for PNG images projects/ => Project files and workspaces for various IDEs owatcom/ => OpenWatcom project diff --git a/media/libpng/arm/arm_init.c b/media/libpng/arm/arm_init.c --- a/media/libpng/arm/arm_init.c +++ b/media/libpng/arm/arm_init.c @@ -33,29 +33,29 @@ #include /* for sig_atomic_t */ #ifndef PNG_ARM_NEON_FILE # if defined(__aarch64__) || defined(_M_ARM64) /* ARM Neon is expected to be unconditionally available on ARM64. */ -# error "PNG_ARM_NEON_CHECK_SUPPORTED must not be defined on ARM64" +# error PNG_ARM_NEON_CHECK_SUPPORTED must not be defined on ARM64 # elif defined(__ARM_NEON__) || defined(__ARM_NEON) /* ARM Neon is expected to be available on the target CPU architecture. */ -# error "PNG_ARM_NEON_CHECK_SUPPORTED must not be defined on this CPU arch" +# error PNG_ARM_NEON_CHECK_SUPPORTED must not be defined on this CPU arch # elif defined(__linux__) -# define PNG_ARM_NEON_FILE "linux.c" +# define PNG_ARM_NEON_FILE "contrib/arm-neon/linux.c" # else -# error "No support for run-time ARM Neon checking; use compile-time options" +# error No support for run-time ARM Neon checking; use compile-time options # endif #endif static int png_have_neon(png_structp png_ptr); #ifdef PNG_ARM_NEON_FILE # include PNG_ARM_NEON_FILE #endif #endif /* PNG_ARM_NEON_CHECK_SUPPORTED */ #ifndef PNG_ALIGNED_MEMORY_SUPPORTED -# error "ALIGNED_MEMORY is required; set: -DPNG_ALIGNED_MEMORY_SUPPORTED" +# error ALIGNED_MEMORY is required; please define PNG_ALIGNED_MEMORY_SUPPORTED #endif void png_init_filter_functions_neon(png_structp pp, unsigned int bpp) { diff --git a/media/libpng/arm/filter_neon.S b/media/libpng/arm/filter_neon.S --- a/media/libpng/arm/filter_neon.S +++ b/media/libpng/arm/filter_neon.S @@ -24,16 +24,10 @@ * Everything should continue to function normally, as long as there are no * deliberate attempts to use the old hand-made assembler code. A build error * will be raised otherwise. */ -/* These are required because Mozilla's moz.build system doesn't pass - * -DDefined macros to the assembler. - */ -#define PNG_READ_SUPPORTED -#define MOZ_PNG_HAVE_ARM_NEON - /* This is required to get the symbol renames, which are #defines, and the * definitions (or not) of PNG_ARM_NEON_OPT and PNG_ARM_NEON_IMPLEMENTATION. */ #define PNG_VERSION_INFO_ONLY #include "../pngpriv.h" diff --git a/media/libpng/libpng-manual.txt b/media/libpng/libpng-manual.txt --- a/media/libpng/libpng-manual.txt +++ b/media/libpng/libpng-manual.txt @@ -7,11 +7,11 @@ For conditions of distribution and use, see the disclaimer and license in png.h Based on: - libpng version 1.6.36, December 2018, through 1.6.47 - February 2025 + libpng version 1.6.36, December 2018, through 1.6.53 - December 2025 Updated and distributed by Cosmin Truta Copyright (c) 2018-2025 Cosmin Truta libpng versions 0.97, January 1998, through 1.6.35 - July 2018 Updated and distributed by Glenn Randers-Pehrson @@ -63,22 +63,26 @@ Libpng was written as a companion to the PNG specification, as a way of reducing the amount of time and effort it takes to support the PNG file format in application programs. -The PNG specification (second edition), November 2003, is available as +The PNG specification (Third Edition), June 2025, is available as +a W3C Recommendation at +. + +The PNG specification (Second Edition), November 2003, is available as a W3C Recommendation and as an ISO Standard (ISO/IEC 15948:2004 (E)) at . The W3C and ISO documents have identical technical content. The PNG-1.2 specification is available at -. -It is technically equivalent -to the PNG specification (second edition) but has some additional material. +. +It is technically equivalent to the PNG specification (Second Edition) +but has some additional material. The PNG-1.0 specification is available as RFC 2083 at - and as a + and as a W3C Recommendation at . Some additional chunks are described in the special-purpose public chunks documents at @@ -3349,23 +3353,10 @@ png_set_unknown_chunks(write_ptr, write_info_ptr, unk_chunk, 2); /* Needed because miNE is not safe-to-copy */ png_set_keep_unknown_chunks(png, PNG_HANDLE_CHUNK_ALWAYS, (png_bytep) "miNE", 1); - # if PNG_LIBPNG_VER < 10600 - /* Deal with unknown chunk location bug in 1.5.x and earlier */ - png_set_unknown_chunk_location(png, info, 0, PNG_HAVE_IHDR); - png_set_unknown_chunk_location(png, info, 1, PNG_AFTER_IDAT); - # endif - # if PNG_LIBPNG_VER < 10500 - /* PNG_AFTER_IDAT writes two copies of the chunk prior to libpng-1.5.0, - * one before IDAT and another after IDAT, so don't use it; only use - * PNG_HAVE_IHDR location. This call resets the location previously - * set by assignment and png_set_unknown_chunk_location() for chunk 1. - */ - png_set_unknown_chunk_location(png, info, 1, PNG_HAVE_IHDR); - # endif #endif The high-level write interface At this point there are two ways to proceed; through the high-level @@ -4087,11 +4078,11 @@ The named file is opened for read and the image header is filled in from the PNG header in the file. int png_image_begin_read_from_stdio (png_imagep image, - FILE* file) + FILE *file) The PNG header is read from the stdio FILE object. int png_image_begin_read_from_memory(png_imagep image, png_const_voidp memory, size_t size) @@ -4162,11 +4153,11 @@ int png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8_bit, const void *buffer, png_int_32 row_stride, const void *colormap) - Write the image to the given (FILE*). + Write the image to the given FILE object. With all write APIs if image is in one of the linear formats with (png_uint_16) data then setting convert_to_8_bit will cause the output to be a (png_byte) PNG gamma encoded according to the sRGB specification, otherwise a 16-bit linear encoded PNG file is written. diff --git a/media/libpng/mips/mips_init.c b/media/libpng/mips/mips_init.c --- a/media/libpng/mips/mips_init.c +++ b/media/libpng/mips/mips_init.c @@ -46,11 +46,11 @@ #include /* for sig_atomic_t */ static int png_have_msa(png_structp png_ptr); #include PNG_MIPS_MSA_FILE #else /* PNG_MIPS_MSA_FILE */ -# error "PNG_MIPS_MSA_FILE undefined: no support for run-time MIPS MSA checks" +# error PNG_MIPS_MSA_FILE undefined: no support for run-time MIPS MSA checks #endif /* PNG_MIPS_MSA_FILE */ #endif /* PNG_MIPS_MSA_CHECK_SUPPORTED */ #ifdef PNG_MIPS_MMI_CHECK_SUPPORTED /* Do MIPS MMI run-times checks */ #ifndef PNG_MIPS_MMI_FILE @@ -64,16 +64,16 @@ #include /* for sig_atomic_t */ static int png_have_mmi(); #include PNG_MIPS_MMI_FILE #else /* PNG_MIPS_MMI_FILE */ -# error "PNG_MIPS_MMI_FILE undefined: no support for run-time MIPS MMI checks" +# error PNG_MIPS_MMI_FILE undefined: no support for run-time MIPS MMI checks #endif /* PNG_MIPS_MMI_FILE */ #endif /* PNG_MIPS_MMI_CHECK_SUPPORTED*/ #ifndef PNG_ALIGNED_MEMORY_SUPPORTED -# error "ALIGNED_MEMORY is required; set: -DPNG_ALIGNED_MEMORY_SUPPORTED" +# error ALIGNED_MEMORY is required; please define PNG_ALIGNED_MEMORY_SUPPORTED #endif /* MIPS supports two optimizations: MMI and MSA. The appropriate * optimization is chosen at runtime */ diff --git a/media/libpng/moz.yaml b/media/libpng/moz.yaml --- a/media/libpng/moz.yaml +++ b/media/libpng/moz.yaml @@ -9,11 +9,11 @@ description: "PNG reference library" url: "http://www.libpng.org/pub/png/libpng.html" license: libpng - release: v1.6.47 (2025-02-18T11:18:30+02:00). + release: v1.6.53 (2025-12-05T23:46:38+02:00). revision: "v1.6.43" license-file: LICENSE diff --git a/media/libpng/png.h b/media/libpng/png.h --- a/media/libpng/png.h +++ b/media/libpng/png.h @@ -1,8 +1,8 @@ /* png.h - header file for PNG reference library * - * libpng version 1.6.47 + * libpng version 1.6.53 * * Copyright (c) 2018-2025 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -12,11 +12,11 @@ * Authors and maintainers: * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat * libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger * libpng versions 0.97, January 1998, through 1.6.35, July 2018: * Glenn Randers-Pehrson - * libpng versions 1.6.36, December 2018, through 1.6.47, February 2025: + * libpng versions 1.6.36, December 2018, through 1.6.53, December 2025: * Cosmin Truta * See also "Contributing Authors", below. */ /* @@ -236,11 +236,11 @@ * ... * 1.4.20 14 10420 14.so.0.20[.0] * ... * 1.5.30 15 10530 15.so.15.30[.0] * ... - * 1.6.47 16 10647 16.so.16.47[.0] + * 1.6.53 16 10651 16.so.16.53[.0] * * Henceforth the source version will match the shared-library major and * minor numbers; the shared-library major version number will be used for * changes in backward compatibility, as it is intended. * The PNG_LIBPNG_VER macro, which is not used within libpng but is @@ -272,22 +272,22 @@ * If you just need to read a PNG file and don't want to read the documentation * skip to the end of this file and read the section entitled 'simplified API'. */ /* Version information for png.h - this should match the version in png.c */ -#define PNG_LIBPNG_VER_STRING "1.6.47" +#define PNG_LIBPNG_VER_STRING "1.6.53" #define PNG_HEADER_VERSION_STRING " libpng version " PNG_LIBPNG_VER_STRING "\n" /* The versions of shared library builds should stay in sync, going forward */ #define PNG_LIBPNG_VER_SHAREDLIB 16 #define PNG_LIBPNG_VER_SONUM PNG_LIBPNG_VER_SHAREDLIB /* [Deprecated] */ #define PNG_LIBPNG_VER_DLLNUM PNG_LIBPNG_VER_SHAREDLIB /* [Deprecated] */ /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */ #define PNG_LIBPNG_VER_MAJOR 1 #define PNG_LIBPNG_VER_MINOR 6 -#define PNG_LIBPNG_VER_RELEASE 47 +#define PNG_LIBPNG_VER_RELEASE 53 /* This should be zero for a public release, or non-zero for a * development version. */ #define PNG_LIBPNG_VER_BUILD 0 @@ -314,11 +314,11 @@ * Versions 0.7 through 1.0.0 were in the range 0 to 100 here * (only version 1.0.0 was mis-numbered 100 instead of 10000). * From version 1.0.1 it is: * XXYYZZ, where XX=major, YY=minor, ZZ=release */ -#define PNG_LIBPNG_VER 10647 /* 1.6.47 */ +#define PNG_LIBPNG_VER 10653 /* 1.6.53 */ /* Library configuration: these options cannot be changed after * the library has been built. */ #ifndef PNGLCONF_H @@ -326,14 +326,10 @@ * copy scripts/pnglibconf.h.prebuilt to pnglibconf.h */ # include "pnglibconf.h" #endif -#define PNG_APNG_SUPPORTED -#define PNG_READ_APNG_SUPPORTED -#define PNG_WRITE_APNG_SUPPORTED - #ifndef PNG_VERSION_INFO_ONLY /* Machine specific configuration. */ # include "pngconf.h" #endif @@ -425,25 +421,14 @@ /* Section 3: type definitions, including structures and compile time * constants. * See pngconf.h for base types that vary by machine/system */ -#ifdef PNG_APNG_SUPPORTED -/* dispose_op flags from inside fcTL */ -#define PNG_DISPOSE_OP_NONE 0x00 -#define PNG_DISPOSE_OP_BACKGROUND 0x01 -#define PNG_DISPOSE_OP_PREVIOUS 0x02 - -/* blend_op flags from inside fcTL */ -#define PNG_BLEND_OP_SOURCE 0x00 -#define PNG_BLEND_OP_OVER 0x01 -#endif /* APNG */ - /* This triggers a compiler error in png.c, if png.c and png.h * do not agree upon the version number. */ -typedef char* png_libpng_version_1_6_47; +typedef char* png_libpng_version_1_6_53; /* Basic control structions. Read libpng-manual.txt or libpng.3 for more info. * * png_struct is the cache of information used while reading or writing a single * PNG file. One of these is always required, although the simplified API @@ -809,14 +794,10 @@ int)); #ifdef PNG_PROGRESSIVE_READ_SUPPORTED typedef PNG_CALLBACK(void, *png_progressive_info_ptr, (png_structp, png_infop)); typedef PNG_CALLBACK(void, *png_progressive_end_ptr, (png_structp, png_infop)); -#ifdef PNG_APNG_SUPPORTED -typedef PNG_CALLBACK(void, *png_progressive_frame_ptr, (png_structp, - png_uint_32)); -#endif /* The following callback receives png_uint_32 row_number, int pass for the * png_bytep data of the row. When transforming an interlaced image the * row number is the row number within the sub-image of the interlace pass, so * the value will increase to the height of the sub-image (not the full image) @@ -1587,11 +1568,11 @@ * more information. */ #ifdef PNG_STDIO_SUPPORTED /* Initialize the input/output for the PNG file to the default functions. */ -PNG_EXPORT(74, void, png_init_io, (png_structrp png_ptr, png_FILE_p fp)); +PNG_EXPORT(74, void, png_init_io, (png_structrp png_ptr, FILE *fp)); #endif /* Replace the (error and abort), and warning functions with user * supplied functions. If no messages are to be printed you must still * write and use replacement functions. The replacement error_fn should @@ -3105,11 +3086,11 @@ /* The named file is opened for read and the image header is filled in * from the PNG header in the file. */ PNG_EXPORT(235, int, png_image_begin_read_from_stdio, (png_imagep image, - FILE* file)); + FILE *file)); /* The PNG header is read from the stdio FILE object. */ #endif /* STDIO */ PNG_EXPORT(236, int, png_image_begin_read_from_memory, (png_imagep image, png_const_voidp memory, size_t size)); @@ -3180,11 +3161,11 @@ /* Write the image to the named file. */ PNG_EXPORT(240, int, png_image_write_to_stdio, (png_imagep image, FILE *file, int convert_to_8_bit, const void *buffer, png_int_32 row_stride, const void *colormap)); - /* Write the image to the given (FILE*). */ + /* Write the image to the given FILE object. */ #endif /* SIMPLIFIED_WRITE_STDIO */ /* With all write APIs if image is in one of the linear formats with 16-bit * data then setting convert_to_8_bit will cause the output to be an 8-bit PNG * gamma encoded according to the sRGB specification, otherwise a 16-bit linear @@ -3320,30 +3301,49 @@ * decrease on some architectures or systems, or with some sets of * PNG images. 'Software' options allow such optimizations to be * selected at run time. */ #ifdef PNG_SET_OPTION_SUPPORTED + +/* HARDWARE: ARM Neon SIMD instructions supported */ #ifdef PNG_ARM_NEON_API_SUPPORTED -# define PNG_ARM_NEON 0 /* HARDWARE: ARM Neon SIMD instructions supported */ +# define PNG_ARM_NEON 0 #endif -#define PNG_MAXIMUM_INFLATE_WINDOW 2 /* SOFTWARE: force maximum window */ -#define PNG_SKIP_sRGB_CHECK_PROFILE 4 /* SOFTWARE: Check ICC profile for sRGB */ + +/* SOFTWARE: Force maximum window */ +#define PNG_MAXIMUM_INFLATE_WINDOW 2 + +/* SOFTWARE: Check ICC profile for sRGB */ +#define PNG_SKIP_sRGB_CHECK_PROFILE 4 + +/* HARDWARE: MIPS MSA SIMD instructions supported */ #ifdef PNG_MIPS_MSA_API_SUPPORTED -# define PNG_MIPS_MSA 6 /* HARDWARE: MIPS Msa SIMD instructions supported */ +# define PNG_MIPS_MSA 6 #endif + +/* SOFTWARE: Disable Adler32 check on IDAT */ #ifdef PNG_DISABLE_ADLER32_CHECK_SUPPORTED -# define PNG_IGNORE_ADLER32 8 /* SOFTWARE: disable Adler32 check on IDAT */ +# define PNG_IGNORE_ADLER32 8 #endif + +/* HARDWARE: PowerPC VSX SIMD instructions supported */ #ifdef PNG_POWERPC_VSX_API_SUPPORTED -# define PNG_POWERPC_VSX 10 /* HARDWARE: PowerPC VSX SIMD instructions - * supported */ +# define PNG_POWERPC_VSX 10 #endif + +/* HARDWARE: MIPS MMI SIMD instructions supported */ #ifdef PNG_MIPS_MMI_API_SUPPORTED -# define PNG_MIPS_MMI 12 /* HARDWARE: MIPS MMI SIMD instructions supported */ +# define PNG_MIPS_MMI 12 #endif -#define PNG_OPTION_NEXT 14 /* Next option - numbers must be even */ +/* HARDWARE: RISC-V RVV SIMD instructions supported */ +#ifdef PNG_RISCV_RVV_API_SUPPORTED +# define PNG_RISCV_RVV 14 +#endif + +/* Next option - numbers must be even */ +#define PNG_OPTION_NEXT 16 /* Return values: NOTE: there are four values and 'off' is *not* zero */ #define PNG_OPTION_UNSET 0 /* Unset - defaults to off */ #define PNG_OPTION_INVALID 1 /* Option number out of range */ #define PNG_OPTION_OFF 2 @@ -3355,92 +3355,19 @@ /******************************************************************************* * END OF HARDWARE AND SOFTWARE OPTIONS ******************************************************************************/ -#ifdef PNG_APNG_SUPPORTED -PNG_EXPORT(260, png_uint_32, png_get_acTL, (png_structp png_ptr, - png_infop info_ptr, png_uint_32 *num_frames, png_uint_32 *num_plays)); - -PNG_EXPORT(261, png_uint_32, png_set_acTL, (png_structp png_ptr, - png_infop info_ptr, png_uint_32 num_frames, png_uint_32 num_plays)); - -PNG_EXPORT(262, png_uint_32, png_get_num_frames, (png_structp png_ptr, - png_infop info_ptr)); - -PNG_EXPORT(263, png_uint_32, png_get_num_plays, (png_structp png_ptr, - png_infop info_ptr)); - -PNG_EXPORT(264, png_uint_32, png_get_next_frame_fcTL, - (png_structp png_ptr, png_infop info_ptr, png_uint_32 *width, - png_uint_32 *height, png_uint_32 *x_offset, png_uint_32 *y_offset, - png_uint_16 *delay_num, png_uint_16 *delay_den, png_byte *dispose_op, - png_byte *blend_op)); - -PNG_EXPORT(265, png_uint_32, png_set_next_frame_fcTL, - (png_structp png_ptr, png_infop info_ptr, png_uint_32 width, - png_uint_32 height, png_uint_32 x_offset, png_uint_32 y_offset, - png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op, - png_byte blend_op)); - -PNG_EXPORT(266, png_uint_32, png_get_next_frame_width, - (png_structp png_ptr, png_infop info_ptr)); -PNG_EXPORT(267, png_uint_32, png_get_next_frame_height, - (png_structp png_ptr, png_infop info_ptr)); -PNG_EXPORT(268, png_uint_32, png_get_next_frame_x_offset, - (png_structp png_ptr, png_infop info_ptr)); -PNG_EXPORT(269, png_uint_32, png_get_next_frame_y_offset, - (png_structp png_ptr, png_infop info_ptr)); -PNG_EXPORT(270, png_uint_16, png_get_next_frame_delay_num, - (png_structp png_ptr, png_infop info_ptr)); -PNG_EXPORT(271, png_uint_16, png_get_next_frame_delay_den, - (png_structp png_ptr, png_infop info_ptr)); -PNG_EXPORT(272, png_byte, png_get_next_frame_dispose_op, - (png_structp png_ptr, png_infop info_ptr)); -PNG_EXPORT(273, png_byte, png_get_next_frame_blend_op, - (png_structp png_ptr, png_infop info_ptr)); -PNG_EXPORT(274, png_byte, png_get_first_frame_is_hidden, - (png_structp png_ptr, png_infop info_ptr)); -PNG_EXPORT(275, png_uint_32, png_set_first_frame_is_hidden, - (png_structp png_ptr, png_infop info_ptr, png_byte is_hidden)); - -#ifdef PNG_READ_APNG_SUPPORTED -PNG_EXPORT(276, void, png_read_frame_head, (png_structp png_ptr, - png_infop info_ptr)); -#ifdef PNG_PROGRESSIVE_READ_SUPPORTED -PNG_EXPORT(277, void, png_set_progressive_frame_fn, (png_structp png_ptr, - png_progressive_frame_ptr frame_info_fn, - png_progressive_frame_ptr frame_end_fn)); -#endif /* PROGRESSIVE_READ */ -#endif /* READ_APNG */ - -#ifdef PNG_WRITE_APNG_SUPPORTED -PNG_EXPORT(278, void, png_write_frame_head, (png_structp png_ptr, - png_infop info_ptr, png_bytepp row_pointers, - png_uint_32 width, png_uint_32 height, - png_uint_32 x_offset, png_uint_32 y_offset, - png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op, - png_byte blend_op)); - -PNG_EXPORT(279, void, png_write_frame_tail, (png_structp png_ptr, - png_infop info_ptr)); -#endif /* WRITE_APNG */ -#endif /* APNG */ - /* Maintainer: Put new public prototypes here ^, in libpng.3, in project * defs, and in scripts/symbols.def. */ /* The last ordinal number (this is the *last* one already used; the next * one to use is one more than this.) */ #ifdef PNG_EXPORT_LAST_ORDINAL -#ifdef PNG_APNG_SUPPORTED - PNG_EXPORT_LAST_ORDINAL(279); -#else PNG_EXPORT_LAST_ORDINAL(259); -#endif /* APNG */ #endif #ifdef __cplusplus } #endif diff --git a/media/libpng/png.c b/media/libpng/png.c --- a/media/libpng/png.c +++ b/media/libpng/png.c @@ -11,11 +11,11 @@ */ #include "pngpriv.h" /* Generate a compiler error if there is an old png.h in the search path. */ -typedef png_libpng_version_1_6_47 Your_png_h_is_not_version_1_6_47; +typedef png_libpng_version_1_6_53 Your_png_h_is_not_version_1_6_53; /* Sanity check the chunks definitions - PNG_KNOWN_CHUNKS from pngpriv.h and the * corresponding macro definitions. This causes a compile time failure if * something is wrong but generates no code. * @@ -106,14 +106,20 @@ png_alloc_size_t num_bytes = size; if (png_ptr == NULL) return NULL; - if (items >= (~(png_alloc_size_t)0)/size) + /* This check against overflow is vestigial, dating back from + * the old times when png_zalloc used to be an exported function. + * We're still keeping it here for now, as an extra-cautious + * prevention against programming errors inside zlib, although it + * should rather be a debug-time assertion instead. + */ + if (size != 0 && items >= (~(png_alloc_size_t)0) / size) { - png_warning (png_voidcast(png_structrp, png_ptr), - "Potential overflow in png_zalloc()"); + png_warning(png_voidcast(png_structrp, png_ptr), + "Potential overflow in png_zalloc()"); return NULL; } num_bytes *= items; return png_malloc_warn(png_voidcast(png_structrp, png_ptr), num_bytes); @@ -236,14 +242,10 @@ PNG_UNUSED(pos) png_warning(png_ptr, m); #endif -#ifdef PNG_ERROR_NUMBERS_SUPPORTED - png_ptr->flags = 0; -#endif - return 0; } /* Success return. */ return 1; @@ -698,11 +700,11 @@ * or png_set_write_fn() instead of png_init_io(). If you have defined * PNG_NO_STDIO or otherwise disabled PNG_STDIO_SUPPORTED, you must use a * function of your own because "FILE *" isn't necessarily available. */ void PNGAPI -png_init_io(png_structrp png_ptr, png_FILE_p fp) +png_init_io(png_structrp png_ptr, FILE *fp) { png_debug(1, "in png_init_io"); if (png_ptr == NULL) return; @@ -813,11 +815,11 @@ PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */ #ifdef PNG_STRING_COPYRIGHT return PNG_STRING_COPYRIGHT #else return PNG_STRING_NEWLINE \ - "libpng version 1.6.47" PNG_STRING_NEWLINE \ + "libpng version 1.6.53" PNG_STRING_NEWLINE \ "Copyright (c) 2018-2025 Cosmin Truta" PNG_STRING_NEWLINE \ "Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson" \ PNG_STRING_NEWLINE \ "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \ "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \ @@ -1489,11 +1491,11 @@ return 0; /*success*/ } #endif /* COLORSPACE */ -#ifdef PNG_iCCP_SUPPORTED +#ifdef PNG_READ_iCCP_SUPPORTED /* Error message generation */ static char png_icc_tag_char(png_uint_32 byte) { byte &= 0xff; @@ -1565,13 +1567,11 @@ png_chunk_benign_error(png_ptr, message); return 0; } -#endif /* iCCP */ - -#ifdef PNG_READ_iCCP_SUPPORTED + /* Encoded value of D50 as an ICC XYZNumber. From the ICC 2010 spec the value * is XYZ(0.9642,1.0,0.8249), which scales to: * * (63189.8112, 65536, 54060.6464) */ @@ -3967,11 +3967,11 @@ /* First free any data held in the control structure. */ # ifdef PNG_STDIO_SUPPORTED if (cp->owned_file != 0) { - FILE *fp = png_voidcast(FILE*, cp->png_ptr->io_ptr); + FILE *fp = png_voidcast(FILE *, cp->png_ptr->io_ptr); cp->owned_file = 0; /* Ignore errors here. */ if (fp != NULL) { diff --git a/media/libpng/pngconf.h b/media/libpng/pngconf.h --- a/media/libpng/pngconf.h +++ b/media/libpng/pngconf.h @@ -1,8 +1,8 @@ /* pngconf.h - machine-configurable file for libpng * - * libpng version 1.6.47 + * libpng version 1.6.53 * * Copyright (c) 2018-2025 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -217,29 +217,17 @@ # endif /* compiler/api */ /* NOTE: PNGCBAPI always defaults to PNGCAPI. */ # if defined(PNGAPI) && !defined(PNG_USER_PRIVATEBUILD) -# error "PNG_USER_PRIVATEBUILD must be defined if PNGAPI is changed" +# error PNG_USER_PRIVATEBUILD must be defined if PNGAPI is changed # endif -# if (defined(_MSC_VER) && _MSC_VER < 800) ||\ - (defined(__BORLANDC__) && __BORLANDC__ < 0x500) - /* older Borland and MSC - * compilers used '__export' and required this to be after - * the type. - */ -# ifndef PNG_EXPORT_TYPE -# define PNG_EXPORT_TYPE(type) type PNG_IMPEXP -# endif -# define PNG_DLL_EXPORT __export -# else /* newer compiler */ -# define PNG_DLL_EXPORT __declspec(dllexport) -# ifndef PNG_DLL_IMPORT -# define PNG_DLL_IMPORT __declspec(dllimport) -# endif -# endif /* compiler */ +# define PNG_DLL_EXPORT __declspec(dllexport) +# ifndef PNG_DLL_IMPORT +# define PNG_DLL_IMPORT __declspec(dllimport) +# endif #else /* !Windows */ # if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__) # define PNGAPI _System # else /* !Windows/x86 && !OS/2 */ @@ -477,43 +465,43 @@ * standard. */ #if CHAR_BIT == 8 && UCHAR_MAX == 255 typedef unsigned char png_byte; #else -# error "libpng requires 8-bit bytes" +# error libpng requires 8-bit bytes #endif #if INT_MIN == -32768 && INT_MAX == 32767 typedef int png_int_16; #elif SHRT_MIN == -32768 && SHRT_MAX == 32767 typedef short png_int_16; #else -# error "libpng requires a signed 16-bit type" +# error libpng requires a signed 16-bit integer type #endif #if UINT_MAX == 65535 typedef unsigned int png_uint_16; #elif USHRT_MAX == 65535 typedef unsigned short png_uint_16; #else -# error "libpng requires an unsigned 16-bit type" +# error libpng requires an unsigned 16-bit integer type #endif #if INT_MIN < -2147483646 && INT_MAX > 2147483646 typedef int png_int_32; #elif LONG_MIN < -2147483646 && LONG_MAX > 2147483646 typedef long int png_int_32; #else -# error "libpng requires a signed 32-bit (or more) type" +# error libpng requires a signed 32-bit (or longer) integer type #endif #if UINT_MAX > 4294967294U typedef unsigned int png_uint_32; #elif ULONG_MAX > 4294967294U typedef unsigned long int png_uint_32; #else -# error "libpng requires an unsigned 32-bit (or more) type" +# error libpng requires an unsigned 32-bit (or longer) integer type #endif /* Prior to 1.6.0, it was possible to disable the use of size_t and ptrdiff_t. * From 1.6.0 onwards, an ISO C90 compiler, as well as a standard-compliant * behavior of sizeof and ptrdiff_t are required. @@ -590,14 +578,10 @@ typedef png_fixed_point * png_fixed_point_p; typedef const png_fixed_point * png_const_fixed_point_p; typedef size_t * png_size_tp; typedef const size_t * png_const_size_tp; -#ifdef PNG_STDIO_SUPPORTED -typedef FILE * png_FILE_p; -#endif - #ifdef PNG_FLOATING_POINT_SUPPORTED typedef double * png_doublep; typedef const double * png_const_doublep; #endif @@ -615,8 +599,17 @@ #endif /* Pointers to pointers to pointers; i.e., pointer to array */ typedef char * * * png_charppp; +#ifdef PNG_STDIO_SUPPORTED +/* With PNG_STDIO_SUPPORTED it was possible to use I/O streams that were + * not necessarily stdio FILE streams, to allow building Windows applications + * before Win32 and Windows CE applications before WinCE 3.0, but that kind + * of support has long been discontinued. + */ +typedef FILE * png_FILE_p; /* [Deprecated] */ +#endif + #endif /* PNG_BUILDING_SYMBOL_TABLE */ #endif /* PNGCONF_H */ diff --git a/media/libpng/pngdebug.h b/media/libpng/pngdebug.h --- a/media/libpng/pngdebug.h +++ b/media/libpng/pngdebug.h @@ -1,17 +1,21 @@ -/* pngdebug.h - Debugging macros for libpng, also used in pngtest.c +/* pngdebug.h - internal debugging macros for libpng * - * Copyright (c) 2018 Cosmin Truta + * Copyright (c) 2018-2025 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2013 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer * and license in png.h */ +#ifndef PNGPRIV_H +# error This file must not be included by applications; please include +#endif + /* Define PNG_DEBUG at compile time for debugging information. Higher * numbers for PNG_DEBUG mean more debugging information. This has * only been added since version 0.95 so it is not implemented throughout * libpng yet, but more support will be added as needed. * @@ -32,13 +36,10 @@ */ #ifndef PNGDEBUG_H #define PNGDEBUG_H /* These settings control the formatting of messages in png.c and pngerror.c */ /* Moved to pngdebug.h at 1.5.0 */ -# ifndef PNG_LITERAL_SHARP -# define PNG_LITERAL_SHARP 0x23 -# endif # ifndef PNG_LITERAL_LEFT_SQUARE_BRACKET # define PNG_LITERAL_LEFT_SQUARE_BRACKET 0x5b # endif # ifndef PNG_LITERAL_RIGHT_SQUARE_BRACKET # define PNG_LITERAL_RIGHT_SQUARE_BRACKET 0x5d diff --git a/media/libpng/pngerror.c b/media/libpng/pngerror.c --- a/media/libpng/pngerror.c +++ b/media/libpng/pngerror.c @@ -1,8 +1,8 @@ /* pngerror.c - stub functions for i/o and memory allocation * - * Copyright (c) 2018-2024 Cosmin Truta + * Copyright (c) 2018-2025 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. @@ -37,50 +37,10 @@ #ifdef PNG_ERROR_TEXT_SUPPORTED PNG_FUNCTION(void,PNGAPI png_error,(png_const_structrp png_ptr, png_const_charp error_message), PNG_NORETURN) { -#ifdef PNG_ERROR_NUMBERS_SUPPORTED - char msg[16]; - if (png_ptr != NULL) - { - if ((png_ptr->flags & - (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) != 0) - { - if (*error_message == PNG_LITERAL_SHARP) - { - /* Strip "#nnnn " from beginning of error message. */ - int offset; - for (offset = 1; offset<15; offset++) - if (error_message[offset] == ' ') - break; - - if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0) - { - int i; - for (i = 0; i < offset - 1; i++) - msg[i] = error_message[i + 1]; - msg[i - 1] = '\0'; - error_message = msg; - } - - else - error_message += offset; - } - - else - { - if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0) - { - msg[0] = '0'; - msg[1] = '\0'; - error_message = msg; - } - } - } - } -#endif if (png_ptr != NULL && png_ptr->error_fn != NULL) (*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr), error_message); /* If the custom handler doesn't exist, or if it returns, @@ -214,25 +174,10 @@ */ void PNGAPI png_warning(png_const_structrp png_ptr, png_const_charp warning_message) { int offset = 0; - if (png_ptr != NULL) - { -#ifdef PNG_ERROR_NUMBERS_SUPPORTED - if ((png_ptr->flags & - (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) != 0) -#endif - { - if (*warning_message == PNG_LITERAL_SHARP) - { - for (offset = 1; offset < 15; offset++) - if (warning_message[offset] == ' ') - break; - } - } - } if (png_ptr != NULL && png_ptr->warning_fn != NULL) (*(png_ptr->warning_fn))(png_constcast(png_structrp,png_ptr), warning_message + offset); else png_default_warning(png_ptr, warning_message + offset); @@ -710,46 +655,13 @@ static PNG_FUNCTION(void /* PRIVATE */, png_default_error,(png_const_structrp png_ptr, png_const_charp error_message), PNG_NORETURN) { #ifdef PNG_CONSOLE_IO_SUPPORTED -#ifdef PNG_ERROR_NUMBERS_SUPPORTED - /* Check on NULL only added in 1.5.4 */ - if (error_message != NULL && *error_message == PNG_LITERAL_SHARP) - { - /* Strip "#nnnn " from beginning of error message. */ - int offset; - char error_number[16]; - for (offset = 0; offset<15; offset++) - { - error_number[offset] = error_message[offset + 1]; - if (error_message[offset] == ' ') - break; - } - - if ((offset > 1) && (offset < 15)) - { - error_number[offset - 1] = '\0'; - fprintf(stderr, "libpng error no. %s: %s", - error_number, error_message + offset + 1); - fprintf(stderr, PNG_STRING_NEWLINE); - } - - else - { - fprintf(stderr, "libpng error: %s, offset=%d", - error_message, offset); - fprintf(stderr, PNG_STRING_NEWLINE); - } - } - else -#endif - { - fprintf(stderr, "libpng error: %s", error_message ? error_message : - "undefined"); - fprintf(stderr, PNG_STRING_NEWLINE); - } + fprintf(stderr, "libpng error: %s", error_message ? error_message : + "undefined"); + fprintf(stderr, PNG_STRING_NEWLINE); #else PNG_UNUSED(error_message) /* Make compiler happy */ #endif png_longjmp(png_ptr, 1); } @@ -783,44 +695,12 @@ */ static void /* PRIVATE */ png_default_warning(png_const_structrp png_ptr, png_const_charp warning_message) { #ifdef PNG_CONSOLE_IO_SUPPORTED -# ifdef PNG_ERROR_NUMBERS_SUPPORTED - if (*warning_message == PNG_LITERAL_SHARP) - { - int offset; - char warning_number[16]; - for (offset = 0; offset < 15; offset++) - { - warning_number[offset] = warning_message[offset + 1]; - if (warning_message[offset] == ' ') - break; - } - - if ((offset > 1) && (offset < 15)) - { - warning_number[offset + 1] = '\0'; - fprintf(stderr, "libpng warning no. %s: %s", - warning_number, warning_message + offset); - fprintf(stderr, PNG_STRING_NEWLINE); - } - - else - { - fprintf(stderr, "libpng warning: %s", - warning_message); - fprintf(stderr, PNG_STRING_NEWLINE); - } - } - else -# endif - - { - fprintf(stderr, "libpng warning: %s", warning_message); - fprintf(stderr, PNG_STRING_NEWLINE); - } + fprintf(stderr, "libpng warning: %s", warning_message); + fprintf(stderr, PNG_STRING_NEWLINE); #else PNG_UNUSED(warning_message) /* Make compiler happy */ #endif PNG_UNUSED(png_ptr) /* Make compiler happy */ } @@ -864,16 +744,12 @@ #ifdef PNG_ERROR_NUMBERS_SUPPORTED void PNGAPI png_set_strip_error_numbers(png_structrp png_ptr, png_uint_32 strip_mode) { - if (png_ptr != NULL) - { - png_ptr->flags &= - ((~(PNG_FLAG_STRIP_ERROR_NUMBERS | - PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode); - } + PNG_UNUSED(png_ptr) + PNG_UNUSED(strip_mode) } #endif #if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\ defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) diff --git a/media/libpng/pngget.c b/media/libpng/pngget.c --- a/media/libpng/pngget.c +++ b/media/libpng/pngget.c @@ -1,8 +1,8 @@ /* pngget.c - retrieval of values from info struct * - * Copyright (c) 2018-2024 Cosmin Truta + * Copyright (c) 2018-2025 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. @@ -1365,168 +1365,6 @@ return -1; } # endif #endif -#ifdef PNG_APNG_SUPPORTED -png_uint_32 PNGAPI -png_get_acTL(png_structp png_ptr, png_infop info_ptr, - png_uint_32 *num_frames, png_uint_32 *num_plays) -{ - png_debug1(1, "in %s retrieval function", "acTL"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_acTL) != 0 && - num_frames != NULL && num_plays != NULL) - { - *num_frames = info_ptr->num_frames; - *num_plays = info_ptr->num_plays; - return (1); - } - - return (0); -} - -png_uint_32 PNGAPI -png_get_num_frames(png_structp png_ptr, png_infop info_ptr) -{ - png_debug(1, "in png_get_num_frames()"); - - if (png_ptr != NULL && info_ptr != NULL) - return (info_ptr->num_frames); - return (0); -} - -png_uint_32 PNGAPI -png_get_num_plays(png_structp png_ptr, png_infop info_ptr) -{ - png_debug(1, "in png_get_num_plays()"); - - if (png_ptr != NULL && info_ptr != NULL) - return (info_ptr->num_plays); - return (0); -} - -png_uint_32 PNGAPI -png_get_next_frame_fcTL(png_structp png_ptr, png_infop info_ptr, - png_uint_32 *width, png_uint_32 *height, - png_uint_32 *x_offset, png_uint_32 *y_offset, - png_uint_16 *delay_num, png_uint_16 *delay_den, - png_byte *dispose_op, png_byte *blend_op) -{ - png_debug1(1, "in %s retrieval function", "fcTL"); - - if (png_ptr != NULL && info_ptr != NULL && - (info_ptr->valid & PNG_INFO_fcTL) != 0 && - width != NULL && height != NULL && - x_offset != NULL && y_offset != NULL && - delay_num != NULL && delay_den != NULL && - dispose_op != NULL && blend_op != NULL) - { - *width = info_ptr->next_frame_width; - *height = info_ptr->next_frame_height; - *x_offset = info_ptr->next_frame_x_offset; - *y_offset = info_ptr->next_frame_y_offset; - *delay_num = info_ptr->next_frame_delay_num; - *delay_den = info_ptr->next_frame_delay_den; - *dispose_op = info_ptr->next_frame_dispose_op; - *blend_op = info_ptr->next_frame_blend_op; - return (1); - } - - return (0); -} - -png_uint_32 PNGAPI -png_get_next_frame_width(png_structp png_ptr, png_infop info_ptr) -{ - png_debug(1, "in png_get_next_frame_width()"); - - if (png_ptr != NULL && info_ptr != NULL) - return (info_ptr->next_frame_width); - return (0); -} - -png_uint_32 PNGAPI -png_get_next_frame_height(png_structp png_ptr, png_infop info_ptr) -{ - png_debug(1, "in png_get_next_frame_height()"); - - if (png_ptr != NULL && info_ptr != NULL) - return (info_ptr->next_frame_height); - return (0); -} - -png_uint_32 PNGAPI -png_get_next_frame_x_offset(png_structp png_ptr, png_infop info_ptr) -{ - png_debug(1, "in png_get_next_frame_x_offset()"); - - if (png_ptr != NULL && info_ptr != NULL) - return (info_ptr->next_frame_x_offset); - return (0); -} - -png_uint_32 PNGAPI -png_get_next_frame_y_offset(png_structp png_ptr, png_infop info_ptr) -{ - png_debug(1, "in png_get_next_frame_y_offset()"); - - if (png_ptr != NULL && info_ptr != NULL) - return (info_ptr->next_frame_y_offset); - return (0); -} - -png_uint_16 PNGAPI -png_get_next_frame_delay_num(png_structp png_ptr, png_infop info_ptr) -{ - png_debug(1, "in png_get_next_frame_delay_num()"); - - if (png_ptr != NULL && info_ptr != NULL) - return (info_ptr->next_frame_delay_num); - return (0); -} - -png_uint_16 PNGAPI -png_get_next_frame_delay_den(png_structp png_ptr, png_infop info_ptr) -{ - png_debug(1, "in png_get_next_frame_delay_den()"); - - if (png_ptr != NULL && info_ptr != NULL) - return (info_ptr->next_frame_delay_den); - return (0); -} - -png_byte PNGAPI -png_get_next_frame_dispose_op(png_structp png_ptr, png_infop info_ptr) -{ - png_debug(1, "in png_get_next_frame_dispose_op()"); - - if (png_ptr != NULL && info_ptr != NULL) - return (info_ptr->next_frame_dispose_op); - return (0); -} - -png_byte PNGAPI -png_get_next_frame_blend_op(png_structp png_ptr, png_infop info_ptr) -{ - png_debug(1, "in png_get_next_frame_blend_op()"); - - if (png_ptr != NULL && info_ptr != NULL) - return (info_ptr->next_frame_blend_op); - return (0); -} - -png_byte PNGAPI -png_get_first_frame_is_hidden(png_structp png_ptr, png_infop info_ptr) -{ - png_debug(1, "in png_first_frame_is_hidden()"); - - if (png_ptr != NULL) - return (png_byte)(png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN); - - PNG_UNUSED(info_ptr) - - return 0; -} -#endif /* APNG */ #endif /* READ || WRITE */ diff --git a/media/libpng/pnginfo.h b/media/libpng/pnginfo.h --- a/media/libpng/pnginfo.h +++ b/media/libpng/pnginfo.h @@ -1,54 +1,31 @@ -/* pnginfo.h - header file for PNG reference library +/* pnginfo.h - internal structures for libpng * - * Copyright (c) 2018 Cosmin Truta + * Copyright (c) 2018-2025 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2013,2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer * and license in png.h */ - /* png_info is a structure that holds the information in a PNG file so - * that the application can find out the characteristics of the image. - * If you are reading the file, this structure will tell you what is - * in the PNG file. If you are writing the file, fill in the information - * you want to put into the PNG file, using png_set_*() functions, then - * call png_write_info(). - * - * The names chosen should be very close to the PNG specification, so - * consult that document for information about the meaning of each field. +#ifndef PNGPRIV_H +# error This file must not be included by applications; please include +#endif + +/* INTERNAL, PRIVATE definition of a PNG. * - * With libpng < 0.95, it was only possible to directly set and read the - * the values in the png_info_struct, which meant that the contents and - * order of the values had to remain fixed. With libpng 0.95 and later, - * however, there are now functions that abstract the contents of - * png_info_struct from the application, so this makes it easier to use - * libpng with dynamic libraries, and even makes it possible to use - * libraries that don't have all of the libpng ancillary chunk-handing - * functionality. In libpng-1.5.0 this was moved into a separate private - * file that is not visible to applications. + * png_info is a modifiable description of a PNG datastream. The fields inside + * this structure are accessed through png_get_() functions and modified + * using png_set_() functions. * - * The following members may have allocated storage attached that should be - * cleaned up before the structure is discarded: palette, trans, text, - * pcal_purpose, pcal_units, pcal_params, hist, iccp_name, iccp_profile, - * splt_palettes, scal_unit, row_pointers, and unknowns. By default, these - * are automatically freed when the info structure is deallocated, if they were - * allocated internally by libpng. This behavior can be changed by means - * of the png_data_freer() function. - * - * More allocation details: all the chunk-reading functions that - * change these members go through the corresponding png_set_* - * functions. A function to clear these members is available: see - * png_free_data(). The png_set_* functions do not depend on being - * able to point info structure members to any of the storage they are - * passed (they make their own copies), EXCEPT that the png_set_text - * functions use the same storage passed to them in the text_ptr or - * itxt_ptr structure argument, and the png_set_rows and png_set_unknowns - * functions do not make their own copies. + * Some functions in libpng do directly access members of png_info. However, + * this should be avoided. png_struct objects contain members which hold + * caches, sometimes optimised, of the values from png_info objects, and + * png_info is not passed to the functions which read and write image data. */ #ifndef PNGINFO_H #define PNGINFO_H struct png_info_def @@ -280,20 +257,7 @@ #endif #ifdef PNG_sRGB_SUPPORTED int rendering_intent; #endif -#ifdef PNG_APNG_SUPPORTED - png_uint_32 num_frames; /* including default image */ - png_uint_32 num_plays; - png_uint_32 next_frame_width; - png_uint_32 next_frame_height; - png_uint_32 next_frame_x_offset; - png_uint_32 next_frame_y_offset; - png_uint_16 next_frame_delay_num; - png_uint_16 next_frame_delay_den; - png_byte next_frame_dispose_op; - png_byte next_frame_blend_op; -#endif - }; #endif /* PNGINFO_H */ diff --git a/media/libpng/pngmem.c b/media/libpng/pngmem.c --- a/media/libpng/pngmem.c +++ b/media/libpng/pngmem.c @@ -1,8 +1,8 @@ /* pngmem.c - stub functions for memory allocation * - * Copyright (c) 2018 Cosmin Truta + * Copyright (c) 2018-2025 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2014,2016 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. diff --git a/media/libpng/pngpread.c b/media/libpng/pngpread.c --- a/media/libpng/pngpread.c +++ b/media/libpng/pngpread.c @@ -1,8 +1,8 @@ /* pngpread.c - read a png file in push mode * - * Copyright (c) 2018-2024 Cosmin Truta + * Copyright (c) 2018-2025 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. @@ -198,93 +198,10 @@ png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; } chunk_name = png_ptr->chunk_name; -#ifdef PNG_READ_APNG_SUPPORTED - if (png_ptr->num_frames_read > 0 && - png_ptr->num_frames_read < info_ptr->num_frames) - { - if (chunk_name == png_IDAT) - { - /* Discard trailing IDATs for the first frame */ - if ((png_ptr->mode & PNG_HAVE_fcTL) != 0 || - png_ptr->num_frames_read > 1) - png_error(png_ptr, "out of place IDAT"); - - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_crc_finish(png_ptr, png_ptr->push_length); - png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; - } - - else if (chunk_name == png_fdAT) - { - PNG_PUSH_SAVE_BUFFER_IF_LT(4) - png_ensure_sequence_number(png_ptr, 4); - - if ((png_ptr->mode & PNG_HAVE_fcTL) == 0) - { - /* Discard trailing fdATs for frames other than the first */ - if (png_ptr->num_frames_read < 2) - png_error(png_ptr, "out of place fdAT"); - - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_crc_finish(png_ptr, png_ptr->push_length); - png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; - } - - else - { - /* frame data follows */ - png_ptr->idat_size = png_ptr->push_length - 4; - png_ptr->mode |= PNG_HAVE_IDAT; - png_ptr->process_mode = PNG_READ_IDAT_MODE; - } - } - - else if (chunk_name == png_fcTL) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_read_reset(png_ptr); - png_ptr->mode &= ~PNG_HAVE_fcTL; - - png_handle_fcTL(png_ptr, info_ptr, png_ptr->push_length); - - if ((png_ptr->mode & PNG_HAVE_fcTL) == 0) - png_error(png_ptr, "missing required fcTL chunk"); - - png_read_reinit(png_ptr, info_ptr); - png_progressive_read_reset(png_ptr); - - if (png_ptr->frame_info_fn != NULL) - (*(png_ptr->frame_info_fn))(png_ptr, png_ptr->num_frames_read); - - png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; - } - - else if (chunk_name == png_IEND) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_warning(png_ptr, "Number of actual frames fewer than expected"); - png_crc_finish(png_ptr, png_ptr->push_length); - png_ptr->process_mode = PNG_READ_DONE_MODE; - png_push_have_end(png_ptr, info_ptr); - } - - else - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_warning(png_ptr, "Skipped (ignored) a chunk " - "between APNG chunks"); - png_crc_finish(png_ptr, png_ptr->push_length); - png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; - } - - return; - } -#endif /* READ_APNG */ - if (chunk_name == png_IDAT) { if ((png_ptr->mode & PNG_AFTER_IDAT) != 0) png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; @@ -310,10 +227,18 @@ if ((png_ptr->mode & PNG_AFTER_IDAT) != 0) png_benign_error(png_ptr, "Too many IDATs found"); } + else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) + { + /* These flags must be set consistently for all non-IDAT chunks, + * including the unknown chunks. + */ + png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT | PNG_AFTER_IDAT; + } + if (chunk_name == png_IHDR) { if (png_ptr->push_length != 13) png_error(png_ptr, "Invalid IHDR length"); @@ -341,37 +266,20 @@ } #endif else if (chunk_name == png_IDAT) { -#ifdef PNG_READ_APNG_SUPPORTED - png_have_info(png_ptr, info_ptr); -#endif png_ptr->idat_size = png_ptr->push_length; png_ptr->process_mode = PNG_READ_IDAT_MODE; png_push_have_info(png_ptr, info_ptr); png_ptr->zstream.avail_out = (uInt) PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1; png_ptr->zstream.next_out = png_ptr->row_buf; return; } -#ifdef PNG_READ_APNG_SUPPORTED - else if (chunk_name == png_acTL) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_acTL(png_ptr, info_ptr, png_ptr->push_length); - } - - else if (chunk_name == png_fcTL) - { - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_handle_fcTL(png_ptr, info_ptr, png_ptr->push_length); - } - -#endif /* READ_APNG */ else { PNG_PUSH_SAVE_BUFFER_IF_FULL png_handle_chunk(png_ptr, info_ptr, png_ptr->push_length); } @@ -499,76 +407,29 @@ { png_byte chunk_length[4]; png_byte chunk_tag[4]; /* TODO: this code can be commoned up with the same code in push_read */ -#ifdef PNG_READ_APNG_SUPPORTED - PNG_PUSH_SAVE_BUFFER_IF_LT(12) -#else PNG_PUSH_SAVE_BUFFER_IF_LT(8) -#endif png_push_fill_buffer(png_ptr, chunk_length, 4); png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length); png_reset_crc(png_ptr); png_crc_read(png_ptr, chunk_tag, 4); png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag); png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; -#ifdef PNG_READ_APNG_SUPPORTED - if (png_ptr->chunk_name != png_fdAT && png_ptr->num_frames_read > 0) - { - if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) != 0) - { - png_ptr->process_mode = PNG_READ_CHUNK_MODE; - if (png_ptr->frame_end_fn != NULL) - (*(png_ptr->frame_end_fn))(png_ptr, png_ptr->num_frames_read); - png_ptr->num_frames_read++; - return; - } - else - { - if (png_ptr->chunk_name == png_IEND) - png_error(png_ptr, "Not enough image data"); - PNG_PUSH_SAVE_BUFFER_IF_FULL - png_warning(png_ptr, "Skipping (ignoring) a chunk between " - "APNG chunks"); - png_crc_finish(png_ptr, png_ptr->push_length); - png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; - return; - } - } - else -#endif -#ifdef PNG_READ_APNG_SUPPORTED - if (png_ptr->chunk_name != png_IDAT && png_ptr->num_frames_read == 0) -#else if (png_ptr->chunk_name != png_IDAT) -#endif { png_ptr->process_mode = PNG_READ_CHUNK_MODE; if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0) png_error(png_ptr, "Not enough compressed data"); -#ifdef PNG_READ_APNG_SUPPORTED - if (png_ptr->frame_end_fn != NULL) - (*(png_ptr->frame_end_fn))(png_ptr, png_ptr->num_frames_read); - png_ptr->num_frames_read++; -#endif - return; } png_ptr->idat_size = png_ptr->push_length; - -#ifdef PNG_READ_APNG_SUPPORTED - if (png_ptr->num_frames_read > 0) - { - png_ensure_sequence_number(png_ptr, 4); - png_ptr->idat_size -= 4; - } -#endif } if (png_ptr->idat_size != 0 && png_ptr->save_buffer_size != 0) { size_t save_size = png_ptr->save_buffer_size; @@ -638,20 +499,10 @@ { /* The caller checks for a non-zero buffer length. */ if (!(buffer_length > 0) || buffer == NULL) png_error(png_ptr, "No IDAT data (internal error)"); -#ifdef PNG_READ_APNG_SUPPORTED - /* If the app is not APNG-aware, decode only the first frame */ - if ((png_ptr->apng_flags & PNG_APNG_APP) == 0 && - png_ptr->num_frames_read > 0) - { - png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; - return; - } -#endif - /* This routine must process all the data it has been given * before returning, calling the row callback as required to * handle the uncompressed results. */ png_ptr->zstream.next_in = buffer; @@ -1081,22 +932,10 @@ png_ptr->end_fn = end_fn; png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer); } -#ifdef PNG_READ_APNG_SUPPORTED -void PNGAPI -png_set_progressive_frame_fn(png_structp png_ptr, - png_progressive_frame_ptr frame_info_fn, - png_progressive_frame_ptr frame_end_fn) -{ - png_ptr->frame_info_fn = frame_info_fn; - png_ptr->frame_end_fn = frame_end_fn; - png_ptr->apng_flags |= PNG_APNG_APP; -} -#endif - png_voidp PNGAPI png_get_progressive_ptr(png_const_structrp png_ptr) { if (png_ptr == NULL) return NULL; diff --git a/media/libpng/pngpriv.h b/media/libpng/pngpriv.h --- a/media/libpng/pngpriv.h +++ b/media/libpng/pngpriv.h @@ -1,8 +1,8 @@ /* pngpriv.h - private declarations for use inside libpng * - * Copyright (c) 2018-2024 Cosmin Truta + * Copyright (c) 2018-2025 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. @@ -17,12 +17,24 @@ * change in an incompatible way, or even disappear. * Although the libpng users are not forbidden to include this header, * they should be well aware of the issues that may arise from doing so. */ + +/* pngpriv.h must be included first in each translation unit inside libpng. + * On the other hand, it must not be included at all, directly or indirectly, + * by any application code that uses the libpng API. + */ #ifndef PNGPRIV_H -#define PNGPRIV_H +# define PNGPRIV_H +#else +# error Duplicate inclusion of pngpriv.h; please check the libpng source files +#endif + +#if defined(PNG_H) || defined(PNGCONF_H) || defined(PNGLCONF_H) +# error This file must not be included by applications; please include +#endif /* Feature Test Macros. The following are defined here to ensure that correctly * implemented libraries reveal the APIs libpng needs to build and hide those * that are not needed and potentially damaging to the compilation. * @@ -55,23 +67,20 @@ * configure generated config.h. Libpng is expected to compile without *any* * special build system support on a reasonably ANSI-C compliant system. */ #if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H) # include - /* Pick up the definition of 'restrict' from config.h if it was read: */ # define PNG_RESTRICT restrict #endif /* To support symbol prefixing it is necessary to know *before* including png.h * whether the fixed point (and maybe other) APIs are exported, because if they * are not internal definitions may be required. This is handled below just * before png.h is included, but load the configuration now if it is available. */ -#ifndef PNGLCONF_H -# include "pnglibconf.h" -#endif +#include "pnglibconf.h" /* Local renames may change non-exported API functions from png.h */ #if defined(PNG_PREFIX) && !defined(PNGPREFIX_H) # include "pngprefix.h" #endif @@ -132,10 +141,24 @@ # else # define PNG_ARM_NEON_OPT 0 # endif #endif +#ifndef PNG_RISCV_RVV_OPT + /* RISCV_RVV optimizations are being controlled by the compiler settings, + * typically the target compiler will define __riscv but the rvv extension + * availability has to be explicitly stated. This is why if no + * PNG_RISCV_RVV_OPT was defined then a runtime check will be executed. + * + * To enable RISCV_RVV optimizations unconditionally, and compile the + * associated code, pass --enable-riscv-rvv=yes or --enable-riscv-rvv=on + * to configure or put -DPNG_RISCV_RVV_OPT=2 in CPPFLAGS. + */ + +# define PNG_RISCV_RVV_OPT 0 +#endif + #if PNG_ARM_NEON_OPT > 0 /* NEON optimizations are to be at least considered by libpng, so enable the * callbacks to do this. */ # define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_neon @@ -277,10 +300,20 @@ # define PNG_LOONGARCH_LSX_IMPLEMENTATION 1 #else # define PNG_LOONGARCH_LSX_IMPLEMENTATION 0 #endif +#if PNG_RISCV_RVV_OPT > 0 && __riscv_v >= 1000000 +# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_rvv +# ifndef PNG_RISCV_RVV_IMPLEMENTATION + /* Use the intrinsics code by default. */ +# define PNG_RISCV_RVV_IMPLEMENTATION 1 +# endif +#else +# define PNG_RISCV_RVV_IMPLEMENTATION 0 +#endif /* PNG_RISCV_RVV_OPT > 0 && __riscv_v >= 1000000 */ + /* Is this a build of a DLL where compilation of the object modules requires * different preprocessor settings to those required for a simple library? If * so PNG_BUILD_DLL must be set. * * If libpng is used inside a DLL but that DLL does not export the libpng APIs @@ -618,14 +651,10 @@ #define PNG_BACKGROUND_IS_GRAY 0x800U #define PNG_HAVE_PNG_SIGNATURE 0x1000U #define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000U /* Have another chunk after IDAT */ #define PNG_WROTE_eXIf 0x4000U #define PNG_IS_READ_STRUCT 0x8000U /* Else is a write struct */ -#ifdef PNG_APNG_SUPPORTED -#define PNG_HAVE_acTL 0x10000U -#define PNG_HAVE_fcTL 0x20000U -#endif /* Flags for the transformations the PNG library does on the image data */ #define PNG_BGR 0x0001U #define PNG_INTERLACE 0x0002U #define PNG_PACK 0x0004U @@ -679,11 +708,11 @@ #define PNG_FLAG_OPTIMIZE_ALPHA 0x2000U /* Added to libpng-1.5.4 */ #define PNG_FLAG_DETECT_UNINITIALIZED 0x4000U /* Added to libpng-1.5.4 */ /* #define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000U */ /* #define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000U */ #define PNG_FLAG_LIBRARY_MISMATCH 0x20000U -#define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000U + /* 0x40000U unused */ #define PNG_FLAG_STRIP_ERROR_TEXT 0x80000U #define PNG_FLAG_BENIGN_ERRORS_WARN 0x100000U /* Added to libpng-1.4.0 */ #define PNG_FLAG_APP_WARNINGS_WARN 0x200000U /* Added to libpng-1.6.0 */ #define PNG_FLAG_APP_ERRORS_WARN 0x400000U /* Added to libpng-1.6.0 */ /* 0x800000U unused */ @@ -886,20 +915,10 @@ #define png_tEXt PNG_U32(116, 69, 88, 116) #define png_tIME PNG_U32(116, 73, 77, 69) #define png_tRNS PNG_U32(116, 82, 78, 83) #define png_zTXt PNG_U32(122, 84, 88, 116) -#ifdef PNG_APNG_SUPPORTED -#define png_acTL PNG_U32( 97, 99, 84, 76) -#define png_fcTL PNG_U32(102, 99, 84, 76) -#define png_fdAT PNG_U32(102, 100, 65, 84) - -/* For png_struct.apng_flags: */ -#define PNG_FIRST_FRAME_HIDDEN 0x0001U -#define PNG_APNG_APP 0x0002U -#endif - /* The following will work on (signed char*) strings, whereas the get_uint_32 * macro will fail on top-bit-set values because of the sign extension. */ #define PNG_CHUNK_FROM_STRING(s)\ PNG_U32(0xff & (s)[0], 0xff & (s)[1], 0xff & (s)[2], 0xff & (s)[3]) @@ -1003,21 +1022,19 @@ /* Validate the include paths - the include path used to generate pnglibconf.h * must match that used in the build, or we must be using pnglibconf.h.prebuilt: */ #if PNG_ZLIB_VERNUM != 0 && PNG_ZLIB_VERNUM != ZLIB_VERNUM -# error ZLIB_VERNUM != PNG_ZLIB_VERNUM \ - "-I (include path) error: see the notes in pngpriv.h" - /* This means that when pnglibconf.h was built the copy of zlib.h that it - * used is not the same as the one being used here. Because the build of - * libpng makes decisions to use inflateInit2 and inflateReset2 based on the - * zlib version number and because this affects handling of certain broken - * PNG files the -I directives must match. +# error The include path of is incorrect + /* When pnglibconf.h was built, the copy of zlib.h that it used was not the + * same as the one being used here. Considering how libpng makes decisions + * to use the zlib API based on the zlib version number, the -I options must + * match. * - * The most likely explanation is that you passed a -I in CFLAGS. This will - * not work; all the preprocessor directives and in particular all the -I - * directives must be in CPPFLAGS. + * A possible cause of this mismatch is that you passed an -I option in + * CFLAGS, which is unlikely to work. All the preprocessor options, and all + * the -I options in particular, should be in CPPFLAGS. */ #endif /* This is used for 16-bit gamma tables -- only the top level pointers are * const; this could be changed: @@ -1527,10 +1544,27 @@ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_lsx,(png_row_infop row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); #endif +#if PNG_RISCV_RVV_IMPLEMENTATION == 1 +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_rvv,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_rvv,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_rvv,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_rvv,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_rvv,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_rvv,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_rvv,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +#endif + /* Choose the best filter to use and filter the row data */ PNG_INTERNAL_FUNCTION(void,png_write_find_filter,(png_structrp png_ptr, png_row_infop row_info),PNG_EMPTY); #ifdef PNG_SEQUENTIAL_READ_SUPPORTED @@ -1683,53 +1717,10 @@ png_inforp info_ptr),PNG_EMPTY); PNG_INTERNAL_FUNCTION(void,png_read_push_finish_row,(png_structrp png_ptr), PNG_EMPTY); #endif /* PROGRESSIVE_READ */ -#ifdef PNG_APNG_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_ensure_fcTL_is_valid,(png_structp png_ptr, - png_uint_32 width, png_uint_32 height, - png_uint_32 x_offset, png_uint_32 y_offset, - png_uint_16 delay_num, png_uint_16 delay_den, - png_byte dispose_op, png_byte blend_op),PNG_EMPTY); - -#ifdef PNG_READ_APNG_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_handle_acTL,(png_structp png_ptr, - png_infop info_ptr, png_uint_32 length),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_handle_fcTL,(png_structp png_ptr, - png_infop info_ptr, png_uint_32 length),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_handle_fdAT,(png_structp png_ptr, - png_infop info_ptr, png_uint_32 length),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_have_info,(png_structp png_ptr, - png_infop info_ptr),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_ensure_sequence_number,(png_structp png_ptr, - png_uint_32 length),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_reset,(png_structp png_ptr),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_read_reinit,(png_structp png_ptr, - png_infop info_ptr),PNG_EMPTY); -#ifdef PNG_PROGRESSIVE_READ_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_progressive_read_reset,(png_structp png_ptr), - PNG_EMPTY); -#endif /* PROGRESSIVE_READ */ -#endif /* READ_APNG */ - -#ifdef PNG_WRITE_APNG_SUPPORTED -PNG_INTERNAL_FUNCTION(void,png_write_acTL,(png_structp png_ptr, - png_uint_32 num_frames, png_uint_32 num_plays),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_write_fcTL,(png_structp png_ptr, - png_uint_32 width, png_uint_32 height, - png_uint_32 x_offset, png_uint_32 y_offset, - png_uint_16 delay_num, png_uint_16 delay_den, - png_byte dispose_op, png_byte blend_op),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_write_fdAT,(png_structp png_ptr, - png_const_bytep data, png_size_t length),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_write_reset,(png_structp png_ptr),PNG_EMPTY); -PNG_INTERNAL_FUNCTION(void,png_write_reinit,(png_structp png_ptr, - png_infop info_ptr, png_uint_32 width, png_uint_32 height),PNG_EMPTY); -#endif /* WRITE_APNG */ -#endif /* APNG */ - #ifdef PNG_iCCP_SUPPORTED /* Routines for checking parts of an ICC profile. */ #ifdef PNG_READ_iCCP_SUPPORTED PNG_INTERNAL_FUNCTION(int,png_icc_check_length,(png_const_structrp png_ptr, png_const_charp name, png_uint_32 profile_length), PNG_EMPTY); @@ -2182,10 +2173,15 @@ #if PNG_LOONGARCH_LSX_OPT > 0 PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_lsx, (png_structp png_ptr, unsigned int bpp), PNG_EMPTY); #endif +# if PNG_RISCV_RVV_IMPLEMENTATION == 1 +PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_rvv, + (png_structp png_ptr, unsigned int bpp), PNG_EMPTY); +#endif + PNG_INTERNAL_FUNCTION(png_uint_32, png_check_keyword, (png_structrp png_ptr, png_const_charp key, png_bytep new_key), PNG_EMPTY); #if PNG_ARM_NEON_IMPLEMENTATION == 1 PNG_INTERNAL_FUNCTION(void, @@ -2217,6 +2213,5 @@ #ifdef __cplusplus } #endif #endif /* PNG_VERSION_INFO_ONLY */ -#endif /* PNGPRIV_H */ diff --git a/media/libpng/pngread.c b/media/libpng/pngread.c --- a/media/libpng/pngread.c +++ b/media/libpng/pngread.c @@ -153,100 +153,20 @@ } #endif else if (chunk_name == png_IDAT) { -#ifdef PNG_READ_APNG_SUPPORTED - png_have_info(png_ptr, info_ptr); -#endif png_ptr->idat_size = length; break; } -#ifdef PNG_READ_APNG_SUPPORTED - else if (chunk_name == png_acTL) - png_handle_acTL(png_ptr, info_ptr, length); - - else if (chunk_name == png_fcTL) - png_handle_fcTL(png_ptr, info_ptr, length); - - else if (chunk_name == png_fdAT) - png_handle_fdAT(png_ptr, info_ptr, length); -#endif - else png_handle_chunk(png_ptr, info_ptr, length); } } #endif /* SEQUENTIAL_READ */ -#ifdef PNG_READ_APNG_SUPPORTED -void PNGAPI -png_read_frame_head(png_structp png_ptr, png_infop info_ptr) -{ - png_byte have_chunk_after_DAT; /* after IDAT or after fdAT */ - - png_debug(0, "Reading frame head"); - - if ((png_ptr->mode & PNG_HAVE_acTL) == 0) - png_error(png_ptr, "attempt to png_read_frame_head() but " - "no acTL present"); - - /* do nothing for the main IDAT */ - if (png_ptr->num_frames_read == 0) - return; - - png_read_reset(png_ptr); - png_ptr->flags &= ~PNG_FLAG_ROW_INIT; - png_ptr->mode &= ~PNG_HAVE_fcTL; - - have_chunk_after_DAT = 0; - for (;;) - { - png_uint_32 length = png_read_chunk_header(png_ptr); - - if (png_ptr->chunk_name == png_IDAT) - { - /* discard trailing IDATs for the first frame */ - if (have_chunk_after_DAT != 0 || png_ptr->num_frames_read > 1) - png_error(png_ptr, "png_read_frame_head(): out of place IDAT"); - png_crc_finish(png_ptr, length); - } - - else if (png_ptr->chunk_name == png_fcTL) - { - png_handle_fcTL(png_ptr, info_ptr, length); - have_chunk_after_DAT = 1; - } - - else if (png_ptr->chunk_name == png_fdAT) - { - png_ensure_sequence_number(png_ptr, length); - - /* discard trailing fdATs for frames other than the first */ - if (have_chunk_after_DAT == 0 && png_ptr->num_frames_read > 1) - png_crc_finish(png_ptr, length - 4); - else if (png_ptr->mode & PNG_HAVE_fcTL) - { - png_ptr->idat_size = length - 4; - png_ptr->mode |= PNG_HAVE_IDAT; - - break; - } - else - png_error(png_ptr, "png_read_frame_head(): out of place fdAT"); - } - else - { - png_warning(png_ptr, "Skipped (ignored) a chunk " - "between APNG chunks"); - png_crc_finish(png_ptr, length); - } - } -} -#endif /* READ_APNG */ - /* Optional call to update the users info_ptr structure */ void PNGAPI png_read_update_info(png_structrp png_ptr, png_inforp info_ptr) { png_debug(1, "in png_read_update_info"); @@ -780,11 +700,16 @@ { png_uint_32 length = png_read_chunk_header(png_ptr); png_uint_32 chunk_name = png_ptr->chunk_name; if (chunk_name != png_IDAT) - png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; + { + /* These flags must be set consistently for all non-IDAT chunks, + * including the unknown chunks. + */ + png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT | PNG_AFTER_IDAT; + } if (chunk_name == png_IEND) png_handle_chunk(png_ptr, info_ptr, length); else if (chunk_name == png_IHDR) @@ -887,11 +812,12 @@ png_free(png_ptr, png_ptr->chunk_list); png_ptr->chunk_list = NULL; #endif #if defined(PNG_READ_EXPAND_SUPPORTED) && \ - defined(PNG_ARM_NEON_IMPLEMENTATION) + (defined(PNG_ARM_NEON_IMPLEMENTATION) || \ + defined(PNG_RISCV_RVV_IMPLEMENTATION)) png_free(png_ptr, png_ptr->riffled_palette); png_ptr->riffled_palette = NULL; #endif /* NOTE: the 'setjmp' buffer may still be allocated and the memory and error @@ -1406,11 +1332,11 @@ return 1; } #ifdef PNG_STDIO_SUPPORTED int PNGAPI -png_image_begin_read_from_stdio(png_imagep image, FILE* file) +png_image_begin_read_from_stdio(png_imagep image, FILE *file) { if (image != NULL && image->version == PNG_IMAGE_VERSION) { if (file != NULL) { @@ -3201,10 +3127,58 @@ return 1; } } +/* Row reading for interlaced 16-to-8 bit depth conversion with local buffer. */ +static int +png_image_read_direct_scaled(png_voidp argument) +{ + png_image_read_control *display = png_voidcast(png_image_read_control*, + argument); + png_imagep image = display->image; + png_structrp png_ptr = image->opaque->png_ptr; + png_bytep local_row = png_voidcast(png_bytep, display->local_row); + png_bytep first_row = png_voidcast(png_bytep, display->first_row); + ptrdiff_t row_bytes = display->row_bytes; + int passes; + + /* Handle interlacing. */ + switch (png_ptr->interlaced) + { + case PNG_INTERLACE_NONE: + passes = 1; + break; + + case PNG_INTERLACE_ADAM7: + passes = PNG_INTERLACE_ADAM7_PASSES; + break; + + default: + png_error(png_ptr, "unknown interlace type"); + } + + /* Read each pass using local_row as intermediate buffer. */ + while (--passes >= 0) + { + png_uint_32 y = image->height; + png_bytep output_row = first_row; + + for (; y > 0; --y) + { + /* Read into local_row (gets transformed 8-bit data). */ + png_read_row(png_ptr, local_row, NULL); + + /* Copy from local_row to user buffer. */ + memcpy(output_row, local_row, (size_t)row_bytes); + output_row += row_bytes; + } + } + + return 1; +} + /* Just the row reading part of png_image_read. */ static int png_image_read_composite(png_voidp argument) { png_image_read_control *display = png_voidcast(png_image_read_control*, @@ -3231,10 +3205,11 @@ png_uint_32 height = image->height; png_uint_32 width = image->width; ptrdiff_t step_row = display->row_bytes; unsigned int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1; + int optimize_alpha = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0; int pass; for (pass = 0; pass < passes; ++pass) { unsigned int startx, stepx, stepy; @@ -3287,24 +3262,48 @@ { png_uint_32 component = inrow[c]; if (alpha < 255) /* else just use component */ { - /* This is PNG_OPTIMIZED_ALPHA, the component value - * is a linear 8-bit value. Combine this with the - * current outrow[c] value which is sRGB encoded. - * Arithmetic here is 16-bits to preserve the output - * values correctly. - */ - component *= 257*255; /* =65535 */ - component += (255-alpha)*png_sRGB_table[outrow[c]]; - - /* So 'component' is scaled by 255*65535 and is - * therefore appropriate for the sRGB to linear - * conversion table. - */ - component = PNG_sRGB_FROM_LINEAR(component); + if (optimize_alpha != 0) + { + /* This is PNG_OPTIMIZED_ALPHA, the component value + * is a linear 8-bit value. Combine this with the + * current outrow[c] value which is sRGB encoded. + * Arithmetic here is 16-bits to preserve the output + * values correctly. + */ + component *= 257*255; /* =65535 */ + component += (255-alpha)*png_sRGB_table[outrow[c]]; + + /* Clamp to the valid range to defend against + * unforeseen cases where the data might be sRGB + * instead of linear premultiplied. + * (Belt-and-suspenders for CVE-2025-66293.) + */ + if (component > 255*65535) + component = 255*65535; + + /* So 'component' is scaled by 255*65535 and is + * therefore appropriate for the sRGB-to-linear + * conversion table. + */ + component = PNG_sRGB_FROM_LINEAR(component); + } + else + { + /* Compositing was already done on the palette + * entries. The data is sRGB premultiplied on black. + * Composite with the background in sRGB space. + * This is not gamma-correct, but matches what was + * done to the palette. + */ + png_uint_32 background = outrow[c]; + component += ((255-alpha) * background + 127) / 255; + if (component > 255) + component = 255; + } } outrow[c] = (png_byte)component; } } @@ -3619,10 +3618,11 @@ png_uint_32 format = image->format; int linear = (format & PNG_FORMAT_FLAG_LINEAR) != 0; int do_local_compose = 0; int do_local_background = 0; /* to avoid double gamma correction bug */ + int do_local_scale = 0; /* for interlaced 16-to-8 bit conversion */ int passes = 0; /* Add transforms to ensure the correct output format is produced then check * that the required implementation support is there. Always expand; always * need 8 bits minimum, no palette and expanded tRNS. @@ -3752,12 +3752,20 @@ { if (linear != 0 /*16-bit output*/) png_set_expand_16(png_ptr); else /* 8-bit output */ + { png_set_scale_16(png_ptr); + /* For interlaced images, use local_row buffer to avoid overflow + * in png_combine_row() which writes using IHDR bit-depth. + */ + if (png_ptr->interlaced != 0) + do_local_scale = 1; + } + change &= ~PNG_FORMAT_FLAG_LINEAR; } /* Now the background/alpha channel changes. */ if ((change & PNG_FORMAT_FLAG_ALPHA) != 0) @@ -4029,10 +4037,28 @@ png_free(png_ptr, row); return result; } + else if (do_local_scale != 0) + { + /* For interlaced 16-to-8 conversion, use an intermediate row buffer + * to avoid buffer overflows in png_combine_row. The local_row is sized + * for the transformed (8-bit) output, preventing the overflow that would + * occur if png_combine_row wrote 16-bit data directly to the user buffer. + */ + int result; + png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); + + display->local_row = row; + result = png_safe_execute(image, png_image_read_direct_scaled, display); + display->local_row = NULL; + png_free(png_ptr, row); + + return result; + } + else { png_alloc_size_t row_bytes = (png_alloc_size_t)display->row_bytes; while (--passes >= 0) diff --git a/media/libpng/pngrio.c b/media/libpng/pngrio.c --- a/media/libpng/pngrio.c +++ b/media/libpng/pngrio.c @@ -1,8 +1,8 @@ /* pngrio.c - functions for data input * - * Copyright (c) 2018 Cosmin Truta + * Copyright (c) 2018-2025 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. @@ -54,11 +54,11 @@ return; /* fread() returns 0 on error, so it is OK to store this in a size_t * instead of an int, which is what fread() actually returns. */ - check = fread(data, 1, length, png_voidcast(png_FILE_p, png_ptr->io_ptr)); + check = fread(data, 1, length, png_voidcast(FILE *, png_ptr->io_ptr)); if (check != length) png_error(png_ptr, "Read Error"); } #endif diff --git a/media/libpng/pngrtran.c b/media/libpng/pngrtran.c --- a/media/libpng/pngrtran.c +++ b/media/libpng/pngrtran.c @@ -1,8 +1,8 @@ /* pngrtran.c - transforms the data in a row for PNG readers * - * Copyright (c) 2018-2024 Cosmin Truta + * Copyright (c) 2018-2025 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. @@ -26,10 +26,16 @@ # include # endif # endif #endif +#ifdef PNG_RISCV_RVV_IMPLEMENTATION +# if PNG_RISCV_RVV_IMPLEMENTATION == 1 +# define PNG_RISCV_RVV_INTRINSICS_AVAILABLE +# endif +#endif + #ifdef PNG_READ_SUPPORTED /* Set the action on getting a CRC error for an ancillary or critical chunk. */ void PNGAPI png_set_crc_action(png_structrp png_ptr, int crit_action, int ancil_action) @@ -493,13 +499,23 @@ if (full_quantize == 0) { int i; + /* Initialize the array to index colors. + * + * Ensure quantize_index can fit 256 elements (PNG_MAX_PALETTE_LENGTH) + * rather than num_palette elements. This is to prevent buffer overflows + * caused by malformed PNG files with out-of-range palette indices. + * + * Be careful to avoid leaking memory. Applications are allowed to call + * this function more than once per png_struct. + */ + png_free(png_ptr, png_ptr->quantize_index); png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr, - (png_alloc_size_t)num_palette); - for (i = 0; i < num_palette; i++) + PNG_MAX_PALETTE_LENGTH); + for (i = 0; i < PNG_MAX_PALETTE_LENGTH; i++) png_ptr->quantize_index[i] = (png_byte)i; } if (num_palette > maximum_colors) { @@ -507,19 +523,18 @@ { /* This is easy enough, just throw out the least used colors. * Perhaps not the best solution, but good enough. */ - int i; - - /* Initialize an array to sort colors */ - png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr, + png_bytep quantize_sort; + int i, j; + + /* Initialize the local array to sort colors. */ + quantize_sort = (png_bytep)png_malloc(png_ptr, (png_alloc_size_t)num_palette); - - /* Initialize the quantize_sort array */ for (i = 0; i < num_palette; i++) - png_ptr->quantize_sort[i] = (png_byte)i; + quantize_sort[i] = (png_byte)i; /* Find the least used palette entries by starting a * bubble sort, and running it until we have sorted * out enough colors. Note that we don't care about * sorting all the colors, just finding which are @@ -527,23 +542,22 @@ */ for (i = num_palette - 1; i >= maximum_colors; i--) { int done; /* To stop early if the list is pre-sorted */ - int j; done = 1; for (j = 0; j < i; j++) { - if (histogram[png_ptr->quantize_sort[j]] - < histogram[png_ptr->quantize_sort[j + 1]]) + if (histogram[quantize_sort[j]] + < histogram[quantize_sort[j + 1]]) { png_byte t; - t = png_ptr->quantize_sort[j]; - png_ptr->quantize_sort[j] = png_ptr->quantize_sort[j + 1]; - png_ptr->quantize_sort[j + 1] = t; + t = quantize_sort[j]; + quantize_sort[j] = quantize_sort[j + 1]; + quantize_sort[j + 1] = t; done = 0; } } if (done != 0) @@ -551,44 +565,44 @@ } /* Swap the palette around, and set up a table, if necessary */ if (full_quantize != 0) { - int j = num_palette; + j = num_palette; /* Put all the useful colors within the max, but don't * move the others. */ for (i = 0; i < maximum_colors; i++) { - if ((int)png_ptr->quantize_sort[i] >= maximum_colors) + if ((int)quantize_sort[i] >= maximum_colors) { do j--; - while ((int)png_ptr->quantize_sort[j] >= maximum_colors); + while ((int)quantize_sort[j] >= maximum_colors); palette[i] = palette[j]; } } } else { - int j = num_palette; + j = num_palette; /* Move all the used colors inside the max limit, and * develop a translation table. */ for (i = 0; i < maximum_colors; i++) { /* Only move the colors we need to */ - if ((int)png_ptr->quantize_sort[i] >= maximum_colors) + if ((int)quantize_sort[i] >= maximum_colors) { png_color tmp_color; do j--; - while ((int)png_ptr->quantize_sort[j] >= maximum_colors); + while ((int)quantize_sort[j] >= maximum_colors); tmp_color = palette[j]; palette[j] = palette[i]; palette[i] = tmp_color; /* Indicate where the color went */ @@ -622,12 +636,11 @@ /* Point to closest color */ png_ptr->quantize_index[i] = (png_byte)min_k; } } } - png_free(png_ptr, png_ptr->quantize_sort); - png_ptr->quantize_sort = NULL; + png_free(png_ptr, quantize_sort); } else { /* This is much harder to do simply (and quickly). Perhaps * we need to go through a median cut routine, but those @@ -1766,23 +1779,55 @@ { palette[i] = back; } else /* if (png_ptr->trans_alpha[i] != 0xff) */ { - png_byte v, w; - - v = png_ptr->gamma_to_1[palette[i].red]; - png_composite(w, v, png_ptr->trans_alpha[i], back_1.red); - palette[i].red = png_ptr->gamma_from_1[w]; - - v = png_ptr->gamma_to_1[palette[i].green]; - png_composite(w, v, png_ptr->trans_alpha[i], back_1.green); - palette[i].green = png_ptr->gamma_from_1[w]; - - v = png_ptr->gamma_to_1[palette[i].blue]; - png_composite(w, v, png_ptr->trans_alpha[i], back_1.blue); - palette[i].blue = png_ptr->gamma_from_1[w]; + if ((png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0) + { + /* Premultiply only: + * component = round((component * alpha) / 255) + */ + png_uint_32 component; + + component = png_ptr->gamma_to_1[palette[i].red]; + component = + (component * png_ptr->trans_alpha[i] + 128) / 255; + palette[i].red = png_ptr->gamma_from_1[component]; + + component = png_ptr->gamma_to_1[palette[i].green]; + component = + (component * png_ptr->trans_alpha[i] + 128) / 255; + palette[i].green = png_ptr->gamma_from_1[component]; + + component = png_ptr->gamma_to_1[palette[i].blue]; + component = + (component * png_ptr->trans_alpha[i] + 128) / 255; + palette[i].blue = png_ptr->gamma_from_1[component]; + } + else + { + /* Composite with background color: + * component = + * alpha * component + (1 - alpha) * background + */ + png_byte v, w; + + v = png_ptr->gamma_to_1[palette[i].red]; + png_composite(w, v, + png_ptr->trans_alpha[i], back_1.red); + palette[i].red = png_ptr->gamma_from_1[w]; + + v = png_ptr->gamma_to_1[palette[i].green]; + png_composite(w, v, + png_ptr->trans_alpha[i], back_1.green); + palette[i].green = png_ptr->gamma_from_1[w]; + + v = png_ptr->gamma_to_1[palette[i].blue]; + png_composite(w, v, + png_ptr->trans_alpha[i], back_1.blue); + palette[i].blue = png_ptr->gamma_from_1[w]; + } } } else { palette[i].red = png_ptr->gamma_table[palette[i].red]; @@ -1796,10 +1841,11 @@ * NOTE: this is highly dubious; it removes the transformations in * place. This seems inconsistent with the general treatment of the * transformations elsewhere. */ png_ptr->transformations &= ~(PNG_COMPOSE | PNG_GAMMA); + png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA; } /* color_type == PNG_COLOR_TYPE_PALETTE */ /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */ else /* color_type != PNG_COLOR_TYPE_PALETTE */ { @@ -5001,17 +5047,12 @@ png_do_chop(row_info, png_ptr->row_buf + 1); #endif #ifdef PNG_READ_QUANTIZE_SUPPORTED if ((png_ptr->transformations & PNG_QUANTIZE) != 0) - { png_do_quantize(row_info, png_ptr->row_buf + 1, png_ptr->palette_lookup, png_ptr->quantize_index); - - if (row_info->rowbytes == 0) - png_error(png_ptr, "png_do_quantize returned rowbytes=0"); - } #endif /* READ_QUANTIZE */ #ifdef PNG_READ_EXPAND_16_SUPPORTED /* Do the expansion now, after all the arithmetic has been done. Notice * that previous transformations can handle the PNG_EXPAND_16 flag if this diff --git a/media/libpng/pngrutil.c b/media/libpng/pngrutil.c --- a/media/libpng/pngrutil.c +++ b/media/libpng/pngrutil.c @@ -1,8 +1,8 @@ /* pngrutil.c - utilities to read a PNG file * - * Copyright (c) 2018-2024 Cosmin Truta + * Copyright (c) 2018-2025 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. @@ -920,15 +920,10 @@ color_type = buf[9]; compression_type = buf[10]; filter_type = buf[11]; interlace_type = buf[12]; -#ifdef PNG_READ_APNG_SUPPORTED - png_ptr->first_frame_width = width; - png_ptr->first_frame_height = height; -#endif - /* Set internal variables */ png_ptr->width = width; png_ptr->height = height; png_ptr->bit_depth = (png_byte)bit_depth; png_ptr->interlaced = (png_byte)interlace_type; @@ -2415,14 +2410,10 @@ return handled_error; } } #endif - /* TODO: this doesn't work and shouldn't be necessary. */ - if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - png_ptr->mode |= PNG_AFTER_IDAT; - buffer = png_read_buffer(png_ptr, length+1); if (buffer == NULL) { png_crc_finish(png_ptr, length); @@ -2489,14 +2480,10 @@ return handled_error; } } #endif - /* TODO: should not be necessary. */ - if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - png_ptr->mode |= PNG_AFTER_IDAT; - /* Note, "length" is sufficient here; we won't be adding * a null terminator later. The limit check in png_handle_chunk should be * sufficient. */ buffer = png_read_buffer(png_ptr, length); @@ -2609,14 +2596,10 @@ return handled_error; } } #endif - /* TODO: should not be necessary. */ - if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - png_ptr->mode |= PNG_AFTER_IDAT; - buffer = png_read_buffer(png_ptr, length+1); if (buffer == NULL) { png_crc_finish(png_ptr, length); @@ -2733,184 +2716,10 @@ } #else # define png_handle_iTXt NULL #endif -#ifdef PNG_READ_APNG_SUPPORTED -void /* PRIVATE */ -png_handle_acTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -{ - png_byte data[8]; - png_uint_32 num_frames; - png_uint_32 num_plays; - png_uint_32 didSet; - - png_debug(1, "in png_handle_acTL"); - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - { - png_error(png_ptr, "Missing IHDR before acTL"); - } - else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - { - png_warning(png_ptr, "Invalid acTL after IDAT skipped"); - png_crc_finish(png_ptr, length); - return; - } - else if ((png_ptr->mode & PNG_HAVE_acTL) != 0) - { - png_warning(png_ptr, "Duplicate acTL skipped"); - png_crc_finish(png_ptr, length); - return; - } - else if (length != 8) - { - png_warning(png_ptr, "acTL with invalid length skipped"); - png_crc_finish(png_ptr, length); - return; - } - - png_crc_read(png_ptr, data, 8); - png_crc_finish(png_ptr, 0); - - num_frames = png_get_uint_31(png_ptr, data); - num_plays = png_get_uint_31(png_ptr, data + 4); - - /* the set function will do error checking on num_frames */ - didSet = png_set_acTL(png_ptr, info_ptr, num_frames, num_plays); - if (didSet != 0) - png_ptr->mode |= PNG_HAVE_acTL; -} - -void /* PRIVATE */ -png_handle_fcTL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -{ - png_byte data[22]; - png_uint_32 width; - png_uint_32 height; - png_uint_32 x_offset; - png_uint_32 y_offset; - png_uint_16 delay_num; - png_uint_16 delay_den; - png_byte dispose_op; - png_byte blend_op; - - png_debug(1, "in png_handle_fcTL"); - - png_ensure_sequence_number(png_ptr, length); - - if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) - { - png_error(png_ptr, "Missing IHDR before fcTL"); - } - else if ((png_ptr->mode & PNG_HAVE_IDAT) != 0) - { - /* for any frames other then the first this message may be misleading, - * but correct. PNG_HAVE_IDAT is unset before the frame head is read - * i can't think of a better message */ - png_warning(png_ptr, "Invalid fcTL after IDAT skipped"); - png_crc_finish(png_ptr, length-4); - return; - } - else if ((png_ptr->mode & PNG_HAVE_fcTL) != 0) - { - png_warning(png_ptr, "Duplicate fcTL within one frame skipped"); - png_crc_finish(png_ptr, length-4); - return; - } - else if (length != 26) - { - png_warning(png_ptr, "fcTL with invalid length skipped"); - png_crc_finish(png_ptr, length-4); - return; - } - - png_crc_read(png_ptr, data, 22); - png_crc_finish(png_ptr, 0); - - width = png_get_uint_31(png_ptr, data); - height = png_get_uint_31(png_ptr, data + 4); - x_offset = png_get_uint_31(png_ptr, data + 8); - y_offset = png_get_uint_31(png_ptr, data + 12); - delay_num = png_get_uint_16(data + 16); - delay_den = png_get_uint_16(data + 18); - dispose_op = data[20]; - blend_op = data[21]; - - if (png_ptr->num_frames_read == 0 && (x_offset != 0 || y_offset != 0)) - { - png_warning(png_ptr, "fcTL for the first frame must have zero offset"); - return; - } - - if (info_ptr != NULL) - { - if (png_ptr->num_frames_read == 0 && - (width != info_ptr->width || height != info_ptr->height)) - { - png_warning(png_ptr, "size in first frame's fcTL must match " - "the size in IHDR"); - return; - } - - /* The set function will do more error checking */ - png_set_next_frame_fcTL(png_ptr, info_ptr, width, height, - x_offset, y_offset, delay_num, delay_den, - dispose_op, blend_op); - - png_read_reinit(png_ptr, info_ptr); - - png_ptr->mode |= PNG_HAVE_fcTL; - } -} - -void /* PRIVATE */ -png_have_info(png_structp png_ptr, png_infop info_ptr) -{ - if ((info_ptr->valid & PNG_INFO_acTL) != 0 && - (info_ptr->valid & PNG_INFO_fcTL) == 0) - { - png_ptr->apng_flags |= PNG_FIRST_FRAME_HIDDEN; - info_ptr->num_frames++; - } -} - -void /* PRIVATE */ -png_handle_fdAT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) -{ - png_ensure_sequence_number(png_ptr, length); - - /* This function is only called from png_read_end(), png_read_info(), - * and png_push_read_chunk() which means that: - * - the user doesn't want to read this frame - * - or this is an out-of-place fdAT - * in either case it is safe to ignore the chunk with a warning */ - png_warning(png_ptr, "ignoring fdAT chunk"); - png_crc_finish(png_ptr, length - 4); - PNG_UNUSED(info_ptr) -} - -void /* PRIVATE */ -png_ensure_sequence_number(png_structp png_ptr, png_uint_32 length) -{ - png_byte data[4]; - png_uint_32 sequence_number; - - if (length < 4) - png_error(png_ptr, "invalid fcTL or fdAT chunk found"); - - png_crc_read(png_ptr, data, 4); - sequence_number = png_get_uint_31(png_ptr, data); - - if (sequence_number != png_ptr->next_seq_num) - png_error(png_ptr, "fcTL or fdAT chunk with out-of-order sequence " - "number found"); - - png_ptr->next_seq_num++; -} -#endif /* READ_APNG */ - #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED /* Utility function for png_handle_unknown; set up png_ptr::unknown_chunk */ static int png_cache_unknown_chunk(png_structrp png_ptr, png_uint_32 length) { @@ -4390,42 +4199,10 @@ if (png_ptr->zstream.avail_in == 0) { uInt avail_in; png_bytep buffer; -#ifdef PNG_READ_APNG_SUPPORTED - png_uint_32 bytes_to_skip = 0; - - while (png_ptr->idat_size == 0 || bytes_to_skip != 0) - { - png_crc_finish(png_ptr, bytes_to_skip); - bytes_to_skip = 0; - - png_ptr->idat_size = png_read_chunk_header(png_ptr); - if (png_ptr->num_frames_read == 0) - { - if (png_ptr->chunk_name != png_IDAT) - png_error(png_ptr, "Not enough image data"); - } - else - { - if (png_ptr->chunk_name == png_IEND) - png_error(png_ptr, "Not enough image data"); - if (png_ptr->chunk_name != png_fdAT) - { - png_warning(png_ptr, "Skipped (ignored) a chunk " - "between APNG chunks"); - bytes_to_skip = png_ptr->idat_size; - continue; - } - - png_ensure_sequence_number(png_ptr, png_ptr->idat_size); - - png_ptr->idat_size -= 4; - } - } -#else while (png_ptr->idat_size == 0) { png_crc_finish(png_ptr, 0); png_ptr->idat_size = png_read_chunk_header(png_ptr); @@ -4433,11 +4210,10 @@ * consumed a non-IDAT header. */ if (png_ptr->chunk_name != png_IDAT) png_error(png_ptr, "Not enough image data"); } -#endif /* READ_APNG */ avail_in = png_ptr->IDAT_read_size; if (avail_in > png_chunk_max(png_ptr)) avail_in = (uInt)/*SAFE*/png_chunk_max(png_ptr); @@ -4505,13 +4281,10 @@ /* Do this for safety; we won't read any more into this row. */ png_ptr->zstream.next_out = NULL; png_ptr->mode |= PNG_AFTER_IDAT; png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; -#ifdef PNG_READ_APNG_SUPPORTED - png_ptr->num_frames_read++; -#endif if (png_ptr->zstream.avail_in > 0 || png_ptr->idat_size > 0) png_chunk_benign_error(png_ptr, "Extra compressed data"); break; } @@ -4917,82 +4690,6 @@ if (png_inflate_claim(png_ptr, png_IDAT) != Z_OK) png_error(png_ptr, png_ptr->zstream.msg); png_ptr->flags |= PNG_FLAG_ROW_INIT; } - -#ifdef PNG_READ_APNG_SUPPORTED -/* This function is to be called after the main IDAT set has been read and - * before a new IDAT is read. It resets some parts of png_ptr - * to make them usable by the read functions again */ -void /* PRIVATE */ -png_read_reset(png_structp png_ptr) -{ - png_ptr->mode &= ~PNG_HAVE_IDAT; - png_ptr->mode &= ~PNG_AFTER_IDAT; - png_ptr->row_number = 0; - png_ptr->pass = 0; -} - -void /* PRIVATE */ -png_read_reinit(png_structp png_ptr, png_infop info_ptr) -{ - png_ptr->width = info_ptr->next_frame_width; - png_ptr->height = info_ptr->next_frame_height; - png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->width); - png_ptr->info_rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, - png_ptr->width); - if (png_ptr->prev_row != NULL) - memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); -} - -#ifdef PNG_PROGRESSIVE_READ_SUPPORTED -/* same as png_read_reset() but for the progressive reader */ -void /* PRIVATE */ -png_progressive_read_reset(png_structp png_ptr) -{ -#ifdef PNG_READ_INTERLACING_SUPPORTED - /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ - - /* Start of interlace block */ - static PNG_CONST png_byte png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; - - /* Offset to next interlace block */ - static PNG_CONST png_byte png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; - - /* Start of interlace block in the y direction */ - static PNG_CONST png_byte png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; - - /* Offset to next interlace block in the y direction */ - static PNG_CONST png_byte png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; - - if (png_ptr->interlaced != 0) - { - if ((png_ptr->transformations & PNG_INTERLACE) == 0) - png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - - png_pass_ystart[0]) / png_pass_yinc[0]; - else - png_ptr->num_rows = png_ptr->height; - - png_ptr->iwidth = (png_ptr->width + - png_pass_inc[png_ptr->pass] - 1 - - png_pass_start[png_ptr->pass]) / - png_pass_inc[png_ptr->pass]; - } - else -#endif /* READ_INTERLACING */ - { - png_ptr->num_rows = png_ptr->height; - png_ptr->iwidth = png_ptr->width; - } - png_ptr->flags &= ~PNG_FLAG_ZSTREAM_ENDED; - if (inflateReset(&(png_ptr->zstream)) != Z_OK) - png_error(png_ptr, "inflateReset failed"); - png_ptr->zstream.avail_in = 0; - png_ptr->zstream.next_in = 0; - png_ptr->zstream.next_out = png_ptr->row_buf; - png_ptr->zstream.avail_out = (uInt)PNG_ROWBYTES(png_ptr->pixel_depth, - png_ptr->iwidth) + 1; -} -#endif /* PROGRESSIVE_READ */ -#endif /* READ_APNG */ #endif /* READ */ diff --git a/media/libpng/pngset.c b/media/libpng/pngset.c --- a/media/libpng/pngset.c +++ b/media/libpng/pngset.c @@ -298,21 +298,18 @@ double white_x, double white_y, double red_x, double red_y, double green_x, double green_y, double blue_x, double blue_y, double maxDL, double minDL) { png_set_mDCV_fixed(png_ptr, info_ptr, - /* The ITU approach is to scale by 50,000, not 100,000 so just divide - * the input values by 2 and use png_fixed: - */ - png_fixed(png_ptr, white_x / 2, "png_set_mDCV(white(x))"), - png_fixed(png_ptr, white_y / 2, "png_set_mDCV(white(y))"), - png_fixed(png_ptr, red_x / 2, "png_set_mDCV(red(x))"), - png_fixed(png_ptr, red_y / 2, "png_set_mDCV(red(y))"), - png_fixed(png_ptr, green_x / 2, "png_set_mDCV(green(x))"), - png_fixed(png_ptr, green_y / 2, "png_set_mDCV(green(y))"), - png_fixed(png_ptr, blue_x / 2, "png_set_mDCV(blue(x))"), - png_fixed(png_ptr, blue_y / 2, "png_set_mDCV(blue(y))"), + png_fixed(png_ptr, white_x, "png_set_mDCV(white(x))"), + png_fixed(png_ptr, white_y, "png_set_mDCV(white(y))"), + png_fixed(png_ptr, red_x, "png_set_mDCV(red(x))"), + png_fixed(png_ptr, red_y, "png_set_mDCV(red(y))"), + png_fixed(png_ptr, green_x, "png_set_mDCV(green(x))"), + png_fixed(png_ptr, green_y, "png_set_mDCV(green(y))"), + png_fixed(png_ptr, blue_x, "png_set_mDCV(blue(x))"), + png_fixed(png_ptr, blue_y, "png_set_mDCV(blue(y))"), png_fixed_ITU(png_ptr, maxDL, "png_set_mDCV(maxDL)"), png_fixed_ITU(png_ptr, minDL, "png_set_mDCV(minDL)")); } # endif /* FLOATING_POINT */ #endif /* mDCV */ @@ -461,15 +458,10 @@ info_ptr->channels++; info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth); info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width); - -#ifdef PNG_APNG_SUPPORTED - /* for non-animated png. this may be overwritten from an acTL chunk later */ - info_ptr->num_frames = 1; -#endif } #ifdef PNG_oFFs_SUPPORTED void PNGAPI png_set_oFFs(png_const_structrp png_ptr, png_inforp info_ptr, @@ -1321,150 +1313,10 @@ if (nentries > 0) png_chunk_report(png_ptr, "sPLT out of memory", PNG_CHUNK_WRITE_ERROR); } #endif /* sPLT */ -#ifdef PNG_APNG_SUPPORTED -png_uint_32 PNGAPI -png_set_acTL(png_structp png_ptr, png_infop info_ptr, - png_uint_32 num_frames, png_uint_32 num_plays) -{ - png_debug1(1, "in %s storage function", "acTL"); - - if (png_ptr == NULL || info_ptr == NULL) - { - png_warning(png_ptr, - "Call to png_set_acTL() with NULL png_ptr " - "or info_ptr ignored"); - return (0); - } - if (num_frames == 0) - { - png_warning(png_ptr, - "Ignoring attempt to set acTL with num_frames zero"); - return (0); - } - if (num_frames > PNG_UINT_31_MAX) - { - png_warning(png_ptr, - "Ignoring attempt to set acTL with num_frames > 2^31-1"); - return (0); - } - if (num_plays > PNG_UINT_31_MAX) - { - png_warning(png_ptr, - "Ignoring attempt to set acTL with num_plays > 2^31-1"); - return (0); - } - - info_ptr->num_frames = num_frames; - info_ptr->num_plays = num_plays; - - info_ptr->valid |= PNG_INFO_acTL; - - return (1); -} - -/* delay_num and delay_den can hold any 16-bit values including zero */ -png_uint_32 PNGAPI -png_set_next_frame_fcTL(png_structp png_ptr, png_infop info_ptr, - png_uint_32 width, png_uint_32 height, - png_uint_32 x_offset, png_uint_32 y_offset, - png_uint_16 delay_num, png_uint_16 delay_den, - png_byte dispose_op, png_byte blend_op) -{ - png_debug1(1, "in %s storage function", "fcTL"); - - if (png_ptr == NULL || info_ptr == NULL) - { - png_warning(png_ptr, - "Call to png_set_fcTL() with NULL png_ptr or info_ptr " - "ignored"); - return (0); - } - - png_ensure_fcTL_is_valid(png_ptr, width, height, x_offset, y_offset, - delay_num, delay_den, dispose_op, blend_op); - - if (blend_op == PNG_BLEND_OP_OVER) - { - if ((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) == 0 && - png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) == 0) - { - png_warning(png_ptr, "PNG_BLEND_OP_OVER is meaningless " - "and wasteful for opaque images, ignored"); - blend_op = PNG_BLEND_OP_SOURCE; - } - } - - info_ptr->next_frame_width = width; - info_ptr->next_frame_height = height; - info_ptr->next_frame_x_offset = x_offset; - info_ptr->next_frame_y_offset = y_offset; - info_ptr->next_frame_delay_num = delay_num; - info_ptr->next_frame_delay_den = delay_den; - info_ptr->next_frame_dispose_op = dispose_op; - info_ptr->next_frame_blend_op = blend_op; - - info_ptr->valid |= PNG_INFO_fcTL; - - return (1); -} - -void /* PRIVATE */ -png_ensure_fcTL_is_valid(png_structp png_ptr, - png_uint_32 width, png_uint_32 height, - png_uint_32 x_offset, png_uint_32 y_offset, - png_uint_16 delay_num, png_uint_16 delay_den, - png_byte dispose_op, png_byte blend_op) -{ - if (width == 0 || width > PNG_UINT_31_MAX) - png_error(png_ptr, "invalid width in fcTL (0 or > 2^31-1)"); - if (height == 0 || height > PNG_UINT_31_MAX) - png_error(png_ptr, "invalid height in fcTL (0 or > 2^31-1)"); - if (x_offset > PNG_UINT_31_MAX) - png_error(png_ptr, "invalid x_offset in fcTL (> 2^31-1)"); - if (y_offset > PNG_UINT_31_MAX) - png_error(png_ptr, "invalid y_offset in fcTL (> 2^31-1)"); - if (width + x_offset > png_ptr->first_frame_width || - height + y_offset > png_ptr->first_frame_height) - png_error(png_ptr, "dimensions of a frame are greater than " - "the ones in IHDR"); - - if (dispose_op != PNG_DISPOSE_OP_NONE && - dispose_op != PNG_DISPOSE_OP_BACKGROUND && - dispose_op != PNG_DISPOSE_OP_PREVIOUS) - png_error(png_ptr, "invalid dispose_op in fcTL"); - - if (blend_op != PNG_BLEND_OP_SOURCE && - blend_op != PNG_BLEND_OP_OVER) - png_error(png_ptr, "invalid blend_op in fcTL"); - - PNG_UNUSED(delay_num) - PNG_UNUSED(delay_den) -} - -png_uint_32 PNGAPI -png_set_first_frame_is_hidden(png_structp png_ptr, png_infop info_ptr, - png_byte is_hidden) -{ - png_debug(1, "in png_first_frame_is_hidden()"); - - if (png_ptr == NULL) - return 0; - - if (is_hidden != 0) - png_ptr->apng_flags |= PNG_FIRST_FRAME_HIDDEN; - else - png_ptr->apng_flags &= ~PNG_FIRST_FRAME_HIDDEN; - - PNG_UNUSED(info_ptr) - - return 1; -} -#endif /* APNG */ - #ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED static png_byte check_location(png_const_structrp png_ptr, int location) { location &= (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT); diff --git a/media/libpng/pngstruct.h b/media/libpng/pngstruct.h --- a/media/libpng/pngstruct.h +++ b/media/libpng/pngstruct.h @@ -1,22 +1,20 @@ -/* pngstruct.h - header file for PNG reference library +/* pngstruct.h - internal structures for libpng * - * Copyright (c) 2018-2022 Cosmin Truta + * Copyright (c) 2018-2025 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer * and license in png.h */ -/* The structure that holds the information to read and write PNG files. - * The only people who need to care about what is inside of this are the - * people who will be modifying the library for their own special needs. - * It should NOT be accessed directly by an application. - */ +#ifndef PNGPRIV_H +# error This file must not be included by applications; please include +#endif #ifndef PNGSTRUCT_H #define PNGSTRUCT_H /* zlib.h defines the structure z_stream, an instance of which is included * in this structure and is required for decompressing the LZ compressed @@ -375,11 +373,12 @@ /* deleted in 1.5.5: rgb_to_gray_blue_coeff; */ #endif /* New member added in libpng-1.6.36 */ #if defined(PNG_READ_EXPAND_SUPPORTED) && \ - defined(PNG_ARM_NEON_IMPLEMENTATION) + (defined(PNG_ARM_NEON_IMPLEMENTATION) || \ + defined(PNG_RISCV_RVV_IMPLEMENTATION)) png_bytep riffled_palette; /* buffer for accelerated palette expansion */ #endif /* New member added in libpng-1.0.4 (renamed in 1.0.9) */ #if defined(PNG_MNG_FEATURES_SUPPORTED) @@ -390,31 +389,10 @@ /* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */ #ifdef PNG_MNG_FEATURES_SUPPORTED png_byte filter_type; #endif -#ifdef PNG_APNG_SUPPORTED - png_uint_32 apng_flags; - png_uint_32 next_seq_num; /* next fcTL/fdAT chunk sequence number */ - png_uint_32 first_frame_width; - png_uint_32 first_frame_height; - -#ifdef PNG_READ_APNG_SUPPORTED - png_uint_32 num_frames_read; /* incremented after all image data of */ - /* a frame is read */ -#ifdef PNG_PROGRESSIVE_READ_SUPPORTED - png_progressive_frame_ptr frame_info_fn; /* frame info read callback */ - png_progressive_frame_ptr frame_end_fn; /* frame data read callback */ -#endif -#endif - -#ifdef PNG_WRITE_APNG_SUPPORTED - png_uint_32 num_frames_to_write; - png_uint_32 num_frames_written; -#endif -#endif /* APNG */ - /* New members added in libpng-1.2.0 */ /* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */ #ifdef PNG_USER_MEM_SUPPORTED png_voidp mem_ptr; /* user supplied struct for mem functions */ @@ -425,11 +403,10 @@ /* New member added in libpng-1.0.13 and 1.2.0 */ png_bytep big_row_buf; /* buffer to save current (unfiltered) row */ #ifdef PNG_READ_QUANTIZE_SUPPORTED /* The following three members were added at version 1.0.14 and 1.2.4 */ - png_bytep quantize_sort; /* working sort array */ png_bytep index_to_palette; /* where the original index currently is in the palette */ png_bytep palette_to_index; /* which original index points to this palette color */ #endif diff --git a/media/libpng/pngwio.c b/media/libpng/pngwio.c --- a/media/libpng/pngwio.c +++ b/media/libpng/pngwio.c @@ -1,8 +1,8 @@ /* pngwio.c - functions for data output * - * Copyright (c) 2018 Cosmin Truta + * Copyright (c) 2018-2025 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2014,2016,2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. @@ -52,11 +52,11 @@ size_t check; if (png_ptr == NULL) return; - check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr)); + check = fwrite(data, 1, length, (FILE *)png_ptr->io_ptr); if (check != length) png_error(png_ptr, "Write Error"); } #endif @@ -75,16 +75,16 @@ # ifdef PNG_STDIO_SUPPORTED void PNGCBAPI png_default_flush(png_structp png_ptr) { - png_FILE_p io_ptr; + FILE *io_ptr; if (png_ptr == NULL) return; - io_ptr = png_voidcast(png_FILE_p, (png_ptr->io_ptr)); + io_ptr = png_voidcast(FILE *, png_ptr->io_ptr); fflush(io_ptr); } # endif #endif diff --git a/media/libpng/pngwrite.c b/media/libpng/pngwrite.c --- a/media/libpng/pngwrite.c +++ b/media/libpng/pngwrite.c @@ -125,14 +125,10 @@ * syncing the info_struct 'valid' flags; this happens if libpng detects * an error and calls png_error while the color space is being set, yet * the application continues writing the PNG. So check the 'invalid' * flag here too. */ -#ifdef PNG_WRITE_APNG_SUPPORTED - if ((info_ptr->valid & PNG_INFO_acTL) != 0) - png_write_acTL(png_ptr, info_ptr->num_frames, info_ptr->num_plays); -#endif #ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED /* Write unknown chunks first; PNG v3 establishes a precedence order * for colourspace chunks. It is certain therefore that new * colourspace chunks will have a precedence and very likely it will be * higher than all known so far. Writing the unknown chunks here is @@ -401,15 +397,10 @@ return; if ((png_ptr->mode & PNG_HAVE_IDAT) == 0) png_error(png_ptr, "No IDATs written into file"); -#ifdef PNG_WRITE_APNG_SUPPORTED - if (png_ptr->num_frames_written != png_ptr->num_frames_to_write) - png_error(png_ptr, "Not enough frames written"); -#endif - #ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && png_ptr->num_palette_max >= png_ptr->num_palette) png_benign_error(png_ptr, "Wrote palette index exceeding num_palette"); #endif @@ -2180,12 +2171,11 @@ /* Check for the cases that currently require a pre-transform on the row * before it is written. This only applies when the input is 16-bit and * either there is an alpha channel or it is converted to 8-bit. */ - if ((linear != 0 && alpha != 0 ) || - (colormap == 0 && display->convert_to_8bit != 0)) + if (linear != 0 && (alpha != 0 || display->convert_to_8bit != 0)) { png_bytep row = png_voidcast(png_bytep, png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr))); int result; @@ -2340,11 +2330,11 @@ #ifdef PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED int PNGAPI png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit, const void *buffer, png_int_32 row_stride, const void *colormap) { - /* Write the image to the given (FILE*). */ + /* Write the image to the given FILE object. */ if (image != NULL && image->version == PNG_IMAGE_VERSION) { if (file != NULL && buffer != NULL) { if (png_image_write_init(image) != 0) @@ -2453,44 +2443,6 @@ else return 0; } #endif /* SIMPLIFIED_WRITE_STDIO */ #endif /* SIMPLIFIED_WRITE */ - -#ifdef PNG_WRITE_APNG_SUPPORTED -void PNGAPI -png_write_frame_head(png_structp png_ptr, png_infop info_ptr, - png_bytepp row_pointers, png_uint_32 width, png_uint_32 height, - png_uint_32 x_offset, png_uint_32 y_offset, - png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op, - png_byte blend_op) -{ - png_debug(1, "in png_write_frame_head"); - - /* there is a chance this has been set after png_write_info was called, - * so it would be set but not written. is there a way to be sure? */ - if ((info_ptr->valid & PNG_INFO_acTL) == 0) - png_error(png_ptr, "png_write_frame_head(): acTL not set"); - - png_write_reset(png_ptr); - - png_write_reinit(png_ptr, info_ptr, width, height); - - if ((png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN) == 0 || - png_ptr->num_frames_written != 0) - png_write_fcTL(png_ptr, width, height, x_offset, y_offset, - delay_num, delay_den, dispose_op, blend_op); - - PNG_UNUSED(row_pointers) -} - -void PNGAPI -png_write_frame_tail(png_structp png_ptr, png_infop info_ptr) -{ - png_debug(1, "in png_write_frame_tail"); - - png_ptr->num_frames_written++; - - PNG_UNUSED(info_ptr) -} -#endif /* WRITE_APNG */ #endif /* WRITE */ diff --git a/media/libpng/pngwutil.c b/media/libpng/pngwutil.c --- a/media/libpng/pngwutil.c +++ b/media/libpng/pngwutil.c @@ -1,8 +1,8 @@ /* pngwutil.c - utilities to write a PNG file * - * Copyright (c) 2018-2024 Cosmin Truta + * Copyright (c) 2018-2025 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. @@ -351,14 +351,12 @@ if (owner == png_IDAT) { if ((png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY) != 0) strategy = png_ptr->zlib_strategy; -#ifdef PNG_WRITE_FILTER_SUPPORTED else if (png_ptr->do_filter != PNG_FILTER_NONE) strategy = PNG_Z_DEFAULT_STRATEGY; -#endif else strategy = PNG_Z_DEFAULT_NOFILTER_STRATEGY; } @@ -838,27 +836,18 @@ buf[12] = (png_byte)interlace_type; /* Write the chunk */ png_write_complete_chunk(png_ptr, png_IHDR, buf, 13); -#ifdef PNG_WRITE_APNG_SUPPORTED - png_ptr->first_frame_width = width; - png_ptr->first_frame_height = height; -#endif - if ((png_ptr->do_filter) == PNG_NO_FILTERS) { -#ifdef PNG_WRITE_FILTER_SUPPORTED if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE || png_ptr->bit_depth < 8) png_ptr->do_filter = PNG_FILTER_NONE; else png_ptr->do_filter = PNG_ALL_FILTERS; -#else - png_ptr->do_filter = PNG_FILTER_NONE; -#endif } png_ptr->mode = PNG_HAVE_IHDR; /* not READY_FOR_ZTXT */ } @@ -1029,21 +1018,11 @@ png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE) optimize_cmf(data, png_image_size(png_ptr)); #endif if (size > 0) -#ifdef PNG_WRITE_APNG_SUPPORTED - { - if (png_ptr->num_frames_written == 0) -#endif png_write_complete_chunk(png_ptr, png_IDAT, data, size); -#ifdef PNG_WRITE_APNG_SUPPORTED - else - png_write_fdAT(png_ptr, data, size); - } -#endif /* WRITE_APNG */ - png_ptr->mode |= PNG_HAVE_IDAT; png_ptr->zstream.next_out = data; png_ptr->zstream.avail_out = size; @@ -1086,21 +1065,11 @@ png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE) optimize_cmf(data, png_image_size(png_ptr)); #endif if (size > 0) -#ifdef PNG_WRITE_APNG_SUPPORTED - { - if (png_ptr->num_frames_written == 0) -#endif png_write_complete_chunk(png_ptr, png_IDAT, data, size); -#ifdef PNG_WRITE_APNG_SUPPORTED - else - png_write_fdAT(png_ptr, data, size); - } -#endif /* WRITE_APNG */ - png_ptr->zstream.avail_out = 0; png_ptr->zstream.next_out = NULL; png_ptr->mode |= PNG_HAVE_IDAT | PNG_AFTER_IDAT; png_ptr->zowner = 0; /* Release the stream */ @@ -1998,86 +1967,10 @@ png_write_complete_chunk(png_ptr, png_tIME, buf, 7); } #endif -#ifdef PNG_WRITE_APNG_SUPPORTED -void /* PRIVATE */ -png_write_acTL(png_structp png_ptr, - png_uint_32 num_frames, png_uint_32 num_plays) -{ - png_byte buf[8]; - - png_debug(1, "in png_write_acTL"); - - png_ptr->num_frames_to_write = num_frames; - - if ((png_ptr->apng_flags & PNG_FIRST_FRAME_HIDDEN) != 0) - num_frames--; - - png_save_uint_32(buf, num_frames); - png_save_uint_32(buf + 4, num_plays); - - png_write_complete_chunk(png_ptr, png_acTL, buf, (png_size_t)8); -} - -void /* PRIVATE */ -png_write_fcTL(png_structp png_ptr, png_uint_32 width, png_uint_32 height, - png_uint_32 x_offset, png_uint_32 y_offset, - png_uint_16 delay_num, png_uint_16 delay_den, png_byte dispose_op, - png_byte blend_op) -{ - png_byte buf[26]; - - png_debug(1, "in png_write_fcTL"); - - if (png_ptr->num_frames_written == 0 && (x_offset != 0 || y_offset != 0)) - png_error(png_ptr, "x and/or y offset for the first frame aren't 0"); - if (png_ptr->num_frames_written == 0 && - (width != png_ptr->first_frame_width || - height != png_ptr->first_frame_height)) - png_error(png_ptr, "width and/or height in the first frame's fcTL " - "don't match the ones in IHDR"); - - /* more error checking */ - png_ensure_fcTL_is_valid(png_ptr, width, height, x_offset, y_offset, - delay_num, delay_den, dispose_op, blend_op); - - png_save_uint_32(buf, png_ptr->next_seq_num); - png_save_uint_32(buf + 4, width); - png_save_uint_32(buf + 8, height); - png_save_uint_32(buf + 12, x_offset); - png_save_uint_32(buf + 16, y_offset); - png_save_uint_16(buf + 20, delay_num); - png_save_uint_16(buf + 22, delay_den); - buf[24] = dispose_op; - buf[25] = blend_op; - - png_write_complete_chunk(png_ptr, png_fcTL, buf, (png_size_t)26); - - png_ptr->next_seq_num++; -} - -void /* PRIVATE */ -png_write_fdAT(png_structp png_ptr, - png_const_bytep data, png_size_t length) -{ - png_byte buf[4]; - - png_write_chunk_header(png_ptr, png_fdAT, (png_uint_32)(4 + length)); - - png_save_uint_32(buf, png_ptr->next_seq_num); - png_write_chunk_data(png_ptr, buf, 4); - - png_write_chunk_data(png_ptr, data, length); - - png_write_chunk_end(png_ptr); - - png_ptr->next_seq_num++; -} -#endif /* WRITE_APNG */ - /* Initializes the row writing capability of libpng */ void /* PRIVATE */ png_write_start_row(png_structrp png_ptr) { png_alloc_size_t buf_size; @@ -2927,41 +2820,6 @@ { png_write_flush(png_ptr); } #endif /* WRITE_FLUSH */ } - -#ifdef PNG_WRITE_APNG_SUPPORTED -void /* PRIVATE */ -png_write_reset(png_structp png_ptr) -{ - png_ptr->row_number = 0; - png_ptr->pass = 0; - png_ptr->mode &= ~PNG_HAVE_IDAT; -} - -void /* PRIVATE */ -png_write_reinit(png_structp png_ptr, png_infop info_ptr, - png_uint_32 width, png_uint_32 height) -{ - if (png_ptr->num_frames_written == 0 && - (width != png_ptr->first_frame_width || - height != png_ptr->first_frame_height)) - png_error(png_ptr, "width and/or height in the first frame's fcTL " - "don't match the ones in IHDR"); - if (width > png_ptr->first_frame_width || - height > png_ptr->first_frame_height) - png_error(png_ptr, "width and/or height for a frame greater than " - "the ones in IHDR"); - - png_set_IHDR(png_ptr, info_ptr, width, height, - info_ptr->bit_depth, info_ptr->color_type, - info_ptr->interlace_type, info_ptr->compression_type, - info_ptr->filter_type); - - png_ptr->width = width; - png_ptr->height = height; - png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width); - png_ptr->usr_width = png_ptr->width; -} -#endif /* WRITE_APNG */ #endif /* WRITE */ diff --git a/media/libpng/powerpc/filter_vsx_intrinsics.c b/media/libpng/powerpc/filter_vsx_intrinsics.c --- a/media/libpng/powerpc/filter_vsx_intrinsics.c +++ b/media/libpng/powerpc/filter_vsx_intrinsics.c @@ -21,11 +21,11 @@ #include #if PNG_POWERPC_VSX_OPT > 0 #ifndef __VSX__ -# error "This code requires VSX support (POWER7 and later). Please provide -mvsx compiler flag." +# error This code requires VSX support (POWER7 and later); please compile with -mvsx #endif #define vec_ld_unaligned(vec,data) vec = vec_vsx_ld(0,data) #define vec_st_unaligned(vec,data) vec_vsx_st(vec,0,data) diff --git a/media/libpng/powerpc/powerpc_init.c b/media/libpng/powerpc/powerpc_init.c --- a/media/libpng/powerpc/powerpc_init.c +++ b/media/libpng/powerpc/powerpc_init.c @@ -44,11 +44,11 @@ #include /* for sig_atomic_t */ static int png_have_vsx(png_structp png_ptr); #include PNG_POWERPC_VSX_FILE #else /* PNG_POWERPC_VSX_FILE */ -# error "PNG_POWERPC_VSX_FILE undefined: no support for run-time POWERPC VSX checks" +# error PNG_POWERPC_VSX_FILE undefined: no support for run-time POWERPC VSX checks #endif /* PNG_POWERPC_VSX_FILE */ #endif /* PNG_POWERPC_VSX_CHECK_SUPPORTED */ void png_init_filter_functions_vsx(png_structp pp, unsigned int bpp)