Compare commits

...

16 Commits

Author SHA1 Message Date
Cosmin Truta
7cecdcae07 Harden a vestigial check against overflow inside png_zalloc
Reported-by: Sergio Atienza Pastor, MTP Métodos y Tecnología
2025-07-03 22:42:11 +03:00
Cosmin Truta
cf59edd364 Bump version to 1.6.51.git 2025-07-02 20:24:24 +03:00
Cosmin Truta
2b978915d8 Release libpng version 1.6.50 2025-07-01 23:50:00 +03:00
Cosmin Truta
254a64ec30 doc: Update the man pages to the final PNG-3 specification
Also make editorial changes regarding the previous PNG specifications.
2025-07-01 22:57:36 +03:00
Cosmin Truta
9eb25bd899 chore: Rerun ./autogen.sh --maintainer 2025-06-30 23:46:32 +03:00
Cosmin Truta
8087a21d0a build: Fix the CMake file for cross-platform builds that require libm
Detect the availability of `libm` on the target platform.
Previously, `libm` was detected on the host platform only.

Also introduce the variable `PNG_LINK_LIBRARIES`.
Stop using `M_LIBRARY`, which was not namespace-clean.
2025-06-30 22:27:17 +03:00
John Bowler
2e5f296bfa fix: Prevent unknown chunks from causing out-of-place IEND errors
PNG_AFTER_IDAT was not set by the IDAT read code if unknown chunk
handling was turned on.  This was hidden in the current tests by checks
within the text handling chunks. (For example, pngtest.png has a zTXt
chunk after IDAT.)

This change modifies both the sequential and the progressive reader to
reliably set PNG_AFTER_IDAT when the first non-IDAT chunk is seen and
before that chunk is processed.

The change is minimalist; PNG_HAVE_CHUNK_AFTER_IDAT can probably be
removed and replaced with PNG_AFTER_IDAT.  Making the latter change is
something to be considered in libpng2.

Co-authored-by: Cosmin Truta <ctruta@gmail.com>
Signed-off-by: John Bowler <jbowler@acm.org>
Signed-off-by: Cosmin Truta <ctruta@gmail.com>
2025-06-30 16:27:22 +03:00
Filip Wasil
4266c75f40 riscv: Remove unused argument
Signed-off-by: Cosmin Truta <ctruta@gmail.com>
2025-06-28 16:19:11 +03:00
Filip Wasil
f451a4de09 riscv: Simplify the runtime check to always be present
Signed-off-by: Cosmin Truta <ctruta@gmail.com>
2025-06-28 16:19:11 +03:00
Filip Wasil
6aa47debba riscv: Do not overwrite -march when testing against SIMD availability
Signed-off-by: Cosmin Truta <ctruta@gmail.com>
2025-06-28 16:19:11 +03:00
Filip Wasil
3391bb98e3 riscv: Use C intrinsics
Signed-off-by: Cosmin Truta <ctruta@gmail.com>
2025-06-28 16:19:11 +03:00
Filip Wasil
21895b05ab riscv: Clearly separate the build flow for autotools and cmake
Signed-off-by: Cosmin Truta <ctruta@gmail.com>
2025-06-18 14:43:36 +03:00
Cosmin Truta
be81ebe1a4 chore: Rerun ./autogen.sh --maintainer 2025-06-17 11:41:32 +03:00
Filip Wasil
edf46621f3 riscv: Improve the RVV availability check
In some cases, the vector extension is not supported, although the
compiler allows the "v" flag in `-march` and includes `<riscv_vector>`
without raising an error.

Signed-off-by: Cosmin Truta <ctruta@gmail.com>
2025-06-17 11:40:57 +03:00
Cosmin Truta
5dc5937b30 chore: Update .gitignore
This is a cherry-pick of commit df3b9173277aae60b08a216dc23484f6ec171ef5
from branch 'libpng18'.
2025-06-14 18:35:46 +03:00
Cosmin Truta
7084241c75 Bump version to 1.6.50.git 2025-06-14 17:13:02 +03:00
33 changed files with 336 additions and 366 deletions

24
.gitignore vendored
View File

@ -122,6 +122,7 @@ ipch/
*.out
*out.png
[._]deps/
[._]libs/
.dirstamp
/Makefile
/autom4te.cache/
@ -143,13 +144,16 @@ pnglibconf.dfn
pnglibconf.pre
pngprefix.h
# Libpng test programs
png-fix-itxt
pngcp
pngfix
pngimage
pngstest
pngtest
pngunknown
pngvalid
timepng
# Libpng test programs, scripts and artifacts
/test-suite.log
/tests/*.log
/tests/*.trs
/png-fix-itxt
/pngcp
/pngfix
/pngimage
/pngstest
/pngtest
/pngunknown
/pngvalid
/timepng

View File

@ -1,5 +1,13 @@
libpng 1.6.49 - June 12, 2025
=============================
libpng 1.6.51.git
=================
This is a development version, not intended to be a public release.
It will be replaced by a public release, or by another development
version, at a later time.
libpng 1.6.50 - July 1, 2025
============================
This is a public release of libpng, intended for use in production code.
@ -9,13 +17,13 @@ Files available for download
Source files with LF line endings (for Unix/Linux):
* libpng-1.6.49.tar.xz (LZMA-compressed, recommended)
* libpng-1.6.49.tar.gz (deflate-compressed)
* libpng-1.6.50.tar.xz (LZMA-compressed, recommended)
* libpng-1.6.50.tar.gz (deflate-compressed)
Source files with CRLF line endings (for Windows):
* lpng1649.7z (LZMA-compressed, recommended)
* lpng1649.zip (deflate-compressed)
* lpng1650.7z (LZMA-compressed, recommended)
* lpng1650.zip (deflate-compressed)
Other information:
@ -25,13 +33,18 @@ Other information:
* TRADEMARK.md
Changes from version 1.6.48 to version 1.6.49
Changes from version 1.6.49 to version 1.6.50
---------------------------------------------
* 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.
* 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`.
Send comments/corrections/commendations to png-mng-implement at lists.sf.net.

13
CHANGES
View File

@ -6267,6 +6267,19 @@ Version 1.6.49 [June 12, 2025]
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 [TODO]
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

View File

@ -18,9 +18,9 @@ cmake_minimum_required(VERSION 3.14...4.0)
set(PNGLIB_MAJOR 1)
set(PNGLIB_MINOR 6)
set(PNGLIB_REVISION 49)
set(PNGLIB_SUBREVISION 0)
#set(PNGLIB_SUBREVISION "git")
set(PNGLIB_REVISION 51)
#set(PNGLIB_SUBREVISION 0)
set(PNGLIB_SUBREVISION "git")
set(PNGLIB_VERSION ${PNGLIB_MAJOR}.${PNGLIB_MINOR}.${PNGLIB_REVISION})
set(PNGLIB_ABI_VERSION ${PNGLIB_MAJOR}${PNGLIB_MINOR})
set(PNGLIB_SHARED_VERSION ${PNGLIB_ABI_VERSION}.${PNGLIB_REVISION}.${PNGLIB_SUBREVISION})
@ -30,6 +30,7 @@ project(libpng
LANGUAGES C ASM)
include(CheckCSourceCompiles)
include(CheckLibraryExists)
include(GNUInstallDirs)
# Allow the users to specify an application-specific API prefix for libpng
@ -138,19 +139,15 @@ endif()
# Find the zlib library.
find_package(ZLIB REQUIRED)
set(PNG_LINK_LIBRARIES ZLIB::ZLIB)
# Find the math library (where available).
if(UNIX
AND NOT (APPLE OR BEOS OR HAIKU)
AND NOT EMSCRIPTEN)
find_library(M_LIBRARY m)
if(M_LIBRARY)
set(M_LIBRARY m)
else()
set(M_LIBRARY "")
# Find the math library (unless we already know it's not available or
# not needed).
if(UNIX AND NOT (APPLE OR BEOS OR HAIKU OR EMSCRIPTEN))
check_library_exists(m pow "" PNG_HAVE_LIBM_POW)
endif()
else()
# libm is not available or not needed.
if(PNG_HAVE_LIBM_POW)
list(APPEND PNG_LINK_LIBRARIES m)
endif()
# Silence function deprecation warnings on the Windows compilers that might
@ -322,26 +319,40 @@ if(PNG_HARDWARE_OPTIMIZATIONS)
# Set definitions and sources for RISC-V.
if(PNG_TARGET_ARCHITECTURE MATCHES "^(riscv)")
include(CheckCCompilerFlag)
set(PNG_RISCV_RVV_POSSIBLE_VALUES check on off)
set(PNG_RISCV_RVV_POSSIBLE_VALUES on off)
set(PNG_RISCV_RVV "off"
CACHE STRING "Enable RISC-V Vector optimizations: check|on|off; off is default")
CACHE STRING "Enable RISC-V Vector optimizations: on|off; off is default")
set_property(CACHE PNG_RISCV_RVV
PROPERTY STRINGS ${PNG_RISCV_RVV_POSSIBLE_VALUES})
list(FIND PNG_RISCV_RVV_POSSIBLE_VALUES ${PNG_RISCV_RVV} index)
if(index EQUAL -1)
message(FATAL_ERROR "PNG_RISCV_RVV must be one of [${PNG_RISCV_RVV_POSSIBLE_VALUES}]")
elseif(NOT PNG_RISCV_RVV STREQUAL "off")
check_c_compiler_flag("-march=rv64gv1p0" COMPILER_SUPPORTS_RVV)
check_c_source_compiles("
#include <riscv_vector.h>
#include <asm/hwcap.h>
#ifndef COMPAT_HWCAP_ISA_V /* added in linux-6.5 */
#error \"COMPAT_HWCAP_ISA_V is not available\"
#endif
int main() {
const float src[] = { 0.0f, 0.0f, 0.0f, 0.0f };
uint64_t ptr[2] = {0x0908060504020100, 0xFFFFFFFF0E0D0C0A};
vuint8m1_t a = __riscv_vreinterpret_v_u64m1_u8m1(__riscv_vle64_v_u64m1(ptr, 2));
vfloat32m1_t val = __riscv_vle32_v_f32m1((const float*)(src), 4);
return (int)__riscv_vfmv_f_s_f32m1_f32(val);
}" COMPILER_SUPPORTS_RVV)
if(NOT COMPILER_SUPPORTS_RVV)
message(FATAL_ERROR "Compiler does not support -march=rv64gv1p0 option")
message(FATAL_ERROR "Compiler does not support RISC-V Vector extension or its unable to detect it")
endif()
set(libpng_riscv_sources
riscv/filter_rvv_intrinsics.c
riscv/riscv_init.c)
if(PNG_RISCV_RVV STREQUAL "on")
add_definitions(-DPNG_RISCV_RVV_OPT=2)
elseif(PNG_RISCV_RVV STREQUAL "check")
add_definitions(-DPNG_RISCV_RVV_CHECK_SUPPORTED)
else()
add_definitions(-DPNG_RISCV_RVV_OPT=0)
endif()
else()
add_definitions(-DPNG_RISCV_RVV_OPT=0)
@ -688,7 +699,7 @@ if(PNG_SHARED)
SYSTEM
INTERFACE "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/libpng${PNGLIB_ABI_VERSION}>")
target_link_libraries(png_shared
PUBLIC ZLIB::ZLIB ${M_LIBRARY})
PUBLIC ${PNG_LINK_LIBRARIES})
endif()
if(PNG_STATIC)
@ -706,7 +717,7 @@ if(PNG_STATIC)
SYSTEM
INTERFACE "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/libpng${PNGLIB_ABI_VERSION}>")
target_link_libraries(png_static
PUBLIC ZLIB::ZLIB ${M_LIBRARY})
PUBLIC ${PNG_LINK_LIBRARIES})
endif()
if(PNG_FRAMEWORK AND NOT APPLE)
@ -739,7 +750,7 @@ if(PNG_FRAMEWORK)
SYSTEM
INTERFACE "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/libpng${PNGLIB_ABI_VERSION}>")
target_link_libraries(png_framework
PUBLIC ZLIB::ZLIB ${M_LIBRARY})
PUBLIC ${PNG_LINK_LIBRARIES})
endif()
if(NOT PNG_LIBRARY_TARGETS)
@ -936,7 +947,7 @@ if(PNG_SHARED AND PNG_TOOLS)
add_executable(png-fix-itxt ${png_fix_itxt_sources})
target_link_libraries(png-fix-itxt
PRIVATE ZLIB::ZLIB ${M_LIBRARY})
PRIVATE ${PNG_LINK_LIBRARIES})
list(APPEND PNG_BIN_TARGETS png-fix-itxt)
endif()

View File

@ -1,4 +1,4 @@
# Makefile.in generated by automake 1.18 from Makefile.am.
# Makefile.in generated by automake 1.18.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2025 Free Software Foundation, Inc.

4
README
View File

@ -1,5 +1,5 @@
README for libpng version 1.6.49
================================
README for libpng version 1.6.51.git
====================================
See the note about version numbers near the top of `png.h`.
See `INSTALL` for instructions on how to install libpng.

6
aclocal.m4 vendored
View File

@ -1,4 +1,4 @@
# generated automatically by aclocal 1.18 -*- Autoconf -*-
# generated automatically by aclocal 1.18.1 -*- Autoconf -*-
# Copyright (C) 1996-2025 Free Software Foundation, Inc.
@ -35,7 +35,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION],
[am__api_version='1.18'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version. Point them to the right macro.
m4_if([$1], [1.18], [],
m4_if([$1], [1.18.1], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
])
@ -51,7 +51,7 @@ m4_define([_AM_AUTOCONF_VERSION], [])
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
[AM_AUTOMAKE_VERSION([1.18])dnl
[AM_AUTOMAKE_VERSION([1.18.1])dnl
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])

View File

@ -1,7 +1,7 @@
#! /bin/sh
# Wrapper for compilers which do not understand '-c -o'.
scriptversion=2025-02-03.05; # UTC
scriptversion=2025-06-18.21; # UTC
# Copyright (C) 1999-2025 Free Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
@ -358,7 +358,7 @@ exit $ret
# sh-indentation: 2
# eval: (add-hook 'before-save-hook 'time-stamp nil t)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-format: "%Y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

View File

@ -108,12 +108,6 @@
/* Enable POWERPC VSX optimizations */
#undef PNG_POWERPC_VSX_OPT
/* Turn on RISC-V Vector optimizations at run-time */
#undef PNG_RISCV_RVV_API_SUPPORTED
/* Check for RISC-V Vector support at run-time */
#undef PNG_RISCV_RVV_CHECK_SUPPORTED
/* Enable RISCV RVV optimizations */
#undef PNG_RISCV_RVV_OPT

63
configure vendored
View File

@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.72 for libpng 1.6.49.
# Generated by GNU Autoconf 2.72 for libpng 1.6.51.git.
#
# Report bugs to <png-mng-implement@lists.sourceforge.net>.
#
@ -614,8 +614,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='libpng'
PACKAGE_TARNAME='libpng'
PACKAGE_VERSION='1.6.49'
PACKAGE_STRING='libpng 1.6.49'
PACKAGE_VERSION='1.6.51.git'
PACKAGE_STRING='libpng 1.6.51.git'
PACKAGE_BUGREPORT='png-mng-implement@lists.sourceforge.net'
PACKAGE_URL=''
@ -1424,7 +1424,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
'configure' configures libpng 1.6.49 to adapt to many kinds of systems.
'configure' configures libpng 1.6.51.git to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1495,7 +1495,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of libpng 1.6.49:";;
short | recursive ) echo "Configuration of libpng 1.6.51.git:";;
esac
cat <<\_ACEOF
@ -1597,8 +1597,8 @@ Optional Features:
api, yes/on: no/off: disable the optimizations;
check: use internal checking code api: disable by
default, enable by a call to png_set_option yes/on:
turn on unconditionally. If not specified:
determined by the compiler.
turn on. If not specified: determined by the
compiler.
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
@ -1698,7 +1698,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
libpng configure 1.6.49
libpng configure 1.6.51.git
generated by GNU Autoconf 2.72
Copyright (C) 2023 Free Software Foundation, Inc.
@ -1961,7 +1961,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by libpng $as_me 1.6.49, which was
It was created by libpng $as_me 1.6.51.git, which was
generated by GNU Autoconf 2.72. Invocation command line was
$ $0$ac_configure_args_raw
@ -3446,7 +3446,7 @@ fi
# Define the identity of the package.
PACKAGE='libpng'
VERSION='1.6.49'
VERSION='1.6.51.git'
printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h
@ -3665,10 +3665,10 @@ fi
PNGLIB_VERSION=1.6.49
PNGLIB_VERSION=1.6.51.git
PNGLIB_MAJOR=1
PNGLIB_MINOR=6
PNGLIB_RELEASE=49
PNGLIB_RELEASE=51
@ -15716,28 +15716,14 @@ printf "%s\n" "#define PNG_RISCV_RVV_OPT 0" >>confdefs.h
# Prevent inclusion of the platform-specific files below:
enable_riscv_rvv=no ;;
check)
printf "%s\n" "#define PNG_RISCV_RVV_CHECK_SUPPORTED /**/" >>confdefs.h
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: --enable-riscv-rvv Please check contrib/riscv-rvv/README file
for the list of supported OSes." >&5
printf "%s\n" "$as_me: WARNING: --enable-riscv-rvv Please check contrib/riscv-rvv/README file
for the list of supported OSes." >&2;};;
api)
printf "%s\n" "#define PNG_RISCV_RVV_API_SUPPORTED /**/" >>confdefs.h
;;
yes|on)
printf "%s\n" "#define PNG_RISCV_RVV_OPT 2" >>confdefs.h
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: --enable-riscv-rvv: please specify 'check' or 'api', if
you want the optimizations unconditionally pass e.g. '-march=rv64gv'
to the compiler." >&5
printf "%s\n" "$as_me: WARNING: --enable-riscv-rvv: please specify 'check' or 'api', if
you want the optimizations unconditionally pass e.g. '-march=rv64gv'
to the compiler." >&2;};;
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: --enable-riscv-rvv:
if you want the optimizations pass e.g. '-march=rv64gv1p0' to the compiler." >&5
printf "%s\n" "$as_me: WARNING: --enable-riscv-rvv:
if you want the optimizations pass e.g. '-march=rv64gv1p0' to the compiler." >&2;};;
*)
as_fn_error $? "--enable-riscv-rvv=${enable_riscv_rvv}: invalid value" "$LINENO" 5
esac
@ -15754,14 +15740,20 @@ then
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to use RISC-V RVV intrinsics" >&5
printf %s "checking whether to use RISC-V RVV intrinsics... " >&6; }
save_CFLAGS=$CFLAGS
CFLAGS="$CFLAGS -march=rv64gv"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <riscv_vector.h>
#include <asm/hwcap.h>
#ifndef COMPAT_HWCAP_ISA_V /* added in linux-6.5 */
#error "COMPAT_HWCAP_ISA_V is not available"
#endif
int main() {
return 0;
const float src[] = { 0.0f, 0.0f, 0.0f, 0.0f };
uint64_t ptr[2] = {0x0908060504020100, 0xFFFFFFFF0E0D0C0A};
vuint8m1_t a = __riscv_vreinterpret_v_u64m1_u8m1(__riscv_vle64_v_u64m1(ptr, 2));
vfloat32m1_t val = __riscv_vle32_v_f32m1((const float*)(src), 4);
return (int)__riscv_vfmv_f_s_f32m1_f32(val);
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
@ -15779,7 +15771,6 @@ printf "%s\n" "#define PNG_RISCV_RVV_OPT 1" >>confdefs.h
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Compiler does not support riscv rvv." >&5
printf "%s\n" "$as_me: WARNING: Compiler does not support riscv rvv." >&2;}
fi
CFLAGS=$save_CFLAGS
fi
# Add RISC-V-specific files to all builds where $host_cpu is riscv ('riscv64')
@ -16419,7 +16410,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by libpng $as_me 1.6.49, which was
This file was extended by libpng $as_me 1.6.51.git, which was
generated by GNU Autoconf 2.72. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@ -16487,7 +16478,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config='$ac_cs_config_escaped'
ac_cs_version="\\
libpng config.status 1.6.49
libpng config.status 1.6.51.git
configured by $0, generated by GNU Autoconf 2.72,
with options \\"\$ac_cs_config\\"

View File

@ -25,7 +25,7 @@ AC_PREREQ([2.68])
dnl Version number stuff here:
AC_INIT([libpng],[1.6.49],[png-mng-implement@lists.sourceforge.net])
AC_INIT([libpng],[1.6.51.git],[png-mng-implement@lists.sourceforge.net])
AC_CONFIG_MACRO_DIR([scripts/autoconf])
# libpng does not follow GNU file name conventions (hence 'foreign')
@ -46,10 +46,10 @@ dnl automake, so the following is not necessary (and is not defined anyway):
dnl AM_PREREQ([1.11.2])
dnl stop configure from automagically running automake
PNGLIB_VERSION=1.6.49
PNGLIB_VERSION=1.6.51.git
PNGLIB_MAJOR=1
PNGLIB_MINOR=6
PNGLIB_RELEASE=49
PNGLIB_RELEASE=51
dnl End of version number stuff
@ -679,8 +679,7 @@ AS_HELP_STRING([[[--enable-riscv-rvv]]],
[Enable RISC-V Vector optimizations: =no/off, check, api, yes/on:]
[no/off: disable the optimizations; check: use internal checking code]
[api: disable by default, enable by a call to png_set_option]
[yes/on: turn on unconditionally.]
[If not specified: determined by the compiler.]),
[yes/on: turn on. If not specified: determined by the compiler.]),
[case "$enableval" in
no|off)
# disable the default enabling on __riscv systems:
@ -688,20 +687,11 @@ AS_HELP_STRING([[[--enable-riscv-rvv]]],
[Disable RISC-V Vector optimizations])
# Prevent inclusion of the platform-specific files below:
enable_riscv_rvv=no ;;
check)
AC_DEFINE([PNG_RISCV_RVV_CHECK_SUPPORTED], [],
[Check for RISC-V Vector support at run-time])
AC_MSG_WARN([--enable-riscv-rvv Please check contrib/riscv-rvv/README file]
[for the list of supported OSes.]);;
api)
AC_DEFINE([PNG_RISCV_RVV_API_SUPPORTED], [],
[Turn on RISC-V Vector optimizations at run-time]);;
yes|on)
AC_DEFINE([PNG_RISCV_RVV_OPT], [2],
[Enable RISC-V Vector optimizations])
AC_MSG_WARN([--enable-riscv-rvv: please specify 'check' or 'api', if]
[you want the optimizations unconditionally pass e.g. '-march=rv64gv']
[to the compiler.]);;
AC_MSG_WARN([--enable-riscv-rvv:]
[if you want the optimizations pass e.g. '-march=rv64gv1p0' to the compiler.]);;
*)
AC_MSG_ERROR([--enable-riscv-rvv=${enable_riscv_rvv}: invalid value])
esac])
@ -715,12 +705,18 @@ then
compiler_support_riscv_rvv=no
AC_MSG_CHECKING(whether to use RISC-V RVV intrinsics)
save_CFLAGS=$CFLAGS
CFLAGS="$CFLAGS -march=rv64gv"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
#include <riscv_vector.h>
#include <asm/hwcap.h>
#ifndef COMPAT_HWCAP_ISA_V /* added in linux-6.5 */
#error "COMPAT_HWCAP_ISA_V is not available"
#endif
int main() {
return 0;
const float src[] = { 0.0f, 0.0f, 0.0f, 0.0f };
uint64_t ptr[2] = {0x0908060504020100, 0xFFFFFFFF0E0D0C0A};
vuint8m1_t a = __riscv_vreinterpret_v_u64m1_u8m1(__riscv_vle64_v_u64m1(ptr, 2));
vfloat32m1_t val = __riscv_vle32_v_f32m1((const float*)(src), 4);
return (int)__riscv_vfmv_f_s_f32m1_f32(val);
}]])],compiler_support_riscv_rvv=yes)
AC_MSG_RESULT($compiler_support_riscv_rvv)
if test "$compiler_support_riscv_rvv" = "yes"; then
@ -729,7 +725,6 @@ int main(){
else
AC_MSG_WARN([Compiler does not support riscv rvv.])
fi
CFLAGS=$save_CFLAGS
fi
# Add RISC-V-specific files to all builds where $host_cpu is riscv ('riscv64')

View File

@ -25,7 +25,7 @@
#endif
static int
png_have_rvv(png_structp png_ptr) {
png_have_rvv() {
#if defined(__linux__)
return getauxval (AT_HWCAP) & COMPAT_HWCAP_ISA_V ? 1 : 0;
#else

View File

@ -1,7 +1,7 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2024-12-03.03; # UTC
scriptversion=2025-06-18.21; # UTC
# Copyright (C) 1999-2025 Free Software Foundation, Inc.
@ -786,7 +786,7 @@ exit 0
# sh-indentation: 2
# eval: (add-hook 'before-save-hook 'time-stamp nil t)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-format: "%Y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

View File

@ -1,7 +1,7 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2024-12-03.03; # UTC
scriptversion=2025-06-18.21; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
@ -535,7 +535,7 @@ done
# Local variables:
# eval: (add-hook 'before-save-hook 'time-stamp nil t)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-format: "%Y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

View File

@ -9,7 +9,7 @@ libpng-manual.txt - A description on how to use and modify libpng
Based on:
libpng version 1.6.36, December 2018, through 1.6.49 - June 2025
libpng version 1.6.36, December 2018, through 1.6.50 - July 2025
Updated and distributed by Cosmin Truta
Copyright (c) 2018-2025 Cosmin Truta
@ -65,18 +65,22 @@ 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
<https://www.w3.org/TR/2025/REC-png-3-20250624/>.
The PNG specification (Second Edition), November 2003, is available as
a W3C Recommendation and as an ISO Standard (ISO/IEC 15948:2004 (E)) at
<https://www.w3.org/TR/2003/REC-PNG-20031110/>.
The W3C and ISO documents have identical technical content.
The PNG-1.2 specification is available at
<https://png-mng.sourceforge.io/pub/png/spec/1.2/>.
It is technically equivalent
to the PNG specification (second edition) but has some additional material.
<https://www.libpng.org/pub/png/spec/1.2/>.
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
<https://png-mng.sourceforge.io/pub/png/spec/1.0/> and as a
<https://www.libpng.org/pub/png/spec/1.0/> and as a
W3C Recommendation at <https://www.w3.org/TR/REC-png-961001>.
Some additional chunks are described in the special-purpose public chunks

View File

@ -1,6 +1,6 @@
.TH LIBPNG 3 "June 12, 2025"
.TH LIBPNG 3 "July 1, 2025"
.SH NAME
libpng \- Portable Network Graphics (PNG) Reference Library 1.6.49
libpng \- Portable Network Graphics (PNG) Reference Library 1.6.50
.SH SYNOPSIS
\fB#include <png.h>\fP
@ -528,7 +528,7 @@ libpng-manual.txt - A description on how to use and modify libpng
Based on:
libpng version 1.6.36, December 2018, through 1.6.49 - June 2025
libpng version 1.6.36, December 2018, through 1.6.50 - July 2025
Updated and distributed by Cosmin Truta
Copyright (c) 2018-2025 Cosmin Truta
@ -584,18 +584,22 @@ 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
<https://www.w3.org/TR/2025/REC-png-3-20250624/>.
The PNG specification (Second Edition), November 2003, is available as
a W3C Recommendation and as an ISO Standard (ISO/IEC 15948:2004 (E)) at
<https://www.w3.org/TR/2003/REC-PNG-20031110/>.
The W3C and ISO documents have identical technical content.
The PNG-1.2 specification is available at
<https://png-mng.sourceforge.io/pub/png/spec/1.2/>.
It is technically equivalent
to the PNG specification (second edition) but has some additional material.
<https://www.libpng.org/pub/png/spec/1.2/>.
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
<https://png-mng.sourceforge.io/pub/png/spec/1.0/> and as a
<https://www.libpng.org/pub/png/spec/1.0/> and as a
W3C Recommendation at <https://www.w3.org/TR/REC-png-961001>.
Some additional chunks are described in the special-purpose public chunks

View File

@ -1,6 +1,6 @@
.TH LIBPNGPF 3 "June 12, 2025"
.TH LIBPNGPF 3 "July 1, 2025"
.SH NAME
libpng \- Portable Network Graphics (PNG) Reference Library 1.6.49
libpng \- Portable Network Graphics (PNG) Reference Library 1.6.50
.SH SYNOPSIS
\fB#include "pngpriv.h"\fP

View File

@ -1,7 +1,7 @@
#! /bin/sh
# Common wrapper for a few potentially missing GNU and other programs.
scriptversion=2024-12-03.03; # UTC
scriptversion=2025-06-18.21; # UTC
# shellcheck disable=SC2006,SC2268 # we must support pre-POSIX shells
@ -230,7 +230,7 @@ exit $st
# Local variables:
# eval: (add-hook 'before-save-hook 'time-stamp nil t)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-format: "%Y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

34
png.5
View File

@ -1,4 +1,4 @@
.TH PNG 5 "June 12, 2025"
.TH PNG 5 "July 1, 2025"
.SH NAME
png \- Portable Network Graphics (PNG) format
@ -20,20 +20,25 @@ matching on heterogeneous platforms.
.SH "SEE ALSO"
.BR "libpng"(3), " zlib"(3), " deflate"(5), " " and " zlib"(5)
.LP
PNG Specification (Third Edition) Proposed Recommendation, May 2025:
PNG Specification (Third Edition), June 2025:
.IP
.br
https://www.w3.org/TR/2025/PR-png-3-20250515/
https://www.w3.org/TR/2025/REC-png-3-20250624/
.LP
PNG Specification (Second Edition), November 2003:
.IP
.br
https://www.w3.org/TR/2003/REC-PNG-20031110/
.LP
PNG 1.2 Specification, July 1999:
PNG 1.2 Specification, August 1999:
.IP
.br
https://png-mng.sourceforge.io/pub/png/spec/1.2/
https://www.libpng.org/pub/png/spec/1.2/
.LP
PNG 1.1 Specification, December 1998:
.IP
.br
https://www.libpng.org/pub/png/spec/1.1/
.LP
PNG 1.0 Specification, October 1996:
.IP
@ -50,15 +55,24 @@ https://www.w3.org/TR/REC-png-961001
.SH AUTHORS
This man page: Glenn Randers-Pehrson, Cosmin Truta
.LP
Portable Network Graphics (PNG) Specification (Third Edition).
W3C Recommendation 24 June 2025:
Chris Blume et al.
.LP
Portable Network Graphics (PNG) Specification (Second Edition)
Information technology - Computer graphics and image processing -
Portable Network Graphics (PNG): Functional specification.
ISO/IEC 15948:2003 (E) (November 10, 2003): David Duce and others.
ISO/IEC 15948:2003 (E), W3C Recommendation 10 November 2003:
David Duce et al.
.LP
Portable Network Graphics (PNG) Specification Version 1.2 (July 8, 1999):
Glenn Randers-Pehrson and others.
Portable Network Graphics (PNG) Specification Version 1.2 (11 August 1999):
Glenn Randers-Pehrson et al.
.LP
Portable Network Graphics (PNG) Specification Version 1.0 (October 1, 1996):
Thomas Boutell and others.
Portable Network Graphics (PNG) Specification Version 1.1 (31 December 1998):
Glenn Randers-Pehrson et al.
.LP
Portable Network Graphics (PNG) Specification Version 1.0.
IETF RFC 2083, W3C Recommendation 1 October 1996:
Thomas Boutell et al.
.\" end of man page

12
png.c
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_49 Your_png_h_is_not_version_1_6_49;
typedef png_libpng_version_1_6_51_git Your_png_h_is_not_version_1_6_51_git;
/* 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()");
@ -815,7 +821,7 @@ png_get_copyright(png_const_structrp png_ptr)
return PNG_STRING_COPYRIGHT
#else
return PNG_STRING_NEWLINE \
"libpng version 1.6.49" PNG_STRING_NEWLINE \
"libpng version 1.6.51.git" 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 \

18
png.h
View File

@ -1,6 +1,6 @@
/* png.h - header file for PNG reference library
*
* libpng version 1.6.49
* libpng version 1.6.51.git
*
* 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.49, June 2025:
* libpng versions 1.6.36, December 2018, through 1.6.50, July 2025:
* Cosmin Truta
* See also "Contributing Authors", below.
*/
@ -238,7 +238,7 @@
* ...
* 1.5.30 15 10530 15.so.15.30[.0]
* ...
* 1.6.49 16 10649 16.so.16.49[.0]
* 1.6.50 16 10650 16.so.16.50[.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.49"
#define PNG_LIBPNG_VER_STRING "1.6.51.git"
#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,12 +285,12 @@
/* 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 49
#define PNG_LIBPNG_VER_RELEASE 51
/* This should be zero for a public release, or non-zero for a
* development version.
*/
#define PNG_LIBPNG_VER_BUILD 0
#define PNG_LIBPNG_VER_BUILD 1
/* Release Status */
#define PNG_LIBPNG_BUILD_ALPHA 1
@ -307,7 +307,7 @@
#define PNG_LIBPNG_BUILD_SPECIAL 32 /* Cannot be OR'ed with
PNG_LIBPNG_BUILD_PRIVATE */
#define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_STABLE
#define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_BETA
/* Careful here. At one time, Guy wanted to use 082, but that
* would be octal. We must not include leading zeros.
@ -316,7 +316,7 @@
* From version 1.0.1 it is:
* XXYYZZ, where XX=major, YY=minor, ZZ=release
*/
#define PNG_LIBPNG_VER 10649 /* 1.6.49 */
#define PNG_LIBPNG_VER 10651 /* 1.6.51.git */
/* 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_49;
typedef char* png_libpng_version_1_6_51_git;
/* Basic control structions. Read libpng-manual.txt or libpng.3 for more info.
*

View File

@ -1,6 +1,6 @@
/* pngconf.h - machine-configurable file for libpng
*
* libpng version 1.6.49
* libpng version 1.6.51.git
*
* Copyright (c) 2018-2025 Cosmin Truta
* Copyright (c) 1998-2002,2004,2006-2016,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

@ -154,12 +154,8 @@
* to configure or put -DPNG_RISCV_RVV_OPT=2 in CPPFLAGS.
*/
# if defined(__riscv) && defined(PNG_ALIGNED_MEMORY_SUPPORTED)
# define PNG_RISCV_RVV_OPT 1
# else
# define PNG_RISCV_RVV_OPT 0
#endif
#endif
#if PNG_ARM_NEON_OPT > 0
/* NEON optimizations are to be at least considered by libpng, so enable the

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);

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

@ -50,7 +50,7 @@
#define STDERR stdout
/* Generate a compiler error if there is an old png.h in the search path. */
typedef png_libpng_version_1_6_49 Your_png_h_is_not_version_1_6_49;
typedef png_libpng_version_1_6_51_git Your_png_h_is_not_version_1_6_51_git;
/* Ensure that all version numbers in png.h are consistent with one another. */
#if (PNG_LIBPNG_VER != PNG_LIBPNG_VER_MAJOR * 10000 + \

View File

@ -51,21 +51,22 @@ png_read_filter_row_sub_rvv(size_t len, size_t bpp, unsigned char* row)
* x .. [v8](e8)
*/
asm volatile ("vsetvli zero, %0, e8, m1" : : "r" (bpp));
size_t vl = __riscv_vsetvl_e8m1(bpp);
/* a = *row */
asm volatile ("vle8.v v0, (%0)" : : "r" (row));
vuint8m1_t a = __riscv_vle8_v_u8m1(row, vl);
row += bpp;
while (row < rp_end)
{
/* x = *row */
asm volatile ("vle8.v v8, (%0)" : : "r" (row));
vuint8m1_t x = __riscv_vle8_v_u8m1(row, vl);
/* a = a + x */
asm volatile ("vadd.vv v0, v0, v8");
a = __riscv_vadd_vv_u8m1(a, x, vl);
/* *row = a */
asm volatile ("vse8.v v0, (%0)" : : "r" (row));
__riscv_vse8_v_u8m1(row, a, vl);
row += bpp;
}
}
@ -110,44 +111,46 @@ png_read_filter_row_avg_rvv(size_t len, size_t bpp, unsigned char* row,
/* first pixel */
asm volatile ("vsetvli zero, %0, e8, m1" : : "r" (bpp));
size_t vl = __riscv_vsetvl_e8m1(bpp);
/* b = *prev_row */
asm volatile ("vle8.v v4, (%0)" : : "r" (prev_row));
vuint8m1_t b = __riscv_vle8_v_u8m1(prev_row, vl);
prev_row += bpp;
/* x = *row */
asm volatile ("vle8.v v8, (%0)" : : "r" (row));
vuint8m1_t x = __riscv_vle8_v_u8m1(row, vl);
/* b = b / 2 */
asm volatile ("vsrl.vi v4, v4, 1");
b = __riscv_vsrl_vx_u8m1(b, 1, vl);
/* a = x + b */
asm volatile ("vadd.vv v2, v4, v8");
vuint8m1_t a = __riscv_vadd_vv_u8m1(b, x, vl);
/* *row = a */
asm volatile ("vse8.v v2, (%0)" : : "r" (row));
__riscv_vse8_v_u8m1(row, a, vl);
row += bpp;
/* remaining pixels */
while (row < rp_end)
{
/* b = *prev_row */
asm volatile ("vle8.v v4, (%0)" : : "r" (prev_row));
b = __riscv_vle8_v_u8m1(prev_row, vl);
prev_row += bpp;
/* x = *row */
asm volatile ("vle8.v v8, (%0)" : : "r" (row));
x = __riscv_vle8_v_u8m1(row, vl);
/* tmp = a + b */
asm volatile ("vwaddu.vv v12, v2, v4"); /* add with widening */
vuint16m2_t tmp = __riscv_vwaddu_vv_u16m2(a, b, vl);
/* a = tmp/2 */
asm volatile ("vnsrl.wi v2, v12, 1"); /* divide/shift with narrowing */
a = __riscv_vnsrl_wx_u8m1(tmp, 1, vl);
/* a += x */
asm volatile ("vadd.vv v2, v2, v8");
a = __riscv_vadd_vv_u8m1(a, x, vl);
/* *row = a */
asm volatile ("vse8.v v2, (%0)" : : "r" (row));
__riscv_vse8_v_u8m1(row, a, vl);
row += bpp;
}
}
@ -205,18 +208,14 @@ static inline vint16m1_t
abs_diff(vuint16m1_t a, vuint16m1_t b, size_t vl)
{
vint16m1_t diff = __riscv_vreinterpret_v_u16m1_i16m1(__riscv_vsub_vv_u16m1(a, b, vl));
vint16m1_t neg = __riscv_vneg_v_i16m1(diff, vl);
return __riscv_vmax_vv_i16m1(diff, neg, vl);
vbool16_t mask = __riscv_vmslt_vx_i16m1_b16(diff, 0, vl);
return __riscv_vrsub_vx_i16m1_m(mask, diff, 0, vl);
}
static inline vint16m1_t
abs_sum(vint16m1_t a, vint16m1_t b, size_t vl)
{
vint16m1_t sum = __riscv_vadd_vv_i16m1(a, b, vl);
vint16m1_t neg = __riscv_vneg_v_i16m1(sum, vl);
return __riscv_vmax_vv_i16m1(sum, neg, vl);
return __riscv_vadd_vv_i16m1(a, b, vl);
}
static inline void
@ -229,119 +228,106 @@ png_read_filter_row_paeth_rvv(size_t len, size_t bpp, unsigned char* row,
* row: | a | x |
* prev: | c | b |
*
* mask .. [v0]
* a .. [v2](e8)
* b .. [v4](e8)
* c .. [v6](e8)
* x .. [v8](e8)
* p .. [v12-v13](e16)
* pa .. [v16-v17](e16)
* pb .. [v20-v21](e16)
* pc .. [v24-v25](e16)
* tmpmask ..[v31]
* pa, pb, pc .. [v16-v17, v20-v21, v24-v25](e16)
*/
/* first pixel */
asm volatile ("vsetvli zero, %0, e8, m1" : : "r" (bpp));
size_t vl = __riscv_vsetvl_e8m1(bpp);
/* a = *row + *prev_row */
asm volatile ("vle8.v v2, (%0)" : : "r" (row));
asm volatile ("vle8.v v6, (%0)" : : "r" (prev));
prev += bpp;
asm volatile ("vadd.vv v2, v2, v6");
/* a = *row */
vuint8m1_t a = __riscv_vle8_v_u8m1(row, vl);
/* c = *prev */
vuint8m1_t c = __riscv_vle8_v_u8m1(prev, vl);
/* a += c */
a = __riscv_vadd_vv_u8m1(a, c, vl);
/* *row = a */
asm volatile ("vse8.v v2, (%0)" : : "r" (row));
__riscv_vse8_v_u8m1(row, a, vl);
row += bpp;
prev += bpp;
/* remaining pixels */
while (row < rp_end)
{
/* b = *prev_row */
asm volatile ("vle8.v v4, (%0)" : : "r" (prev));
/* b = *prev */
vuint8m1_t b = __riscv_vle8_v_u8m1(prev, vl);
prev += bpp;
/* x = *row */
asm volatile ("vle8.v v8, (%0)" : : "r" (row));
vuint8m1_t x = __riscv_vle8_v_u8m1(row, vl);
/* sub (widening to 16bit) */
/* p = b - c */
asm volatile ("vwsubu.vv v12, v4, v6");
/* pc = a - c */
asm volatile ("vwsubu.vv v24, v2, v6");
/* Calculate p = b - c and pc = a - c using widening subtraction */
vuint16m2_t p_wide = __riscv_vwsubu_vv_u16m2(b, c, vl);
vuint16m2_t pc_wide = __riscv_vwsubu_vv_u16m2(a, c, vl);
/* switch to widened */
asm volatile ("vsetvli zero, %0, e16, m2" : : "r" (bpp));
/* Convert to signed for easier manipulation */
size_t vl16 = __riscv_vsetvl_e16m2(bpp);
vint16m2_t p = __riscv_vreinterpret_v_u16m2_i16m2(p_wide);
vint16m2_t pc = __riscv_vreinterpret_v_u16m2_i16m2(pc_wide);
/* pa = abs(p) -> pa = p < 0 ? -p : p */
asm volatile ("vmv.v.v v16, v12"); /* pa = p */
asm volatile ("vmslt.vx v0, v16, zero"); /* set mask[i] if pa[i] < 0 */
asm volatile ("vrsub.vx v16, v16, zero, v0.t"); /* invert negative values in pa; vd[i] = 0 - vs2[i] (if mask[i])
* could be replaced by vneg in rvv >= 1.0
*/
/* pa = |p| */
vbool8_t p_neg_mask = __riscv_vmslt_vx_i16m2_b8(p, 0, vl16);
vint16m2_t pa = __riscv_vrsub_vx_i16m2_m(p_neg_mask, p, 0, vl16);
/* pb = abs(p) -> pb = pc < 0 ? -pc : pc */
asm volatile ("vmv.v.v v20, v24"); /* pb = pc */
asm volatile ("vmslt.vx v0, v20, zero"); /* set mask[i] if pc[i] < 0 */
asm volatile ("vrsub.vx v20, v20, zero, v0.t"); /* invert negative values in pb; vd[i] = 0 - vs2[i] (if mask[i])
* could be replaced by vneg in rvv >= 1.0
*/
/* pb = |pc| */
vbool8_t pc_neg_mask = __riscv_vmslt_vx_i16m2_b8(pc, 0, vl16);
vint16m2_t pb = __riscv_vrsub_vx_i16m2_m(pc_neg_mask, pc, 0, vl16);
/* pc = abs(p + pc) -> pc = (p + pc) < 0 ? -(p + pc) : p + pc */
asm volatile ("vadd.vv v24, v24, v12"); /* pc = p + pc */
asm volatile ("vmslt.vx v0, v24, zero"); /* set mask[i] if pc[i] < 0 */
asm volatile ("vrsub.vx v24, v24, zero, v0.t"); /* invert negative values in pc; vd[i] = 0 - vs2[i] (if mask[i])
* could be replaced by vneg in rvv >= 1.0
*/
/* pc = |p + pc| */
vint16m2_t p_plus_pc = __riscv_vadd_vv_i16m2(p, pc, vl16);
vbool8_t p_plus_pc_neg_mask = __riscv_vmslt_vx_i16m2_b8(p_plus_pc, 0, vl16);
pc = __riscv_vrsub_vx_i16m2_m(p_plus_pc_neg_mask, p_plus_pc, 0, vl16);
/*
* if (pb < pa)
* {
* pa = pb;
* a = b;
* // see (*1)
* }
* The key insight is that we want the minimum of pa, pb, pc.
* - If pa <= pb and pa <= pc, use a
* - Else if pb <= pc, use b
* - Else use c
*/
asm volatile ("vmslt.vv v0, v20, v16"); /* set mask[i] if pb[i] < pa[i] */
asm volatile ("vmerge.vvm v16, v16, v20, v0"); /* pa[i] = pb[i] (if mask[i]) */
/*
* if (pc < pa)
* {
* a = c;
* // see (*2)
* }
*/
asm volatile ("vmslt.vv v31, v24, v16"); /* set tmpmask[i] if pc[i] < pa[i] */
/* Find which predictor to use based on minimum absolute difference */
vbool8_t pa_le_pb = __riscv_vmsle_vv_i16m2_b8(pa, pb, vl16);
vbool8_t pa_le_pc = __riscv_vmsle_vv_i16m2_b8(pa, pc, vl16);
vbool8_t pb_le_pc = __riscv_vmsle_vv_i16m2_b8(pb, pc, vl16);
/* switch to narrow */
asm volatile ("vsetvli zero, %0, e8, m1" : : "r" (bpp));
/* use_a = pa <= pb && pa <= pc */
vbool8_t use_a = __riscv_vmand_mm_b8(pa_le_pb, pa_le_pc, vl16);
/* (*1) */
asm volatile ("vmerge.vvm v2, v2, v4, v0"); /* a = b (if mask[i]) */
/* use_b = !use_a && pb <= pc */
vbool8_t not_use_a = __riscv_vmnot_m_b8(use_a, vl16);
vbool8_t use_b = __riscv_vmand_mm_b8(not_use_a, pb_le_pc, vl16);
/* (*2) */
asm volatile ("vmand.mm v0, v31, v31"); /* mask = tmpmask
* vmand works for rvv 0.7 up to 1.0
* could be replaced by vmcpy in 0.7.1/0.8.1
* or vmmv.m in 1.0
*/
asm volatile ("vmerge.vvm v2, v2, v6, v0"); /* a = c (if mask[i]) */
/* Switch back to e8m1 for final operations */
vl = __riscv_vsetvl_e8m1(bpp);
/* a += x */
asm volatile ("vadd.vv v2, v2, v8");
/* Start with a, then conditionally replace with b or c */
vuint8m1_t result = a;
result = __riscv_vmerge_vvm_u8m1(result, b, use_b, vl);
/* use_c = !use_a && !use_b */
vbool8_t use_c = __riscv_vmnand_mm_b8(__riscv_vmor_mm_b8(use_a, use_b, vl), __riscv_vmor_mm_b8(use_a, use_b, vl), vl);
result = __riscv_vmerge_vvm_u8m1(result, c, use_c, vl);
/* a = result + x */
a = __riscv_vadd_vv_u8m1(result, x, vl);
/* *row = a */
asm volatile ("vse8.v v2, (%0)" : : "r" (row));
__riscv_vse8_v_u8m1(row, a, vl);
row += bpp;
/* prepare next iteration (prev is already in a) */
/* c = b */
asm volatile ("vmv.v.v v6, v4");
/* c = b for next iteration */
c = b;
}
}
void
png_read_filter_row_paeth3_rvv(png_row_infop row_info, png_bytep row,
png_const_bytep prev_row)
@ -349,8 +335,6 @@ png_read_filter_row_paeth3_rvv(png_row_infop row_info, png_bytep row,
size_t len = row_info->rowbytes;
png_read_filter_row_paeth_rvv(len, 3, row, prev_row);
PNG_UNUSED(prev_row)
}
void
@ -360,9 +344,7 @@ png_read_filter_row_paeth4_rvv(png_row_infop row_info, png_bytep row,
size_t len = row_info->rowbytes;
png_read_filter_row_paeth_rvv(len, 4, row, prev_row);
PNG_UNUSED(prev_row)
}
#endif /* PNG_RISCV_RVV_IMPLEMENTATION */
#endif /* READ */
#endif /* PNG_RISCV_RVV_IMPLEMENTATION == 1 */
#endif /* PNG_READ_SUPPORTED */

View File

@ -16,20 +16,6 @@
#include <riscv_vector.h>
#ifdef PNG_RISCV_RVV_CHECK_SUPPORTED /* Do run-time checks */
/* WARNING: it is strongly recommended that you do not build libpng with
* run-time checks for CPU features if at all possible. In the case of the
* RISC-V Vector instructions there is no processor-specific way of detecting
* the presence of the required support, therefore run-time detection is
* extremely OS specific.
*
* You may set the macro PNG_RISCV_RVV_FILE to the file name of file containing
* a fragment of C source code which defines the png_have_rvv function. There
* are a number of implementations in contrib/riscv-rvv, but the only one that
* has partial support is contrib/riscv-rvv/linux.c - a generic Linux
* implementation which reads /proc/cpuinfo.
*/
#include <signal.h>
#ifndef PNG_RISCV_RVV_FILE
@ -40,11 +26,10 @@
# endif
#endif
static int png_have_rvv(png_structp png_ptr);
static int png_have_rvv();
#ifdef PNG_RISCV_RVV_FILE
# include PNG_RISCV_RVV_FILE
#endif
#endif /* PNG_RISCV_RVV_CHECK_SUPPORTED */
#ifndef PNG_ALIGNED_MEMORY_SUPPORTED
# error "ALIGNED_MEMORY is required; set: -DPNG_ALIGNED_MEMORY_SUPPORTED"
@ -53,59 +38,16 @@ static int png_have_rvv(png_structp png_ptr);
void
png_init_filter_functions_rvv(png_structp pp, unsigned int bpp)
{
/* The switch statement is compiled in for RISCV_RVV_API, the call to
* png_have_rvv is compiled in for RISCV_RVV_CHECK. If both are
* defined the check is only performed if the API has not set the VECTOR
* option on or off explicitly. In this case the check controls what
* happens.
*/
png_debug(1, "in png_init_filter_functions_rvv");
#ifdef PNG_RISCV_RVV_API_SUPPORTED
switch ((pp->options >> PNG_RISCV_RVV) & 3)
{
case PNG_OPTION_UNSET:
/* Allow the run-time check to execute if it has been enabled -
* thus both API and CHECK can be turned on. If it isn't supported
* this case will fall through to the 'default' below, which just
* returns.
*/
#endif /* PNG_RISCV_RVV_API_SUPPORTED */
#ifdef PNG_RISCV_RVV_CHECK_SUPPORTED
{
static volatile sig_atomic_t no_rvv = -1; /* not checked */
if (no_rvv < 0)
no_rvv = !png_have_rvv(pp);
no_rvv = !png_have_rvv();
if (no_rvv)
return;
}
#ifdef PNG_RISCV_RVV_API_SUPPORTED
break;
#endif
#endif /* PNG_RISCV_RVV_CHECK_SUPPORTED */
#ifdef PNG_RISCV_RVV_API_SUPPORTED
default: /* OFF or INVALID */
return;
case PNG_OPTION_ON:
/* Option turned on */
break;
}
#endif /* PNG_RISCV_RVV_API_SUPPORTED */
/* IMPORTANT: any new external functions used here must be declared using
* PNG_INTERNAL_FUNCTION in ../pngpriv.h. This is required so that the
* 'prefix' option to configure works:
*
* ./configure --with-libpng-prefix=foobar_
*
* Verify you have got this right by running the above command, doing a build
* and examining pngprefix.h; it must contain a #define for every external
* function you add. (Notice that this happens automatically for the
* initialization function.)
*/
pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up_rvv;
if (bpp == 3)

View File

@ -11,7 +11,7 @@
# Modeled after libxml-config.
version=1.6.49
version=1.6.51.git
prefix=""
libdir=""
libs=""

View File

@ -5,6 +5,6 @@ includedir=@includedir@/libpng16
Name: libpng
Description: Loads and saves PNG files
Version: 1.6.49
Version: 1.6.51.git
Libs: -L${libdir} -lpng16
Cflags: -I${includedir}

View File

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

View File

@ -1,7 +1,7 @@
#! /bin/sh
# test-driver - basic testsuite driver script.
scriptversion=2024-12-03.03; # UTC
scriptversion=2025-06-18.21; # UTC
# Copyright (C) 2011-2025 Free Software Foundation, Inc.
#
@ -154,7 +154,7 @@ echo ":copy-in-global-log: $gcopy" >> $trs_file
# sh-indentation: 2
# eval: (add-hook 'before-save-hook 'time-stamp nil t)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-format: "%Y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End: