mirror of
https://github.com/izzy2lost/dolphin.git
synced 2026-06-19 01:16:48 -07:00
replace libpng with libspng
This commit is contained in:
+1
-15
@@ -53,7 +53,6 @@ if(NOT ANDROID)
|
||||
endif()
|
||||
|
||||
option(USE_SHARED_ENET "Use shared libenet if found rather than Dolphin's soon-to-compatibly-diverge version" OFF)
|
||||
option(USE_SHARED_LIBPNG "Use shared libpng if found" ON)
|
||||
option(USE_UPNP "Enables UPnP port mapping support" ON)
|
||||
option(ENABLE_NOGUI "Enable NoGUI frontend" ON)
|
||||
option(ENABLE_QT "Enable Qt (Default)" ON)
|
||||
@@ -411,9 +410,6 @@ if(CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||
find_library(IOB_LIBRARY IOBluetooth)
|
||||
find_library(IOK_LIBRARY IOKit)
|
||||
find_library(OPENGL_LIBRARY OpenGL)
|
||||
|
||||
# We don't want to use shared libpng.
|
||||
set(USE_SHARED_LIBPNG OFF)
|
||||
endif()
|
||||
|
||||
if(ENABLE_LTO)
|
||||
@@ -810,17 +806,7 @@ else()
|
||||
set(LZO lzo2)
|
||||
endif()
|
||||
|
||||
if(USE_SHARED_LIBPNG)
|
||||
check_lib(PNG libpng png png.h QUIET)
|
||||
endif()
|
||||
if (PNG_FOUND)
|
||||
message(STATUS "Using shared libpng")
|
||||
else()
|
||||
check_vendoring_approved(libpng)
|
||||
message(STATUS "Using static libpng from Externals")
|
||||
add_subdirectory(Externals/libpng)
|
||||
set(PNG png)
|
||||
endif()
|
||||
add_subdirectory(Externals/libspng)
|
||||
|
||||
# Using static FreeSurround from Externals
|
||||
# There is no system FreeSurround library.
|
||||
|
||||
+2
-2
@@ -52,8 +52,8 @@
|
||||
<ProjectReference Include="$(ExternalsDir)liblzma\liblzma.vcxproj">
|
||||
<Project>{055a775f-b4f5-4970-9240-f6cf7661f37b}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(ExternalsDir)libpng\png\png.vcxproj">
|
||||
<Project>{4c9f135b-a85e-430c-bad4-4c67ef5fc12c}</Project>
|
||||
<ProjectReference Include="$(ExternalsDir)libspng\spng.vcxproj">
|
||||
<Project>{447B7B1E-1D74-4AEF-B2B9-6EB41C5D5313}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(ExternalsDir)libusb\libusb-1.0.vcxproj">
|
||||
<Project>{349ee8f9-7d25-4909-aaf5-ff3fade72187}</Project>
|
||||
|
||||
Vendored
-204
@@ -1,204 +0,0 @@
|
||||
# selectively extracted and adapted from the libpng CMakeLists.txt, which has the following copyright notice:
|
||||
|
||||
|
||||
# Copyright (C) 2018 Cosmin Truta
|
||||
# Copyright (C) 2007,2009-2018 Glenn Randers-Pehrson
|
||||
# Written by Christian Ehrlicher, 2007
|
||||
# Revised by Roger Lowman, 2009-2010
|
||||
# Revised by Clifford Yapp, 2011-2012,2017
|
||||
# Revised by Roger Leigh, 2016
|
||||
# Revised by Andreas Franek, 2016
|
||||
# Revised by Sam Serrels, 2017
|
||||
# Revised by Vadim Barkov, 2017
|
||||
# Revised by Vicky Pfau, 2018
|
||||
# Revised by Cameron Cawley, 2018
|
||||
# Revised by Cosmin Truta, 2018
|
||||
# Revised by Kyle Bentley, 2018
|
||||
|
||||
# This code is released under the libpng license.
|
||||
# For conditions of distribution and use, see the disclaimer
|
||||
# and license in png.h
|
||||
|
||||
|
||||
|
||||
add_library(png STATIC
|
||||
png.c
|
||||
pngerror.c
|
||||
pngget.c
|
||||
pngmem.c
|
||||
pngpread.c
|
||||
pngread.c
|
||||
pngrio.c
|
||||
pngrtran.c
|
||||
pngrutil.c
|
||||
pngset.c
|
||||
pngtrans.c
|
||||
pngwio.c
|
||||
pngwrite.c
|
||||
pngwtran.c
|
||||
pngwutil.c
|
||||
)
|
||||
|
||||
dolphin_disable_warnings_msvc(png)
|
||||
|
||||
option(PNG_HARDWARE_OPTIMIZATIONS "Enable hardware optimizations for libpng" OFF)
|
||||
|
||||
if(PNG_HARDWARE_OPTIMIZATIONS)
|
||||
|
||||
message(STATUS "CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}")
|
||||
|
||||
# set definitions and sources for arm
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm" OR
|
||||
CMAKE_SYSTEM_PROCESSOR MATCHES "^aarch64")
|
||||
set(PNG_ARM_NEON_POSSIBLE_VALUES check on off)
|
||||
set(PNG_ARM_NEON "check" CACHE STRING "Enable ARM NEON optimizations:
|
||||
check: (default) use internal checking code;
|
||||
off: disable the optimizations;
|
||||
on: turn on unconditionally.")
|
||||
set_property(CACHE PNG_ARM_NEON PROPERTY STRINGS
|
||||
${PNG_ARM_NEON_POSSIBLE_VALUES})
|
||||
list(FIND PNG_ARM_NEON_POSSIBLE_VALUES ${PNG_ARM_NEON} index)
|
||||
if(index EQUAL -1)
|
||||
message(FATAL_ERROR
|
||||
"PNG_ARM_NEON must be one of [${PNG_ARM_NEON_POSSIBLE_VALUES}]")
|
||||
elseif(NOT ${PNG_ARM_NEON} STREQUAL "off")
|
||||
target_sources(png PRIVATE
|
||||
arm/arm_init.c
|
||||
arm/filter_neon.S
|
||||
arm/filter_neon_intrinsics.c
|
||||
arm/palette_neon_intrinsics.c)
|
||||
|
||||
if(${PNG_ARM_NEON} STREQUAL "on")
|
||||
target_compile_definitions(png PUBLIC -DPNG_ARM_NEON_OPT=2)
|
||||
elseif(${PNG_ARM_NEON} STREQUAL "check")
|
||||
target_compile_definitions(png PUBLIC -DPNG_ARM_NEON_CHECK_SUPPORTED)
|
||||
endif()
|
||||
else()
|
||||
target_compile_definitions(png PUBLIC -DPNG_ARM_NEON_OPT=0)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# set definitions and sources for powerpc
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^powerpc*" OR
|
||||
CMAKE_SYSTEM_PROCESSOR MATCHES "^ppc64*")
|
||||
set(PNG_POWERPC_VSX_POSSIBLE_VALUES on off)
|
||||
set(PNG_POWERPC_VSX "on" CACHE STRING "Enable POWERPC VSX optimizations:
|
||||
off: disable the optimizations.")
|
||||
set_property(CACHE PNG_POWERPC_VSX PROPERTY STRINGS
|
||||
${PNG_POWERPC_VSX_POSSIBLE_VALUES})
|
||||
list(FIND PNG_POWERPC_VSX_POSSIBLE_VALUES ${PNG_POWERPC_VSX} index)
|
||||
if(index EQUAL -1)
|
||||
message(FATAL_ERROR
|
||||
"PNG_POWERPC_VSX must be one of [${PNG_POWERPC_VSX_POSSIBLE_VALUES}]")
|
||||
elseif(NOT ${PNG_POWERPC_VSX} STREQUAL "off")
|
||||
target_sources(png PRIVATE
|
||||
powerpc/powerpc_init.c
|
||||
powerpc/filter_vsx_intrinsics.c)
|
||||
if(${PNG_POWERPC_VSX} STREQUAL "on")
|
||||
target_compile_definitions(png PUBLIC -DPNG_POWERPC_VSX_OPT=2)
|
||||
endif()
|
||||
else()
|
||||
target_compile_definitions(png PUBLIC -DPNG_POWERPC_VSX_OPT=0)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# set definitions and sources for intel
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^i?86" OR
|
||||
CMAKE_SYSTEM_PROCESSOR MATCHES "^x86_64*")
|
||||
set(PNG_INTEL_SSE_POSSIBLE_VALUES on off)
|
||||
set(PNG_INTEL_SSE "on" CACHE STRING "Enable INTEL_SSE optimizations:
|
||||
off: disable the optimizations")
|
||||
set_property(CACHE PNG_INTEL_SSE PROPERTY STRINGS
|
||||
${PNG_INTEL_SSE_POSSIBLE_VALUES})
|
||||
list(FIND PNG_INTEL_SSE_POSSIBLE_VALUES ${PNG_INTEL_SSE} index)
|
||||
if(index EQUAL -1)
|
||||
message(FATAL_ERROR
|
||||
"PNG_INTEL_SSE must be one of [${PNG_INTEL_SSE_POSSIBLE_VALUES}]")
|
||||
elseif(NOT ${PNG_INTEL_SSE} STREQUAL "off")
|
||||
target_sources(png PRIVATE
|
||||
intel/intel_init.c
|
||||
intel/filter_sse2_intrinsics.c)
|
||||
if(${PNG_INTEL_SSE} STREQUAL "on")
|
||||
target_compile_definitions(png PUBLIC -DPNG_INTEL_SSE_OPT=1)
|
||||
endif()
|
||||
else()
|
||||
target_compile_definitions(png PUBLIC -DPNG_INTEL_SSE_OPT=0)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# set definitions and sources for MIPS
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "mipsel*" OR
|
||||
CMAKE_SYSTEM_PROCESSOR MATCHES "mips64el*")
|
||||
set(PNG_MIPS_MSA_POSSIBLE_VALUES on off)
|
||||
set(PNG_MIPS_MSA "on" CACHE STRING "Enable MIPS_MSA optimizations:
|
||||
off: disable the optimizations")
|
||||
set_property(CACHE PNG_MIPS_MSA PROPERTY STRINGS
|
||||
${PNG_MIPS_MSA_POSSIBLE_VALUES})
|
||||
list(FIND PNG_MIPS_MSA_POSSIBLE_VALUES ${PNG_MIPS_MSA} index)
|
||||
if(index EQUAL -1)
|
||||
message(FATAL_ERROR
|
||||
"PNG_MIPS_MSA must be one of [${PNG_MIPS_MSA_POSSIBLE_VALUES}]")
|
||||
elseif(NOT ${PNG_MIPS_MSA} STREQUAL "off")
|
||||
target_sources(png PRIVATE
|
||||
mips/mips_init.c
|
||||
mips/filter_msa_intrinsics.c)
|
||||
if(${PNG_MIPS_MSA} STREQUAL "on")
|
||||
target_compile_definitions(png PUBLIC -DPNG_MIPS_MSA_OPT=2)
|
||||
endif()
|
||||
else()
|
||||
target_compile_definitions(png PUBLIC -DPNG_MIPS_MSA_OPT=0)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
else(PNG_HARDWARE_OPTIMIZATIONS)
|
||||
|
||||
# set definitions and sources for arm
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm" OR
|
||||
CMAKE_SYSTEM_PROCESSOR MATCHES "^aarch64")
|
||||
target_compile_definitions(png PUBLIC -DPNG_ARM_NEON_OPT=0)
|
||||
endif()
|
||||
|
||||
# set definitions and sources for powerpc
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^powerpc*" OR
|
||||
CMAKE_SYSTEM_PROCESSOR MATCHES "^ppc64*")
|
||||
target_compile_definitions(png PUBLIC -DPNG_POWERPC_VSX_OPT=0)
|
||||
endif()
|
||||
|
||||
# set definitions and sources for intel
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^i?86" OR
|
||||
CMAKE_SYSTEM_PROCESSOR MATCHES "^x86_64*")
|
||||
target_compile_definitions(png PUBLIC -DPNG_INTEL_SSE_OPT=0)
|
||||
endif()
|
||||
|
||||
# set definitions and sources for MIPS
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "mipsel*" OR
|
||||
CMAKE_SYSTEM_PROCESSOR MATCHES "mips64el*")
|
||||
target_compile_definitions(png PUBLIC -DPNG_MIPS_MSA_OPT=0)
|
||||
endif()
|
||||
|
||||
endif(PNG_HARDWARE_OPTIMIZATIONS)
|
||||
|
||||
target_sources(png PRIVATE
|
||||
# public headers
|
||||
png.h
|
||||
pngconf.h
|
||||
pnglibconf.h
|
||||
|
||||
# private headers
|
||||
pngpriv.h
|
||||
pngdebug.h
|
||||
pnginfo.h
|
||||
pngstruct.h
|
||||
)
|
||||
|
||||
target_include_directories(png PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
target_link_libraries(png PUBLIC ZLIB::ZLIB)
|
||||
|
||||
if(NOT MSVC)
|
||||
target_compile_options(png PRIVATE
|
||||
-Wno-self-assign
|
||||
)
|
||||
endif()
|
||||
Vendored
-134
@@ -1,134 +0,0 @@
|
||||
COPYRIGHT NOTICE, DISCLAIMER, and LICENSE
|
||||
=========================================
|
||||
|
||||
PNG Reference Library License version 2
|
||||
---------------------------------------
|
||||
|
||||
* Copyright (c) 1995-2019 The PNG Reference Library Authors.
|
||||
* Copyright (c) 2018-2019 Cosmin Truta.
|
||||
* Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson.
|
||||
* Copyright (c) 1996-1997 Andreas Dilger.
|
||||
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
|
||||
|
||||
The software is supplied "as is", without warranty of any kind,
|
||||
express or implied, including, without limitation, the warranties
|
||||
of merchantability, fitness for a particular purpose, title, and
|
||||
non-infringement. In no event shall the Copyright owners, or
|
||||
anyone distributing the software, be liable for any damages or
|
||||
other liability, whether in contract, tort or otherwise, arising
|
||||
from, out of, or in connection with the software, or the use or
|
||||
other dealings in the software, even if advised of the possibility
|
||||
of such damage.
|
||||
|
||||
Permission is hereby granted to use, copy, modify, and distribute
|
||||
this software, or portions hereof, for any purpose, without fee,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you
|
||||
must not claim that you wrote the original software. If you
|
||||
use this software in a product, an acknowledgment in the product
|
||||
documentation would be appreciated, but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must
|
||||
not be misrepresented as being the original software.
|
||||
|
||||
3. This Copyright notice may not be removed or altered from any
|
||||
source or altered source distribution.
|
||||
|
||||
|
||||
PNG Reference Library License version 1 (for libpng 0.5 through 1.6.35)
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
libpng versions 1.0.7, July 1, 2000, through 1.6.35, July 15, 2018 are
|
||||
Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson, are
|
||||
derived from libpng-1.0.6, and are distributed according to the same
|
||||
disclaimer and license as libpng-1.0.6 with the following individuals
|
||||
added to the list of Contributing Authors:
|
||||
|
||||
Simon-Pierre Cadieux
|
||||
Eric S. Raymond
|
||||
Mans Rullgard
|
||||
Cosmin Truta
|
||||
Gilles Vollant
|
||||
James Yu
|
||||
Mandar Sahastrabuddhe
|
||||
Google Inc.
|
||||
Vadim Barkov
|
||||
|
||||
and with the following additions to the disclaimer:
|
||||
|
||||
There is no warranty against interference with your enjoyment of
|
||||
the library or against infringement. There is no warranty that our
|
||||
efforts or the library will fulfill any of your particular purposes
|
||||
or needs. This library is provided with all faults, and the entire
|
||||
risk of satisfactory quality, performance, accuracy, and effort is
|
||||
with the user.
|
||||
|
||||
Some files in the "contrib" directory and some configure-generated
|
||||
files that are distributed with libpng have other copyright owners, and
|
||||
are released under other open source licenses.
|
||||
|
||||
libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
|
||||
Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from
|
||||
libpng-0.96, and are distributed according to the same disclaimer and
|
||||
license as libpng-0.96, with the following individuals added to the
|
||||
list of Contributing Authors:
|
||||
|
||||
Tom Lane
|
||||
Glenn Randers-Pehrson
|
||||
Willem van Schaik
|
||||
|
||||
libpng versions 0.89, June 1996, through 0.96, May 1997, are
|
||||
Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88,
|
||||
and are distributed according to the same disclaimer and license as
|
||||
libpng-0.88, with the following individuals added to the list of
|
||||
Contributing Authors:
|
||||
|
||||
John Bowler
|
||||
Kevin Bracey
|
||||
Sam Bushell
|
||||
Magnus Holmgren
|
||||
Greg Roelofs
|
||||
Tom Tanner
|
||||
|
||||
Some files in the "scripts" directory have other copyright owners,
|
||||
but are released under this license.
|
||||
|
||||
libpng versions 0.5, May 1995, through 0.88, January 1996, are
|
||||
Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
|
||||
|
||||
For the purposes of this copyright and license, "Contributing Authors"
|
||||
is defined as the following set of individuals:
|
||||
|
||||
Andreas Dilger
|
||||
Dave Martindale
|
||||
Guy Eric Schalnat
|
||||
Paul Schmidt
|
||||
Tim Wegner
|
||||
|
||||
The PNG Reference Library is supplied "AS IS". The Contributing
|
||||
Authors and Group 42, Inc. disclaim all warranties, expressed or
|
||||
implied, including, without limitation, the warranties of
|
||||
merchantability and of fitness for any purpose. The Contributing
|
||||
Authors and Group 42, Inc. assume no liability for direct, indirect,
|
||||
incidental, special, exemplary, or consequential damages, which may
|
||||
result from the use of the PNG Reference Library, even if advised of
|
||||
the possibility of such damage.
|
||||
|
||||
Permission is hereby granted to use, copy, modify, and distribute this
|
||||
source code, or portions hereof, for any purpose, without fee, subject
|
||||
to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented.
|
||||
|
||||
2. Altered versions must be plainly marked as such and must not
|
||||
be misrepresented as being the original source.
|
||||
|
||||
3. This Copyright notice may not be removed or altered from any
|
||||
source or altered source distribution.
|
||||
|
||||
The Contributing Authors and Group 42, Inc. specifically permit,
|
||||
without fee, and encourage the use of this source code as a component
|
||||
to supporting the PNG file format in commercial products. If you use
|
||||
this source code in a product, acknowledgment is not required but would
|
||||
be appreciated.
|
||||
Vendored
-136
@@ -1,136 +0,0 @@
|
||||
|
||||
/* arm_init.c - NEON optimised filter functions
|
||||
*
|
||||
* Copyright (c) 2018 Cosmin Truta
|
||||
* Copyright (c) 2014,2016 Glenn Randers-Pehrson
|
||||
* Written by Mans Rullgard, 2011.
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
* and license in png.h
|
||||
*/
|
||||
|
||||
/* Below, after checking __linux__, various non-C90 POSIX 1003.1 functions are
|
||||
* called.
|
||||
*/
|
||||
#define _POSIX_SOURCE 1
|
||||
|
||||
#include "../pngpriv.h"
|
||||
|
||||
#ifdef PNG_READ_SUPPORTED
|
||||
|
||||
#if PNG_ARM_NEON_OPT > 0
|
||||
#ifdef PNG_ARM_NEON_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 ARM
|
||||
* NEON 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_ARM_NEON_FILE to the file name of file containing
|
||||
* a fragment of C source code which defines the png_have_neon function. There
|
||||
* are a number of implementations in contrib/arm-neon, but the only one that
|
||||
* has partial support is contrib/arm-neon/linux.c - a generic Linux
|
||||
* implementation which reads /proc/cpufino.
|
||||
*/
|
||||
#ifndef PNG_ARM_NEON_FILE
|
||||
# ifdef __linux__
|
||||
# define PNG_ARM_NEON_FILE "contrib/arm-neon/linux.c"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef PNG_ARM_NEON_FILE
|
||||
|
||||
#include <signal.h> /* for sig_atomic_t */
|
||||
static int png_have_neon(png_structp png_ptr);
|
||||
#include PNG_ARM_NEON_FILE
|
||||
|
||||
#else /* PNG_ARM_NEON_FILE */
|
||||
# error "PNG_ARM_NEON_FILE undefined: no support for run-time ARM NEON checks"
|
||||
#endif /* PNG_ARM_NEON_FILE */
|
||||
#endif /* PNG_ARM_NEON_CHECK_SUPPORTED */
|
||||
|
||||
#ifndef PNG_ALIGNED_MEMORY_SUPPORTED
|
||||
# error "ALIGNED_MEMORY is required; set: -DPNG_ALIGNED_MEMORY_SUPPORTED"
|
||||
#endif
|
||||
|
||||
void
|
||||
png_init_filter_functions_neon(png_structp pp, unsigned int bpp)
|
||||
{
|
||||
/* The switch statement is compiled in for ARM_NEON_API, the call to
|
||||
* png_have_neon is compiled in for ARM_NEON_CHECK. If both are defined
|
||||
* the check is only performed if the API has not set the NEON option on
|
||||
* or off explicitly. In this case the check controls what happens.
|
||||
*
|
||||
* If the CHECK is not compiled in and the option is UNSET the behavior prior
|
||||
* to 1.6.7 was to use the NEON code - this was a bug caused by having the
|
||||
* wrong order of the 'ON' and 'default' cases. UNSET now defaults to OFF,
|
||||
* as documented in png.h
|
||||
*/
|
||||
png_debug(1, "in png_init_filter_functions_neon");
|
||||
#ifdef PNG_ARM_NEON_API_SUPPORTED
|
||||
switch ((pp->options >> PNG_ARM_NEON) & 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_ARM_NEON_API_SUPPORTED */
|
||||
#ifdef PNG_ARM_NEON_CHECK_SUPPORTED
|
||||
{
|
||||
static volatile sig_atomic_t no_neon = -1; /* not checked */
|
||||
|
||||
if (no_neon < 0)
|
||||
no_neon = !png_have_neon(pp);
|
||||
|
||||
if (no_neon)
|
||||
return;
|
||||
}
|
||||
#ifdef PNG_ARM_NEON_API_SUPPORTED
|
||||
break;
|
||||
#endif
|
||||
#endif /* PNG_ARM_NEON_CHECK_SUPPORTED */
|
||||
|
||||
#ifdef PNG_ARM_NEON_API_SUPPORTED
|
||||
default: /* OFF or INVALID */
|
||||
return;
|
||||
|
||||
case PNG_OPTION_ON:
|
||||
/* Option turned on */
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 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_neon;
|
||||
|
||||
if (bpp == 3)
|
||||
{
|
||||
pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_neon;
|
||||
pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_neon;
|
||||
pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
|
||||
png_read_filter_row_paeth3_neon;
|
||||
}
|
||||
|
||||
else if (bpp == 4)
|
||||
{
|
||||
pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_neon;
|
||||
pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_neon;
|
||||
pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
|
||||
png_read_filter_row_paeth4_neon;
|
||||
}
|
||||
}
|
||||
#endif /* PNG_ARM_NEON_OPT > 0 */
|
||||
#endif /* READ */
|
||||
Vendored
-253
@@ -1,253 +0,0 @@
|
||||
|
||||
/* filter_neon.S - NEON optimised filter functions
|
||||
*
|
||||
* Copyright (c) 2018 Cosmin Truta
|
||||
* Copyright (c) 2014,2017 Glenn Randers-Pehrson
|
||||
* Written by Mans Rullgard, 2011.
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
* and license in png.h
|
||||
*/
|
||||
|
||||
/* This is required to get the symbol renames, which are #defines, and the
|
||||
* definitions (or not) of PNG_ARM_NEON_OPT and PNG_ARM_NEON_IMPLEMENTATION.
|
||||
*/
|
||||
#define PNG_VERSION_INFO_ONLY
|
||||
#include "../pngpriv.h"
|
||||
|
||||
#if (defined(__linux__) || defined(__FreeBSD__)) && defined(__ELF__)
|
||||
.section .note.GNU-stack,"",%progbits /* mark stack as non-executable */
|
||||
#endif
|
||||
|
||||
#ifdef PNG_READ_SUPPORTED
|
||||
|
||||
/* Assembler NEON support - only works for 32-bit ARM (i.e. it does not work for
|
||||
* ARM64). The code in arm/filter_neon_intrinsics.c supports ARM64, however it
|
||||
* only works if -mfpu=neon is specified on the GCC command line. See pngpriv.h
|
||||
* for the logic which sets PNG_USE_ARM_NEON_ASM:
|
||||
*/
|
||||
#if PNG_ARM_NEON_IMPLEMENTATION == 2 /* hand-coded assembler */
|
||||
|
||||
#if PNG_ARM_NEON_OPT > 0
|
||||
|
||||
#ifdef __ELF__
|
||||
# define ELF
|
||||
#else
|
||||
# define ELF @
|
||||
#endif
|
||||
|
||||
.arch armv7-a
|
||||
.fpu neon
|
||||
|
||||
.macro func name, export=0
|
||||
.macro endfunc
|
||||
ELF .size \name, . - \name
|
||||
.endfunc
|
||||
.purgem endfunc
|
||||
.endm
|
||||
.text
|
||||
|
||||
/* Explicitly specifying alignment here because some versions of
|
||||
* GAS don't align code correctly. This is harmless in correctly
|
||||
* written versions of GAS.
|
||||
*/
|
||||
.align 2
|
||||
|
||||
.if \export
|
||||
.global \name
|
||||
.endif
|
||||
ELF .type \name, STT_FUNC
|
||||
.func \name
|
||||
\name:
|
||||
.endm
|
||||
|
||||
func png_read_filter_row_sub4_neon, export=1
|
||||
ldr r3, [r0, #4] @ rowbytes
|
||||
vmov.i8 d3, #0
|
||||
1:
|
||||
vld4.32 {d4[],d5[],d6[],d7[]}, [r1,:128]
|
||||
vadd.u8 d0, d3, d4
|
||||
vadd.u8 d1, d0, d5
|
||||
vadd.u8 d2, d1, d6
|
||||
vadd.u8 d3, d2, d7
|
||||
vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1,:128]!
|
||||
subs r3, r3, #16
|
||||
bgt 1b
|
||||
|
||||
bx lr
|
||||
endfunc
|
||||
|
||||
func png_read_filter_row_sub3_neon, export=1
|
||||
ldr r3, [r0, #4] @ rowbytes
|
||||
vmov.i8 d3, #0
|
||||
mov r0, r1
|
||||
mov r2, #3
|
||||
mov r12, #12
|
||||
vld1.8 {q11}, [r0], r12
|
||||
1:
|
||||
vext.8 d5, d22, d23, #3
|
||||
vadd.u8 d0, d3, d22
|
||||
vext.8 d6, d22, d23, #6
|
||||
vadd.u8 d1, d0, d5
|
||||
vext.8 d7, d23, d23, #1
|
||||
vld1.8 {q11}, [r0], r12
|
||||
vst1.32 {d0[0]}, [r1,:32], r2
|
||||
vadd.u8 d2, d1, d6
|
||||
vst1.32 {d1[0]}, [r1], r2
|
||||
vadd.u8 d3, d2, d7
|
||||
vst1.32 {d2[0]}, [r1], r2
|
||||
vst1.32 {d3[0]}, [r1], r2
|
||||
subs r3, r3, #12
|
||||
bgt 1b
|
||||
|
||||
bx lr
|
||||
endfunc
|
||||
|
||||
func png_read_filter_row_up_neon, export=1
|
||||
ldr r3, [r0, #4] @ rowbytes
|
||||
1:
|
||||
vld1.8 {q0}, [r1,:128]
|
||||
vld1.8 {q1}, [r2,:128]!
|
||||
vadd.u8 q0, q0, q1
|
||||
vst1.8 {q0}, [r1,:128]!
|
||||
subs r3, r3, #16
|
||||
bgt 1b
|
||||
|
||||
bx lr
|
||||
endfunc
|
||||
|
||||
func png_read_filter_row_avg4_neon, export=1
|
||||
ldr r12, [r0, #4] @ rowbytes
|
||||
vmov.i8 d3, #0
|
||||
1:
|
||||
vld4.32 {d4[],d5[],d6[],d7[]}, [r1,:128]
|
||||
vld4.32 {d16[],d17[],d18[],d19[]},[r2,:128]!
|
||||
vhadd.u8 d0, d3, d16
|
||||
vadd.u8 d0, d0, d4
|
||||
vhadd.u8 d1, d0, d17
|
||||
vadd.u8 d1, d1, d5
|
||||
vhadd.u8 d2, d1, d18
|
||||
vadd.u8 d2, d2, d6
|
||||
vhadd.u8 d3, d2, d19
|
||||
vadd.u8 d3, d3, d7
|
||||
vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1,:128]!
|
||||
subs r12, r12, #16
|
||||
bgt 1b
|
||||
|
||||
bx lr
|
||||
endfunc
|
||||
|
||||
func png_read_filter_row_avg3_neon, export=1
|
||||
push {r4,lr}
|
||||
ldr r12, [r0, #4] @ rowbytes
|
||||
vmov.i8 d3, #0
|
||||
mov r0, r1
|
||||
mov r4, #3
|
||||
mov lr, #12
|
||||
vld1.8 {q11}, [r0], lr
|
||||
1:
|
||||
vld1.8 {q10}, [r2], lr
|
||||
vext.8 d5, d22, d23, #3
|
||||
vhadd.u8 d0, d3, d20
|
||||
vext.8 d17, d20, d21, #3
|
||||
vadd.u8 d0, d0, d22
|
||||
vext.8 d6, d22, d23, #6
|
||||
vhadd.u8 d1, d0, d17
|
||||
vext.8 d18, d20, d21, #6
|
||||
vadd.u8 d1, d1, d5
|
||||
vext.8 d7, d23, d23, #1
|
||||
vld1.8 {q11}, [r0], lr
|
||||
vst1.32 {d0[0]}, [r1,:32], r4
|
||||
vhadd.u8 d2, d1, d18
|
||||
vst1.32 {d1[0]}, [r1], r4
|
||||
vext.8 d19, d21, d21, #1
|
||||
vadd.u8 d2, d2, d6
|
||||
vhadd.u8 d3, d2, d19
|
||||
vst1.32 {d2[0]}, [r1], r4
|
||||
vadd.u8 d3, d3, d7
|
||||
vst1.32 {d3[0]}, [r1], r4
|
||||
subs r12, r12, #12
|
||||
bgt 1b
|
||||
|
||||
pop {r4,pc}
|
||||
endfunc
|
||||
|
||||
.macro paeth rx, ra, rb, rc
|
||||
vaddl.u8 q12, \ra, \rb @ a + b
|
||||
vaddl.u8 q15, \rc, \rc @ 2*c
|
||||
vabdl.u8 q13, \rb, \rc @ pa
|
||||
vabdl.u8 q14, \ra, \rc @ pb
|
||||
vabd.u16 q15, q12, q15 @ pc
|
||||
vcle.u16 q12, q13, q14 @ pa <= pb
|
||||
vcle.u16 q13, q13, q15 @ pa <= pc
|
||||
vcle.u16 q14, q14, q15 @ pb <= pc
|
||||
vand q12, q12, q13 @ pa <= pb && pa <= pc
|
||||
vmovn.u16 d28, q14
|
||||
vmovn.u16 \rx, q12
|
||||
vbsl d28, \rb, \rc
|
||||
vbsl \rx, \ra, d28
|
||||
.endm
|
||||
|
||||
func png_read_filter_row_paeth4_neon, export=1
|
||||
ldr r12, [r0, #4] @ rowbytes
|
||||
vmov.i8 d3, #0
|
||||
vmov.i8 d20, #0
|
||||
1:
|
||||
vld4.32 {d4[],d5[],d6[],d7[]}, [r1,:128]
|
||||
vld4.32 {d16[],d17[],d18[],d19[]},[r2,:128]!
|
||||
paeth d0, d3, d16, d20
|
||||
vadd.u8 d0, d0, d4
|
||||
paeth d1, d0, d17, d16
|
||||
vadd.u8 d1, d1, d5
|
||||
paeth d2, d1, d18, d17
|
||||
vadd.u8 d2, d2, d6
|
||||
paeth d3, d2, d19, d18
|
||||
vmov d20, d19
|
||||
vadd.u8 d3, d3, d7
|
||||
vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1,:128]!
|
||||
subs r12, r12, #16
|
||||
bgt 1b
|
||||
|
||||
bx lr
|
||||
endfunc
|
||||
|
||||
func png_read_filter_row_paeth3_neon, export=1
|
||||
push {r4,lr}
|
||||
ldr r12, [r0, #4] @ rowbytes
|
||||
vmov.i8 d3, #0
|
||||
vmov.i8 d4, #0
|
||||
mov r0, r1
|
||||
mov r4, #3
|
||||
mov lr, #12
|
||||
vld1.8 {q11}, [r0], lr
|
||||
1:
|
||||
vld1.8 {q10}, [r2], lr
|
||||
paeth d0, d3, d20, d4
|
||||
vext.8 d5, d22, d23, #3
|
||||
vadd.u8 d0, d0, d22
|
||||
vext.8 d17, d20, d21, #3
|
||||
paeth d1, d0, d17, d20
|
||||
vst1.32 {d0[0]}, [r1,:32], r4
|
||||
vext.8 d6, d22, d23, #6
|
||||
vadd.u8 d1, d1, d5
|
||||
vext.8 d18, d20, d21, #6
|
||||
paeth d2, d1, d18, d17
|
||||
vext.8 d7, d23, d23, #1
|
||||
vld1.8 {q11}, [r0], lr
|
||||
vst1.32 {d1[0]}, [r1], r4
|
||||
vadd.u8 d2, d2, d6
|
||||
vext.8 d19, d21, d21, #1
|
||||
paeth d3, d2, d19, d18
|
||||
vst1.32 {d2[0]}, [r1], r4
|
||||
vmov d4, d19
|
||||
vadd.u8 d3, d3, d7
|
||||
vst1.32 {d3[0]}, [r1], r4
|
||||
subs r12, r12, #12
|
||||
bgt 1b
|
||||
|
||||
pop {r4,pc}
|
||||
endfunc
|
||||
#endif /* PNG_ARM_NEON_OPT > 0 */
|
||||
#endif /* PNG_ARM_NEON_IMPLEMENTATION == 2 (assembler) */
|
||||
#endif /* READ */
|
||||
-402
@@ -1,402 +0,0 @@
|
||||
|
||||
/* filter_neon_intrinsics.c - NEON optimised filter functions
|
||||
*
|
||||
* Copyright (c) 2018 Cosmin Truta
|
||||
* Copyright (c) 2014,2016 Glenn Randers-Pehrson
|
||||
* Written by James Yu <james.yu at linaro.org>, October 2013.
|
||||
* Based on filter_neon.S, written by Mans Rullgard, 2011.
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
* and license in png.h
|
||||
*/
|
||||
|
||||
#include "../pngpriv.h"
|
||||
|
||||
#ifdef PNG_READ_SUPPORTED
|
||||
|
||||
/* This code requires -mfpu=neon on the command line: */
|
||||
#if PNG_ARM_NEON_IMPLEMENTATION == 1 /* intrinsics code from pngpriv.h */
|
||||
|
||||
#if defined(_MSC_VER) && defined(_M_ARM64)
|
||||
# include <arm64_neon.h>
|
||||
#else
|
||||
# include <arm_neon.h>
|
||||
#endif
|
||||
|
||||
/* libpng row pointers are not necessarily aligned to any particular boundary,
|
||||
* however this code will only work with appropriate alignment. arm/arm_init.c
|
||||
* checks for this (and will not compile unless it is done). This code uses
|
||||
* variants of png_aligncast to avoid compiler warnings.
|
||||
*/
|
||||
#define png_ptr(type,pointer) png_aligncast(type *,pointer)
|
||||
#define png_ptrc(type,pointer) png_aligncastconst(const type *,pointer)
|
||||
|
||||
/* The following relies on a variable 'temp_pointer' being declared with type
|
||||
* 'type'. This is written this way just to hide the GCC strict aliasing
|
||||
* warning; note that the code is safe because there never is an alias between
|
||||
* the input and output pointers.
|
||||
*
|
||||
* When compiling with MSVC ARM64, the png_ldr macro can't be passed directly
|
||||
* to vst4_lane_u32, because of an internal compiler error inside MSVC.
|
||||
* To avoid this compiler bug, we use a temporary variable (vdest_val) to store
|
||||
* the result of png_ldr.
|
||||
*/
|
||||
#define png_ldr(type,pointer)\
|
||||
(temp_pointer = png_ptr(type,pointer), *temp_pointer)
|
||||
|
||||
#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_bytep rp = row;
|
||||
png_bytep rp_stop = row + row_info->rowbytes;
|
||||
png_const_bytep pp = prev_row;
|
||||
|
||||
png_debug(1, "in png_read_filter_row_up_neon");
|
||||
|
||||
for (; rp < rp_stop; rp += 16, pp += 16)
|
||||
{
|
||||
uint8x16_t qrp, qpp;
|
||||
|
||||
qrp = vld1q_u8(rp);
|
||||
qpp = vld1q_u8(pp);
|
||||
qrp = vaddq_u8(qrp, qpp);
|
||||
vst1q_u8(rp, qrp);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
png_read_filter_row_sub3_neon(png_row_infop row_info, png_bytep row,
|
||||
png_const_bytep prev_row)
|
||||
{
|
||||
png_bytep rp = row;
|
||||
png_bytep rp_stop = row + row_info->rowbytes;
|
||||
|
||||
uint8x16_t vtmp = vld1q_u8(rp);
|
||||
uint8x8x2_t *vrpt = png_ptr(uint8x8x2_t, &vtmp);
|
||||
uint8x8x2_t vrp = *vrpt;
|
||||
|
||||
uint8x8x4_t vdest;
|
||||
vdest.val[3] = vdup_n_u8(0);
|
||||
|
||||
png_debug(1, "in png_read_filter_row_sub3_neon");
|
||||
|
||||
for (; rp < rp_stop;)
|
||||
{
|
||||
uint8x8_t vtmp1, vtmp2;
|
||||
uint32x2_t *temp_pointer;
|
||||
|
||||
vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3);
|
||||
vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]);
|
||||
vtmp2 = vext_u8(vrp.val[0], vrp.val[1], 6);
|
||||
vdest.val[1] = vadd_u8(vdest.val[0], vtmp1);
|
||||
|
||||
vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1);
|
||||
vdest.val[2] = vadd_u8(vdest.val[1], vtmp2);
|
||||
vdest.val[3] = vadd_u8(vdest.val[2], vtmp1);
|
||||
|
||||
vtmp = vld1q_u8(rp + 12);
|
||||
vrpt = png_ptr(uint8x8x2_t, &vtmp);
|
||||
vrp = *vrpt;
|
||||
|
||||
vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0);
|
||||
rp += 3;
|
||||
vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0);
|
||||
rp += 3;
|
||||
vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0);
|
||||
rp += 3;
|
||||
vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0);
|
||||
rp += 3;
|
||||
}
|
||||
|
||||
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_bytep rp = row;
|
||||
png_bytep rp_stop = row + row_info->rowbytes;
|
||||
|
||||
uint8x8x4_t vdest;
|
||||
vdest.val[3] = vdup_n_u8(0);
|
||||
|
||||
png_debug(1, "in png_read_filter_row_sub4_neon");
|
||||
|
||||
for (; rp < rp_stop; rp += 16)
|
||||
{
|
||||
uint32x2x4_t vtmp = vld4_u32(png_ptr(uint32_t,rp));
|
||||
uint8x8x4_t *vrpt = png_ptr(uint8x8x4_t,&vtmp);
|
||||
uint8x8x4_t vrp = *vrpt;
|
||||
uint32x2x4_t *temp_pointer;
|
||||
uint32x2x4_t vdest_val;
|
||||
|
||||
vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]);
|
||||
vdest.val[1] = vadd_u8(vdest.val[0], vrp.val[1]);
|
||||
vdest.val[2] = vadd_u8(vdest.val[1], vrp.val[2]);
|
||||
vdest.val[3] = vadd_u8(vdest.val[2], vrp.val[3]);
|
||||
|
||||
vdest_val = png_ldr(uint32x2x4_t, &vdest);
|
||||
vst4_lane_u32(png_ptr(uint32_t,rp), vdest_val, 0);
|
||||
}
|
||||
|
||||
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_bytep rp = row;
|
||||
png_const_bytep pp = prev_row;
|
||||
png_bytep rp_stop = row + row_info->rowbytes;
|
||||
|
||||
uint8x16_t vtmp;
|
||||
uint8x8x2_t *vrpt;
|
||||
uint8x8x2_t vrp;
|
||||
uint8x8x4_t vdest;
|
||||
vdest.val[3] = vdup_n_u8(0);
|
||||
|
||||
vtmp = vld1q_u8(rp);
|
||||
vrpt = png_ptr(uint8x8x2_t,&vtmp);
|
||||
vrp = *vrpt;
|
||||
|
||||
png_debug(1, "in png_read_filter_row_avg3_neon");
|
||||
|
||||
for (; rp < rp_stop; pp += 12)
|
||||
{
|
||||
uint8x8_t vtmp1, vtmp2, vtmp3;
|
||||
|
||||
uint8x8x2_t *vppt;
|
||||
uint8x8x2_t vpp;
|
||||
|
||||
uint32x2_t *temp_pointer;
|
||||
|
||||
vtmp = vld1q_u8(pp);
|
||||
vppt = png_ptr(uint8x8x2_t,&vtmp);
|
||||
vpp = *vppt;
|
||||
|
||||
vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3);
|
||||
vdest.val[0] = vhadd_u8(vdest.val[3], vpp.val[0]);
|
||||
vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]);
|
||||
|
||||
vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 3);
|
||||
vtmp3 = vext_u8(vrp.val[0], vrp.val[1], 6);
|
||||
vdest.val[1] = vhadd_u8(vdest.val[0], vtmp2);
|
||||
vdest.val[1] = vadd_u8(vdest.val[1], vtmp1);
|
||||
|
||||
vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 6);
|
||||
vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1);
|
||||
|
||||
vtmp = vld1q_u8(rp + 12);
|
||||
vrpt = png_ptr(uint8x8x2_t,&vtmp);
|
||||
vrp = *vrpt;
|
||||
|
||||
vdest.val[2] = vhadd_u8(vdest.val[1], vtmp2);
|
||||
vdest.val[2] = vadd_u8(vdest.val[2], vtmp3);
|
||||
|
||||
vtmp2 = vext_u8(vpp.val[1], vpp.val[1], 1);
|
||||
|
||||
vdest.val[3] = vhadd_u8(vdest.val[2], vtmp2);
|
||||
vdest.val[3] = vadd_u8(vdest.val[3], vtmp1);
|
||||
|
||||
vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0);
|
||||
rp += 3;
|
||||
vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0);
|
||||
rp += 3;
|
||||
vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0);
|
||||
rp += 3;
|
||||
vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0);
|
||||
rp += 3;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
png_read_filter_row_avg4_neon(png_row_infop row_info, png_bytep row,
|
||||
png_const_bytep prev_row)
|
||||
{
|
||||
png_bytep rp = row;
|
||||
png_bytep rp_stop = row + row_info->rowbytes;
|
||||
png_const_bytep pp = prev_row;
|
||||
|
||||
uint8x8x4_t vdest;
|
||||
vdest.val[3] = vdup_n_u8(0);
|
||||
|
||||
png_debug(1, "in png_read_filter_row_avg4_neon");
|
||||
|
||||
for (; rp < rp_stop; rp += 16, pp += 16)
|
||||
{
|
||||
uint32x2x4_t vtmp;
|
||||
uint8x8x4_t *vrpt, *vppt;
|
||||
uint8x8x4_t vrp, vpp;
|
||||
uint32x2x4_t *temp_pointer;
|
||||
uint32x2x4_t vdest_val;
|
||||
|
||||
vtmp = vld4_u32(png_ptr(uint32_t,rp));
|
||||
vrpt = png_ptr(uint8x8x4_t,&vtmp);
|
||||
vrp = *vrpt;
|
||||
vtmp = vld4_u32(png_ptrc(uint32_t,pp));
|
||||
vppt = png_ptr(uint8x8x4_t,&vtmp);
|
||||
vpp = *vppt;
|
||||
|
||||
vdest.val[0] = vhadd_u8(vdest.val[3], vpp.val[0]);
|
||||
vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]);
|
||||
vdest.val[1] = vhadd_u8(vdest.val[0], vpp.val[1]);
|
||||
vdest.val[1] = vadd_u8(vdest.val[1], vrp.val[1]);
|
||||
vdest.val[2] = vhadd_u8(vdest.val[1], vpp.val[2]);
|
||||
vdest.val[2] = vadd_u8(vdest.val[2], vrp.val[2]);
|
||||
vdest.val[3] = vhadd_u8(vdest.val[2], vpp.val[3]);
|
||||
vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]);
|
||||
|
||||
vdest_val = png_ldr(uint32x2x4_t, &vdest);
|
||||
vst4_lane_u32(png_ptr(uint32_t,rp), vdest_val, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static uint8x8_t
|
||||
paeth(uint8x8_t a, uint8x8_t b, uint8x8_t c)
|
||||
{
|
||||
uint8x8_t d, e;
|
||||
uint16x8_t p1, pa, pb, pc;
|
||||
|
||||
p1 = vaddl_u8(a, b); /* a + b */
|
||||
pc = vaddl_u8(c, c); /* c * 2 */
|
||||
pa = vabdl_u8(b, c); /* pa */
|
||||
pb = vabdl_u8(a, c); /* pb */
|
||||
pc = vabdq_u16(p1, pc); /* pc */
|
||||
|
||||
p1 = vcleq_u16(pa, pb); /* pa <= pb */
|
||||
pa = vcleq_u16(pa, pc); /* pa <= pc */
|
||||
pb = vcleq_u16(pb, pc); /* pb <= pc */
|
||||
|
||||
p1 = vandq_u16(p1, pa); /* pa <= pb && pa <= pc */
|
||||
|
||||
d = vmovn_u16(pb);
|
||||
e = vmovn_u16(p1);
|
||||
|
||||
d = vbsl_u8(d, b, c);
|
||||
e = vbsl_u8(e, a, d);
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
void
|
||||
png_read_filter_row_paeth3_neon(png_row_infop row_info, 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;
|
||||
|
||||
uint8x16_t vtmp;
|
||||
uint8x8x2_t *vrpt;
|
||||
uint8x8x2_t vrp;
|
||||
uint8x8_t vlast = vdup_n_u8(0);
|
||||
uint8x8x4_t vdest;
|
||||
vdest.val[3] = vdup_n_u8(0);
|
||||
|
||||
vtmp = vld1q_u8(rp);
|
||||
vrpt = png_ptr(uint8x8x2_t,&vtmp);
|
||||
vrp = *vrpt;
|
||||
|
||||
png_debug(1, "in png_read_filter_row_paeth3_neon");
|
||||
|
||||
for (; rp < rp_stop; pp += 12)
|
||||
{
|
||||
uint8x8x2_t *vppt;
|
||||
uint8x8x2_t vpp;
|
||||
uint8x8_t vtmp1, vtmp2, vtmp3;
|
||||
uint32x2_t *temp_pointer;
|
||||
|
||||
vtmp = vld1q_u8(pp);
|
||||
vppt = png_ptr(uint8x8x2_t,&vtmp);
|
||||
vpp = *vppt;
|
||||
|
||||
vdest.val[0] = paeth(vdest.val[3], vpp.val[0], vlast);
|
||||
vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]);
|
||||
|
||||
vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3);
|
||||
vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 3);
|
||||
vdest.val[1] = paeth(vdest.val[0], vtmp2, vpp.val[0]);
|
||||
vdest.val[1] = vadd_u8(vdest.val[1], vtmp1);
|
||||
|
||||
vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 6);
|
||||
vtmp3 = vext_u8(vpp.val[0], vpp.val[1], 6);
|
||||
vdest.val[2] = paeth(vdest.val[1], vtmp3, vtmp2);
|
||||
vdest.val[2] = vadd_u8(vdest.val[2], vtmp1);
|
||||
|
||||
vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1);
|
||||
vtmp2 = vext_u8(vpp.val[1], vpp.val[1], 1);
|
||||
|
||||
vtmp = vld1q_u8(rp + 12);
|
||||
vrpt = png_ptr(uint8x8x2_t,&vtmp);
|
||||
vrp = *vrpt;
|
||||
|
||||
vdest.val[3] = paeth(vdest.val[2], vtmp2, vtmp3);
|
||||
vdest.val[3] = vadd_u8(vdest.val[3], vtmp1);
|
||||
|
||||
vlast = vtmp2;
|
||||
|
||||
vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0);
|
||||
rp += 3;
|
||||
vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0);
|
||||
rp += 3;
|
||||
vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0);
|
||||
rp += 3;
|
||||
vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0);
|
||||
rp += 3;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
png_read_filter_row_paeth4_neon(png_row_infop row_info, png_bytep row,
|
||||
png_const_bytep prev_row)
|
||||
{
|
||||
png_bytep rp = row;
|
||||
png_bytep rp_stop = row + row_info->rowbytes;
|
||||
png_const_bytep pp = prev_row;
|
||||
|
||||
uint8x8_t vlast = vdup_n_u8(0);
|
||||
uint8x8x4_t vdest;
|
||||
vdest.val[3] = vdup_n_u8(0);
|
||||
|
||||
png_debug(1, "in png_read_filter_row_paeth4_neon");
|
||||
|
||||
for (; rp < rp_stop; rp += 16, pp += 16)
|
||||
{
|
||||
uint32x2x4_t vtmp;
|
||||
uint8x8x4_t *vrpt, *vppt;
|
||||
uint8x8x4_t vrp, vpp;
|
||||
uint32x2x4_t *temp_pointer;
|
||||
uint32x2x4_t vdest_val;
|
||||
|
||||
vtmp = vld4_u32(png_ptr(uint32_t,rp));
|
||||
vrpt = png_ptr(uint8x8x4_t,&vtmp);
|
||||
vrp = *vrpt;
|
||||
vtmp = vld4_u32(png_ptrc(uint32_t,pp));
|
||||
vppt = png_ptr(uint8x8x4_t,&vtmp);
|
||||
vpp = *vppt;
|
||||
|
||||
vdest.val[0] = paeth(vdest.val[3], vpp.val[0], vlast);
|
||||
vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]);
|
||||
vdest.val[1] = paeth(vdest.val[0], vpp.val[1], vpp.val[0]);
|
||||
vdest.val[1] = vadd_u8(vdest.val[1], vrp.val[1]);
|
||||
vdest.val[2] = paeth(vdest.val[1], vpp.val[2], vpp.val[1]);
|
||||
vdest.val[2] = vadd_u8(vdest.val[2], vrp.val[2]);
|
||||
vdest.val[3] = paeth(vdest.val[2], vpp.val[3], vpp.val[2]);
|
||||
vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]);
|
||||
|
||||
vlast = vpp.val[3];
|
||||
|
||||
vdest_val = png_ldr(uint32x2x4_t, &vdest);
|
||||
vst4_lane_u32(png_ptr(uint32_t,rp), vdest_val, 0);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* PNG_ARM_NEON_OPT > 0 */
|
||||
#endif /* PNG_ARM_NEON_IMPLEMENTATION == 1 (intrinsics) */
|
||||
#endif /* READ */
|
||||
-149
@@ -1,149 +0,0 @@
|
||||
|
||||
/* palette_neon_intrinsics.c - NEON optimised palette expansion functions
|
||||
*
|
||||
* Copyright (c) 2018-2019 Cosmin Truta
|
||||
* Copyright (c) 2017-2018 Arm Holdings. All rights reserved.
|
||||
* Written by Richard Townsend <Richard.Townsend@arm.com>, February 2017.
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
* and license in png.h
|
||||
*/
|
||||
|
||||
#include "../pngpriv.h"
|
||||
|
||||
#if PNG_ARM_NEON_IMPLEMENTATION == 1
|
||||
|
||||
#if defined(_MSC_VER) && defined(_M_ARM64)
|
||||
# include <arm64_neon.h>
|
||||
#else
|
||||
# include <arm_neon.h>
|
||||
#endif
|
||||
|
||||
/* Build an RGBA8 palette from the separate RGB and alpha palettes. */
|
||||
void
|
||||
png_riffle_palette_neon(png_structrp png_ptr)
|
||||
{
|
||||
png_const_colorp palette = png_ptr->palette;
|
||||
png_bytep riffled_palette = png_ptr->riffled_palette;
|
||||
png_const_bytep trans_alpha = png_ptr->trans_alpha;
|
||||
int num_trans = png_ptr->num_trans;
|
||||
int i;
|
||||
|
||||
png_debug(1, "in png_riffle_palette_neon");
|
||||
|
||||
/* Initially black, opaque. */
|
||||
uint8x16x4_t w = {{
|
||||
vdupq_n_u8(0x00),
|
||||
vdupq_n_u8(0x00),
|
||||
vdupq_n_u8(0x00),
|
||||
vdupq_n_u8(0xff),
|
||||
}};
|
||||
|
||||
/* First, riffle the RGB colours into an RGBA8 palette.
|
||||
* The alpha component is set to opaque for now.
|
||||
*/
|
||||
for (i = 0; i < 256; i += 16)
|
||||
{
|
||||
uint8x16x3_t v = vld3q_u8((png_const_bytep)(palette + i));
|
||||
w.val[0] = v.val[0];
|
||||
w.val[1] = v.val[1];
|
||||
w.val[2] = v.val[2];
|
||||
vst4q_u8(riffled_palette + (i << 2), w);
|
||||
}
|
||||
|
||||
/* Fix up the missing transparency values. */
|
||||
for (i = 0; i < num_trans; i++)
|
||||
riffled_palette[(i << 2) + 3] = trans_alpha[i];
|
||||
}
|
||||
|
||||
/* Expands a palettized row into RGBA8. */
|
||||
int
|
||||
png_do_expand_palette_rgba8_neon(png_structrp png_ptr, png_row_infop row_info,
|
||||
png_const_bytep row, png_bytepp ssp, png_bytepp ddp)
|
||||
{
|
||||
png_uint_32 row_width = row_info->width;
|
||||
const png_uint_32 *riffled_palette =
|
||||
(const png_uint_32 *)png_ptr->riffled_palette;
|
||||
const png_int_32 pixels_per_chunk = 4;
|
||||
int i;
|
||||
|
||||
png_debug(1, "in png_do_expand_palette_rgba8_neon");
|
||||
|
||||
if (row_width < pixels_per_chunk)
|
||||
return 0;
|
||||
|
||||
/* This function originally gets the last byte of the output row.
|
||||
* The NEON part writes forward from a given position, so we have
|
||||
* to seek this back by 4 pixels x 4 bytes.
|
||||
*/
|
||||
*ddp = *ddp - ((pixels_per_chunk * sizeof(png_uint_32)) - 1);
|
||||
|
||||
for (i = 0; i < row_width; i += pixels_per_chunk)
|
||||
{
|
||||
uint32x4_t cur;
|
||||
png_bytep sp = *ssp - i, dp = *ddp - (i << 2);
|
||||
cur = vld1q_dup_u32 (riffled_palette + *(sp - 3));
|
||||
cur = vld1q_lane_u32(riffled_palette + *(sp - 2), cur, 1);
|
||||
cur = vld1q_lane_u32(riffled_palette + *(sp - 1), cur, 2);
|
||||
cur = vld1q_lane_u32(riffled_palette + *(sp - 0), cur, 3);
|
||||
vst1q_u32((void *)dp, cur);
|
||||
}
|
||||
if (i != row_width)
|
||||
{
|
||||
/* Remove the amount that wasn't processed. */
|
||||
i -= pixels_per_chunk;
|
||||
}
|
||||
|
||||
/* Decrement output pointers. */
|
||||
*ssp = *ssp - i;
|
||||
*ddp = *ddp - (i << 2);
|
||||
return i;
|
||||
}
|
||||
|
||||
/* Expands a palettized row into RGB8. */
|
||||
int
|
||||
png_do_expand_palette_rgb8_neon(png_structrp png_ptr, png_row_infop row_info,
|
||||
png_const_bytep row, png_bytepp ssp, png_bytepp ddp)
|
||||
{
|
||||
png_uint_32 row_width = row_info->width;
|
||||
png_const_bytep palette = (png_const_bytep)png_ptr->palette;
|
||||
const png_uint_32 pixels_per_chunk = 8;
|
||||
int i;
|
||||
|
||||
png_debug(1, "in png_do_expand_palette_rgb8_neon");
|
||||
|
||||
if (row_width <= pixels_per_chunk)
|
||||
return 0;
|
||||
|
||||
/* Seeking this back by 8 pixels x 3 bytes. */
|
||||
*ddp = *ddp - ((pixels_per_chunk * sizeof(png_color)) - 1);
|
||||
|
||||
for (i = 0; i < row_width; i += pixels_per_chunk)
|
||||
{
|
||||
uint8x8x3_t cur;
|
||||
png_bytep sp = *ssp - i, dp = *ddp - ((i << 1) + i);
|
||||
cur = vld3_dup_u8(palette + sizeof(png_color) * (*(sp - 7)));
|
||||
cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 6)), cur, 1);
|
||||
cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 5)), cur, 2);
|
||||
cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 4)), cur, 3);
|
||||
cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 3)), cur, 4);
|
||||
cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 2)), cur, 5);
|
||||
cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 1)), cur, 6);
|
||||
cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 0)), cur, 7);
|
||||
vst3_u8((void *)dp, cur);
|
||||
}
|
||||
|
||||
if (i != row_width)
|
||||
{
|
||||
/* Remove the amount that wasn't processed. */
|
||||
i -= pixels_per_chunk;
|
||||
}
|
||||
|
||||
/* Decrement output pointers. */
|
||||
*ssp = *ssp - i;
|
||||
*ddp = *ddp - ((i << 1) + i);
|
||||
return i;
|
||||
}
|
||||
|
||||
#endif /* PNG_ARM_NEON_IMPLEMENTATION */
|
||||
-391
@@ -1,391 +0,0 @@
|
||||
|
||||
/* filter_sse2_intrinsics.c - SSE2 optimized filter functions
|
||||
*
|
||||
* Copyright (c) 2018 Cosmin Truta
|
||||
* Copyright (c) 2016-2017 Glenn Randers-Pehrson
|
||||
* Written by Mike Klein and Matt Sarett
|
||||
* Derived from arm/filter_neon_intrinsics.c
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
* and license in png.h
|
||||
*/
|
||||
|
||||
#include "../pngpriv.h"
|
||||
|
||||
#ifdef PNG_READ_SUPPORTED
|
||||
|
||||
#if PNG_INTEL_SSE_IMPLEMENTATION > 0
|
||||
|
||||
#include <immintrin.h>
|
||||
|
||||
/* Functions in this file look at most 3 pixels (a,b,c) to predict the 4th (d).
|
||||
* They're positioned like this:
|
||||
* prev: c b
|
||||
* row: a d
|
||||
* The Sub filter predicts d=a, Avg d=(a+b)/2, and Paeth predicts d to be
|
||||
* whichever of a, b, or c is closest to p=a+b-c.
|
||||
*/
|
||||
|
||||
static __m128i load4(const void* p) {
|
||||
int tmp;
|
||||
memcpy(&tmp, p, sizeof(tmp));
|
||||
return _mm_cvtsi32_si128(tmp);
|
||||
}
|
||||
|
||||
static void store4(void* p, __m128i v) {
|
||||
int tmp = _mm_cvtsi128_si32(v);
|
||||
memcpy(p, &tmp, sizeof(int));
|
||||
}
|
||||
|
||||
static __m128i load3(const void* p) {
|
||||
png_uint_32 tmp = 0;
|
||||
memcpy(&tmp, p, 3);
|
||||
return _mm_cvtsi32_si128(tmp);
|
||||
}
|
||||
|
||||
static void store3(void* p, __m128i v) {
|
||||
int tmp = _mm_cvtsi128_si32(v);
|
||||
memcpy(p, &tmp, 3);
|
||||
}
|
||||
|
||||
void png_read_filter_row_sub3_sse2(png_row_infop row_info, png_bytep row,
|
||||
png_const_bytep prev)
|
||||
{
|
||||
/* The Sub filter predicts each pixel as the previous pixel, a.
|
||||
* There is no pixel to the left of the first pixel. It's encoded directly.
|
||||
* That works with our main loop if we just say that left pixel was zero.
|
||||
*/
|
||||
size_t rb;
|
||||
|
||||
__m128i a, d = _mm_setzero_si128();
|
||||
|
||||
png_debug(1, "in png_read_filter_row_sub3_sse2");
|
||||
|
||||
rb = row_info->rowbytes;
|
||||
while (rb >= 4) {
|
||||
a = d; d = load4(row);
|
||||
d = _mm_add_epi8(d, a);
|
||||
store3(row, d);
|
||||
|
||||
row += 3;
|
||||
rb -= 3;
|
||||
}
|
||||
if (rb > 0) {
|
||||
a = d; d = load3(row);
|
||||
d = _mm_add_epi8(d, a);
|
||||
store3(row, d);
|
||||
|
||||
row += 3;
|
||||
rb -= 3;
|
||||
}
|
||||
PNG_UNUSED(prev)
|
||||
}
|
||||
|
||||
void png_read_filter_row_sub4_sse2(png_row_infop row_info, png_bytep row,
|
||||
png_const_bytep prev)
|
||||
{
|
||||
/* The Sub filter predicts each pixel as the previous pixel, a.
|
||||
* There is no pixel to the left of the first pixel. It's encoded directly.
|
||||
* That works with our main loop if we just say that left pixel was zero.
|
||||
*/
|
||||
size_t rb;
|
||||
|
||||
__m128i a, d = _mm_setzero_si128();
|
||||
|
||||
png_debug(1, "in png_read_filter_row_sub4_sse2");
|
||||
|
||||
rb = row_info->rowbytes+4;
|
||||
while (rb > 4) {
|
||||
a = d; d = load4(row);
|
||||
d = _mm_add_epi8(d, a);
|
||||
store4(row, d);
|
||||
|
||||
row += 4;
|
||||
rb -= 4;
|
||||
}
|
||||
PNG_UNUSED(prev)
|
||||
}
|
||||
|
||||
void png_read_filter_row_avg3_sse2(png_row_infop row_info, png_bytep row,
|
||||
png_const_bytep prev)
|
||||
{
|
||||
/* The Avg filter predicts each pixel as the (truncated) average of a and b.
|
||||
* There's no pixel to the left of the first pixel. Luckily, it's
|
||||
* predicted to be half of the pixel above it. So again, this works
|
||||
* perfectly with our loop if we make sure a starts at zero.
|
||||
*/
|
||||
|
||||
size_t rb;
|
||||
|
||||
const __m128i zero = _mm_setzero_si128();
|
||||
|
||||
__m128i b;
|
||||
__m128i a, d = zero;
|
||||
|
||||
png_debug(1, "in png_read_filter_row_avg3_sse2");
|
||||
rb = row_info->rowbytes;
|
||||
while (rb >= 4) {
|
||||
__m128i avg;
|
||||
b = load4(prev);
|
||||
a = d; d = load4(row );
|
||||
|
||||
/* PNG requires a truncating average, so we can't just use _mm_avg_epu8 */
|
||||
avg = _mm_avg_epu8(a,b);
|
||||
/* ...but we can fix it up by subtracting off 1 if it rounded up. */
|
||||
avg = _mm_sub_epi8(avg, _mm_and_si128(_mm_xor_si128(a,b),
|
||||
_mm_set1_epi8(1)));
|
||||
d = _mm_add_epi8(d, avg);
|
||||
store3(row, d);
|
||||
|
||||
prev += 3;
|
||||
row += 3;
|
||||
rb -= 3;
|
||||
}
|
||||
if (rb > 0) {
|
||||
__m128i avg;
|
||||
b = load3(prev);
|
||||
a = d; d = load3(row );
|
||||
|
||||
/* PNG requires a truncating average, so we can't just use _mm_avg_epu8 */
|
||||
avg = _mm_avg_epu8(a,b);
|
||||
/* ...but we can fix it up by subtracting off 1 if it rounded up. */
|
||||
avg = _mm_sub_epi8(avg, _mm_and_si128(_mm_xor_si128(a,b),
|
||||
_mm_set1_epi8(1)));
|
||||
|
||||
d = _mm_add_epi8(d, avg);
|
||||
store3(row, d);
|
||||
|
||||
prev += 3;
|
||||
row += 3;
|
||||
rb -= 3;
|
||||
}
|
||||
}
|
||||
|
||||
void png_read_filter_row_avg4_sse2(png_row_infop row_info, png_bytep row,
|
||||
png_const_bytep prev)
|
||||
{
|
||||
/* The Avg filter predicts each pixel as the (truncated) average of a and b.
|
||||
* There's no pixel to the left of the first pixel. Luckily, it's
|
||||
* predicted to be half of the pixel above it. So again, this works
|
||||
* perfectly with our loop if we make sure a starts at zero.
|
||||
*/
|
||||
size_t rb;
|
||||
const __m128i zero = _mm_setzero_si128();
|
||||
__m128i b;
|
||||
__m128i a, d = zero;
|
||||
|
||||
png_debug(1, "in png_read_filter_row_avg4_sse2");
|
||||
|
||||
rb = row_info->rowbytes+4;
|
||||
while (rb > 4) {
|
||||
__m128i avg;
|
||||
b = load4(prev);
|
||||
a = d; d = load4(row );
|
||||
|
||||
/* PNG requires a truncating average, so we can't just use _mm_avg_epu8 */
|
||||
avg = _mm_avg_epu8(a,b);
|
||||
/* ...but we can fix it up by subtracting off 1 if it rounded up. */
|
||||
avg = _mm_sub_epi8(avg, _mm_and_si128(_mm_xor_si128(a,b),
|
||||
_mm_set1_epi8(1)));
|
||||
|
||||
d = _mm_add_epi8(d, avg);
|
||||
store4(row, d);
|
||||
|
||||
prev += 4;
|
||||
row += 4;
|
||||
rb -= 4;
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns |x| for 16-bit lanes. */
|
||||
static __m128i abs_i16(__m128i x) {
|
||||
#if PNG_INTEL_SSE_IMPLEMENTATION >= 2
|
||||
return _mm_abs_epi16(x);
|
||||
#else
|
||||
/* Read this all as, return x<0 ? -x : x.
|
||||
* To negate two's complement, you flip all the bits then add 1.
|
||||
*/
|
||||
__m128i is_negative = _mm_cmplt_epi16(x, _mm_setzero_si128());
|
||||
|
||||
/* Flip negative lanes. */
|
||||
x = _mm_xor_si128(x, is_negative);
|
||||
|
||||
/* +1 to negative lanes, else +0. */
|
||||
x = _mm_sub_epi16(x, is_negative);
|
||||
return x;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Bytewise c ? t : e. */
|
||||
static __m128i if_then_else(__m128i c, __m128i t, __m128i e) {
|
||||
#if PNG_INTEL_SSE_IMPLEMENTATION >= 3
|
||||
return _mm_blendv_epi8(e,t,c);
|
||||
#else
|
||||
return _mm_or_si128(_mm_and_si128(c, t), _mm_andnot_si128(c, e));
|
||||
#endif
|
||||
}
|
||||
|
||||
void png_read_filter_row_paeth3_sse2(png_row_infop row_info, png_bytep row,
|
||||
png_const_bytep prev)
|
||||
{
|
||||
/* Paeth tries to predict pixel d using the pixel to the left of it, a,
|
||||
* and two pixels from the previous row, b and c:
|
||||
* prev: c b
|
||||
* row: a d
|
||||
* The Paeth function predicts d to be whichever of a, b, or c is nearest to
|
||||
* p=a+b-c.
|
||||
*
|
||||
* The first pixel has no left context, and so uses an Up filter, p = b.
|
||||
* This works naturally with our main loop's p = a+b-c if we force a and c
|
||||
* to zero.
|
||||
* Here we zero b and d, which become c and a respectively at the start of
|
||||
* the loop.
|
||||
*/
|
||||
size_t rb;
|
||||
const __m128i zero = _mm_setzero_si128();
|
||||
__m128i c, b = zero,
|
||||
a, d = zero;
|
||||
|
||||
png_debug(1, "in png_read_filter_row_paeth3_sse2");
|
||||
|
||||
rb = row_info->rowbytes;
|
||||
while (rb >= 4) {
|
||||
/* It's easiest to do this math (particularly, deal with pc) with 16-bit
|
||||
* intermediates.
|
||||
*/
|
||||
__m128i pa,pb,pc,smallest,nearest;
|
||||
c = b; b = _mm_unpacklo_epi8(load4(prev), zero);
|
||||
a = d; d = _mm_unpacklo_epi8(load4(row ), zero);
|
||||
|
||||
/* (p-a) == (a+b-c - a) == (b-c) */
|
||||
|
||||
pa = _mm_sub_epi16(b,c);
|
||||
|
||||
/* (p-b) == (a+b-c - b) == (a-c) */
|
||||
pb = _mm_sub_epi16(a,c);
|
||||
|
||||
/* (p-c) == (a+b-c - c) == (a+b-c-c) == (b-c)+(a-c) */
|
||||
pc = _mm_add_epi16(pa,pb);
|
||||
|
||||
pa = abs_i16(pa); /* |p-a| */
|
||||
pb = abs_i16(pb); /* |p-b| */
|
||||
pc = abs_i16(pc); /* |p-c| */
|
||||
|
||||
smallest = _mm_min_epi16(pc, _mm_min_epi16(pa, pb));
|
||||
|
||||
/* Paeth breaks ties favoring a over b over c. */
|
||||
nearest = if_then_else(_mm_cmpeq_epi16(smallest, pa), a,
|
||||
if_then_else(_mm_cmpeq_epi16(smallest, pb), b,
|
||||
c));
|
||||
|
||||
/* Note `_epi8`: we need addition to wrap modulo 255. */
|
||||
d = _mm_add_epi8(d, nearest);
|
||||
store3(row, _mm_packus_epi16(d,d));
|
||||
|
||||
prev += 3;
|
||||
row += 3;
|
||||
rb -= 3;
|
||||
}
|
||||
if (rb > 0) {
|
||||
/* It's easiest to do this math (particularly, deal with pc) with 16-bit
|
||||
* intermediates.
|
||||
*/
|
||||
__m128i pa,pb,pc,smallest,nearest;
|
||||
c = b; b = _mm_unpacklo_epi8(load3(prev), zero);
|
||||
a = d; d = _mm_unpacklo_epi8(load3(row ), zero);
|
||||
|
||||
/* (p-a) == (a+b-c - a) == (b-c) */
|
||||
pa = _mm_sub_epi16(b,c);
|
||||
|
||||
/* (p-b) == (a+b-c - b) == (a-c) */
|
||||
pb = _mm_sub_epi16(a,c);
|
||||
|
||||
/* (p-c) == (a+b-c - c) == (a+b-c-c) == (b-c)+(a-c) */
|
||||
pc = _mm_add_epi16(pa,pb);
|
||||
|
||||
pa = abs_i16(pa); /* |p-a| */
|
||||
pb = abs_i16(pb); /* |p-b| */
|
||||
pc = abs_i16(pc); /* |p-c| */
|
||||
|
||||
smallest = _mm_min_epi16(pc, _mm_min_epi16(pa, pb));
|
||||
|
||||
/* Paeth breaks ties favoring a over b over c. */
|
||||
nearest = if_then_else(_mm_cmpeq_epi16(smallest, pa), a,
|
||||
if_then_else(_mm_cmpeq_epi16(smallest, pb), b,
|
||||
c));
|
||||
|
||||
/* Note `_epi8`: we need addition to wrap modulo 255. */
|
||||
d = _mm_add_epi8(d, nearest);
|
||||
store3(row, _mm_packus_epi16(d,d));
|
||||
|
||||
prev += 3;
|
||||
row += 3;
|
||||
rb -= 3;
|
||||
}
|
||||
}
|
||||
|
||||
void png_read_filter_row_paeth4_sse2(png_row_infop row_info, png_bytep row,
|
||||
png_const_bytep prev)
|
||||
{
|
||||
/* Paeth tries to predict pixel d using the pixel to the left of it, a,
|
||||
* and two pixels from the previous row, b and c:
|
||||
* prev: c b
|
||||
* row: a d
|
||||
* The Paeth function predicts d to be whichever of a, b, or c is nearest to
|
||||
* p=a+b-c.
|
||||
*
|
||||
* The first pixel has no left context, and so uses an Up filter, p = b.
|
||||
* This works naturally with our main loop's p = a+b-c if we force a and c
|
||||
* to zero.
|
||||
* Here we zero b and d, which become c and a respectively at the start of
|
||||
* the loop.
|
||||
*/
|
||||
size_t rb;
|
||||
const __m128i zero = _mm_setzero_si128();
|
||||
__m128i pa,pb,pc,smallest,nearest;
|
||||
__m128i c, b = zero,
|
||||
a, d = zero;
|
||||
|
||||
png_debug(1, "in png_read_filter_row_paeth4_sse2");
|
||||
|
||||
rb = row_info->rowbytes+4;
|
||||
while (rb > 4) {
|
||||
/* It's easiest to do this math (particularly, deal with pc) with 16-bit
|
||||
* intermediates.
|
||||
*/
|
||||
c = b; b = _mm_unpacklo_epi8(load4(prev), zero);
|
||||
a = d; d = _mm_unpacklo_epi8(load4(row ), zero);
|
||||
|
||||
/* (p-a) == (a+b-c - a) == (b-c) */
|
||||
pa = _mm_sub_epi16(b,c);
|
||||
|
||||
/* (p-b) == (a+b-c - b) == (a-c) */
|
||||
pb = _mm_sub_epi16(a,c);
|
||||
|
||||
/* (p-c) == (a+b-c - c) == (a+b-c-c) == (b-c)+(a-c) */
|
||||
pc = _mm_add_epi16(pa,pb);
|
||||
|
||||
pa = abs_i16(pa); /* |p-a| */
|
||||
pb = abs_i16(pb); /* |p-b| */
|
||||
pc = abs_i16(pc); /* |p-c| */
|
||||
|
||||
smallest = _mm_min_epi16(pc, _mm_min_epi16(pa, pb));
|
||||
|
||||
/* Paeth breaks ties favoring a over b over c. */
|
||||
nearest = if_then_else(_mm_cmpeq_epi16(smallest, pa), a,
|
||||
if_then_else(_mm_cmpeq_epi16(smallest, pb), b,
|
||||
c));
|
||||
|
||||
/* Note `_epi8`: we need addition to wrap modulo 255. */
|
||||
d = _mm_add_epi8(d, nearest);
|
||||
store4(row, _mm_packus_epi16(d,d));
|
||||
|
||||
prev += 4;
|
||||
row += 4;
|
||||
rb -= 4;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* PNG_INTEL_SSE_IMPLEMENTATION > 0 */
|
||||
#endif /* READ */
|
||||
Vendored
-52
@@ -1,52 +0,0 @@
|
||||
|
||||
/* intel_init.c - SSE2 optimized filter functions
|
||||
*
|
||||
* Copyright (c) 2018 Cosmin Truta
|
||||
* Copyright (c) 2016-2017 Glenn Randers-Pehrson
|
||||
* Written by Mike Klein and Matt Sarett, Google, Inc.
|
||||
* Derived from arm/arm_init.c
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
* and license in png.h
|
||||
*/
|
||||
|
||||
#include "../pngpriv.h"
|
||||
|
||||
#ifdef PNG_READ_SUPPORTED
|
||||
#if PNG_INTEL_SSE_IMPLEMENTATION > 0
|
||||
|
||||
void
|
||||
png_init_filter_functions_sse2(png_structp pp, unsigned int bpp)
|
||||
{
|
||||
/* The techniques used to implement each of these filters in SSE operate on
|
||||
* one pixel at a time.
|
||||
* So they generally speed up 3bpp images about 3x, 4bpp images about 4x.
|
||||
* They can scale up to 6 and 8 bpp images and down to 2 bpp images,
|
||||
* but they'd not likely have any benefit for 1bpp images.
|
||||
* Most of these can be implemented using only MMX and 64-bit registers,
|
||||
* but they end up a bit slower than using the equally-ubiquitous SSE2.
|
||||
*/
|
||||
png_debug(1, "in png_init_filter_functions_sse2");
|
||||
if (bpp == 3)
|
||||
{
|
||||
pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_sse2;
|
||||
pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_sse2;
|
||||
pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
|
||||
png_read_filter_row_paeth3_sse2;
|
||||
}
|
||||
else if (bpp == 4)
|
||||
{
|
||||
pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_sse2;
|
||||
pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_sse2;
|
||||
pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
|
||||
png_read_filter_row_paeth4_sse2;
|
||||
}
|
||||
|
||||
/* No need optimize PNG_FILTER_VALUE_UP. The compiler should
|
||||
* autovectorize.
|
||||
*/
|
||||
}
|
||||
|
||||
#endif /* PNG_INTEL_SSE_IMPLEMENTATION > 0 */
|
||||
#endif /* PNG_READ_SUPPORTED */
|
||||
-808
File diff suppressed because it is too large
Load Diff
Vendored
-130
@@ -1,130 +0,0 @@
|
||||
|
||||
/* mips_init.c - MSA optimised filter functions
|
||||
*
|
||||
* Copyright (c) 2018 Cosmin Truta
|
||||
* Copyright (c) 2016 Glenn Randers-Pehrson
|
||||
* Written by Mandar Sahastrabuddhe, 2016.
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
* and license in png.h
|
||||
*/
|
||||
|
||||
/* Below, after checking __linux__, various non-C90 POSIX 1003.1 functions are
|
||||
* called.
|
||||
*/
|
||||
#define _POSIX_SOURCE 1
|
||||
|
||||
#include <stdio.h>
|
||||
#include "../pngpriv.h"
|
||||
|
||||
#ifdef PNG_READ_SUPPORTED
|
||||
|
||||
#if PNG_MIPS_MSA_OPT > 0
|
||||
#ifdef PNG_MIPS_MSA_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 MIPS
|
||||
* MSA 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_MIPS_MSA_FILE to the file name of file containing
|
||||
* a fragment of C source code which defines the png_have_msa function. There
|
||||
* are a number of implementations in contrib/mips-msa, but the only one that
|
||||
* has partial support is contrib/mips-msa/linux.c - a generic Linux
|
||||
* implementation which reads /proc/cpufino.
|
||||
*/
|
||||
#ifndef PNG_MIPS_MSA_FILE
|
||||
# ifdef __linux__
|
||||
# define PNG_MIPS_MSA_FILE "contrib/mips-msa/linux.c"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef PNG_MIPS_MSA_FILE
|
||||
|
||||
#include <signal.h> /* for sig_atomic_t */
|
||||
static int png_have_msa(png_structp png_ptr);
|
||||
#include PNG_MIPS_MSA_FILE
|
||||
|
||||
#else /* PNG_MIPS_MSA_FILE */
|
||||
# error "PNG_MIPS_MSA_FILE undefined: no support for run-time MIPS MSA checks"
|
||||
#endif /* PNG_MIPS_MSA_FILE */
|
||||
#endif /* PNG_MIPS_MSA_CHECK_SUPPORTED */
|
||||
|
||||
#ifndef PNG_ALIGNED_MEMORY_SUPPORTED
|
||||
# error "ALIGNED_MEMORY is required; set: -DPNG_ALIGNED_MEMORY_SUPPORTED"
|
||||
#endif
|
||||
|
||||
void
|
||||
png_init_filter_functions_msa(png_structp pp, unsigned int bpp)
|
||||
{
|
||||
/* The switch statement is compiled in for MIPS_MSA_API, the call to
|
||||
* png_have_msa is compiled in for MIPS_MSA_CHECK. If both are defined
|
||||
* the check is only performed if the API has not set the MSA option on
|
||||
* or off explicitly. In this case the check controls what happens.
|
||||
*/
|
||||
|
||||
#ifdef PNG_MIPS_MSA_API_SUPPORTED
|
||||
switch ((pp->options >> PNG_MIPS_MSA) & 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_MIPS_MSA_API_SUPPORTED */
|
||||
#ifdef PNG_MIPS_MSA_CHECK_SUPPORTED
|
||||
{
|
||||
static volatile sig_atomic_t no_msa = -1; /* not checked */
|
||||
|
||||
if (no_msa < 0)
|
||||
no_msa = !png_have_msa(pp);
|
||||
|
||||
if (no_msa)
|
||||
return;
|
||||
}
|
||||
#ifdef PNG_MIPS_MSA_API_SUPPORTED
|
||||
break;
|
||||
#endif
|
||||
#endif /* PNG_MIPS_MSA_CHECK_SUPPORTED */
|
||||
|
||||
#ifdef PNG_MIPS_MSA_API_SUPPORTED
|
||||
default: /* OFF or INVALID */
|
||||
return;
|
||||
|
||||
case PNG_OPTION_ON:
|
||||
/* Option turned on */
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 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_msa;
|
||||
|
||||
if (bpp == 3)
|
||||
{
|
||||
pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_msa;
|
||||
pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_msa;
|
||||
pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = png_read_filter_row_paeth3_msa;
|
||||
}
|
||||
|
||||
else if (bpp == 4)
|
||||
{
|
||||
pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_msa;
|
||||
pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_msa;
|
||||
pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = png_read_filter_row_paeth4_msa;
|
||||
}
|
||||
}
|
||||
#endif /* PNG_MIPS_MSA_OPT > 0 */
|
||||
#endif /* READ */
|
||||
Vendored
-4607
File diff suppressed because it is too large
Load Diff
Vendored
-3247
File diff suppressed because it is too large
Load Diff
Vendored
-50
@@ -1,50 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project>
|
||||
<Import Project="..\..\..\Source\VSProps\Base.Macros.props" />
|
||||
<Import Project="$(VSPropsDir)Base.Targets.props" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{4C9F135B-A85E-430C-BAD4-4C67EF5FC12C}</ProjectGuid>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<Import Project="$(VSPropsDir)Configuration.StaticLibrary.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings" />
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VSPropsDir)Base.props" />
|
||||
<Import Project="$(VSPropsDir)ClDisableAllWarnings.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<ItemGroup>
|
||||
<Text Include="..\CMakeLists.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\png.c" />
|
||||
<ClCompile Include="..\pngerror.c" />
|
||||
<ClCompile Include="..\pngget.c" />
|
||||
<ClCompile Include="..\pngmem.c" />
|
||||
<ClCompile Include="..\pngpread.c" />
|
||||
<ClCompile Include="..\pngread.c" />
|
||||
<ClCompile Include="..\pngrio.c" />
|
||||
<ClCompile Include="..\pngrtran.c" />
|
||||
<ClCompile Include="..\pngrutil.c" />
|
||||
<ClCompile Include="..\pngset.c" />
|
||||
<ClCompile Include="..\pngtrans.c" />
|
||||
<ClCompile Include="..\pngwio.c" />
|
||||
<ClCompile Include="..\pngwrite.c" />
|
||||
<ClCompile Include="..\pngwtran.c" />
|
||||
<ClCompile Include="..\pngwutil.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\png.h" />
|
||||
<ClInclude Include="..\pngconf.h" />
|
||||
<ClInclude Include="..\pngdebug.h" />
|
||||
<ClInclude Include="..\pnginfo.h" />
|
||||
<ClInclude Include="..\pnglibconf.h" />
|
||||
<ClInclude Include="..\pngpriv.h" />
|
||||
<ClInclude Include="..\pngstruct.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
Vendored
-623
File diff suppressed because it is too large
Load Diff
Vendored
-153
@@ -1,153 +0,0 @@
|
||||
|
||||
/* pngdebug.h - Debugging macros for libpng, also used in pngtest.c
|
||||
*
|
||||
* Copyright (c) 2018 Cosmin Truta
|
||||
* Copyright (c) 1998-2002,2004,2006-2013 Glenn Randers-Pehrson
|
||||
* Copyright (c) 1996-1997 Andreas Dilger
|
||||
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
* and license in png.h
|
||||
*/
|
||||
|
||||
/* Define PNG_DEBUG at compile time for debugging information. Higher
|
||||
* numbers for PNG_DEBUG mean more debugging information. This has
|
||||
* only been added since version 0.95 so it is not implemented throughout
|
||||
* libpng yet, but more support will be added as needed.
|
||||
*
|
||||
* png_debug[1-2]?(level, message ,arg{0-2})
|
||||
* Expands to a statement (either a simple expression or a compound
|
||||
* do..while(0) statement) that outputs a message with parameter
|
||||
* substitution if PNG_DEBUG is defined to 2 or more. If PNG_DEBUG
|
||||
* is undefined, 0 or 1 every png_debug expands to a simple expression
|
||||
* (actually ((void)0)).
|
||||
*
|
||||
* level: level of detail of message, starting at 0. A level 'n'
|
||||
* message is preceded by 'n' 3-space indentations (not implemented
|
||||
* on Microsoft compilers unless PNG_DEBUG_FILE is also
|
||||
* defined, to allow debug DLL compilation with no standard IO).
|
||||
* message: a printf(3) style text string. A trailing '\n' is added
|
||||
* to the message.
|
||||
* arg: 0 to 2 arguments for printf(3) style substitution in message.
|
||||
*/
|
||||
#ifndef PNGDEBUG_H
|
||||
#define PNGDEBUG_H
|
||||
/* These settings control the formatting of messages in png.c and pngerror.c */
|
||||
/* Moved to pngdebug.h at 1.5.0 */
|
||||
# ifndef PNG_LITERAL_SHARP
|
||||
# define PNG_LITERAL_SHARP 0x23
|
||||
# endif
|
||||
# ifndef PNG_LITERAL_LEFT_SQUARE_BRACKET
|
||||
# define PNG_LITERAL_LEFT_SQUARE_BRACKET 0x5b
|
||||
# endif
|
||||
# ifndef PNG_LITERAL_RIGHT_SQUARE_BRACKET
|
||||
# define PNG_LITERAL_RIGHT_SQUARE_BRACKET 0x5d
|
||||
# endif
|
||||
# ifndef PNG_STRING_NEWLINE
|
||||
# define PNG_STRING_NEWLINE "\n"
|
||||
# endif
|
||||
|
||||
#ifdef PNG_DEBUG
|
||||
# if (PNG_DEBUG > 0)
|
||||
# if !defined(PNG_DEBUG_FILE) && defined(_MSC_VER)
|
||||
# include <crtdbg.h>
|
||||
# if (PNG_DEBUG > 1)
|
||||
# ifndef _DEBUG
|
||||
# define _DEBUG
|
||||
# endif
|
||||
# ifndef png_debug
|
||||
# define png_debug(l,m) _RPT0(_CRT_WARN,m PNG_STRING_NEWLINE)
|
||||
# endif
|
||||
# ifndef png_debug1
|
||||
# define png_debug1(l,m,p1) _RPT1(_CRT_WARN,m PNG_STRING_NEWLINE,p1)
|
||||
# endif
|
||||
# ifndef png_debug2
|
||||
# define png_debug2(l,m,p1,p2) \
|
||||
_RPT2(_CRT_WARN,m PNG_STRING_NEWLINE,p1,p2)
|
||||
# endif
|
||||
# endif
|
||||
# else /* PNG_DEBUG_FILE || !_MSC_VER */
|
||||
# ifndef PNG_STDIO_SUPPORTED
|
||||
# include <stdio.h> /* not included yet */
|
||||
# endif
|
||||
# ifndef PNG_DEBUG_FILE
|
||||
# define PNG_DEBUG_FILE stderr
|
||||
# endif /* PNG_DEBUG_FILE */
|
||||
|
||||
# if (PNG_DEBUG > 1)
|
||||
# ifdef __STDC__
|
||||
# ifndef png_debug
|
||||
# define png_debug(l,m) \
|
||||
do { \
|
||||
int num_tabs=l; \
|
||||
fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? " " : \
|
||||
(num_tabs==2 ? " " : (num_tabs>2 ? " " : "")))); \
|
||||
} while (0)
|
||||
# endif
|
||||
# ifndef png_debug1
|
||||
# define png_debug1(l,m,p1) \
|
||||
do { \
|
||||
int num_tabs=l; \
|
||||
fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? " " : \
|
||||
(num_tabs==2 ? " " : (num_tabs>2 ? " " : ""))),p1); \
|
||||
} while (0)
|
||||
# endif
|
||||
# ifndef png_debug2
|
||||
# define png_debug2(l,m,p1,p2) \
|
||||
do { \
|
||||
int num_tabs=l; \
|
||||
fprintf(PNG_DEBUG_FILE,"%s" m PNG_STRING_NEWLINE,(num_tabs==1 ? " " : \
|
||||
(num_tabs==2 ? " " : (num_tabs>2 ? " " : ""))),p1,p2);\
|
||||
} while (0)
|
||||
# endif
|
||||
# else /* __STDC __ */
|
||||
# ifndef png_debug
|
||||
# define png_debug(l,m) \
|
||||
do { \
|
||||
int num_tabs=l; \
|
||||
char format[256]; \
|
||||
snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \
|
||||
(num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \
|
||||
m,PNG_STRING_NEWLINE); \
|
||||
fprintf(PNG_DEBUG_FILE,format); \
|
||||
} while (0)
|
||||
# endif
|
||||
# ifndef png_debug1
|
||||
# define png_debug1(l,m,p1) \
|
||||
do { \
|
||||
int num_tabs=l; \
|
||||
char format[256]; \
|
||||
snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \
|
||||
(num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \
|
||||
m,PNG_STRING_NEWLINE); \
|
||||
fprintf(PNG_DEBUG_FILE,format,p1); \
|
||||
} while (0)
|
||||
# endif
|
||||
# ifndef png_debug2
|
||||
# define png_debug2(l,m,p1,p2) \
|
||||
do { \
|
||||
int num_tabs=l; \
|
||||
char format[256]; \
|
||||
snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \
|
||||
(num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \
|
||||
m,PNG_STRING_NEWLINE); \
|
||||
fprintf(PNG_DEBUG_FILE,format,p1,p2); \
|
||||
} while (0)
|
||||
# endif
|
||||
# endif /* __STDC __ */
|
||||
# endif /* (PNG_DEBUG > 1) */
|
||||
|
||||
# endif /* _MSC_VER */
|
||||
# endif /* (PNG_DEBUG > 0) */
|
||||
#endif /* PNG_DEBUG */
|
||||
#ifndef png_debug
|
||||
# define png_debug(l, m) ((void)0)
|
||||
#endif
|
||||
#ifndef png_debug1
|
||||
# define png_debug1(l, m, p1) ((void)0)
|
||||
#endif
|
||||
#ifndef png_debug2
|
||||
# define png_debug2(l, m, p1, p2) ((void)0)
|
||||
#endif
|
||||
#endif /* PNGDEBUG_H */
|
||||
Vendored
-963
File diff suppressed because it is too large
Load Diff
Vendored
-1249
File diff suppressed because it is too large
Load Diff
Vendored
-267
@@ -1,267 +0,0 @@
|
||||
|
||||
/* pnginfo.h - header file for PNG reference library
|
||||
*
|
||||
* Copyright (c) 2018 Cosmin Truta
|
||||
* Copyright (c) 1998-2002,2004,2006-2013,2018 Glenn Randers-Pehrson
|
||||
* Copyright (c) 1996-1997 Andreas Dilger
|
||||
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
* and license in png.h
|
||||
*/
|
||||
|
||||
/* png_info is a structure that holds the information in a PNG file so
|
||||
* that the application can find out the characteristics of the image.
|
||||
* If you are reading the file, this structure will tell you what is
|
||||
* in the PNG file. If you are writing the file, fill in the information
|
||||
* you want to put into the PNG file, using png_set_*() functions, then
|
||||
* call png_write_info().
|
||||
*
|
||||
* The names chosen should be very close to the PNG specification, so
|
||||
* consult that document for information about the meaning of each field.
|
||||
*
|
||||
* With libpng < 0.95, it was only possible to directly set and read the
|
||||
* the values in the png_info_struct, which meant that the contents and
|
||||
* order of the values had to remain fixed. With libpng 0.95 and later,
|
||||
* however, there are now functions that abstract the contents of
|
||||
* png_info_struct from the application, so this makes it easier to use
|
||||
* libpng with dynamic libraries, and even makes it possible to use
|
||||
* libraries that don't have all of the libpng ancillary chunk-handing
|
||||
* functionality. In libpng-1.5.0 this was moved into a separate private
|
||||
* file that is not visible to applications.
|
||||
*
|
||||
* The following members may have allocated storage attached that should be
|
||||
* cleaned up before the structure is discarded: palette, trans, text,
|
||||
* pcal_purpose, pcal_units, pcal_params, hist, iccp_name, iccp_profile,
|
||||
* splt_palettes, scal_unit, row_pointers, and unknowns. By default, these
|
||||
* are automatically freed when the info structure is deallocated, if they were
|
||||
* allocated internally by libpng. This behavior can be changed by means
|
||||
* of the png_data_freer() function.
|
||||
*
|
||||
* More allocation details: all the chunk-reading functions that
|
||||
* change these members go through the corresponding png_set_*
|
||||
* functions. A function to clear these members is available: see
|
||||
* png_free_data(). The png_set_* functions do not depend on being
|
||||
* able to point info structure members to any of the storage they are
|
||||
* passed (they make their own copies), EXCEPT that the png_set_text
|
||||
* functions use the same storage passed to them in the text_ptr or
|
||||
* itxt_ptr structure argument, and the png_set_rows and png_set_unknowns
|
||||
* functions do not make their own copies.
|
||||
*/
|
||||
#ifndef PNGINFO_H
|
||||
#define PNGINFO_H
|
||||
|
||||
struct png_info_def
|
||||
{
|
||||
/* The following are necessary for every PNG file */
|
||||
png_uint_32 width; /* width of image in pixels (from IHDR) */
|
||||
png_uint_32 height; /* height of image in pixels (from IHDR) */
|
||||
png_uint_32 valid; /* valid chunk data (see PNG_INFO_ below) */
|
||||
size_t rowbytes; /* bytes needed to hold an untransformed row */
|
||||
png_colorp palette; /* array of color values (valid & PNG_INFO_PLTE) */
|
||||
png_uint_16 num_palette; /* number of color entries in "palette" (PLTE) */
|
||||
png_uint_16 num_trans; /* number of transparent palette color (tRNS) */
|
||||
png_byte bit_depth; /* 1, 2, 4, 8, or 16 bits/channel (from IHDR) */
|
||||
png_byte color_type; /* see PNG_COLOR_TYPE_ below (from IHDR) */
|
||||
/* The following three should have been named *_method not *_type */
|
||||
png_byte compression_type; /* must be PNG_COMPRESSION_TYPE_BASE (IHDR) */
|
||||
png_byte filter_type; /* must be PNG_FILTER_TYPE_BASE (from IHDR) */
|
||||
png_byte interlace_type; /* One of PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
|
||||
|
||||
/* The following are set by png_set_IHDR, called from the application on
|
||||
* write, but the are never actually used by the write code.
|
||||
*/
|
||||
png_byte channels; /* number of data channels per pixel (1, 2, 3, 4) */
|
||||
png_byte pixel_depth; /* number of bits per pixel */
|
||||
png_byte spare_byte; /* to align the data, and for future use */
|
||||
|
||||
#ifdef PNG_READ_SUPPORTED
|
||||
/* This is never set during write */
|
||||
png_byte signature[8]; /* magic bytes read by libpng from start of file */
|
||||
#endif
|
||||
|
||||
/* The rest of the data is optional. If you are reading, check the
|
||||
* valid field to see if the information in these are valid. If you
|
||||
* are writing, set the valid field to those chunks you want written,
|
||||
* and initialize the appropriate fields below.
|
||||
*/
|
||||
|
||||
#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED)
|
||||
/* png_colorspace only contains 'flags' if neither GAMMA or COLORSPACE are
|
||||
* defined. When COLORSPACE is switched on all the colorspace-defining
|
||||
* chunks should be enabled, when GAMMA is switched on all the gamma-defining
|
||||
* chunks should be enabled. If this is not done it becomes possible to read
|
||||
* inconsistent PNG files and assign a probably incorrect interpretation to
|
||||
* the information. (In other words, by carefully choosing which chunks to
|
||||
* recognize the system configuration can select an interpretation for PNG
|
||||
* files containing ambiguous data and this will result in inconsistent
|
||||
* behavior between different libpng builds!)
|
||||
*/
|
||||
png_colorspace colorspace;
|
||||
#endif
|
||||
|
||||
#ifdef PNG_iCCP_SUPPORTED
|
||||
/* iCCP chunk data. */
|
||||
png_charp iccp_name; /* profile name */
|
||||
png_bytep iccp_profile; /* International Color Consortium profile data */
|
||||
png_uint_32 iccp_proflen; /* ICC profile data length */
|
||||
#endif
|
||||
|
||||
#ifdef PNG_TEXT_SUPPORTED
|
||||
/* The tEXt, and zTXt chunks contain human-readable textual data in
|
||||
* uncompressed, compressed, and optionally compressed forms, respectively.
|
||||
* The data in "text" is an array of pointers to uncompressed,
|
||||
* null-terminated C strings. Each chunk has a keyword that describes the
|
||||
* textual data contained in that chunk. Keywords are not required to be
|
||||
* unique, and the text string may be empty. Any number of text chunks may
|
||||
* be in an image.
|
||||
*/
|
||||
int num_text; /* number of comments read or comments to write */
|
||||
int max_text; /* current size of text array */
|
||||
png_textp text; /* array of comments read or comments to write */
|
||||
#endif /* TEXT */
|
||||
|
||||
#ifdef PNG_tIME_SUPPORTED
|
||||
/* The tIME chunk holds the last time the displayed image data was
|
||||
* modified. See the png_time struct for the contents of this struct.
|
||||
*/
|
||||
png_time mod_time;
|
||||
#endif
|
||||
|
||||
#ifdef PNG_sBIT_SUPPORTED
|
||||
/* The sBIT chunk specifies the number of significant high-order bits
|
||||
* in the pixel data. Values are in the range [1, bit_depth], and are
|
||||
* only specified for the channels in the pixel data. The contents of
|
||||
* the low-order bits is not specified. Data is valid if
|
||||
* (valid & PNG_INFO_sBIT) is non-zero.
|
||||
*/
|
||||
png_color_8 sig_bit; /* significant bits in color channels */
|
||||
#endif
|
||||
|
||||
#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_EXPAND_SUPPORTED) || \
|
||||
defined(PNG_READ_BACKGROUND_SUPPORTED)
|
||||
/* The tRNS chunk supplies transparency data for paletted images and
|
||||
* other image types that don't need a full alpha channel. There are
|
||||
* "num_trans" transparency values for a paletted image, stored in the
|
||||
* same order as the palette colors, starting from index 0. Values
|
||||
* for the data are in the range [0, 255], ranging from fully transparent
|
||||
* to fully opaque, respectively. For non-paletted images, there is a
|
||||
* single color specified that should be treated as fully transparent.
|
||||
* Data is valid if (valid & PNG_INFO_tRNS) is non-zero.
|
||||
*/
|
||||
png_bytep trans_alpha; /* alpha values for paletted image */
|
||||
png_color_16 trans_color; /* transparent color for non-palette image */
|
||||
#endif
|
||||
|
||||
#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
|
||||
/* The bKGD chunk gives the suggested image background color if the
|
||||
* display program does not have its own background color and the image
|
||||
* is needs to composited onto a background before display. The colors
|
||||
* in "background" are normally in the same color space/depth as the
|
||||
* pixel data. Data is valid if (valid & PNG_INFO_bKGD) is non-zero.
|
||||
*/
|
||||
png_color_16 background;
|
||||
#endif
|
||||
|
||||
#ifdef PNG_oFFs_SUPPORTED
|
||||
/* The oFFs chunk gives the offset in "offset_unit_type" units rightwards
|
||||
* and downwards from the top-left corner of the display, page, or other
|
||||
* application-specific co-ordinate space. See the PNG_OFFSET_ defines
|
||||
* below for the unit types. Valid if (valid & PNG_INFO_oFFs) non-zero.
|
||||
*/
|
||||
png_int_32 x_offset; /* x offset on page */
|
||||
png_int_32 y_offset; /* y offset on page */
|
||||
png_byte offset_unit_type; /* offset units type */
|
||||
#endif
|
||||
|
||||
#ifdef PNG_pHYs_SUPPORTED
|
||||
/* The pHYs chunk gives the physical pixel density of the image for
|
||||
* display or printing in "phys_unit_type" units (see PNG_RESOLUTION_
|
||||
* defines below). Data is valid if (valid & PNG_INFO_pHYs) is non-zero.
|
||||
*/
|
||||
png_uint_32 x_pixels_per_unit; /* horizontal pixel density */
|
||||
png_uint_32 y_pixels_per_unit; /* vertical pixel density */
|
||||
png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */
|
||||
#endif
|
||||
|
||||
#ifdef PNG_eXIf_SUPPORTED
|
||||
int num_exif; /* Added at libpng-1.6.31 */
|
||||
png_bytep exif;
|
||||
# ifdef PNG_READ_eXIf_SUPPORTED
|
||||
png_bytep eXIf_buf; /* Added at libpng-1.6.32 */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef PNG_hIST_SUPPORTED
|
||||
/* The hIST chunk contains the relative frequency or importance of the
|
||||
* various palette entries, so that a viewer can intelligently select a
|
||||
* reduced-color palette, if required. Data is an array of "num_palette"
|
||||
* values in the range [0,65535]. Data valid if (valid & PNG_INFO_hIST)
|
||||
* is non-zero.
|
||||
*/
|
||||
png_uint_16p hist;
|
||||
#endif
|
||||
|
||||
#ifdef PNG_pCAL_SUPPORTED
|
||||
/* The pCAL chunk describes a transformation between the stored pixel
|
||||
* values and original physical data values used to create the image.
|
||||
* The integer range [0, 2^bit_depth - 1] maps to the floating-point
|
||||
* range given by [pcal_X0, pcal_X1], and are further transformed by a
|
||||
* (possibly non-linear) transformation function given by "pcal_type"
|
||||
* and "pcal_params" into "pcal_units". Please see the PNG_EQUATION_
|
||||
* defines below, and the PNG-Group's PNG extensions document for a
|
||||
* complete description of the transformations and how they should be
|
||||
* implemented, and for a description of the ASCII parameter strings.
|
||||
* Data values are valid if (valid & PNG_INFO_pCAL) non-zero.
|
||||
*/
|
||||
png_charp pcal_purpose; /* pCAL chunk description string */
|
||||
png_int_32 pcal_X0; /* minimum value */
|
||||
png_int_32 pcal_X1; /* maximum value */
|
||||
png_charp pcal_units; /* Latin-1 string giving physical units */
|
||||
png_charpp pcal_params; /* ASCII strings containing parameter values */
|
||||
png_byte pcal_type; /* equation type (see PNG_EQUATION_ below) */
|
||||
png_byte pcal_nparams; /* number of parameters given in pcal_params */
|
||||
#endif
|
||||
|
||||
/* New members added in libpng-1.0.6 */
|
||||
png_uint_32 free_me; /* flags items libpng is responsible for freeing */
|
||||
|
||||
#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
|
||||
/* Storage for unknown chunks that the library doesn't recognize. */
|
||||
png_unknown_chunkp unknown_chunks;
|
||||
|
||||
/* The type of this field is limited by the type of
|
||||
* png_struct::user_chunk_cache_max, else overflow can occur.
|
||||
*/
|
||||
int unknown_chunks_num;
|
||||
#endif
|
||||
|
||||
#ifdef PNG_sPLT_SUPPORTED
|
||||
/* Data on sPLT chunks (there may be more than one). */
|
||||
png_sPLT_tp splt_palettes;
|
||||
int splt_palettes_num; /* Match type returned by png_get API */
|
||||
#endif
|
||||
|
||||
#ifdef PNG_sCAL_SUPPORTED
|
||||
/* The sCAL chunk describes the actual physical dimensions of the
|
||||
* subject matter of the graphic. The chunk contains a unit specification
|
||||
* a byte value, and two ASCII strings representing floating-point
|
||||
* values. The values are width and height corresponding to one pixel
|
||||
* in the image. Data values are valid if (valid & PNG_INFO_sCAL) is
|
||||
* non-zero.
|
||||
*/
|
||||
png_byte scal_unit; /* unit of physical scale */
|
||||
png_charp scal_s_width; /* string containing height */
|
||||
png_charp scal_s_height; /* string containing width */
|
||||
#endif
|
||||
|
||||
#ifdef PNG_INFO_IMAGE_SUPPORTED
|
||||
/* Memory has been allocated if (valid & PNG_ALLOCATED_INFO_ROWS)
|
||||
non-zero */
|
||||
/* Data valid if (valid & PNG_INFO_IDAT) non-zero */
|
||||
png_bytepp row_pointers; /* the image bits */
|
||||
#endif
|
||||
|
||||
};
|
||||
#endif /* PNGINFO_H */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user