libpng: Update to 1.6.51

This commit is contained in:
Jakub Marcowski
2025-06-30 11:59:44 +02:00
parent 9dd6c4dbac
commit 2b3501923f
14 changed files with 282 additions and 226 deletions

View File

@ -579,7 +579,7 @@ Files extracted from upstream source:
## libpng
- Upstream: http://libpng.org/pub/png/libpng.html
- Version: 1.6.48 (ea127968204cc5d10f3fc9250c306b9e8cbd9b80, 2025)
- Version: 1.6.51 (49363adcfaf098748d7a4c8c624ad8c45a8c3a86, 2025)
- License: libpng/zlib
Files extracted from upstream source:

View File

@ -13,7 +13,7 @@
#include "pngpriv.h"
/* Generate a compiler error if there is an old png.h in the search path. */
typedef png_libpng_version_1_6_48 Your_png_h_is_not_version_1_6_48;
typedef png_libpng_version_1_6_51 Your_png_h_is_not_version_1_6_51;
/* Sanity check the chunks definitions - PNG_KNOWN_CHUNKS from pngpriv.h and the
* corresponding macro definitions. This causes a compile time failure if
@ -108,7 +108,13 @@ png_zalloc,(voidpf png_ptr, uInt items, uInt size),PNG_ALLOCATED)
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()");
@ -238,10 +244,6 @@ png_user_version_check(png_structrp png_ptr, png_const_charp user_png_ver)
png_warning(png_ptr, m);
#endif
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
png_ptr->flags = 0;
#endif
return 0;
}
@ -815,7 +817,7 @@ png_get_copyright(png_const_structrp png_ptr)
return PNG_STRING_COPYRIGHT
#else
return PNG_STRING_NEWLINE \
"libpng version 1.6.48" PNG_STRING_NEWLINE \
"libpng version 1.6.51" 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 \

View File

@ -1,6 +1,6 @@
/* png.h - header file for PNG reference library
*
* libpng version 1.6.48
* libpng version 1.6.51
*
* Copyright (c) 2018-2025 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
@ -14,7 +14,7 @@
* 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.48, April 2025:
* libpng versions 1.6.36, December 2018, through 1.6.51, November 2025:
* Cosmin Truta
* See also "Contributing Authors", below.
*/
@ -238,7 +238,7 @@
* ...
* 1.5.30 15 10530 15.so.15.30[.0]
* ...
* 1.6.48 16 10648 16.so.16.48[.0]
* 1.6.51 16 10651 16.so.16.51[.0]
*
* Henceforth the source version will match the shared-library major and
* minor numbers; the shared-library major version number will be used for
@ -274,7 +274,7 @@
*/
/* Version information for png.h - this should match the version in png.c */
#define PNG_LIBPNG_VER_STRING "1.6.48"
#define PNG_LIBPNG_VER_STRING "1.6.51"
#define PNG_HEADER_VERSION_STRING " libpng version " PNG_LIBPNG_VER_STRING "\n"
/* The versions of shared library builds should stay in sync, going forward */
@ -285,7 +285,7 @@
/* 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 48
#define PNG_LIBPNG_VER_RELEASE 51
/* This should be zero for a public release, or non-zero for a
* development version.
@ -316,7 +316,7 @@
* From version 1.0.1 it is:
* XXYYZZ, where XX=major, YY=minor, ZZ=release
*/
#define PNG_LIBPNG_VER 10648 /* 1.6.48 */
#define PNG_LIBPNG_VER 10651 /* 1.6.51 */
/* Library configuration: these options cannot be changed after
* the library has been built.
@ -426,7 +426,7 @@ extern "C" {
/* 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_48;
typedef char* png_libpng_version_1_6_51;
/* Basic control structions. Read libpng-manual.txt or libpng.3 for more info.
*
@ -3303,26 +3303,45 @@ PNG_EXPORT(245, int, png_image_write_to_memory, (png_imagep image, void *memory,
* 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 */
#endif
#define PNG_MAXIMUM_INFLATE_WINDOW 2 /* SOFTWARE: force maximum window */
#define PNG_SKIP_sRGB_CHECK_PROFILE 4 /* SOFTWARE: Check ICC profile for sRGB */
#ifdef PNG_MIPS_MSA_API_SUPPORTED
# define PNG_MIPS_MSA 6 /* HARDWARE: MIPS Msa SIMD instructions supported */
#endif
#ifdef PNG_DISABLE_ADLER32_CHECK_SUPPORTED
# define PNG_IGNORE_ADLER32 8 /* SOFTWARE: disable Adler32 check on IDAT */
#endif
#ifdef PNG_POWERPC_VSX_API_SUPPORTED
# define PNG_POWERPC_VSX 10 /* HARDWARE: PowerPC VSX SIMD instructions
* supported */
#endif
#ifdef PNG_MIPS_MMI_API_SUPPORTED
# define PNG_MIPS_MMI 12 /* HARDWARE: MIPS MMI SIMD instructions supported */
# define PNG_ARM_NEON 0
#endif
#define PNG_OPTION_NEXT 14 /* Next option - numbers must be even */
/* 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
#endif
/* SOFTWARE: Disable Adler32 check on IDAT */
#ifdef PNG_DISABLE_ADLER32_CHECK_SUPPORTED
# define PNG_IGNORE_ADLER32 8
#endif
/* HARDWARE: PowerPC VSX SIMD instructions supported */
#ifdef PNG_POWERPC_VSX_API_SUPPORTED
# define PNG_POWERPC_VSX 10
#endif
/* HARDWARE: MIPS MMI SIMD instructions supported */
#ifdef PNG_MIPS_MMI_API_SUPPORTED
# define PNG_MIPS_MMI 12
#endif
/* 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 */

View File

@ -1,6 +1,6 @@
/* pngconf.h - machine-configurable file for libpng
*
* libpng version 1.6.48
* libpng version 1.6.51
*
* Copyright (c) 2018-2025 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson

View File

@ -38,9 +38,6 @@
#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

View File

@ -39,46 +39,6 @@ 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);
@ -216,21 +176,6 @@ 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);
@ -712,42 +657,9 @@ 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);
}
#else
PNG_UNUSED(error_message) /* Make compiler happy */
#endif
@ -785,40 +697,8 @@ 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);
}
#else
PNG_UNUSED(warning_message) /* Make compiler happy */
#endif
@ -866,12 +746,8 @@ png_get_error_ptr(png_const_structrp png_ptr)
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

View File

@ -1,6 +1,6 @@
/* pnglibconf.h - library build configuration */
/* libpng version 1.6.48 */
/* libpng version 1.6.51 */
/* Copyright (c) 2018-2025 Cosmin Truta */
/* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson */

View File

@ -229,6 +229,14 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
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)

View File

@ -143,6 +143,20 @@
# 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.
@ -288,6 +302,16 @@
# 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.
@ -686,7 +710,7 @@
/* #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 */
@ -1522,6 +1546,23 @@ 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);
@ -2134,6 +2175,11 @@ 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);

View File

@ -702,7 +702,12 @@ png_read_end(png_structrp png_ptr, png_inforp info_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);
@ -809,7 +814,8 @@ png_read_destroy(png_structrp png_ptr)
#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
@ -3123,6 +3129,54 @@ png_image_read_colormapped(png_voidp argument)
}
}
/* 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)
@ -3541,6 +3595,7 @@ png_image_read_direct(png_voidp argument)
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
@ -3674,8 +3729,16 @@ png_image_read_direct(png_voidp argument)
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;
}
@ -3951,6 +4014,24 @@ png_image_read_direct(png_voidp argument)
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;

View File

@ -28,6 +28,12 @@
# 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. */
@ -495,9 +501,19 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
{
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;
}
@ -509,15 +525,14 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
* Perhaps not the best solution, but good enough.
*/
int i;
png_bytep quantize_sort;
int i, j;
/* Initialize an array to sort colors */
png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr,
/* 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
@ -529,19 +544,18 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
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;
}
}
@ -553,18 +567,18 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
/* 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];
}
@ -572,7 +586,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
}
else
{
int j = num_palette;
j = num_palette;
/* Move all the used colors inside the max limit, and
* develop a translation table.
@ -580,13 +594,13 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
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];
@ -624,8 +638,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
}
}
}
png_free(png_ptr, png_ptr->quantize_sort);
png_ptr->quantize_sort = NULL;
png_free(png_ptr, quantize_sort);
}
else
{
@ -1768,21 +1781,53 @@ png_init_read_transformations(png_structrp png_ptr)
}
else /* if (png_ptr->trans_alpha[i] != 0xff) */
{
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);
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);
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);
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];
@ -5003,13 +5048,8 @@ png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info)
#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

View File

@ -2412,10 +2412,6 @@ png_handle_tEXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
}
#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)
@ -2486,10 +2482,6 @@ png_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
}
#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.
@ -2606,10 +2598,6 @@ png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
}
#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)

View File

@ -375,7 +375,8 @@ struct png_struct_def
/* 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
@ -404,7 +405,6 @@ struct png_struct_def
#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

View File

@ -2173,8 +2173,7 @@ png_image_write_main(png_voidp argument)
* 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)));