diff --git a/Makefile.am b/Makefile.am index a06944090..9aea5a600 100644 --- a/Makefile.am +++ b/Makefile.am @@ -84,9 +84,12 @@ libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES = png.c pngerror.c\ pngset.c pngtrans.c pngwio.c pngwrite.c pngwtran.c pngwutil.c\ png.h pngconf.h pngdebug.h pnginfo.h pngpriv.h pngstruct.h pngusr.dfa -if PNG_ARM_NEON -libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES += arm/arm_init.c\ - arm/filter_neon.S arm/filter_neon_intrinsics.c +# Include libpng extensions, if appropriate. This uses a Makefile.am fragment, +# pre-set things that might be changed by addition: +AM_CPPFLAGS = +DFA_EXTENSION = +if LIBPNG_EXTENSIONS +include $(top_srcdir)/contrib/extensions.am endif nodist_libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES = pnglibconf.h @@ -244,17 +247,17 @@ endif rm -f $@ $*.tf[12] test -d scripts || mkdir scripts || test -d scripts $(DFNCPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES)\ - $(CPPFLAGS) $(SYMBOL_CFLAGS) $< > $*.tf1 + $(AM_CPPFLAGS) $(CPPFLAGS) $(SYMBOL_CFLAGS) $< > $*.tf1 $(AWK) -f "${srcdir}/scripts/dfn.awk" out="$*.tf2" $*.tf1 1>&2 rm -f $*.tf1 mv $*.tf2 $@ # The .c file for pnglibconf.h is machine generated -pnglibconf.c: scripts/pnglibconf.dfa scripts/options.awk pngconf.h pngusr.dfa $(DFA_XTRA) +pnglibconf.c: scripts/pnglibconf.dfa scripts/options.awk pngconf.h pngusr.dfa $(DFA_EXTENSION) $(DFA_XTRA) rm -f $@ $*.tf[45] $(AWK) -f ${srcdir}/scripts/options.awk out=$*.tf4 version=search\ ${srcdir}/pngconf.h ${srcdir}/scripts/pnglibconf.dfa\ - ${srcdir}/pngusr.dfa $(DFA_XTRA) 1>&2 + $(DFA_EXTENSION) ${srcdir}/pngusr.dfa $(DFA_XTRA) 1>&2 $(AWK) -f ${srcdir}/scripts/options.awk out=$*.tf5 $*.tf4 1>&2 rm $*.tf4 mv $*.tf5 $@ @@ -272,8 +275,8 @@ scripts/symbols.chk: scripts/checksym.awk scripts/symbols.def scripts/symbols.ou # be empty - no non-standard defines scripts/pnglibconf.c: scripts/pnglibconf.dfa scripts/options.awk pngconf.h rm -f $@ pnglibconf.tf[67] - test -z "$(CPPFLAGS)" - echo "com @PNGLIB_VERSION@ STANDARD API DEFINITION" |\ + test -z "$(CPPFLAGS)" -a -z "$(AM_CPPFLAGS)" + echo "com libpng @PNGLIB_VERSION@ STANDARD API DEFINITION" |\ $(AWK) -f ${srcdir}/scripts/options.awk out=pnglibconf.tf6\ logunsupported=1 version=search ${srcdir}/pngconf.h -\ ${srcdir}/scripts/pnglibconf.dfa 1>&2 diff --git a/configure.ac b/configure.ac index 525155b3b..bfa154f90 100644 --- a/configure.ac +++ b/configure.ac @@ -27,7 +27,8 @@ AC_CONFIG_MACRO_DIR([scripts]) # dist-xz requires automake 1.11 or later # 1.12.2 fixes a security issue in 1.11.2 and 1.12.1 # 1.13 is required for parallel tests -AM_INIT_AUTOMAKE([1.13 foreign dist-xz color-tests silent-rules subdir-objects]) +# 1.14.1 is required for %reldir% support +AM_INIT_AUTOMAKE([1.14.1 foreign dist-xz color-tests silent-rules subdir-objects]) # The following line causes --disable-maintainer-mode to be the default to # configure, this is necessary because libpng distributions cannot rely on the # time stamps of the autotools generated files being correct @@ -381,54 +382,11 @@ AC_ARG_ENABLE([unversioned-libpng-config], AM_CONDITIONAL([DO_INSTALL_LIBPNG_CONFIG], [test "$enable_unversioned_libpng_config" != "no"]) -# HOST SPECIFIC OPTIONS -# ===================== -# -# ARM -# === -# -# ARM NEON (SIMD) support. - -AC_ARG_ENABLE([arm-neon], - AS_HELP_STRING([[[--enable-arm-neon]]], - [Enable ARM NEON optimizations: =no/off, check, api, yes/on:] - [no/off: disable the optimizations; check: use internal checking code] - [(deprecated and poorly supported); api: disable by default, enable by] - [a call to png_set_option; yes/on: turn on unconditionally.] - [If not specified: determined by the compiler.]), - [case "$enableval" in - no|off) - # disable the default enabling on __ARM_NEON__ systems: - AC_DEFINE([PNG_ARM_NEON_OPT], [0], - [Disable ARM Neon optimizations]) - # Prevent inclusion of the assembler files below: - enable_arm_neon=no;; - check) - AC_DEFINE([PNG_ARM_NEON_CHECK_SUPPORTED], [], - [Check for ARM Neon support at run-time]);; - api) - AC_DEFINE([PNG_ARM_NEON_API_SUPPORTED], [], - [Turn on ARM Neon optimizations at run-time]);; - yes|on) - AC_DEFINE([PNG_ARM_NEON_OPT], [2], - [Enable ARM Neon optimizations]) - AC_MSG_WARN([--enable-arm-neon: please specify 'check' or 'api', if] - [you want the optimizations unconditionally pass -mfpu=neon] - [to the compiler.]);; - *) - AC_MSG_ERROR([--enable-arm-neon=${enable_arm_neon}: invalid value]) - esac]) - -# Add ARM specific files to all builds where the host_cpu is arm ('arm*') or -# where ARM optimizations were explicitly requested (this allows a fallback if a -# future host CPU does not match 'arm*') - -AM_CONDITIONAL([PNG_ARM_NEON], - [test "$enable_arm_neon" != 'no' && - case "$host_cpu" in - arm*|aarch64*) :;; - *) test "$enable_arm_neon" != '';; - esac]) +# EXTENSIONS +# Configure (and all other) support for extensions is included when autoconf is +# run by virtue of the existence (or not) of the following file: +sinclude([contrib/extensions.ac]) +AM_CONDITIONAL([LIBPNG_EXTENSIONS],[test -n "$libpng_automake_extensions"]) AC_MSG_NOTICE([[Extra options for compiler: $PNG_COPTS]]) diff --git a/contrib/extensions.ac b/contrib/extensions.ac new file mode 100644 index 000000000..f5725a6e0 --- /dev/null +++ b/contrib/extensions.ac @@ -0,0 +1,16 @@ +# CONTRIBUTED EXTENSIONS +# +# The following extensions are part of a standard libpng distribution. They are +# not supported parts of libpng and they are not necessarily released under the +# same license as libpng. Please consult the relevant directory for copyright +# and support information before uncommenting any of the lines below. +# +# After you change this file you MUST re-run "autoreconf" to regenerate the +# configure script, otherwise the change may have no effect. +# +# Include the ARM NEON extension: +#sinclude([contrib/neon/neon.ac]) +# +# If any of the extensions require automake support (this is likely) automake +# must include the file contrib/extensions.am +#libpng_automake_extensions="yes" diff --git a/contrib/extensions.am b/contrib/extensions.am new file mode 100644 index 000000000..ed7383c2b --- /dev/null +++ b/contrib/extensions.am @@ -0,0 +1,7 @@ +# CONTRIBUTED EXTENSIONS +# +# Please read the file "contrib/extensions.ac" before making changes to this +# file. +# +# Include the ARM NEON extension: +#include %reldir%/neon/neon.am diff --git a/contrib/neon/arm_init.c b/contrib/neon/arm_init.c index 79702c907..eee291bc8 100644 --- a/contrib/neon/arm_init.c +++ b/contrib/neon/arm_init.c @@ -14,7 +14,7 @@ */ #define _POSIX_SOURCE 1 -#include "../pngpriv.h" +#include "../../pngpriv.h" #define PNG_SRC_FILE PNG_SRC_FILE_arm_arm_init #ifdef PNG_READ_SUPPORTED diff --git a/contrib/neon/extensions.ac b/contrib/neon/extensions.ac new file mode 100644 index 000000000..d76151b45 --- /dev/null +++ b/contrib/neon/extensions.ac @@ -0,0 +1,10 @@ +# To just this extension either copy the 'sinclude' line and the setting of +# libpng_automake_extensions into contrib/extensions.am or link/copy the whole +# file there. Do the same with the associated file extensions.am +# +# Include the ARM NEON extension: +sinclude([contrib/neon/neon.ac]) +# +# If any of the extensions require automake support (this is likely) automake +# must include the file contrib/extensions.am +libpng_automake_extensions="yes" diff --git a/contrib/neon/extensions.am b/contrib/neon/extensions.am new file mode 100644 index 000000000..020db6dcc --- /dev/null +++ b/contrib/neon/extensions.am @@ -0,0 +1,5 @@ +# To just this extension either copy the 'include' line into +# contrib/extensions.am or link/copy the whole file there. Do the same with the +# associated file extensions.ac +# Include the ARM NEON extension: +include %reldir%/neon/neon.am diff --git a/contrib/neon/filter_neon.S b/contrib/neon/filter_neon.S index b7c0a90b4..f67f30e2f 100644 --- a/contrib/neon/filter_neon.S +++ b/contrib/neon/filter_neon.S @@ -14,7 +14,7 @@ * definitions (or not) of PNG_ARM_NEON_OPT and PNG_ARM_NEON_IMPLEMENTATION. */ #define PNG_VERSION_INFO_ONLY -#include "../pngpriv.h" +#include "../../pngpriv.h" #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits /* mark stack as non-executable */ diff --git a/contrib/neon/filter_neon_intrinsics.c b/contrib/neon/filter_neon_intrinsics.c index 843a1ab16..d6f6fef63 100644 --- a/contrib/neon/filter_neon_intrinsics.c +++ b/contrib/neon/filter_neon_intrinsics.c @@ -12,7 +12,7 @@ * and license in png.h */ -#include "../pngpriv.h" +#include "../../pngpriv.h" #define PNG_SRC_FILE PNG_SRC_FILE_arm_filter_neon_intrinsics #ifdef PNG_READ_SUPPORTED @@ -41,11 +41,11 @@ #if PNG_ARM_NEON_OPT > 0 void -png_read_filter_row_up_neon(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) +png_read_filter_row_up_neon(png_alloc_size_t rowbytes, unsigned int bpp, + png_bytep row, png_const_bytep prev_row) { png_bytep rp = row; - png_bytep rp_stop = row + row_info->rowbytes; + png_bytep rp_stop = row + rowbytes; png_const_bytep pp = prev_row; for (; rp < rp_stop; rp += 16, pp += 16) @@ -57,14 +57,15 @@ png_read_filter_row_up_neon(png_row_infop row_info, png_bytep row, qrp = vaddq_u8(qrp, qpp); vst1q_u8(rp, qrp); } + + PNG_UNUSED(bpp) } void -png_read_filter_row_sub3_neon(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) +png_read_filter_row_sub3_neon(png_alloc_size_t rowbytes, unsigned int bpp, png_bytep row, png_const_bytep prev_row) { png_bytep rp = row; - png_bytep rp_stop = row + row_info->rowbytes; + png_bytep rp_stop = row + rowbytes; uint8x16_t vtmp = vld1q_u8(rp); uint8x8x2_t *vrpt = png_ptr(uint8x8x2_t, &vtmp); @@ -101,15 +102,16 @@ png_read_filter_row_sub3_neon(png_row_infop row_info, png_bytep row, rp += 3; } + PNG_UNUSED(bpp) PNG_UNUSED(prev_row) } void -png_read_filter_row_sub4_neon(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) +png_read_filter_row_sub4_neon(png_alloc_size_t rowbytes, unsigned int bpp, + png_bytep row, png_const_bytep prev_row) { png_bytep rp = row; - png_bytep rp_stop = row + row_info->rowbytes; + png_bytep rp_stop = row + rowbytes; uint8x8x4_t vdest; vdest.val[3] = vdup_n_u8(0); @@ -128,16 +130,17 @@ png_read_filter_row_sub4_neon(png_row_infop row_info, png_bytep row, vst4_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2x4_t,&vdest), 0); } + PNG_UNUSED(bpp) PNG_UNUSED(prev_row) } void -png_read_filter_row_avg3_neon(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) +png_read_filter_row_avg3_neon(png_alloc_size_t rowbytes, unsigned int bpp, + png_bytep row, png_const_bytep prev_row) { png_bytep rp = row; png_const_bytep pp = prev_row; - png_bytep rp_stop = row + row_info->rowbytes; + png_bytep rp_stop = row + rowbytes; uint8x16_t vtmp; uint8x8x2_t *vrpt; @@ -195,14 +198,16 @@ png_read_filter_row_avg3_neon(png_row_infop row_info, png_bytep row, vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0); rp += 3; } + + PNG_UNUSED(bpp) } void -png_read_filter_row_avg4_neon(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) +png_read_filter_row_avg4_neon(png_alloc_size_t rowbytes, unsigned int bpp, + png_bytep row, png_const_bytep prev_row) { png_bytep rp = row; - png_bytep rp_stop = row + row_info->rowbytes; + png_bytep rp_stop = row + rowbytes; png_const_bytep pp = prev_row; uint8x8x4_t vdest; @@ -233,6 +238,8 @@ png_read_filter_row_avg4_neon(png_row_infop row_info, png_bytep row, vst4_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2x4_t,&vdest), 0); } + + PNG_UNUSED(bpp) } static uint8x8_t @@ -263,12 +270,12 @@ paeth(uint8x8_t a, uint8x8_t b, uint8x8_t c) } void -png_read_filter_row_paeth3_neon(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) +png_read_filter_row_paeth3_neon(png_alloc_size_t rowbytes, unsigned int bpp, + png_bytep row, png_const_bytep prev_row) { png_bytep rp = row; png_const_bytep pp = prev_row; - png_bytep rp_stop = row + row_info->rowbytes; + png_bytep rp_stop = row + rowbytes; uint8x16_t vtmp; uint8x8x2_t *vrpt; @@ -326,14 +333,16 @@ png_read_filter_row_paeth3_neon(png_row_infop row_info, png_bytep row, vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0); rp += 3; } + + PNG_UNUSED(bpp) } void -png_read_filter_row_paeth4_neon(png_row_infop row_info, png_bytep row, - png_const_bytep prev_row) +png_read_filter_row_paeth4_neon(png_alloc_size_t rowbytes, unsigned int bpp, + png_bytep row, png_const_bytep prev_row) { png_bytep rp = row; - png_bytep rp_stop = row + row_info->rowbytes; + png_bytep rp_stop = row + rowbytes; png_const_bytep pp = prev_row; uint8x8_t vlast = vdup_n_u8(0); @@ -367,8 +376,9 @@ png_read_filter_row_paeth4_neon(png_row_infop row_info, png_bytep row, vst4_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2x4_t,&vdest), 0); } -} + PNG_UNUSED(bpp) +} #endif /* PNG_ARM_NEON_OPT > 0 */ #endif /* PNG_ARM_NEON_IMPLEMENTATION == 1 (intrinsics) */ #endif /* READ */ diff --git a/contrib/neon/neon.ac b/contrib/neon/neon.ac new file mode 100644 index 000000000..04bd2af9b --- /dev/null +++ b/contrib/neon/neon.ac @@ -0,0 +1,47 @@ +# LIBPNG EXTENSION: NEON +# +# ARM NEON (SIMD) support. +# +# This file contains configure.ac additions to libpng configure to enable +# building of the ARM NEON filter optimizations. +# +AC_ARG_ENABLE([arm-neon], + AS_HELP_STRING([[[--enable-arm-neon]]], + [Enable ARM NEON optimizations: =no/off, check, api, yes/on:] + [no/off: disable the optimizations; check: use internal checking code] + [(deprecated and poorly supported); api: disable by default, enable by] + [a call to png_set_option; yes/on: turn on unconditionally.] + [If not specified: determined by the compiler.]), + [case "$enableval" in + no|off) + # disable the default enabling on __ARM_NEON__ systems: + AC_DEFINE([PNG_ARM_NEON_OPT], [0], + [Disable ARM Neon optimizations]) + # Prevent inclusion of the assembler files below: + enable_arm_neon=no;; + check) + AC_DEFINE([PNG_ARM_NEON_CHECK_SUPPORTED], [], + [Check for ARM Neon support at run-time]);; + api) + AC_DEFINE([PNG_ARM_NEON_API_SUPPORTED], [], + [Turn on ARM Neon optimizations at run-time]);; + yes|on) + AC_DEFINE([PNG_ARM_NEON_OPT], [2], + [Enable ARM Neon optimizations]) + AC_MSG_WARN([--enable-arm-neon: please specify 'check' or 'api', if] + [you want the optimizations unconditionally pass -mfpu=neon] + [to the compiler.]);; + *) + AC_MSG_ERROR([--enable-arm-neon=${enable_arm_neon}: invalid value]) + esac]) + +# Add ARM specific files to all builds where the host_cpu is arm ('arm*') or +# where ARM optimizations were explicitly requested (this allows a fallback if a +# future host CPU does not match 'arm*') + +AM_CONDITIONAL([PNG_ARM_NEON], + [test "$enable_arm_neon" != 'no' && + case "$host_cpu" in + arm*|aarch64*) :;; + *) test "$enable_arm_neon" != '';; + esac]) diff --git a/contrib/neon/neon.am b/contrib/neon/neon.am new file mode 100644 index 000000000..f20d59e4a --- /dev/null +++ b/contrib/neon/neon.am @@ -0,0 +1,27 @@ +# contrib/neon/neon.am +# +# This is an automake fragment included by the top-level Makefile.am if +# contrib/neon/neon.ac is included in configure +# +# It builds the source files in this directory into ARM hardware support for +# libpng. +# +if PNG_ARM_NEON +libpng@PNGLIB_MAJOR@@PNGLIB_MINOR@_la_SOURCES += %D%/arm_init.c\ + %D%/filter_neon.S %D%/filter_neon_intrinsics.c + +DFA_EXTENSION += ${srcdir}/%D%/neon.dfa + +# This causes pngpriv.h to include the named header. It is VERY important to +# understand that this MUST be defined and the header MUST define internal +# 'extern' functions with PNG_INTERNAL_FUNCTION. This allows vendors to use +# static library builds of libpng without clashing with the installed system +# libpng; see the libpng-prefix option in configure.ac The value of this +# #define is included in pnglibconf.h +# +# NOTE: you must include the double quotes in the value and you must therefore +# support the whole thing with single quotes. If you need to use <> for a +# header be aware that if you miss out the single quotes you will create a +# random file. +AM_CPPFLAGS += -DPNG_EXTENSION_HEADER='"%D%/neon.h"' +endif diff --git a/contrib/neon/neon.dfa b/contrib/neon/neon.dfa new file mode 100644 index 000000000..570f5f3ea --- /dev/null +++ b/contrib/neon/neon.dfa @@ -0,0 +1,41 @@ +# contrib/arm/neon.dfa +# +# This is a dfa fragment that is added to DFA_HARDWARE in Makefile.am and +# consequently is inserted after scripts/pnglibconf.dfa to define extra, +# hardware, options. +# +# The following are required in any fragment to record the copyright holder of +# the *changes* and the appropriate email for bug reports. Note that the +# copyright here is just for the specific configuration; additional files may +# have additional and/or different copyrights. +# +# Later settings (e.g. in user.dfa) will override these settings. +# +setting USER_PRIVATEBUILD default "John Bowler" +setting USER_BUG_REPORTS default "jbowler@acm.org" +# +# These options are specific to the ARM NEON hardware optimizations. At present +# these optimizations depend on GCC specific pre-processing of an assembler (.S) +# file so they probably won't work with other compilers. +# +# ARM_NEON_OPT: unset: check at compile time (__ARM_NEON__ must be defined by +# the compiler, typically as a result of specifying +# CC="gcc -mfpu=neon".) +# 0: disable (even if the CPU has a NEON FPU.) +# 1: check at run time (via ARM_NEON_{API,CHECK}) +# 2: switch on unconditionally (inadvisable - instead pass +# -mfpu=neon to GCC in CC) +# When building libpng avoid using any setting other than '0'; '1' is +# set automatically when either 'API' or 'CHECK' are configured in, +# '2' should not be necessary as -mfpu=neon will achieve the same +# effect as well as applying NEON optimizations to the rest of the +# libpng code. +# NOTE: any setting other than '0' requires ALIGNED_MEMORY +# ARM_NEON_API: (PNG_ARM_NEON == 1) allow the optimization to be switched on +# with png_set_option +# ARM_NEON_CHECK: (PNG_ARM_NEON == 1) compile a run-time check to see if Neon +# extensions are supported. This is poorly supported and +# deprecated - use the png_set_option API. +setting ARM_NEON_OPT +option ARM_NEON_API disabled enables SET_OPTION sets ARM_NEON_OPT 1 +option ARM_NEON_CHECK disabled sets ARM_NEON_OPT 1 diff --git a/contrib/neon/neon.h b/contrib/neon/neon.h new file mode 100644 index 000000000..2485cd9bf --- /dev/null +++ b/contrib/neon/neon.h @@ -0,0 +1,124 @@ +/* Compile time options. + * ===================== + * In a multi-arch build the compiler may compile the code several times for the + * same object module, producing different binaries for different architectures. + * When this happens configure-time setting of the target host options cannot be + * done. An example is iOS vs Android compilation of ARM NEON support. + * + * NOTE: symbol prefixing does not pass $(CFLAGS) to the preprocessor, because + * this is not possible with certain compilers (Oracle SUN OS CC), as a result + * it is necessary to ensure that all extern functions that *might* be used + * regardless of $(CFLAGS) get declared in this file. The test on __ARM_NEON + * below is one example of this behavior because it is controlled by the + * presence or not of -mfpu=neon on the GCC command line, it is possible to do + * this in $(CC), e.g. "CC=gcc -mfpu=neon", but people who build libpng rarely + * do this. + */ +#ifndef PNG_ARM_NEON_OPT + /* ARM NEON optimizations are being controlled by the compiler settings, + * typically the target FPU. If the FPU supports NEON instructions then the + * compiler will define __ARM_NEON and we can rely unconditionally on NEON + * instructions not crashing, otherwise we must disable use of NEON + * instructions. + * + * NOTE: at present these optimizations depend on 'ALIGNED_MEMORY', so they + * can only be turned on automatically if that is supported too. If + * PNG_ARM_NEON_OPT is set in CPPFLAGS (to >0) then arm/arm_init.c will fail + * to compile with an appropriate #error if ALIGNED_MEMORY has been turned + * off. + * + * Note that older versions of GCC defined __ARM_NEON__; this is no longer + * supported. Also 32-bit ARM versions of GCC required the NEON FPU mode to + * be turned on explicitly on the command line. If this is not done (on + * 32-bit ARM) NEON code will not be included. + * + * To disable ARM_NEON optimizations entirely, and skip compiling the + * associated assembler code, pass --enable-arm-neon=no to configure + * or put -DPNG_ARM_NEON_OPT=0 in CPPFLAGS. + */ +# if defined(__ARM_NEON) && defined(PNG_ALIGNED_MEMORY_SUPPORTED) +# define PNG_ARM_NEON_OPT 2 +# else +# define PNG_ARM_NEON_OPT 0 +# endif +#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 + + /* By default the 'intrinsics' code in arm/filter_neon_intrinsics.c is used + * if possible - if __ARM_NEON is set and the compiler version is not known + * to be broken. This is controlled by PNG_ARM_NEON_IMPLEMENTATION which can + * be: + * + * 1 The intrinsics code (the default with __ARM_NEON) + * 2 The hand coded assembler (the default without __ARM_NEON) + * + * It is possible to set PNG_ARM_NEON_IMPLEMENTATION in CPPFLAGS, however + * this is *NOT* supported and may cease to work even after a minor revision + * to libpng. It *is* valid to do this for testing purposes, e.g. speed + * testing or a new compiler, but the results should be communicated to the + * libpng implementation list for incorporation in the next minor release. + */ +# ifndef PNG_ARM_NEON_IMPLEMENTATION +# ifdef __ARM_NEON +# if defined(__clang__) + /* At present it is unknown by the libpng developers which versions + * of clang support the intrinsics, however some or perhaps all + * versions do not work with the assembler so this may be + * irrelevant, so just use the default (do nothing here.) + */ +# elif defined(__GNUC__) + /* GCC 4.5.4 NEON support is known to be broken. 4.6.3 is known to + * work, so if this *is* GCC, or G++, look for a version >4.5 + */ +# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 6) +# define PNG_ARM_NEON_IMPLEMENTATION 2 +# endif /* no GNUC support */ +# endif /* __GNUC__ */ +# else /* !defined __ARM_NEON */ + /* The 'intrinsics' code simply won't compile without compiler support + * and that support switches on __ARM_NEON, so use the assembler: + */ +# define PNG_ARM_NEON_IMPLEMENTATION 2 +# endif /* __ARM_NEON */ +# endif /* !defined PNG_ARM_NEON_IMPLEMENTATION */ + +# ifndef PNG_ARM_NEON_IMPLEMENTATION + /* Use the intrinsics code by default. */ +# define PNG_ARM_NEON_IMPLEMENTATION 1 +# endif +#endif /* PNG_ARM_NEON_OPT > 0 */ + +#ifdef PNG_SET_OPTION_SUPPORTED +#ifdef PNG_ARM_NEON_API_SUPPORTED +# define PNG_ARM_NEON 0 /* HARDWARE: ARM Neon SIMD instructions supported */ +#endif +#endif /* SET_OPTION */ + +#if PNG_ARM_NEON_OPT > 0 +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_neon, + (png_alloc_size_t row_bytes, unsigned int bpp, png_bytep row, + png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_neon, + (png_alloc_size_t row_bytes, unsigned int bpp, png_bytep row, + png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_neon, + (png_alloc_size_t row_bytes, unsigned int bpp, png_bytep row, + png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_neon, + (png_alloc_size_t row_bytes, unsigned int bpp, png_bytep row, + png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_neon, + (png_alloc_size_t row_bytes, unsigned int bpp, png_bytep row, + png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_neon, + (png_alloc_size_t row_bytes, unsigned int bpp, png_bytep row, + png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_neon, + (png_alloc_size_t row_bytes, unsigned int bpp, png_bytep row, + png_const_bytep prev_row),PNG_EMPTY); +#endif