Merge pull request #10889 from shuffle2/spng
replace libpng with libspng
This commit is contained in:
commit
a9edf129e3
|
@ -32,3 +32,8 @@
|
||||||
path = Externals/zlib-ng/zlib-ng
|
path = Externals/zlib-ng/zlib-ng
|
||||||
url = https://github.com/zlib-ng/zlib-ng.git
|
url = https://github.com/zlib-ng/zlib-ng.git
|
||||||
shallow = true
|
shallow = true
|
||||||
|
[submodule "Externals/libspng/libspng"]
|
||||||
|
path = Externals/libspng/libspng
|
||||||
|
url = https://github.com/randy408/libspng.git
|
||||||
|
branch = v0.7.2
|
||||||
|
shallow = true
|
||||||
|
|
|
@ -53,7 +53,6 @@ if(NOT ANDROID)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
option(USE_SHARED_ENET "Use shared libenet if found rather than Dolphin's soon-to-compatibly-diverge version" OFF)
|
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(USE_UPNP "Enables UPnP port mapping support" ON)
|
||||||
option(ENABLE_NOGUI "Enable NoGUI frontend" ON)
|
option(ENABLE_NOGUI "Enable NoGUI frontend" ON)
|
||||||
option(ENABLE_QT "Enable Qt (Default)" 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(IOB_LIBRARY IOBluetooth)
|
||||||
find_library(IOK_LIBRARY IOKit)
|
find_library(IOK_LIBRARY IOKit)
|
||||||
find_library(OPENGL_LIBRARY OpenGL)
|
find_library(OPENGL_LIBRARY OpenGL)
|
||||||
|
|
||||||
# We don't want to use shared libpng.
|
|
||||||
set(USE_SHARED_LIBPNG OFF)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(ENABLE_LTO)
|
if(ENABLE_LTO)
|
||||||
|
@ -810,17 +806,7 @@ else()
|
||||||
set(LZO lzo2)
|
set(LZO lzo2)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(USE_SHARED_LIBPNG)
|
add_subdirectory(Externals/libspng)
|
||||||
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()
|
|
||||||
|
|
||||||
# Using static FreeSurround from Externals
|
# Using static FreeSurround from Externals
|
||||||
# There is no system FreeSurround library.
|
# There is no system FreeSurround library.
|
||||||
|
|
|
@ -52,8 +52,8 @@
|
||||||
<ProjectReference Include="$(ExternalsDir)liblzma\liblzma.vcxproj">
|
<ProjectReference Include="$(ExternalsDir)liblzma\liblzma.vcxproj">
|
||||||
<Project>{055a775f-b4f5-4970-9240-f6cf7661f37b}</Project>
|
<Project>{055a775f-b4f5-4970-9240-f6cf7661f37b}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
<ProjectReference Include="$(ExternalsDir)libpng\png\png.vcxproj">
|
<ProjectReference Include="$(ExternalsDir)libspng\spng.vcxproj">
|
||||||
<Project>{4c9f135b-a85e-430c-bad4-4c67ef5fc12c}</Project>
|
<Project>{447B7B1E-1D74-4AEF-B2B9-6EB41C5D5313}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
<ProjectReference Include="$(ExternalsDir)libusb\libusb-1.0.vcxproj">
|
<ProjectReference Include="$(ExternalsDir)libusb\libusb-1.0.vcxproj">
|
||||||
<Project>{349ee8f9-7d25-4909-aaf5-ff3fade72187}</Project>
|
<Project>{349ee8f9-7d25-4909-aaf5-ff3fade72187}</Project>
|
||||||
|
|
|
@ -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()
|
|
|
@ -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.
|
|
|
@ -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 */
|
|
|
@ -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 */
|
|
|
@ -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 */
|
|
|
@ -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 */
|
|
|
@ -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 */
|
|
|
@ -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 */
|
|
|
@ -1,808 +0,0 @@
|
||||||
|
|
||||||
/* filter_msa_intrinsics.c - MSA optimised filter functions
|
|
||||||
*
|
|
||||||
* Copyright (c) 2018 Cosmin Truta
|
|
||||||
* Copyright (c) 2016 Glenn Randers-Pehrson
|
|
||||||
* Written by Mandar Sahastrabuddhe, August 2016.
|
|
||||||
*
|
|
||||||
* This code is released under the libpng license.
|
|
||||||
* For conditions of distribution and use, see the disclaimer
|
|
||||||
* and license in png.h
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "../pngpriv.h"
|
|
||||||
|
|
||||||
#ifdef PNG_READ_SUPPORTED
|
|
||||||
|
|
||||||
/* This code requires -mfpu=msa on the command line: */
|
|
||||||
#if PNG_MIPS_MSA_IMPLEMENTATION == 1 /* intrinsics code from pngpriv.h */
|
|
||||||
|
|
||||||
#include <msa.h>
|
|
||||||
|
|
||||||
/* libpng row pointers are not necessarily aligned to any particular boundary,
|
|
||||||
* however this code will only work with appropriate alignment. mips/mips_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.
|
|
||||||
*/
|
|
||||||
#define png_ldr(type,pointer)\
|
|
||||||
(temp_pointer = png_ptr(type,pointer), *temp_pointer)
|
|
||||||
|
|
||||||
#if PNG_MIPS_MSA_OPT > 0
|
|
||||||
|
|
||||||
#ifdef CLANG_BUILD
|
|
||||||
#define MSA_SRLI_B(a, b) __msa_srli_b((v16i8) a, b)
|
|
||||||
|
|
||||||
#define LW(psrc) \
|
|
||||||
( { \
|
|
||||||
uint8_t *psrc_lw_m = (uint8_t *) (psrc); \
|
|
||||||
uint32_t val_m; \
|
|
||||||
\
|
|
||||||
asm volatile ( \
|
|
||||||
"lw %[val_m], %[psrc_lw_m] \n\t" \
|
|
||||||
\
|
|
||||||
: [val_m] "=r" (val_m) \
|
|
||||||
: [psrc_lw_m] "m" (*psrc_lw_m) \
|
|
||||||
); \
|
|
||||||
\
|
|
||||||
val_m; \
|
|
||||||
} )
|
|
||||||
|
|
||||||
#define SH(val, pdst) \
|
|
||||||
{ \
|
|
||||||
uint8_t *pdst_sh_m = (uint8_t *) (pdst); \
|
|
||||||
uint16_t val_m = (val); \
|
|
||||||
\
|
|
||||||
asm volatile ( \
|
|
||||||
"sh %[val_m], %[pdst_sh_m] \n\t" \
|
|
||||||
\
|
|
||||||
: [pdst_sh_m] "=m" (*pdst_sh_m) \
|
|
||||||
: [val_m] "r" (val_m) \
|
|
||||||
); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SW(val, pdst) \
|
|
||||||
{ \
|
|
||||||
uint8_t *pdst_sw_m = (uint8_t *) (pdst); \
|
|
||||||
uint32_t val_m = (val); \
|
|
||||||
\
|
|
||||||
asm volatile ( \
|
|
||||||
"sw %[val_m], %[pdst_sw_m] \n\t" \
|
|
||||||
\
|
|
||||||
: [pdst_sw_m] "=m" (*pdst_sw_m) \
|
|
||||||
: [val_m] "r" (val_m) \
|
|
||||||
); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#if (__mips == 64)
|
|
||||||
#define SD(val, pdst) \
|
|
||||||
{ \
|
|
||||||
uint8_t *pdst_sd_m = (uint8_t *) (pdst); \
|
|
||||||
uint64_t val_m = (val); \
|
|
||||||
\
|
|
||||||
asm volatile ( \
|
|
||||||
"sd %[val_m], %[pdst_sd_m] \n\t" \
|
|
||||||
\
|
|
||||||
: [pdst_sd_m] "=m" (*pdst_sd_m) \
|
|
||||||
: [val_m] "r" (val_m) \
|
|
||||||
); \
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#define SD(val, pdst) \
|
|
||||||
{ \
|
|
||||||
uint8_t *pdst_sd_m = (uint8_t *) (pdst); \
|
|
||||||
uint32_t val0_m, val1_m; \
|
|
||||||
\
|
|
||||||
val0_m = (uint32_t) ((val) & 0x00000000FFFFFFFF); \
|
|
||||||
val1_m = (uint32_t) (((val) >> 32) & 0x00000000FFFFFFFF); \
|
|
||||||
\
|
|
||||||
SW(val0_m, pdst_sd_m); \
|
|
||||||
SW(val1_m, pdst_sd_m + 4); \
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#define MSA_SRLI_B(a, b) (a >> b)
|
|
||||||
|
|
||||||
#if (__mips_isa_rev >= 6)
|
|
||||||
#define LW(psrc) \
|
|
||||||
( { \
|
|
||||||
uint8_t *psrc_lw_m = (uint8_t *) (psrc); \
|
|
||||||
uint32_t val_m; \
|
|
||||||
\
|
|
||||||
asm volatile ( \
|
|
||||||
"lw %[val_m], %[psrc_lw_m] \n\t" \
|
|
||||||
\
|
|
||||||
: [val_m] "=r" (val_m) \
|
|
||||||
: [psrc_lw_m] "m" (*psrc_lw_m) \
|
|
||||||
); \
|
|
||||||
\
|
|
||||||
val_m; \
|
|
||||||
} )
|
|
||||||
|
|
||||||
#define SH(val, pdst) \
|
|
||||||
{ \
|
|
||||||
uint8_t *pdst_sh_m = (uint8_t *) (pdst); \
|
|
||||||
uint16_t val_m = (val); \
|
|
||||||
\
|
|
||||||
asm volatile ( \
|
|
||||||
"sh %[val_m], %[pdst_sh_m] \n\t" \
|
|
||||||
\
|
|
||||||
: [pdst_sh_m] "=m" (*pdst_sh_m) \
|
|
||||||
: [val_m] "r" (val_m) \
|
|
||||||
); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SW(val, pdst) \
|
|
||||||
{ \
|
|
||||||
uint8_t *pdst_sw_m = (uint8_t *) (pdst); \
|
|
||||||
uint32_t val_m = (val); \
|
|
||||||
\
|
|
||||||
asm volatile ( \
|
|
||||||
"sw %[val_m], %[pdst_sw_m] \n\t" \
|
|
||||||
\
|
|
||||||
: [pdst_sw_m] "=m" (*pdst_sw_m) \
|
|
||||||
: [val_m] "r" (val_m) \
|
|
||||||
); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#if (__mips == 64)
|
|
||||||
#define SD(val, pdst) \
|
|
||||||
{ \
|
|
||||||
uint8_t *pdst_sd_m = (uint8_t *) (pdst); \
|
|
||||||
uint64_t val_m = (val); \
|
|
||||||
\
|
|
||||||
asm volatile ( \
|
|
||||||
"sd %[val_m], %[pdst_sd_m] \n\t" \
|
|
||||||
\
|
|
||||||
: [pdst_sd_m] "=m" (*pdst_sd_m) \
|
|
||||||
: [val_m] "r" (val_m) \
|
|
||||||
); \
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#define SD(val, pdst) \
|
|
||||||
{ \
|
|
||||||
uint8_t *pdst_sd_m = (uint8_t *) (pdst); \
|
|
||||||
uint32_t val0_m, val1_m; \
|
|
||||||
\
|
|
||||||
val0_m = (uint32_t) ((val) & 0x00000000FFFFFFFF); \
|
|
||||||
val1_m = (uint32_t) (((val) >> 32) & 0x00000000FFFFFFFF); \
|
|
||||||
\
|
|
||||||
SW(val0_m, pdst_sd_m); \
|
|
||||||
SW(val1_m, pdst_sd_m + 4); \
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#else // !(__mips_isa_rev >= 6)
|
|
||||||
#define LW(psrc) \
|
|
||||||
( { \
|
|
||||||
uint8_t *psrc_lw_m = (uint8_t *) (psrc); \
|
|
||||||
uint32_t val_m; \
|
|
||||||
\
|
|
||||||
asm volatile ( \
|
|
||||||
"ulw %[val_m], %[psrc_lw_m] \n\t" \
|
|
||||||
\
|
|
||||||
: [val_m] "=r" (val_m) \
|
|
||||||
: [psrc_lw_m] "m" (*psrc_lw_m) \
|
|
||||||
); \
|
|
||||||
\
|
|
||||||
val_m; \
|
|
||||||
} )
|
|
||||||
|
|
||||||
#define SH(val, pdst) \
|
|
||||||
{ \
|
|
||||||
uint8_t *pdst_sh_m = (uint8_t *) (pdst); \
|
|
||||||
uint16_t val_m = (val); \
|
|
||||||
\
|
|
||||||
asm volatile ( \
|
|
||||||
"ush %[val_m], %[pdst_sh_m] \n\t" \
|
|
||||||
\
|
|
||||||
: [pdst_sh_m] "=m" (*pdst_sh_m) \
|
|
||||||
: [val_m] "r" (val_m) \
|
|
||||||
); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SW(val, pdst) \
|
|
||||||
{ \
|
|
||||||
uint8_t *pdst_sw_m = (uint8_t *) (pdst); \
|
|
||||||
uint32_t val_m = (val); \
|
|
||||||
\
|
|
||||||
asm volatile ( \
|
|
||||||
"usw %[val_m], %[pdst_sw_m] \n\t" \
|
|
||||||
\
|
|
||||||
: [pdst_sw_m] "=m" (*pdst_sw_m) \
|
|
||||||
: [val_m] "r" (val_m) \
|
|
||||||
); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SD(val, pdst) \
|
|
||||||
{ \
|
|
||||||
uint8_t *pdst_sd_m = (uint8_t *) (pdst); \
|
|
||||||
uint32_t val0_m, val1_m; \
|
|
||||||
\
|
|
||||||
val0_m = (uint32_t) ((val) & 0x00000000FFFFFFFF); \
|
|
||||||
val1_m = (uint32_t) (((val) >> 32) & 0x00000000FFFFFFFF); \
|
|
||||||
\
|
|
||||||
SW(val0_m, pdst_sd_m); \
|
|
||||||
SW(val1_m, pdst_sd_m + 4); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SW_ZERO(pdst) \
|
|
||||||
{ \
|
|
||||||
uint8_t *pdst_m = (uint8_t *) (pdst); \
|
|
||||||
\
|
|
||||||
asm volatile ( \
|
|
||||||
"usw $0, %[pdst_m] \n\t" \
|
|
||||||
\
|
|
||||||
: [pdst_m] "=m" (*pdst_m) \
|
|
||||||
: \
|
|
||||||
); \
|
|
||||||
}
|
|
||||||
#endif // (__mips_isa_rev >= 6)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define LD_B(RTYPE, psrc) *((RTYPE *) (psrc))
|
|
||||||
#define LD_UB(...) LD_B(v16u8, __VA_ARGS__)
|
|
||||||
#define LD_B2(RTYPE, psrc, stride, out0, out1) \
|
|
||||||
{ \
|
|
||||||
out0 = LD_B(RTYPE, (psrc)); \
|
|
||||||
out1 = LD_B(RTYPE, (psrc) + stride); \
|
|
||||||
}
|
|
||||||
#define LD_UB2(...) LD_B2(v16u8, __VA_ARGS__)
|
|
||||||
#define LD_B4(RTYPE, psrc, stride, out0, out1, out2, out3) \
|
|
||||||
{ \
|
|
||||||
LD_B2(RTYPE, (psrc), stride, out0, out1); \
|
|
||||||
LD_B2(RTYPE, (psrc) + 2 * stride , stride, out2, out3); \
|
|
||||||
}
|
|
||||||
#define LD_UB4(...) LD_B4(v16u8, __VA_ARGS__)
|
|
||||||
|
|
||||||
#define ST_B(RTYPE, in, pdst) *((RTYPE *) (pdst)) = (in)
|
|
||||||
#define ST_UB(...) ST_B(v16u8, __VA_ARGS__)
|
|
||||||
#define ST_B2(RTYPE, in0, in1, pdst, stride) \
|
|
||||||
{ \
|
|
||||||
ST_B(RTYPE, in0, (pdst)); \
|
|
||||||
ST_B(RTYPE, in1, (pdst) + stride); \
|
|
||||||
}
|
|
||||||
#define ST_UB2(...) ST_B2(v16u8, __VA_ARGS__)
|
|
||||||
#define ST_B4(RTYPE, in0, in1, in2, in3, pdst, stride) \
|
|
||||||
{ \
|
|
||||||
ST_B2(RTYPE, in0, in1, (pdst), stride); \
|
|
||||||
ST_B2(RTYPE, in2, in3, (pdst) + 2 * stride, stride); \
|
|
||||||
}
|
|
||||||
#define ST_UB4(...) ST_B4(v16u8, __VA_ARGS__)
|
|
||||||
|
|
||||||
#define ADD2(in0, in1, in2, in3, out0, out1) \
|
|
||||||
{ \
|
|
||||||
out0 = in0 + in1; \
|
|
||||||
out1 = in2 + in3; \
|
|
||||||
}
|
|
||||||
#define ADD3(in0, in1, in2, in3, in4, in5, \
|
|
||||||
out0, out1, out2) \
|
|
||||||
{ \
|
|
||||||
ADD2(in0, in1, in2, in3, out0, out1); \
|
|
||||||
out2 = in4 + in5; \
|
|
||||||
}
|
|
||||||
#define ADD4(in0, in1, in2, in3, in4, in5, in6, in7, \
|
|
||||||
out0, out1, out2, out3) \
|
|
||||||
{ \
|
|
||||||
ADD2(in0, in1, in2, in3, out0, out1); \
|
|
||||||
ADD2(in4, in5, in6, in7, out2, out3); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define ILVR_B2(RTYPE, in0, in1, in2, in3, out0, out1) \
|
|
||||||
{ \
|
|
||||||
out0 = (RTYPE) __msa_ilvr_b((v16i8) in0, (v16i8) in1); \
|
|
||||||
out1 = (RTYPE) __msa_ilvr_b((v16i8) in2, (v16i8) in3); \
|
|
||||||
}
|
|
||||||
#define ILVR_B2_SH(...) ILVR_B2(v8i16, __VA_ARGS__)
|
|
||||||
|
|
||||||
#define HSUB_UB2(RTYPE, in0, in1, out0, out1) \
|
|
||||||
{ \
|
|
||||||
out0 = (RTYPE) __msa_hsub_u_h((v16u8) in0, (v16u8) in0); \
|
|
||||||
out1 = (RTYPE) __msa_hsub_u_h((v16u8) in1, (v16u8) in1); \
|
|
||||||
}
|
|
||||||
#define HSUB_UB2_SH(...) HSUB_UB2(v8i16, __VA_ARGS__)
|
|
||||||
|
|
||||||
#define SLDI_B2_0(RTYPE, in0, in1, out0, out1, slide_val) \
|
|
||||||
{ \
|
|
||||||
v16i8 zero_m = { 0 }; \
|
|
||||||
out0 = (RTYPE) __msa_sldi_b((v16i8) zero_m, (v16i8) in0, slide_val); \
|
|
||||||
out1 = (RTYPE) __msa_sldi_b((v16i8) zero_m, (v16i8) in1, slide_val); \
|
|
||||||
}
|
|
||||||
#define SLDI_B2_0_UB(...) SLDI_B2_0(v16u8, __VA_ARGS__)
|
|
||||||
|
|
||||||
#define SLDI_B3_0(RTYPE, in0, in1, in2, out0, out1, out2, slide_val) \
|
|
||||||
{ \
|
|
||||||
v16i8 zero_m = { 0 }; \
|
|
||||||
SLDI_B2_0(RTYPE, in0, in1, out0, out1, slide_val); \
|
|
||||||
out2 = (RTYPE) __msa_sldi_b((v16i8) zero_m, (v16i8) in2, slide_val); \
|
|
||||||
}
|
|
||||||
#define SLDI_B3_0_UB(...) SLDI_B3_0(v16u8, __VA_ARGS__)
|
|
||||||
|
|
||||||
#define ILVEV_W2(RTYPE, in0, in1, in2, in3, out0, out1) \
|
|
||||||
{ \
|
|
||||||
out0 = (RTYPE) __msa_ilvev_w((v4i32) in1, (v4i32) in0); \
|
|
||||||
out1 = (RTYPE) __msa_ilvev_w((v4i32) in3, (v4i32) in2); \
|
|
||||||
}
|
|
||||||
#define ILVEV_W2_UB(...) ILVEV_W2(v16u8, __VA_ARGS__)
|
|
||||||
|
|
||||||
#define ADD_ABS_H3(RTYPE, in0, in1, in2, out0, out1, out2) \
|
|
||||||
{ \
|
|
||||||
RTYPE zero = {0}; \
|
|
||||||
\
|
|
||||||
out0 = __msa_add_a_h((v8i16) zero, in0); \
|
|
||||||
out1 = __msa_add_a_h((v8i16) zero, in1); \
|
|
||||||
out2 = __msa_add_a_h((v8i16) zero, in2); \
|
|
||||||
}
|
|
||||||
#define ADD_ABS_H3_SH(...) ADD_ABS_H3(v8i16, __VA_ARGS__)
|
|
||||||
|
|
||||||
#define VSHF_B2(RTYPE, in0, in1, in2, in3, mask0, mask1, out0, out1) \
|
|
||||||
{ \
|
|
||||||
out0 = (RTYPE) __msa_vshf_b((v16i8) mask0, (v16i8) in1, (v16i8) in0); \
|
|
||||||
out1 = (RTYPE) __msa_vshf_b((v16i8) mask1, (v16i8) in3, (v16i8) in2); \
|
|
||||||
}
|
|
||||||
#define VSHF_B2_UB(...) VSHF_B2(v16u8, __VA_ARGS__)
|
|
||||||
|
|
||||||
#define CMP_AND_SELECT(inp0, inp1, inp2, inp3, inp4, inp5, out0) \
|
|
||||||
{ \
|
|
||||||
v8i16 _sel_h0, _sel_h1; \
|
|
||||||
v16u8 _sel_b0, _sel_b1; \
|
|
||||||
_sel_h0 = (v8i16) __msa_clt_u_h((v8u16) inp1, (v8u16) inp0); \
|
|
||||||
_sel_b0 = (v16u8) __msa_pckev_b((v16i8) _sel_h0, (v16i8) _sel_h0); \
|
|
||||||
inp0 = (v8i16) __msa_bmnz_v((v16u8) inp0, (v16u8) inp1, (v16u8) _sel_h0); \
|
|
||||||
inp4 = (v16u8) __msa_bmnz_v(inp3, inp4, _sel_b0); \
|
|
||||||
_sel_h1 = (v8i16) __msa_clt_u_h((v8u16) inp2, (v8u16) inp0); \
|
|
||||||
_sel_b1 = (v16u8) __msa_pckev_b((v16i8) _sel_h1, (v16i8) _sel_h1); \
|
|
||||||
inp4 = (v16u8) __msa_bmnz_v(inp4, inp5, _sel_b1); \
|
|
||||||
out0 += inp4; \
|
|
||||||
}
|
|
||||||
|
|
||||||
void png_read_filter_row_up_msa(png_row_infop row_info, png_bytep row,
|
|
||||||
png_const_bytep prev_row)
|
|
||||||
{
|
|
||||||
size_t i, cnt, cnt16, cnt32;
|
|
||||||
size_t istop = row_info->rowbytes;
|
|
||||||
png_bytep rp = row;
|
|
||||||
png_const_bytep pp = prev_row;
|
|
||||||
v16u8 src0, src1, src2, src3, src4, src5, src6, src7;
|
|
||||||
|
|
||||||
for (i = 0; i < (istop >> 6); i++)
|
|
||||||
{
|
|
||||||
LD_UB4(rp, 16, src0, src1, src2, src3);
|
|
||||||
LD_UB4(pp, 16, src4, src5, src6, src7);
|
|
||||||
pp += 64;
|
|
||||||
|
|
||||||
ADD4(src0, src4, src1, src5, src2, src6, src3, src7,
|
|
||||||
src0, src1, src2, src3);
|
|
||||||
|
|
||||||
ST_UB4(src0, src1, src2, src3, rp, 16);
|
|
||||||
rp += 64;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (istop & 0x3F)
|
|
||||||
{
|
|
||||||
cnt32 = istop & 0x20;
|
|
||||||
cnt16 = istop & 0x10;
|
|
||||||
cnt = istop & 0xF;
|
|
||||||
|
|
||||||
if(cnt32)
|
|
||||||
{
|
|
||||||
if (cnt16 && cnt)
|
|
||||||
{
|
|
||||||
LD_UB4(rp, 16, src0, src1, src2, src3);
|
|
||||||
LD_UB4(pp, 16, src4, src5, src6, src7);
|
|
||||||
|
|
||||||
ADD4(src0, src4, src1, src5, src2, src6, src3, src7,
|
|
||||||
src0, src1, src2, src3);
|
|
||||||
|
|
||||||
ST_UB4(src0, src1, src2, src3, rp, 16);
|
|
||||||
rp += 64;
|
|
||||||
}
|
|
||||||
else if (cnt16 || cnt)
|
|
||||||
{
|
|
||||||
LD_UB2(rp, 16, src0, src1);
|
|
||||||
LD_UB2(pp, 16, src4, src5);
|
|
||||||
pp += 32;
|
|
||||||
src2 = LD_UB(rp + 32);
|
|
||||||
src6 = LD_UB(pp);
|
|
||||||
|
|
||||||
ADD3(src0, src4, src1, src5, src2, src6, src0, src1, src2);
|
|
||||||
|
|
||||||
ST_UB2(src0, src1, rp, 16);
|
|
||||||
rp += 32;
|
|
||||||
ST_UB(src2, rp);
|
|
||||||
rp += 16;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LD_UB2(rp, 16, src0, src1);
|
|
||||||
LD_UB2(pp, 16, src4, src5);
|
|
||||||
|
|
||||||
ADD2(src0, src4, src1, src5, src0, src1);
|
|
||||||
|
|
||||||
ST_UB2(src0, src1, rp, 16);
|
|
||||||
rp += 32;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (cnt16 && cnt)
|
|
||||||
{
|
|
||||||
LD_UB2(rp, 16, src0, src1);
|
|
||||||
LD_UB2(pp, 16, src4, src5);
|
|
||||||
|
|
||||||
ADD2(src0, src4, src1, src5, src0, src1);
|
|
||||||
|
|
||||||
ST_UB2(src0, src1, rp, 16);
|
|
||||||
rp += 32;
|
|
||||||
}
|
|
||||||
else if (cnt16 || cnt)
|
|
||||||
{
|
|
||||||
src0 = LD_UB(rp);
|
|
||||||
src4 = LD_UB(pp);
|
|
||||||
pp += 16;
|
|
||||||
|
|
||||||
src0 += src4;
|
|
||||||
|
|
||||||
ST_UB(src0, rp);
|
|
||||||
rp += 16;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void png_read_filter_row_sub4_msa(png_row_infop row_info, png_bytep row,
|
|
||||||
png_const_bytep prev_row)
|
|
||||||
{
|
|
||||||
size_t count;
|
|
||||||
size_t istop = row_info->rowbytes;
|
|
||||||
png_bytep src = row;
|
|
||||||
png_bytep nxt = row + 4;
|
|
||||||
int32_t inp0;
|
|
||||||
v16u8 src0, src1, src2, src3, src4;
|
|
||||||
v16u8 dst0, dst1;
|
|
||||||
v16u8 zero = { 0 };
|
|
||||||
|
|
||||||
istop -= 4;
|
|
||||||
|
|
||||||
inp0 = LW(src);
|
|
||||||
src += 4;
|
|
||||||
src0 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp0);
|
|
||||||
|
|
||||||
for (count = 0; count < istop; count += 16)
|
|
||||||
{
|
|
||||||
src1 = LD_UB(src);
|
|
||||||
src += 16;
|
|
||||||
|
|
||||||
src2 = (v16u8) __msa_sldi_b((v16i8) zero, (v16i8) src1, 4);
|
|
||||||
src3 = (v16u8) __msa_sldi_b((v16i8) zero, (v16i8) src1, 8);
|
|
||||||
src4 = (v16u8) __msa_sldi_b((v16i8) zero, (v16i8) src1, 12);
|
|
||||||
src1 += src0;
|
|
||||||
src2 += src1;
|
|
||||||
src3 += src2;
|
|
||||||
src4 += src3;
|
|
||||||
src0 = src4;
|
|
||||||
ILVEV_W2_UB(src1, src2, src3, src4, dst0, dst1);
|
|
||||||
dst0 = (v16u8) __msa_pckev_d((v2i64) dst1, (v2i64) dst0);
|
|
||||||
|
|
||||||
ST_UB(dst0, nxt);
|
|
||||||
nxt += 16;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void png_read_filter_row_sub3_msa(png_row_infop row_info, png_bytep row,
|
|
||||||
png_const_bytep prev_row)
|
|
||||||
{
|
|
||||||
size_t count;
|
|
||||||
size_t istop = row_info->rowbytes;
|
|
||||||
png_bytep src = row;
|
|
||||||
png_bytep nxt = row + 3;
|
|
||||||
int64_t out0;
|
|
||||||
int32_t inp0, out1;
|
|
||||||
v16u8 src0, src1, src2, src3, src4, dst0, dst1;
|
|
||||||
v16u8 zero = { 0 };
|
|
||||||
v16i8 mask0 = { 0, 1, 2, 16, 17, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
|
||||||
v16i8 mask1 = { 0, 1, 2, 3, 4, 5, 16, 17, 18, 19, 20, 21, 0, 0, 0, 0 };
|
|
||||||
|
|
||||||
istop -= 3;
|
|
||||||
|
|
||||||
inp0 = LW(src);
|
|
||||||
src += 3;
|
|
||||||
src0 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp0);
|
|
||||||
|
|
||||||
for (count = 0; count < istop; count += 12)
|
|
||||||
{
|
|
||||||
src1 = LD_UB(src);
|
|
||||||
src += 12;
|
|
||||||
|
|
||||||
src2 = (v16u8) __msa_sldi_b((v16i8) zero, (v16i8) src1, 3);
|
|
||||||
src3 = (v16u8) __msa_sldi_b((v16i8) zero, (v16i8) src1, 6);
|
|
||||||
src4 = (v16u8) __msa_sldi_b((v16i8) zero, (v16i8) src1, 9);
|
|
||||||
src1 += src0;
|
|
||||||
src2 += src1;
|
|
||||||
src3 += src2;
|
|
||||||
src4 += src3;
|
|
||||||
src0 = src4;
|
|
||||||
VSHF_B2_UB(src1, src2, src3, src4, mask0, mask0, dst0, dst1);
|
|
||||||
dst0 = (v16u8) __msa_vshf_b(mask1, (v16i8) dst1, (v16i8) dst0);
|
|
||||||
out0 = __msa_copy_s_d((v2i64) dst0, 0);
|
|
||||||
out1 = __msa_copy_s_w((v4i32) dst0, 2);
|
|
||||||
|
|
||||||
SD(out0, nxt);
|
|
||||||
nxt += 8;
|
|
||||||
SW(out1, nxt);
|
|
||||||
nxt += 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void png_read_filter_row_avg4_msa(png_row_infop row_info, png_bytep row,
|
|
||||||
png_const_bytep prev_row)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
png_bytep src = row;
|
|
||||||
png_bytep nxt = row;
|
|
||||||
png_const_bytep pp = prev_row;
|
|
||||||
size_t istop = row_info->rowbytes - 4;
|
|
||||||
int32_t inp0, inp1, out0;
|
|
||||||
v16u8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, dst0, dst1;
|
|
||||||
v16u8 zero = { 0 };
|
|
||||||
|
|
||||||
inp0 = LW(pp);
|
|
||||||
pp += 4;
|
|
||||||
inp1 = LW(src);
|
|
||||||
src += 4;
|
|
||||||
src0 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp0);
|
|
||||||
src1 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp1);
|
|
||||||
src0 = (v16u8) MSA_SRLI_B(src0, 1);
|
|
||||||
src1 += src0;
|
|
||||||
out0 = __msa_copy_s_w((v4i32) src1, 0);
|
|
||||||
SW(out0, nxt);
|
|
||||||
nxt += 4;
|
|
||||||
|
|
||||||
for (i = 0; i < istop; i += 16)
|
|
||||||
{
|
|
||||||
src2 = LD_UB(pp);
|
|
||||||
pp += 16;
|
|
||||||
src6 = LD_UB(src);
|
|
||||||
src += 16;
|
|
||||||
|
|
||||||
SLDI_B2_0_UB(src2, src6, src3, src7, 4);
|
|
||||||
SLDI_B2_0_UB(src2, src6, src4, src8, 8);
|
|
||||||
SLDI_B2_0_UB(src2, src6, src5, src9, 12);
|
|
||||||
src2 = __msa_ave_u_b(src2, src1);
|
|
||||||
src6 += src2;
|
|
||||||
src3 = __msa_ave_u_b(src3, src6);
|
|
||||||
src7 += src3;
|
|
||||||
src4 = __msa_ave_u_b(src4, src7);
|
|
||||||
src8 += src4;
|
|
||||||
src5 = __msa_ave_u_b(src5, src8);
|
|
||||||
src9 += src5;
|
|
||||||
src1 = src9;
|
|
||||||
ILVEV_W2_UB(src6, src7, src8, src9, dst0, dst1);
|
|
||||||
dst0 = (v16u8) __msa_pckev_d((v2i64) dst1, (v2i64) dst0);
|
|
||||||
|
|
||||||
ST_UB(dst0, nxt);
|
|
||||||
nxt += 16;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void png_read_filter_row_avg3_msa(png_row_infop row_info, png_bytep row,
|
|
||||||
png_const_bytep prev_row)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
png_bytep src = row;
|
|
||||||
png_bytep nxt = row;
|
|
||||||
png_const_bytep pp = prev_row;
|
|
||||||
size_t istop = row_info->rowbytes - 3;
|
|
||||||
int64_t out0;
|
|
||||||
int32_t inp0, inp1, out1;
|
|
||||||
int16_t out2;
|
|
||||||
v16u8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, dst0, dst1;
|
|
||||||
v16u8 zero = { 0 };
|
|
||||||
v16i8 mask0 = { 0, 1, 2, 16, 17, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
|
||||||
v16i8 mask1 = { 0, 1, 2, 3, 4, 5, 16, 17, 18, 19, 20, 21, 0, 0, 0, 0 };
|
|
||||||
|
|
||||||
inp0 = LW(pp);
|
|
||||||
pp += 3;
|
|
||||||
inp1 = LW(src);
|
|
||||||
src += 3;
|
|
||||||
src0 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp0);
|
|
||||||
src1 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp1);
|
|
||||||
src0 = (v16u8) MSA_SRLI_B(src0, 1);
|
|
||||||
src1 += src0;
|
|
||||||
out2 = __msa_copy_s_h((v8i16) src1, 0);
|
|
||||||
SH(out2, nxt);
|
|
||||||
nxt += 2;
|
|
||||||
nxt[0] = src1[2];
|
|
||||||
nxt++;
|
|
||||||
|
|
||||||
for (i = 0; i < istop; i += 12)
|
|
||||||
{
|
|
||||||
src2 = LD_UB(pp);
|
|
||||||
pp += 12;
|
|
||||||
src6 = LD_UB(src);
|
|
||||||
src += 12;
|
|
||||||
|
|
||||||
SLDI_B2_0_UB(src2, src6, src3, src7, 3);
|
|
||||||
SLDI_B2_0_UB(src2, src6, src4, src8, 6);
|
|
||||||
SLDI_B2_0_UB(src2, src6, src5, src9, 9);
|
|
||||||
src2 = __msa_ave_u_b(src2, src1);
|
|
||||||
src6 += src2;
|
|
||||||
src3 = __msa_ave_u_b(src3, src6);
|
|
||||||
src7 += src3;
|
|
||||||
src4 = __msa_ave_u_b(src4, src7);
|
|
||||||
src8 += src4;
|
|
||||||
src5 = __msa_ave_u_b(src5, src8);
|
|
||||||
src9 += src5;
|
|
||||||
src1 = src9;
|
|
||||||
VSHF_B2_UB(src6, src7, src8, src9, mask0, mask0, dst0, dst1);
|
|
||||||
dst0 = (v16u8) __msa_vshf_b(mask1, (v16i8) dst1, (v16i8) dst0);
|
|
||||||
out0 = __msa_copy_s_d((v2i64) dst0, 0);
|
|
||||||
out1 = __msa_copy_s_w((v4i32) dst0, 2);
|
|
||||||
|
|
||||||
SD(out0, nxt);
|
|
||||||
nxt += 8;
|
|
||||||
SW(out1, nxt);
|
|
||||||
nxt += 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void png_read_filter_row_paeth4_msa(png_row_infop row_info,
|
|
||||||
png_bytep row,
|
|
||||||
png_const_bytep prev_row)
|
|
||||||
{
|
|
||||||
int32_t count, rp_end;
|
|
||||||
png_bytep nxt;
|
|
||||||
png_const_bytep prev_nxt;
|
|
||||||
int32_t inp0, inp1, res0;
|
|
||||||
v16u8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9;
|
|
||||||
v16u8 src10, src11, src12, src13, dst0, dst1;
|
|
||||||
v8i16 vec0, vec1, vec2;
|
|
||||||
v16u8 zero = { 0 };
|
|
||||||
|
|
||||||
nxt = row;
|
|
||||||
prev_nxt = prev_row;
|
|
||||||
|
|
||||||
inp0 = LW(nxt);
|
|
||||||
inp1 = LW(prev_nxt);
|
|
||||||
prev_nxt += 4;
|
|
||||||
src0 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp0);
|
|
||||||
src1 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp1);
|
|
||||||
|
|
||||||
src1 += src0;
|
|
||||||
res0 = __msa_copy_s_w((v4i32) src1, 0);
|
|
||||||
|
|
||||||
SW(res0, nxt);
|
|
||||||
nxt += 4;
|
|
||||||
|
|
||||||
/* Remainder */
|
|
||||||
rp_end = row_info->rowbytes - 4;
|
|
||||||
|
|
||||||
for (count = 0; count < rp_end; count += 16)
|
|
||||||
{
|
|
||||||
src2 = LD_UB(prev_nxt);
|
|
||||||
prev_nxt += 16;
|
|
||||||
src6 = LD_UB(prev_row);
|
|
||||||
prev_row += 16;
|
|
||||||
src10 = LD_UB(nxt);
|
|
||||||
|
|
||||||
SLDI_B3_0_UB(src2, src6, src10, src3, src7, src11, 4);
|
|
||||||
SLDI_B3_0_UB(src2, src6, src10, src4, src8, src12, 8);
|
|
||||||
SLDI_B3_0_UB(src2, src6, src10, src5, src9, src13, 12);
|
|
||||||
ILVR_B2_SH(src2, src6, src1, src6, vec0, vec1);
|
|
||||||
HSUB_UB2_SH(vec0, vec1, vec0, vec1);
|
|
||||||
vec2 = vec0 + vec1;
|
|
||||||
ADD_ABS_H3_SH(vec0, vec1, vec2, vec0, vec1, vec2);
|
|
||||||
CMP_AND_SELECT(vec0, vec1, vec2, src1, src2, src6, src10);
|
|
||||||
ILVR_B2_SH(src3, src7, src10, src7, vec0, vec1);
|
|
||||||
HSUB_UB2_SH(vec0, vec1, vec0, vec1);
|
|
||||||
vec2 = vec0 + vec1;
|
|
||||||
ADD_ABS_H3_SH(vec0, vec1, vec2, vec0, vec1, vec2);
|
|
||||||
CMP_AND_SELECT(vec0, vec1, vec2, src10, src3, src7, src11);
|
|
||||||
ILVR_B2_SH(src4, src8, src11, src8, vec0, vec1);
|
|
||||||
HSUB_UB2_SH(vec0, vec1, vec0, vec1);
|
|
||||||
vec2 = vec0 + vec1;
|
|
||||||
ADD_ABS_H3_SH(vec0, vec1, vec2, vec0, vec1, vec2);
|
|
||||||
CMP_AND_SELECT(vec0, vec1, vec2, src11, src4, src8, src12);
|
|
||||||
ILVR_B2_SH(src5, src9, src12, src9, vec0, vec1);
|
|
||||||
HSUB_UB2_SH(vec0, vec1, vec0, vec1);
|
|
||||||
vec2 = vec0 + vec1;
|
|
||||||
ADD_ABS_H3_SH(vec0, vec1, vec2, vec0, vec1, vec2);
|
|
||||||
CMP_AND_SELECT(vec0, vec1, vec2, src12, src5, src9, src13);
|
|
||||||
src1 = src13;
|
|
||||||
ILVEV_W2_UB(src10, src11, src12, src1, dst0, dst1);
|
|
||||||
dst0 = (v16u8) __msa_pckev_d((v2i64) dst1, (v2i64) dst0);
|
|
||||||
|
|
||||||
ST_UB(dst0, nxt);
|
|
||||||
nxt += 16;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void png_read_filter_row_paeth3_msa(png_row_infop row_info,
|
|
||||||
png_bytep row,
|
|
||||||
png_const_bytep prev_row)
|
|
||||||
{
|
|
||||||
int32_t count, rp_end;
|
|
||||||
png_bytep nxt;
|
|
||||||
png_const_bytep prev_nxt;
|
|
||||||
int64_t out0;
|
|
||||||
int32_t inp0, inp1, out1;
|
|
||||||
int16_t out2;
|
|
||||||
v16u8 src0, src1, src2, src3, src4, src5, src6, src7, src8, src9, dst0, dst1;
|
|
||||||
v16u8 src10, src11, src12, src13;
|
|
||||||
v8i16 vec0, vec1, vec2;
|
|
||||||
v16u8 zero = { 0 };
|
|
||||||
v16i8 mask0 = { 0, 1, 2, 16, 17, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
|
||||||
v16i8 mask1 = { 0, 1, 2, 3, 4, 5, 16, 17, 18, 19, 20, 21, 0, 0, 0, 0 };
|
|
||||||
|
|
||||||
nxt = row;
|
|
||||||
prev_nxt = prev_row;
|
|
||||||
|
|
||||||
inp0 = LW(nxt);
|
|
||||||
inp1 = LW(prev_nxt);
|
|
||||||
prev_nxt += 3;
|
|
||||||
src0 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp0);
|
|
||||||
src1 = (v16u8) __msa_insert_w((v4i32) zero, 0, inp1);
|
|
||||||
|
|
||||||
src1 += src0;
|
|
||||||
out2 = __msa_copy_s_h((v8i16) src1, 0);
|
|
||||||
|
|
||||||
SH(out2, nxt);
|
|
||||||
nxt += 2;
|
|
||||||
nxt[0] = src1[2];
|
|
||||||
nxt++;
|
|
||||||
|
|
||||||
/* Remainder */
|
|
||||||
rp_end = row_info->rowbytes - 3;
|
|
||||||
|
|
||||||
for (count = 0; count < rp_end; count += 12)
|
|
||||||
{
|
|
||||||
src2 = LD_UB(prev_nxt);
|
|
||||||
prev_nxt += 12;
|
|
||||||
src6 = LD_UB(prev_row);
|
|
||||||
prev_row += 12;
|
|
||||||
src10 = LD_UB(nxt);
|
|
||||||
|
|
||||||
SLDI_B3_0_UB(src2, src6, src10, src3, src7, src11, 3);
|
|
||||||
SLDI_B3_0_UB(src2, src6, src10, src4, src8, src12, 6);
|
|
||||||
SLDI_B3_0_UB(src2, src6, src10, src5, src9, src13, 9);
|
|
||||||
ILVR_B2_SH(src2, src6, src1, src6, vec0, vec1);
|
|
||||||
HSUB_UB2_SH(vec0, vec1, vec0, vec1);
|
|
||||||
vec2 = vec0 + vec1;
|
|
||||||
ADD_ABS_H3_SH(vec0, vec1, vec2, vec0, vec1, vec2);
|
|
||||||
CMP_AND_SELECT(vec0, vec1, vec2, src1, src2, src6, src10);
|
|
||||||
ILVR_B2_SH(src3, src7, src10, src7, vec0, vec1);
|
|
||||||
HSUB_UB2_SH(vec0, vec1, vec0, vec1);
|
|
||||||
vec2 = vec0 + vec1;
|
|
||||||
ADD_ABS_H3_SH(vec0, vec1, vec2, vec0, vec1, vec2);
|
|
||||||
CMP_AND_SELECT(vec0, vec1, vec2, src10, src3, src7, src11);
|
|
||||||
ILVR_B2_SH(src4, src8, src11, src8, vec0, vec1);
|
|
||||||
HSUB_UB2_SH(vec0, vec1, vec0, vec1);
|
|
||||||
vec2 = vec0 + vec1;
|
|
||||||
ADD_ABS_H3_SH(vec0, vec1, vec2, vec0, vec1, vec2);
|
|
||||||
CMP_AND_SELECT(vec0, vec1, vec2, src11, src4, src8, src12);
|
|
||||||
ILVR_B2_SH(src5, src9, src12, src9, vec0, vec1);
|
|
||||||
HSUB_UB2_SH(vec0, vec1, vec0, vec1);
|
|
||||||
vec2 = vec0 + vec1;
|
|
||||||
ADD_ABS_H3_SH(vec0, vec1, vec2, vec0, vec1, vec2);
|
|
||||||
CMP_AND_SELECT(vec0, vec1, vec2, src12, src5, src9, src13);
|
|
||||||
src1 = src13;
|
|
||||||
VSHF_B2_UB(src10, src11, src12, src13, mask0, mask0, dst0, dst1);
|
|
||||||
dst0 = (v16u8) __msa_vshf_b(mask1, (v16i8) dst1, (v16i8) dst0);
|
|
||||||
out0 = __msa_copy_s_d((v2i64) dst0, 0);
|
|
||||||
out1 = __msa_copy_s_w((v4i32) dst0, 2);
|
|
||||||
|
|
||||||
SD(out0, nxt);
|
|
||||||
nxt += 8;
|
|
||||||
SW(out1, nxt);
|
|
||||||
nxt += 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* PNG_MIPS_MSA_OPT > 0 */
|
|
||||||
#endif /* PNG_MIPS_MSA_IMPLEMENTATION == 1 (intrinsics) */
|
|
||||||
#endif /* READ */
|
|
|
@ -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 */
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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>
|
|
|
@ -1,623 +0,0 @@
|
||||||
|
|
||||||
/* pngconf.h - machine-configurable file for libpng
|
|
||||||
*
|
|
||||||
* libpng version 1.6.37
|
|
||||||
*
|
|
||||||
* Copyright (c) 2018-2019 Cosmin Truta
|
|
||||||
* Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson
|
|
||||||
* Copyright (c) 1996-1997 Andreas Dilger
|
|
||||||
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
|
|
||||||
*
|
|
||||||
* This code is released under the libpng license.
|
|
||||||
* For conditions of distribution and use, see the disclaimer
|
|
||||||
* and license in png.h
|
|
||||||
*
|
|
||||||
* Any machine specific code is near the front of this file, so if you
|
|
||||||
* are configuring libpng for a machine, you may want to read the section
|
|
||||||
* starting here down to where it starts to typedef png_color, png_text,
|
|
||||||
* and png_info.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PNGCONF_H
|
|
||||||
#define PNGCONF_H
|
|
||||||
|
|
||||||
#ifndef PNG_BUILDING_SYMBOL_TABLE /* else includes may cause problems */
|
|
||||||
|
|
||||||
/* From libpng 1.6.0 libpng requires an ANSI X3.159-1989 ("ISOC90") compliant C
|
|
||||||
* compiler for correct compilation. The following header files are required by
|
|
||||||
* the standard. If your compiler doesn't provide these header files, or they
|
|
||||||
* do not match the standard, you will need to provide/improve them.
|
|
||||||
*/
|
|
||||||
#include <limits.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
/* Library header files. These header files are all defined by ISOC90; libpng
|
|
||||||
* expects conformant implementations, however, an ISOC90 conformant system need
|
|
||||||
* not provide these header files if the functionality cannot be implemented.
|
|
||||||
* In this case it will be necessary to disable the relevant parts of libpng in
|
|
||||||
* the build of pnglibconf.h.
|
|
||||||
*
|
|
||||||
* Prior to 1.6.0 string.h was included here; the API changes in 1.6.0 to not
|
|
||||||
* include this unnecessary header file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef PNG_STDIO_SUPPORTED
|
|
||||||
/* Required for the definition of FILE: */
|
|
||||||
# include <stdio.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PNG_SETJMP_SUPPORTED
|
|
||||||
/* Required for the definition of jmp_buf and the declaration of longjmp: */
|
|
||||||
# include <setjmp.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PNG_CONVERT_tIME_SUPPORTED
|
|
||||||
/* Required for struct tm: */
|
|
||||||
# include <time.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* PNG_BUILDING_SYMBOL_TABLE */
|
|
||||||
|
|
||||||
/* Prior to 1.6.0, it was possible to turn off 'const' in declarations,
|
|
||||||
* using PNG_NO_CONST. This is no longer supported.
|
|
||||||
*/
|
|
||||||
#define PNG_CONST const /* backward compatibility only */
|
|
||||||
|
|
||||||
/* This controls optimization of the reading of 16-bit and 32-bit
|
|
||||||
* values from PNG files. It can be set on a per-app-file basis: it
|
|
||||||
* just changes whether a macro is used when the function is called.
|
|
||||||
* The library builder sets the default; if read functions are not
|
|
||||||
* built into the library the macro implementation is forced on.
|
|
||||||
*/
|
|
||||||
#ifndef PNG_READ_INT_FUNCTIONS_SUPPORTED
|
|
||||||
# define PNG_USE_READ_MACROS
|
|
||||||
#endif
|
|
||||||
#if !defined(PNG_NO_USE_READ_MACROS) && !defined(PNG_USE_READ_MACROS)
|
|
||||||
# if PNG_DEFAULT_READ_MACROS
|
|
||||||
# define PNG_USE_READ_MACROS
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* COMPILER SPECIFIC OPTIONS.
|
|
||||||
*
|
|
||||||
* These options are provided so that a variety of difficult compilers
|
|
||||||
* can be used. Some are fixed at build time (e.g. PNG_API_RULE
|
|
||||||
* below) but still have compiler specific implementations, others
|
|
||||||
* may be changed on a per-file basis when compiling against libpng.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* The PNGARG macro was used in versions of libpng prior to 1.6.0 to protect
|
|
||||||
* against legacy (pre ISOC90) compilers that did not understand function
|
|
||||||
* prototypes. It is not required for modern C compilers.
|
|
||||||
*/
|
|
||||||
#ifndef PNGARG
|
|
||||||
# define PNGARG(arglist) arglist
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Function calling conventions.
|
|
||||||
* =============================
|
|
||||||
* Normally it is not necessary to specify to the compiler how to call
|
|
||||||
* a function - it just does it - however on x86 systems derived from
|
|
||||||
* Microsoft and Borland C compilers ('IBM PC', 'DOS', 'Windows' systems
|
|
||||||
* and some others) there are multiple ways to call a function and the
|
|
||||||
* default can be changed on the compiler command line. For this reason
|
|
||||||
* libpng specifies the calling convention of every exported function and
|
|
||||||
* every function called via a user supplied function pointer. This is
|
|
||||||
* done in this file by defining the following macros:
|
|
||||||
*
|
|
||||||
* PNGAPI Calling convention for exported functions.
|
|
||||||
* PNGCBAPI Calling convention for user provided (callback) functions.
|
|
||||||
* PNGCAPI Calling convention used by the ANSI-C library (required
|
|
||||||
* for longjmp callbacks and sometimes used internally to
|
|
||||||
* specify the calling convention for zlib).
|
|
||||||
*
|
|
||||||
* These macros should never be overridden. If it is necessary to
|
|
||||||
* change calling convention in a private build this can be done
|
|
||||||
* by setting PNG_API_RULE (which defaults to 0) to one of the values
|
|
||||||
* below to select the correct 'API' variants.
|
|
||||||
*
|
|
||||||
* PNG_API_RULE=0 Use PNGCAPI - the 'C' calling convention - throughout.
|
|
||||||
* This is correct in every known environment.
|
|
||||||
* PNG_API_RULE=1 Use the operating system convention for PNGAPI and
|
|
||||||
* the 'C' calling convention (from PNGCAPI) for
|
|
||||||
* callbacks (PNGCBAPI). This is no longer required
|
|
||||||
* in any known environment - if it has to be used
|
|
||||||
* please post an explanation of the problem to the
|
|
||||||
* libpng mailing list.
|
|
||||||
*
|
|
||||||
* These cases only differ if the operating system does not use the C
|
|
||||||
* calling convention, at present this just means the above cases
|
|
||||||
* (x86 DOS/Windows systems) and, even then, this does not apply to
|
|
||||||
* Cygwin running on those systems.
|
|
||||||
*
|
|
||||||
* Note that the value must be defined in pnglibconf.h so that what
|
|
||||||
* the application uses to call the library matches the conventions
|
|
||||||
* set when building the library.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Symbol export
|
|
||||||
* =============
|
|
||||||
* When building a shared library it is almost always necessary to tell
|
|
||||||
* the compiler which symbols to export. The png.h macro 'PNG_EXPORT'
|
|
||||||
* is used to mark the symbols. On some systems these symbols can be
|
|
||||||
* extracted at link time and need no special processing by the compiler,
|
|
||||||
* on other systems the symbols are flagged by the compiler and just
|
|
||||||
* the declaration requires a special tag applied (unfortunately) in a
|
|
||||||
* compiler dependent way. Some systems can do either.
|
|
||||||
*
|
|
||||||
* A small number of older systems also require a symbol from a DLL to
|
|
||||||
* be flagged to the program that calls it. This is a problem because
|
|
||||||
* we do not know in the header file included by application code that
|
|
||||||
* the symbol will come from a shared library, as opposed to a statically
|
|
||||||
* linked one. For this reason the application must tell us by setting
|
|
||||||
* the magic flag PNG_USE_DLL to turn on the special processing before
|
|
||||||
* it includes png.h.
|
|
||||||
*
|
|
||||||
* Four additional macros are used to make this happen:
|
|
||||||
*
|
|
||||||
* PNG_IMPEXP The magic (if any) to cause a symbol to be exported from
|
|
||||||
* the build or imported if PNG_USE_DLL is set - compiler
|
|
||||||
* and system specific.
|
|
||||||
*
|
|
||||||
* PNG_EXPORT_TYPE(type) A macro that pre or appends PNG_IMPEXP to
|
|
||||||
* 'type', compiler specific.
|
|
||||||
*
|
|
||||||
* PNG_DLL_EXPORT Set to the magic to use during a libpng build to
|
|
||||||
* make a symbol exported from the DLL. Not used in the
|
|
||||||
* public header files; see pngpriv.h for how it is used
|
|
||||||
* in the libpng build.
|
|
||||||
*
|
|
||||||
* PNG_DLL_IMPORT Set to the magic to force the libpng symbols to come
|
|
||||||
* from a DLL - used to define PNG_IMPEXP when
|
|
||||||
* PNG_USE_DLL is set.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* System specific discovery.
|
|
||||||
* ==========================
|
|
||||||
* This code is used at build time to find PNG_IMPEXP, the API settings
|
|
||||||
* and PNG_EXPORT_TYPE(), it may also set a macro to indicate the DLL
|
|
||||||
* import processing is possible. On Windows systems it also sets
|
|
||||||
* compiler-specific macros to the values required to change the calling
|
|
||||||
* conventions of the various functions.
|
|
||||||
*/
|
|
||||||
#if defined(_Windows) || defined(_WINDOWS) || defined(WIN32) ||\
|
|
||||||
defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
|
|
||||||
/* Windows system (DOS doesn't support DLLs). Includes builds under Cygwin or
|
|
||||||
* MinGW on any architecture currently supported by Windows. Also includes
|
|
||||||
* Watcom builds but these need special treatment because they are not
|
|
||||||
* compatible with GCC or Visual C because of different calling conventions.
|
|
||||||
*/
|
|
||||||
# if PNG_API_RULE == 2
|
|
||||||
/* If this line results in an error, either because __watcall is not
|
|
||||||
* understood or because of a redefine just below you cannot use *this*
|
|
||||||
* build of the library with the compiler you are using. *This* build was
|
|
||||||
* build using Watcom and applications must also be built using Watcom!
|
|
||||||
*/
|
|
||||||
# define PNGCAPI __watcall
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# if defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER >= 800))
|
|
||||||
# define PNGCAPI __cdecl
|
|
||||||
# if PNG_API_RULE == 1
|
|
||||||
/* If this line results in an error __stdcall is not understood and
|
|
||||||
* PNG_API_RULE should not have been set to '1'.
|
|
||||||
*/
|
|
||||||
# define PNGAPI __stdcall
|
|
||||||
# endif
|
|
||||||
# else
|
|
||||||
/* An older compiler, or one not detected (erroneously) above,
|
|
||||||
* if necessary override on the command line to get the correct
|
|
||||||
* variants for the compiler.
|
|
||||||
*/
|
|
||||||
# ifndef PNGCAPI
|
|
||||||
# define PNGCAPI _cdecl
|
|
||||||
# endif
|
|
||||||
# if PNG_API_RULE == 1 && !defined(PNGAPI)
|
|
||||||
# define PNGAPI _stdcall
|
|
||||||
# endif
|
|
||||||
# endif /* compiler/api */
|
|
||||||
|
|
||||||
/* NOTE: PNGCBAPI always defaults to PNGCAPI. */
|
|
||||||
|
|
||||||
# if defined(PNGAPI) && !defined(PNG_USER_PRIVATEBUILD)
|
|
||||||
# error "PNG_USER_PRIVATEBUILD must be defined if PNGAPI is changed"
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# if (defined(_MSC_VER) && _MSC_VER < 800) ||\
|
|
||||||
(defined(__BORLANDC__) && __BORLANDC__ < 0x500)
|
|
||||||
/* older Borland and MSC
|
|
||||||
* compilers used '__export' and required this to be after
|
|
||||||
* the type.
|
|
||||||
*/
|
|
||||||
# ifndef PNG_EXPORT_TYPE
|
|
||||||
# define PNG_EXPORT_TYPE(type) type PNG_IMPEXP
|
|
||||||
# endif
|
|
||||||
# define PNG_DLL_EXPORT __export
|
|
||||||
# else /* newer compiler */
|
|
||||||
# define PNG_DLL_EXPORT __declspec(dllexport)
|
|
||||||
# ifndef PNG_DLL_IMPORT
|
|
||||||
# define PNG_DLL_IMPORT __declspec(dllimport)
|
|
||||||
# endif
|
|
||||||
# endif /* compiler */
|
|
||||||
|
|
||||||
#else /* !Windows */
|
|
||||||
# if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__)
|
|
||||||
# define PNGAPI _System
|
|
||||||
# else /* !Windows/x86 && !OS/2 */
|
|
||||||
/* Use the defaults, or define PNG*API on the command line (but
|
|
||||||
* this will have to be done for every compile!)
|
|
||||||
*/
|
|
||||||
# endif /* other system, !OS/2 */
|
|
||||||
#endif /* !Windows/x86 */
|
|
||||||
|
|
||||||
/* Now do all the defaulting . */
|
|
||||||
#ifndef PNGCAPI
|
|
||||||
# define PNGCAPI
|
|
||||||
#endif
|
|
||||||
#ifndef PNGCBAPI
|
|
||||||
# define PNGCBAPI PNGCAPI
|
|
||||||
#endif
|
|
||||||
#ifndef PNGAPI
|
|
||||||
# define PNGAPI PNGCAPI
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* PNG_IMPEXP may be set on the compilation system command line or (if not set)
|
|
||||||
* then in an internal header file when building the library, otherwise (when
|
|
||||||
* using the library) it is set here.
|
|
||||||
*/
|
|
||||||
#ifndef PNG_IMPEXP
|
|
||||||
# if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT)
|
|
||||||
/* This forces use of a DLL, disallowing static linking */
|
|
||||||
# define PNG_IMPEXP PNG_DLL_IMPORT
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifndef PNG_IMPEXP
|
|
||||||
# define PNG_IMPEXP
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* In 1.5.2 the definition of PNG_FUNCTION has been changed to always treat
|
|
||||||
* 'attributes' as a storage class - the attributes go at the start of the
|
|
||||||
* function definition, and attributes are always appended regardless of the
|
|
||||||
* compiler. This considerably simplifies these macros but may cause problems
|
|
||||||
* if any compilers both need function attributes and fail to handle them as
|
|
||||||
* a storage class (this is unlikely.)
|
|
||||||
*/
|
|
||||||
#ifndef PNG_FUNCTION
|
|
||||||
# define PNG_FUNCTION(type, name, args, attributes) attributes type name args
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PNG_EXPORT_TYPE
|
|
||||||
# define PNG_EXPORT_TYPE(type) PNG_IMPEXP type
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* The ordinal value is only relevant when preprocessing png.h for symbol
|
|
||||||
* table entries, so we discard it here. See the .dfn files in the
|
|
||||||
* scripts directory.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PNG_EXPORTA
|
|
||||||
# define PNG_EXPORTA(ordinal, type, name, args, attributes) \
|
|
||||||
PNG_FUNCTION(PNG_EXPORT_TYPE(type), (PNGAPI name), PNGARG(args), \
|
|
||||||
PNG_LINKAGE_API attributes)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ANSI-C (C90) does not permit a macro to be invoked with an empty argument,
|
|
||||||
* so make something non-empty to satisfy the requirement:
|
|
||||||
*/
|
|
||||||
#define PNG_EMPTY /*empty list*/
|
|
||||||
|
|
||||||
#define PNG_EXPORT(ordinal, type, name, args) \
|
|
||||||
PNG_EXPORTA(ordinal, type, name, args, PNG_EMPTY)
|
|
||||||
|
|
||||||
/* Use PNG_REMOVED to comment out a removed interface. */
|
|
||||||
#ifndef PNG_REMOVED
|
|
||||||
# define PNG_REMOVED(ordinal, type, name, args, attributes)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PNG_CALLBACK
|
|
||||||
# define PNG_CALLBACK(type, name, args) type (PNGCBAPI name) PNGARG(args)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Support for compiler specific function attributes. These are used
|
|
||||||
* so that where compiler support is available incorrect use of API
|
|
||||||
* functions in png.h will generate compiler warnings.
|
|
||||||
*
|
|
||||||
* Added at libpng-1.2.41.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PNG_NO_PEDANTIC_WARNINGS
|
|
||||||
# ifndef PNG_PEDANTIC_WARNINGS_SUPPORTED
|
|
||||||
# define PNG_PEDANTIC_WARNINGS_SUPPORTED
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PNG_PEDANTIC_WARNINGS_SUPPORTED
|
|
||||||
/* Support for compiler specific function attributes. These are used
|
|
||||||
* so that where compiler support is available, incorrect use of API
|
|
||||||
* functions in png.h will generate compiler warnings. Added at libpng
|
|
||||||
* version 1.2.41. Disabling these removes the warnings but may also produce
|
|
||||||
* less efficient code.
|
|
||||||
*/
|
|
||||||
# if defined(__clang__) && defined(__has_attribute)
|
|
||||||
/* Clang defines both __clang__ and __GNUC__. Check __clang__ first. */
|
|
||||||
# if !defined(PNG_USE_RESULT) && __has_attribute(__warn_unused_result__)
|
|
||||||
# define PNG_USE_RESULT __attribute__((__warn_unused_result__))
|
|
||||||
# endif
|
|
||||||
# if !defined(PNG_NORETURN) && __has_attribute(__noreturn__)
|
|
||||||
# define PNG_NORETURN __attribute__((__noreturn__))
|
|
||||||
# endif
|
|
||||||
# if !defined(PNG_ALLOCATED) && __has_attribute(__malloc__)
|
|
||||||
# define PNG_ALLOCATED __attribute__((__malloc__))
|
|
||||||
# endif
|
|
||||||
# if !defined(PNG_DEPRECATED) && __has_attribute(__deprecated__)
|
|
||||||
# define PNG_DEPRECATED __attribute__((__deprecated__))
|
|
||||||
# endif
|
|
||||||
# if !defined(PNG_PRIVATE)
|
|
||||||
# ifdef __has_extension
|
|
||||||
# if __has_extension(attribute_unavailable_with_message)
|
|
||||||
# define PNG_PRIVATE __attribute__((__unavailable__(\
|
|
||||||
"This function is not exported by libpng.")))
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
# ifndef PNG_RESTRICT
|
|
||||||
# define PNG_RESTRICT __restrict
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# elif defined(__GNUC__)
|
|
||||||
# ifndef PNG_USE_RESULT
|
|
||||||
# define PNG_USE_RESULT __attribute__((__warn_unused_result__))
|
|
||||||
# endif
|
|
||||||
# ifndef PNG_NORETURN
|
|
||||||
# define PNG_NORETURN __attribute__((__noreturn__))
|
|
||||||
# endif
|
|
||||||
# if __GNUC__ >= 3
|
|
||||||
# ifndef PNG_ALLOCATED
|
|
||||||
# define PNG_ALLOCATED __attribute__((__malloc__))
|
|
||||||
# endif
|
|
||||||
# ifndef PNG_DEPRECATED
|
|
||||||
# define PNG_DEPRECATED __attribute__((__deprecated__))
|
|
||||||
# endif
|
|
||||||
# ifndef PNG_PRIVATE
|
|
||||||
# if 0 /* Doesn't work so we use deprecated instead*/
|
|
||||||
# define PNG_PRIVATE \
|
|
||||||
__attribute__((warning("This function is not exported by libpng.")))
|
|
||||||
# else
|
|
||||||
# define PNG_PRIVATE \
|
|
||||||
__attribute__((__deprecated__))
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
# if ((__GNUC__ > 3) || !defined(__GNUC_MINOR__) || (__GNUC_MINOR__ >= 1))
|
|
||||||
# ifndef PNG_RESTRICT
|
|
||||||
# define PNG_RESTRICT __restrict
|
|
||||||
# endif
|
|
||||||
# endif /* __GNUC__.__GNUC_MINOR__ > 3.0 */
|
|
||||||
# endif /* __GNUC__ >= 3 */
|
|
||||||
|
|
||||||
# elif defined(_MSC_VER) && (_MSC_VER >= 1300)
|
|
||||||
# ifndef PNG_USE_RESULT
|
|
||||||
# define PNG_USE_RESULT /* not supported */
|
|
||||||
# endif
|
|
||||||
# ifndef PNG_NORETURN
|
|
||||||
# define PNG_NORETURN __declspec(noreturn)
|
|
||||||
# endif
|
|
||||||
# ifndef PNG_ALLOCATED
|
|
||||||
# if (_MSC_VER >= 1400)
|
|
||||||
# define PNG_ALLOCATED __declspec(restrict)
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
# ifndef PNG_DEPRECATED
|
|
||||||
# define PNG_DEPRECATED __declspec(deprecated)
|
|
||||||
# endif
|
|
||||||
# ifndef PNG_PRIVATE
|
|
||||||
# define PNG_PRIVATE __declspec(deprecated)
|
|
||||||
# endif
|
|
||||||
# ifndef PNG_RESTRICT
|
|
||||||
# if (_MSC_VER >= 1400)
|
|
||||||
# define PNG_RESTRICT __restrict
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# elif defined(__WATCOMC__)
|
|
||||||
# ifndef PNG_RESTRICT
|
|
||||||
# define PNG_RESTRICT __restrict
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
#endif /* PNG_PEDANTIC_WARNINGS */
|
|
||||||
|
|
||||||
#ifndef PNG_DEPRECATED
|
|
||||||
# define PNG_DEPRECATED /* Use of this function is deprecated */
|
|
||||||
#endif
|
|
||||||
#ifndef PNG_USE_RESULT
|
|
||||||
# define PNG_USE_RESULT /* The result of this function must be checked */
|
|
||||||
#endif
|
|
||||||
#ifndef PNG_NORETURN
|
|
||||||
# define PNG_NORETURN /* This function does not return */
|
|
||||||
#endif
|
|
||||||
#ifndef PNG_ALLOCATED
|
|
||||||
# define PNG_ALLOCATED /* The result of the function is new memory */
|
|
||||||
#endif
|
|
||||||
#ifndef PNG_PRIVATE
|
|
||||||
# define PNG_PRIVATE /* This is a private libpng function */
|
|
||||||
#endif
|
|
||||||
#ifndef PNG_RESTRICT
|
|
||||||
# define PNG_RESTRICT /* The C99 "restrict" feature */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PNG_FP_EXPORT /* A floating point API. */
|
|
||||||
# ifdef PNG_FLOATING_POINT_SUPPORTED
|
|
||||||
# define PNG_FP_EXPORT(ordinal, type, name, args)\
|
|
||||||
PNG_EXPORT(ordinal, type, name, args);
|
|
||||||
# else /* No floating point APIs */
|
|
||||||
# define PNG_FP_EXPORT(ordinal, type, name, args)
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
#ifndef PNG_FIXED_EXPORT /* A fixed point API. */
|
|
||||||
# ifdef PNG_FIXED_POINT_SUPPORTED
|
|
||||||
# define PNG_FIXED_EXPORT(ordinal, type, name, args)\
|
|
||||||
PNG_EXPORT(ordinal, type, name, args);
|
|
||||||
# else /* No fixed point APIs */
|
|
||||||
# define PNG_FIXED_EXPORT(ordinal, type, name, args)
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PNG_BUILDING_SYMBOL_TABLE
|
|
||||||
/* Some typedefs to get us started. These should be safe on most of the common
|
|
||||||
* platforms.
|
|
||||||
*
|
|
||||||
* png_uint_32 and png_int_32 may, currently, be larger than required to hold a
|
|
||||||
* 32-bit value however this is not normally advisable.
|
|
||||||
*
|
|
||||||
* png_uint_16 and png_int_16 should always be two bytes in size - this is
|
|
||||||
* verified at library build time.
|
|
||||||
*
|
|
||||||
* png_byte must always be one byte in size.
|
|
||||||
*
|
|
||||||
* The checks below use constants from limits.h, as defined by the ISOC90
|
|
||||||
* standard.
|
|
||||||
*/
|
|
||||||
#if CHAR_BIT == 8 && UCHAR_MAX == 255
|
|
||||||
typedef unsigned char png_byte;
|
|
||||||
#else
|
|
||||||
# error "libpng requires 8-bit bytes"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if INT_MIN == -32768 && INT_MAX == 32767
|
|
||||||
typedef int png_int_16;
|
|
||||||
#elif SHRT_MIN == -32768 && SHRT_MAX == 32767
|
|
||||||
typedef short png_int_16;
|
|
||||||
#else
|
|
||||||
# error "libpng requires a signed 16-bit type"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if UINT_MAX == 65535
|
|
||||||
typedef unsigned int png_uint_16;
|
|
||||||
#elif USHRT_MAX == 65535
|
|
||||||
typedef unsigned short png_uint_16;
|
|
||||||
#else
|
|
||||||
# error "libpng requires an unsigned 16-bit type"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if INT_MIN < -2147483646 && INT_MAX > 2147483646
|
|
||||||
typedef int png_int_32;
|
|
||||||
#elif LONG_MIN < -2147483646 && LONG_MAX > 2147483646
|
|
||||||
typedef long int png_int_32;
|
|
||||||
#else
|
|
||||||
# error "libpng requires a signed 32-bit (or more) type"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if UINT_MAX > 4294967294U
|
|
||||||
typedef unsigned int png_uint_32;
|
|
||||||
#elif ULONG_MAX > 4294967294U
|
|
||||||
typedef unsigned long int png_uint_32;
|
|
||||||
#else
|
|
||||||
# error "libpng requires an unsigned 32-bit (or more) type"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Prior to 1.6.0, it was possible to disable the use of size_t and ptrdiff_t.
|
|
||||||
* From 1.6.0 onwards, an ISO C90 compiler, as well as a standard-compliant
|
|
||||||
* behavior of sizeof and ptrdiff_t are required.
|
|
||||||
* The legacy typedefs are provided here for backwards compatibility.
|
|
||||||
*/
|
|
||||||
typedef size_t png_size_t;
|
|
||||||
typedef ptrdiff_t png_ptrdiff_t;
|
|
||||||
|
|
||||||
/* libpng needs to know the maximum value of 'size_t' and this controls the
|
|
||||||
* definition of png_alloc_size_t, below. This maximum value of size_t limits
|
|
||||||
* but does not control the maximum allocations the library makes - there is
|
|
||||||
* direct application control of this through png_set_user_limits().
|
|
||||||
*/
|
|
||||||
#ifndef PNG_SMALL_SIZE_T
|
|
||||||
/* Compiler specific tests for systems where size_t is known to be less than
|
|
||||||
* 32 bits (some of these systems may no longer work because of the lack of
|
|
||||||
* 'far' support; see above.)
|
|
||||||
*/
|
|
||||||
# if (defined(__TURBOC__) && !defined(__FLAT__)) ||\
|
|
||||||
(defined(_MSC_VER) && defined(MAXSEG_64K))
|
|
||||||
# define PNG_SMALL_SIZE_T
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* png_alloc_size_t is guaranteed to be no smaller than size_t, and no smaller
|
|
||||||
* than png_uint_32. Casts from size_t or png_uint_32 to png_alloc_size_t are
|
|
||||||
* not necessary; in fact, it is recommended not to use them at all, so that
|
|
||||||
* the compiler can complain when something turns out to be problematic.
|
|
||||||
*
|
|
||||||
* Casts in the other direction (from png_alloc_size_t to size_t or
|
|
||||||
* png_uint_32) should be explicitly applied; however, we do not expect to
|
|
||||||
* encounter practical situations that require such conversions.
|
|
||||||
*
|
|
||||||
* PNG_SMALL_SIZE_T must be defined if the maximum value of size_t is less than
|
|
||||||
* 4294967295 - i.e. less than the maximum value of png_uint_32.
|
|
||||||
*/
|
|
||||||
#ifdef PNG_SMALL_SIZE_T
|
|
||||||
typedef png_uint_32 png_alloc_size_t;
|
|
||||||
#else
|
|
||||||
typedef size_t png_alloc_size_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Prior to 1.6.0 libpng offered limited support for Microsoft C compiler
|
|
||||||
* implementations of Intel CPU specific support of user-mode segmented address
|
|
||||||
* spaces, where 16-bit pointers address more than 65536 bytes of memory using
|
|
||||||
* separate 'segment' registers. The implementation requires two different
|
|
||||||
* types of pointer (only one of which includes the segment value.)
|
|
||||||
*
|
|
||||||
* If required this support is available in version 1.2 of libpng and may be
|
|
||||||
* available in versions through 1.5, although the correctness of the code has
|
|
||||||
* not been verified recently.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Typedef for floating-point numbers that are converted to fixed-point with a
|
|
||||||
* multiple of 100,000, e.g., gamma
|
|
||||||
*/
|
|
||||||
typedef png_int_32 png_fixed_point;
|
|
||||||
|
|
||||||
/* Add typedefs for pointers */
|
|
||||||
typedef void * png_voidp;
|
|
||||||
typedef const void * png_const_voidp;
|
|
||||||
typedef png_byte * png_bytep;
|
|
||||||
typedef const png_byte * png_const_bytep;
|
|
||||||
typedef png_uint_32 * png_uint_32p;
|
|
||||||
typedef const png_uint_32 * png_const_uint_32p;
|
|
||||||
typedef png_int_32 * png_int_32p;
|
|
||||||
typedef const png_int_32 * png_const_int_32p;
|
|
||||||
typedef png_uint_16 * png_uint_16p;
|
|
||||||
typedef const png_uint_16 * png_const_uint_16p;
|
|
||||||
typedef png_int_16 * png_int_16p;
|
|
||||||
typedef const png_int_16 * png_const_int_16p;
|
|
||||||
typedef char * png_charp;
|
|
||||||
typedef const char * png_const_charp;
|
|
||||||
typedef png_fixed_point * png_fixed_point_p;
|
|
||||||
typedef const png_fixed_point * png_const_fixed_point_p;
|
|
||||||
typedef size_t * png_size_tp;
|
|
||||||
typedef const size_t * png_const_size_tp;
|
|
||||||
|
|
||||||
#ifdef PNG_STDIO_SUPPORTED
|
|
||||||
typedef FILE * png_FILE_p;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PNG_FLOATING_POINT_SUPPORTED
|
|
||||||
typedef double * png_doublep;
|
|
||||||
typedef const double * png_const_doublep;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Pointers to pointers; i.e. arrays */
|
|
||||||
typedef png_byte * * png_bytepp;
|
|
||||||
typedef png_uint_32 * * png_uint_32pp;
|
|
||||||
typedef png_int_32 * * png_int_32pp;
|
|
||||||
typedef png_uint_16 * * png_uint_16pp;
|
|
||||||
typedef png_int_16 * * png_int_16pp;
|
|
||||||
typedef const char * * png_const_charpp;
|
|
||||||
typedef char * * png_charpp;
|
|
||||||
typedef png_fixed_point * * png_fixed_point_pp;
|
|
||||||
#ifdef PNG_FLOATING_POINT_SUPPORTED
|
|
||||||
typedef double * * png_doublepp;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Pointers to pointers to pointers; i.e., pointer to array */
|
|
||||||
typedef char * * * png_charppp;
|
|
||||||
|
|
||||||
#endif /* PNG_BUILDING_SYMBOL_TABLE */
|
|
||||||
|
|
||||||
#endif /* PNGCONF_H */
|
|
|
@ -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 */
|
|
|
@ -1,963 +0,0 @@
|
||||||
|
|
||||||
/* pngerror.c - stub functions for i/o and memory allocation
|
|
||||||
*
|
|
||||||
* Copyright (c) 2018 Cosmin Truta
|
|
||||||
* Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
|
|
||||||
* Copyright (c) 1996-1997 Andreas Dilger
|
|
||||||
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
|
|
||||||
*
|
|
||||||
* This code is released under the libpng license.
|
|
||||||
* For conditions of distribution and use, see the disclaimer
|
|
||||||
* and license in png.h
|
|
||||||
*
|
|
||||||
* This file provides a location for all error handling. Users who
|
|
||||||
* need special error handling are expected to write replacement functions
|
|
||||||
* and use png_set_error_fn() to use those functions. See the instructions
|
|
||||||
* at each function.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "pngpriv.h"
|
|
||||||
|
|
||||||
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
|
|
||||||
|
|
||||||
static PNG_FUNCTION(void, png_default_error,PNGARG((png_const_structrp png_ptr,
|
|
||||||
png_const_charp error_message)),PNG_NORETURN);
|
|
||||||
|
|
||||||
#ifdef PNG_WARNINGS_SUPPORTED
|
|
||||||
static void /* PRIVATE */
|
|
||||||
png_default_warning PNGARG((png_const_structrp png_ptr,
|
|
||||||
png_const_charp warning_message));
|
|
||||||
#endif /* WARNINGS */
|
|
||||||
|
|
||||||
/* This function is called whenever there is a fatal error. This function
|
|
||||||
* should not be changed. If there is a need to handle errors differently,
|
|
||||||
* you should supply a replacement error function and use png_set_error_fn()
|
|
||||||
* to replace the error function at run-time.
|
|
||||||
*/
|
|
||||||
#ifdef PNG_ERROR_TEXT_SUPPORTED
|
|
||||||
PNG_FUNCTION(void,PNGAPI
|
|
||||||
png_error,(png_const_structrp png_ptr, png_const_charp error_message),
|
|
||||||
PNG_NORETURN)
|
|
||||||
{
|
|
||||||
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
|
|
||||||
char msg[16];
|
|
||||||
if (png_ptr != NULL)
|
|
||||||
{
|
|
||||||
if ((png_ptr->flags &
|
|
||||||
(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) != 0)
|
|
||||||
{
|
|
||||||
if (*error_message == PNG_LITERAL_SHARP)
|
|
||||||
{
|
|
||||||
/* Strip "#nnnn " from beginning of error message. */
|
|
||||||
int offset;
|
|
||||||
for (offset = 1; offset<15; offset++)
|
|
||||||
if (error_message[offset] == ' ')
|
|
||||||
break;
|
|
||||||
|
|
||||||
if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < offset - 1; i++)
|
|
||||||
msg[i] = error_message[i + 1];
|
|
||||||
msg[i - 1] = '\0';
|
|
||||||
error_message = msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
error_message += offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ((png_ptr->flags & PNG_FLAG_STRIP_ERROR_TEXT) != 0)
|
|
||||||
{
|
|
||||||
msg[0] = '0';
|
|
||||||
msg[1] = '\0';
|
|
||||||
error_message = msg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (png_ptr != NULL && png_ptr->error_fn != NULL)
|
|
||||||
(*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr),
|
|
||||||
error_message);
|
|
||||||
|
|
||||||
/* If the custom handler doesn't exist, or if it returns,
|
|
||||||
use the default handler, which will not return. */
|
|
||||||
png_default_error(png_ptr, error_message);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
PNG_FUNCTION(void,PNGAPI
|
|
||||||
png_err,(png_const_structrp png_ptr),PNG_NORETURN)
|
|
||||||
{
|
|
||||||
/* Prior to 1.5.2 the error_fn received a NULL pointer, expressed
|
|
||||||
* erroneously as '\0', instead of the empty string "". This was
|
|
||||||
* apparently an error, introduced in libpng-1.2.20, and png_default_error
|
|
||||||
* will crash in this case.
|
|
||||||
*/
|
|
||||||
if (png_ptr != NULL && png_ptr->error_fn != NULL)
|
|
||||||
(*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr), "");
|
|
||||||
|
|
||||||
/* If the custom handler doesn't exist, or if it returns,
|
|
||||||
use the default handler, which will not return. */
|
|
||||||
png_default_error(png_ptr, "");
|
|
||||||
}
|
|
||||||
#endif /* ERROR_TEXT */
|
|
||||||
|
|
||||||
/* Utility to safely appends strings to a buffer. This never errors out so
|
|
||||||
* error checking is not required in the caller.
|
|
||||||
*/
|
|
||||||
size_t
|
|
||||||
png_safecat(png_charp buffer, size_t bufsize, size_t pos,
|
|
||||||
png_const_charp string)
|
|
||||||
{
|
|
||||||
if (buffer != NULL && pos < bufsize)
|
|
||||||
{
|
|
||||||
if (string != NULL)
|
|
||||||
while (*string != '\0' && pos < bufsize-1)
|
|
||||||
buffer[pos++] = *string++;
|
|
||||||
|
|
||||||
buffer[pos] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
return pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_TIME_RFC1123_SUPPORTED)
|
|
||||||
/* Utility to dump an unsigned value into a buffer, given a start pointer and
|
|
||||||
* and end pointer (which should point just *beyond* the end of the buffer!)
|
|
||||||
* Returns the pointer to the start of the formatted string.
|
|
||||||
*/
|
|
||||||
png_charp
|
|
||||||
png_format_number(png_const_charp start, png_charp end, int format,
|
|
||||||
png_alloc_size_t number)
|
|
||||||
{
|
|
||||||
int count = 0; /* number of digits output */
|
|
||||||
int mincount = 1; /* minimum number required */
|
|
||||||
int output = 0; /* digit output (for the fixed point format) */
|
|
||||||
|
|
||||||
*--end = '\0';
|
|
||||||
|
|
||||||
/* This is written so that the loop always runs at least once, even with
|
|
||||||
* number zero.
|
|
||||||
*/
|
|
||||||
while (end > start && (number != 0 || count < mincount))
|
|
||||||
{
|
|
||||||
|
|
||||||
static const char digits[] = "0123456789ABCDEF";
|
|
||||||
|
|
||||||
switch (format)
|
|
||||||
{
|
|
||||||
case PNG_NUMBER_FORMAT_fixed:
|
|
||||||
/* Needs five digits (the fraction) */
|
|
||||||
mincount = 5;
|
|
||||||
if (output != 0 || number % 10 != 0)
|
|
||||||
{
|
|
||||||
*--end = digits[number % 10];
|
|
||||||
output = 1;
|
|
||||||
}
|
|
||||||
number /= 10;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PNG_NUMBER_FORMAT_02u:
|
|
||||||
/* Expects at least 2 digits. */
|
|
||||||
mincount = 2;
|
|
||||||
/* FALLTHROUGH */
|
|
||||||
|
|
||||||
case PNG_NUMBER_FORMAT_u:
|
|
||||||
*--end = digits[number % 10];
|
|
||||||
number /= 10;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PNG_NUMBER_FORMAT_02x:
|
|
||||||
/* This format expects at least two digits */
|
|
||||||
mincount = 2;
|
|
||||||
/* FALLTHROUGH */
|
|
||||||
|
|
||||||
case PNG_NUMBER_FORMAT_x:
|
|
||||||
*--end = digits[number & 0xf];
|
|
||||||
number >>= 4;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default: /* an error */
|
|
||||||
number = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Keep track of the number of digits added */
|
|
||||||
++count;
|
|
||||||
|
|
||||||
/* Float a fixed number here: */
|
|
||||||
if ((format == PNG_NUMBER_FORMAT_fixed) && (count == 5) && (end > start))
|
|
||||||
{
|
|
||||||
/* End of the fraction, but maybe nothing was output? In that case
|
|
||||||
* drop the decimal point. If the number is a true zero handle that
|
|
||||||
* here.
|
|
||||||
*/
|
|
||||||
if (output != 0)
|
|
||||||
*--end = '.';
|
|
||||||
else if (number == 0) /* and !output */
|
|
||||||
*--end = '0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return end;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PNG_WARNINGS_SUPPORTED
|
|
||||||
/* This function is called whenever there is a non-fatal error. This function
|
|
||||||
* should not be changed. If there is a need to handle warnings differently,
|
|
||||||
* you should supply a replacement warning function and use
|
|
||||||
* png_set_error_fn() to replace the warning function at run-time.
|
|
||||||
*/
|
|
||||||
void PNGAPI
|
|
||||||
png_warning(png_const_structrp png_ptr, png_const_charp warning_message)
|
|
||||||
{
|
|
||||||
int offset = 0;
|
|
||||||
if (png_ptr != NULL)
|
|
||||||
{
|
|
||||||
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
|
|
||||||
if ((png_ptr->flags &
|
|
||||||
(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT)) != 0)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
if (*warning_message == PNG_LITERAL_SHARP)
|
|
||||||
{
|
|
||||||
for (offset = 1; offset < 15; offset++)
|
|
||||||
if (warning_message[offset] == ' ')
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (png_ptr != NULL && png_ptr->warning_fn != NULL)
|
|
||||||
(*(png_ptr->warning_fn))(png_constcast(png_structrp,png_ptr),
|
|
||||||
warning_message + offset);
|
|
||||||
else
|
|
||||||
png_default_warning(png_ptr, warning_message + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* These functions support 'formatted' warning messages with up to
|
|
||||||
* PNG_WARNING_PARAMETER_COUNT parameters. In the format string the parameter
|
|
||||||
* is introduced by @<number>, where 'number' starts at 1. This follows the
|
|
||||||
* standard established by X/Open for internationalizable error messages.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
png_warning_parameter(png_warning_parameters p, int number,
|
|
||||||
png_const_charp string)
|
|
||||||
{
|
|
||||||
if (number > 0 && number <= PNG_WARNING_PARAMETER_COUNT)
|
|
||||||
(void)png_safecat(p[number-1], (sizeof p[number-1]), 0, string);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
png_warning_parameter_unsigned(png_warning_parameters p, int number, int format,
|
|
||||||
png_alloc_size_t value)
|
|
||||||
{
|
|
||||||
char buffer[PNG_NUMBER_BUFFER_SIZE];
|
|
||||||
png_warning_parameter(p, number, PNG_FORMAT_NUMBER(buffer, format, value));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
png_warning_parameter_signed(png_warning_parameters p, int number, int format,
|
|
||||||
png_int_32 value)
|
|
||||||
{
|
|
||||||
png_alloc_size_t u;
|
|
||||||
png_charp str;
|
|
||||||
char buffer[PNG_NUMBER_BUFFER_SIZE];
|
|
||||||
|
|
||||||
/* Avoid overflow by doing the negate in a png_alloc_size_t: */
|
|
||||||
u = (png_alloc_size_t)value;
|
|
||||||
if (value < 0)
|
|
||||||
u = ~u + 1;
|
|
||||||
|
|
||||||
str = PNG_FORMAT_NUMBER(buffer, format, u);
|
|
||||||
|
|
||||||
if (value < 0 && str > buffer)
|
|
||||||
*--str = '-';
|
|
||||||
|
|
||||||
png_warning_parameter(p, number, str);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
png_formatted_warning(png_const_structrp png_ptr, png_warning_parameters p,
|
|
||||||
png_const_charp message)
|
|
||||||
{
|
|
||||||
/* The internal buffer is just 192 bytes - enough for all our messages,
|
|
||||||
* overflow doesn't happen because this code checks! If someone figures
|
|
||||||
* out how to send us a message longer than 192 bytes, all that will
|
|
||||||
* happen is that the message will be truncated appropriately.
|
|
||||||
*/
|
|
||||||
size_t i = 0; /* Index in the msg[] buffer: */
|
|
||||||
char msg[192];
|
|
||||||
|
|
||||||
/* Each iteration through the following loop writes at most one character
|
|
||||||
* to msg[i++] then returns here to validate that there is still space for
|
|
||||||
* the trailing '\0'. It may (in the case of a parameter) read more than
|
|
||||||
* one character from message[]; it must check for '\0' and continue to the
|
|
||||||
* test if it finds the end of string.
|
|
||||||
*/
|
|
||||||
while (i<(sizeof msg)-1 && *message != '\0')
|
|
||||||
{
|
|
||||||
/* '@' at end of string is now just printed (previously it was skipped);
|
|
||||||
* it is an error in the calling code to terminate the string with @.
|
|
||||||
*/
|
|
||||||
if (p != NULL && *message == '@' && message[1] != '\0')
|
|
||||||
{
|
|
||||||
int parameter_char = *++message; /* Consume the '@' */
|
|
||||||
static const char valid_parameters[] = "123456789";
|
|
||||||
int parameter = 0;
|
|
||||||
|
|
||||||
/* Search for the parameter digit, the index in the string is the
|
|
||||||
* parameter to use.
|
|
||||||
*/
|
|
||||||
while (valid_parameters[parameter] != parameter_char &&
|
|
||||||
valid_parameters[parameter] != '\0')
|
|
||||||
++parameter;
|
|
||||||
|
|
||||||
/* If the parameter digit is out of range it will just get printed. */
|
|
||||||
if (parameter < PNG_WARNING_PARAMETER_COUNT)
|
|
||||||
{
|
|
||||||
/* Append this parameter */
|
|
||||||
png_const_charp parm = p[parameter];
|
|
||||||
png_const_charp pend = p[parameter] + (sizeof p[parameter]);
|
|
||||||
|
|
||||||
/* No need to copy the trailing '\0' here, but there is no guarantee
|
|
||||||
* that parm[] has been initialized, so there is no guarantee of a
|
|
||||||
* trailing '\0':
|
|
||||||
*/
|
|
||||||
while (i<(sizeof msg)-1 && *parm != '\0' && parm < pend)
|
|
||||||
msg[i++] = *parm++;
|
|
||||||
|
|
||||||
/* Consume the parameter digit too: */
|
|
||||||
++message;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* else not a parameter and there is a character after the @ sign; just
|
|
||||||
* copy that. This is known not to be '\0' because of the test above.
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/* At this point *message can't be '\0', even in the bad parameter case
|
|
||||||
* above where there is a lone '@' at the end of the message string.
|
|
||||||
*/
|
|
||||||
msg[i++] = *message++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* i is always less than (sizeof msg), so: */
|
|
||||||
msg[i] = '\0';
|
|
||||||
|
|
||||||
/* And this is the formatted message. It may be larger than
|
|
||||||
* PNG_MAX_ERROR_TEXT, but that is only used for 'chunk' errors and these
|
|
||||||
* are not (currently) formatted.
|
|
||||||
*/
|
|
||||||
png_warning(png_ptr, msg);
|
|
||||||
}
|
|
||||||
#endif /* WARNINGS */
|
|
||||||
|
|
||||||
#ifdef PNG_BENIGN_ERRORS_SUPPORTED
|
|
||||||
void PNGAPI
|
|
||||||
png_benign_error(png_const_structrp png_ptr, png_const_charp error_message)
|
|
||||||
{
|
|
||||||
if ((png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) != 0)
|
|
||||||
{
|
|
||||||
# ifdef PNG_READ_SUPPORTED
|
|
||||||
if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
|
|
||||||
png_ptr->chunk_name != 0)
|
|
||||||
png_chunk_warning(png_ptr, error_message);
|
|
||||||
else
|
|
||||||
# endif
|
|
||||||
png_warning(png_ptr, error_message);
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
# ifdef PNG_READ_SUPPORTED
|
|
||||||
if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
|
|
||||||
png_ptr->chunk_name != 0)
|
|
||||||
png_chunk_error(png_ptr, error_message);
|
|
||||||
else
|
|
||||||
# endif
|
|
||||||
png_error(png_ptr, error_message);
|
|
||||||
}
|
|
||||||
|
|
||||||
# ifndef PNG_ERROR_TEXT_SUPPORTED
|
|
||||||
PNG_UNUSED(error_message)
|
|
||||||
# endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void /* PRIVATE */
|
|
||||||
png_app_warning(png_const_structrp png_ptr, png_const_charp error_message)
|
|
||||||
{
|
|
||||||
if ((png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN) != 0)
|
|
||||||
png_warning(png_ptr, error_message);
|
|
||||||
else
|
|
||||||
png_error(png_ptr, error_message);
|
|
||||||
|
|
||||||
# ifndef PNG_ERROR_TEXT_SUPPORTED
|
|
||||||
PNG_UNUSED(error_message)
|
|
||||||
# endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void /* PRIVATE */
|
|
||||||
png_app_error(png_const_structrp png_ptr, png_const_charp error_message)
|
|
||||||
{
|
|
||||||
if ((png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN) != 0)
|
|
||||||
png_warning(png_ptr, error_message);
|
|
||||||
else
|
|
||||||
png_error(png_ptr, error_message);
|
|
||||||
|
|
||||||
# ifndef PNG_ERROR_TEXT_SUPPORTED
|
|
||||||
PNG_UNUSED(error_message)
|
|
||||||
# endif
|
|
||||||
}
|
|
||||||
#endif /* BENIGN_ERRORS */
|
|
||||||
|
|
||||||
#define PNG_MAX_ERROR_TEXT 196 /* Currently limited by profile_error in png.c */
|
|
||||||
#if defined(PNG_WARNINGS_SUPPORTED) || \
|
|
||||||
(defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED))
|
|
||||||
/* These utilities are used internally to build an error message that relates
|
|
||||||
* to the current chunk. The chunk name comes from png_ptr->chunk_name,
|
|
||||||
* which is used to prefix the message. The message is limited in length
|
|
||||||
* to 63 bytes. The name characters are output as hex digits wrapped in []
|
|
||||||
* if the character is invalid.
|
|
||||||
*/
|
|
||||||
#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
|
|
||||||
static const char png_digit[16] = {
|
|
||||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
|
|
||||||
'A', 'B', 'C', 'D', 'E', 'F'
|
|
||||||
};
|
|
||||||
|
|
||||||
static void /* PRIVATE */
|
|
||||||
png_format_buffer(png_const_structrp png_ptr, png_charp buffer, png_const_charp
|
|
||||||
error_message)
|
|
||||||
{
|
|
||||||
png_uint_32 chunk_name = png_ptr->chunk_name;
|
|
||||||
int iout = 0, ishift = 24;
|
|
||||||
|
|
||||||
while (ishift >= 0)
|
|
||||||
{
|
|
||||||
int c = (int)(chunk_name >> ishift) & 0xff;
|
|
||||||
|
|
||||||
ishift -= 8;
|
|
||||||
if (isnonalpha(c) != 0)
|
|
||||||
{
|
|
||||||
buffer[iout++] = PNG_LITERAL_LEFT_SQUARE_BRACKET;
|
|
||||||
buffer[iout++] = png_digit[(c & 0xf0) >> 4];
|
|
||||||
buffer[iout++] = png_digit[c & 0x0f];
|
|
||||||
buffer[iout++] = PNG_LITERAL_RIGHT_SQUARE_BRACKET;
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
buffer[iout++] = (char)c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error_message == NULL)
|
|
||||||
buffer[iout] = '\0';
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int iin = 0;
|
|
||||||
|
|
||||||
buffer[iout++] = ':';
|
|
||||||
buffer[iout++] = ' ';
|
|
||||||
|
|
||||||
while (iin < PNG_MAX_ERROR_TEXT-1 && error_message[iin] != '\0')
|
|
||||||
buffer[iout++] = error_message[iin++];
|
|
||||||
|
|
||||||
/* iin < PNG_MAX_ERROR_TEXT, so the following is safe: */
|
|
||||||
buffer[iout] = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* WARNINGS || ERROR_TEXT */
|
|
||||||
|
|
||||||
#if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)
|
|
||||||
PNG_FUNCTION(void,PNGAPI
|
|
||||||
png_chunk_error,(png_const_structrp png_ptr, png_const_charp error_message),
|
|
||||||
PNG_NORETURN)
|
|
||||||
{
|
|
||||||
char msg[18+PNG_MAX_ERROR_TEXT];
|
|
||||||
if (png_ptr == NULL)
|
|
||||||
png_error(png_ptr, error_message);
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
png_format_buffer(png_ptr, msg, error_message);
|
|
||||||
png_error(png_ptr, msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* READ && ERROR_TEXT */
|
|
||||||
|
|
||||||
#ifdef PNG_WARNINGS_SUPPORTED
|
|
||||||
void PNGAPI
|
|
||||||
png_chunk_warning(png_const_structrp png_ptr, png_const_charp warning_message)
|
|
||||||
{
|
|
||||||
char msg[18+PNG_MAX_ERROR_TEXT];
|
|
||||||
if (png_ptr == NULL)
|
|
||||||
png_warning(png_ptr, warning_message);
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
png_format_buffer(png_ptr, msg, warning_message);
|
|
||||||
png_warning(png_ptr, msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* WARNINGS */
|
|
||||||
|
|
||||||
#ifdef PNG_READ_SUPPORTED
|
|
||||||
#ifdef PNG_BENIGN_ERRORS_SUPPORTED
|
|
||||||
void PNGAPI
|
|
||||||
png_chunk_benign_error(png_const_structrp png_ptr, png_const_charp
|
|
||||||
error_message)
|
|
||||||
{
|
|
||||||
if ((png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN) != 0)
|
|
||||||
png_chunk_warning(png_ptr, error_message);
|
|
||||||
|
|
||||||
else
|
|
||||||
png_chunk_error(png_ptr, error_message);
|
|
||||||
|
|
||||||
# ifndef PNG_ERROR_TEXT_SUPPORTED
|
|
||||||
PNG_UNUSED(error_message)
|
|
||||||
# endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* READ */
|
|
||||||
|
|
||||||
void /* PRIVATE */
|
|
||||||
png_chunk_report(png_const_structrp png_ptr, png_const_charp message, int error)
|
|
||||||
{
|
|
||||||
# ifndef PNG_WARNINGS_SUPPORTED
|
|
||||||
PNG_UNUSED(message)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
/* This is always supported, but for just read or just write it
|
|
||||||
* unconditionally does the right thing.
|
|
||||||
*/
|
|
||||||
# if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED)
|
|
||||||
if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifdef PNG_READ_SUPPORTED
|
|
||||||
{
|
|
||||||
if (error < PNG_CHUNK_ERROR)
|
|
||||||
png_chunk_warning(png_ptr, message);
|
|
||||||
|
|
||||||
else
|
|
||||||
png_chunk_benign_error(png_ptr, message);
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED)
|
|
||||||
else if ((png_ptr->mode & PNG_IS_READ_STRUCT) == 0)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifdef PNG_WRITE_SUPPORTED
|
|
||||||
{
|
|
||||||
if (error < PNG_CHUNK_WRITE_ERROR)
|
|
||||||
png_app_warning(png_ptr, message);
|
|
||||||
|
|
||||||
else
|
|
||||||
png_app_error(png_ptr, message);
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef PNG_ERROR_TEXT_SUPPORTED
|
|
||||||
#ifdef PNG_FLOATING_POINT_SUPPORTED
|
|
||||||
PNG_FUNCTION(void,
|
|
||||||
png_fixed_error,(png_const_structrp png_ptr, png_const_charp name),PNG_NORETURN)
|
|
||||||
{
|
|
||||||
# define fixed_message "fixed point overflow in "
|
|
||||||
# define fixed_message_ln ((sizeof fixed_message)-1)
|
|
||||||
unsigned int iin;
|
|
||||||
char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT];
|
|
||||||
memcpy(msg, fixed_message, fixed_message_ln);
|
|
||||||
iin = 0;
|
|
||||||
if (name != NULL)
|
|
||||||
while (iin < (PNG_MAX_ERROR_TEXT-1) && name[iin] != 0)
|
|
||||||
{
|
|
||||||
msg[fixed_message_ln + iin] = name[iin];
|
|
||||||
++iin;
|
|
||||||
}
|
|
||||||
msg[fixed_message_ln + iin] = 0;
|
|
||||||
png_error(png_ptr, msg);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PNG_SETJMP_SUPPORTED
|
|
||||||
/* This API only exists if ANSI-C style error handling is used,
|
|
||||||
* otherwise it is necessary for png_default_error to be overridden.
|
|
||||||
*/
|
|
||||||
jmp_buf* PNGAPI
|
|
||||||
png_set_longjmp_fn(png_structrp png_ptr, png_longjmp_ptr longjmp_fn,
|
|
||||||
size_t jmp_buf_size)
|
|
||||||
{
|
|
||||||
/* From libpng 1.6.0 the app gets one chance to set a 'jmpbuf_size' value
|
|
||||||
* and it must not change after that. Libpng doesn't care how big the
|
|
||||||
* buffer is, just that it doesn't change.
|
|
||||||
*
|
|
||||||
* If the buffer size is no *larger* than the size of jmp_buf when libpng is
|
|
||||||
* compiled a built in jmp_buf is returned; this preserves the pre-1.6.0
|
|
||||||
* semantics that this call will not fail. If the size is larger, however,
|
|
||||||
* the buffer is allocated and this may fail, causing the function to return
|
|
||||||
* NULL.
|
|
||||||
*/
|
|
||||||
if (png_ptr == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (png_ptr->jmp_buf_ptr == NULL)
|
|
||||||
{
|
|
||||||
png_ptr->jmp_buf_size = 0; /* not allocated */
|
|
||||||
|
|
||||||
if (jmp_buf_size <= (sizeof png_ptr->jmp_buf_local))
|
|
||||||
png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local;
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
png_ptr->jmp_buf_ptr = png_voidcast(jmp_buf *,
|
|
||||||
png_malloc_warn(png_ptr, jmp_buf_size));
|
|
||||||
|
|
||||||
if (png_ptr->jmp_buf_ptr == NULL)
|
|
||||||
return NULL; /* new NULL return on OOM */
|
|
||||||
|
|
||||||
png_ptr->jmp_buf_size = jmp_buf_size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else /* Already allocated: check the size */
|
|
||||||
{
|
|
||||||
size_t size = png_ptr->jmp_buf_size;
|
|
||||||
|
|
||||||
if (size == 0)
|
|
||||||
{
|
|
||||||
size = (sizeof png_ptr->jmp_buf_local);
|
|
||||||
if (png_ptr->jmp_buf_ptr != &png_ptr->jmp_buf_local)
|
|
||||||
{
|
|
||||||
/* This is an internal error in libpng: somehow we have been left
|
|
||||||
* with a stack allocated jmp_buf when the application regained
|
|
||||||
* control. It's always possible to fix this up, but for the moment
|
|
||||||
* this is a png_error because that makes it easy to detect.
|
|
||||||
*/
|
|
||||||
png_error(png_ptr, "Libpng jmp_buf still allocated");
|
|
||||||
/* png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local; */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size != jmp_buf_size)
|
|
||||||
{
|
|
||||||
png_warning(png_ptr, "Application jmp_buf size changed");
|
|
||||||
return NULL; /* caller will probably crash: no choice here */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Finally fill in the function, now we have a satisfactory buffer. It is
|
|
||||||
* valid to change the function on every call.
|
|
||||||
*/
|
|
||||||
png_ptr->longjmp_fn = longjmp_fn;
|
|
||||||
return png_ptr->jmp_buf_ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void /* PRIVATE */
|
|
||||||
png_free_jmpbuf(png_structrp png_ptr)
|
|
||||||
{
|
|
||||||
if (png_ptr != NULL)
|
|
||||||
{
|
|
||||||
jmp_buf *jb = png_ptr->jmp_buf_ptr;
|
|
||||||
|
|
||||||
/* A size of 0 is used to indicate a local, stack, allocation of the
|
|
||||||
* pointer; used here and in png.c
|
|
||||||
*/
|
|
||||||
if (jb != NULL && png_ptr->jmp_buf_size > 0)
|
|
||||||
{
|
|
||||||
|
|
||||||
/* This stuff is so that a failure to free the error control structure
|
|
||||||
* does not leave libpng in a state with no valid error handling: the
|
|
||||||
* free always succeeds, if there is an error it gets ignored.
|
|
||||||
*/
|
|
||||||
if (jb != &png_ptr->jmp_buf_local)
|
|
||||||
{
|
|
||||||
/* Make an internal, libpng, jmp_buf to return here */
|
|
||||||
jmp_buf free_jmp_buf;
|
|
||||||
|
|
||||||
if (!setjmp(free_jmp_buf))
|
|
||||||
{
|
|
||||||
png_ptr->jmp_buf_ptr = &free_jmp_buf; /* come back here */
|
|
||||||
png_ptr->jmp_buf_size = 0; /* stack allocation */
|
|
||||||
png_ptr->longjmp_fn = longjmp;
|
|
||||||
png_free(png_ptr, jb); /* Return to setjmp on error */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* *Always* cancel everything out: */
|
|
||||||
png_ptr->jmp_buf_size = 0;
|
|
||||||
png_ptr->jmp_buf_ptr = NULL;
|
|
||||||
png_ptr->longjmp_fn = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* This is the default error handling function. Note that replacements for
|
|
||||||
* this function MUST NOT RETURN, or the program will likely crash. This
|
|
||||||
* function is used by default, or if the program supplies NULL for the
|
|
||||||
* error function pointer in png_set_error_fn().
|
|
||||||
*/
|
|
||||||
static PNG_FUNCTION(void /* PRIVATE */,
|
|
||||||
png_default_error,(png_const_structrp png_ptr, png_const_charp error_message),
|
|
||||||
PNG_NORETURN)
|
|
||||||
{
|
|
||||||
#ifdef PNG_CONSOLE_IO_SUPPORTED
|
|
||||||
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
|
|
||||||
/* Check on NULL only added in 1.5.4 */
|
|
||||||
if (error_message != NULL && *error_message == PNG_LITERAL_SHARP)
|
|
||||||
{
|
|
||||||
/* Strip "#nnnn " from beginning of error message. */
|
|
||||||
int offset;
|
|
||||||
char error_number[16];
|
|
||||||
for (offset = 0; offset<15; offset++)
|
|
||||||
{
|
|
||||||
error_number[offset] = error_message[offset + 1];
|
|
||||||
if (error_message[offset] == ' ')
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((offset > 1) && (offset < 15))
|
|
||||||
{
|
|
||||||
error_number[offset - 1] = '\0';
|
|
||||||
fprintf(stderr, "libpng error no. %s: %s",
|
|
||||||
error_number, error_message + offset + 1);
|
|
||||||
fprintf(stderr, PNG_STRING_NEWLINE);
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fprintf(stderr, "libpng error: %s, offset=%d",
|
|
||||||
error_message, offset);
|
|
||||||
fprintf(stderr, PNG_STRING_NEWLINE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
fprintf(stderr, "libpng error: %s", error_message ? error_message :
|
|
||||||
"undefined");
|
|
||||||
fprintf(stderr, PNG_STRING_NEWLINE);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
PNG_UNUSED(error_message) /* Make compiler happy */
|
|
||||||
#endif
|
|
||||||
png_longjmp(png_ptr, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
PNG_FUNCTION(void,PNGAPI
|
|
||||||
png_longjmp,(png_const_structrp png_ptr, int val),PNG_NORETURN)
|
|
||||||
{
|
|
||||||
#ifdef PNG_SETJMP_SUPPORTED
|
|
||||||
if (png_ptr != NULL && png_ptr->longjmp_fn != NULL &&
|
|
||||||
png_ptr->jmp_buf_ptr != NULL)
|
|
||||||
png_ptr->longjmp_fn(*png_ptr->jmp_buf_ptr, val);
|
|
||||||
#else
|
|
||||||
PNG_UNUSED(png_ptr)
|
|
||||||
PNG_UNUSED(val)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* If control reaches this point, png_longjmp() must not return. The only
|
|
||||||
* choice is to terminate the whole process (or maybe the thread); to do
|
|
||||||
* this the ANSI-C abort() function is used unless a different method is
|
|
||||||
* implemented by overriding the default configuration setting for
|
|
||||||
* PNG_ABORT().
|
|
||||||
*/
|
|
||||||
PNG_ABORT();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef PNG_WARNINGS_SUPPORTED
|
|
||||||
/* This function is called when there is a warning, but the library thinks
|
|
||||||
* it can continue anyway. Replacement functions don't have to do anything
|
|
||||||
* here if you don't want them to. In the default configuration, png_ptr is
|
|
||||||
* not used, but it is passed in case it may be useful.
|
|
||||||
*/
|
|
||||||
static void /* PRIVATE */
|
|
||||||
png_default_warning(png_const_structrp png_ptr, png_const_charp warning_message)
|
|
||||||
{
|
|
||||||
#ifdef PNG_CONSOLE_IO_SUPPORTED
|
|
||||||
# ifdef PNG_ERROR_NUMBERS_SUPPORTED
|
|
||||||
if (*warning_message == PNG_LITERAL_SHARP)
|
|
||||||
{
|
|
||||||
int offset;
|
|
||||||
char warning_number[16];
|
|
||||||
for (offset = 0; offset < 15; offset++)
|
|
||||||
{
|
|
||||||
warning_number[offset] = warning_message[offset + 1];
|
|
||||||
if (warning_message[offset] == ' ')
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((offset > 1) && (offset < 15))
|
|
||||||
{
|
|
||||||
warning_number[offset + 1] = '\0';
|
|
||||||
fprintf(stderr, "libpng warning no. %s: %s",
|
|
||||||
warning_number, warning_message + offset);
|
|
||||||
fprintf(stderr, PNG_STRING_NEWLINE);
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fprintf(stderr, "libpng warning: %s",
|
|
||||||
warning_message);
|
|
||||||
fprintf(stderr, PNG_STRING_NEWLINE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
# endif
|
|
||||||
|
|
||||||
{
|
|
||||||
fprintf(stderr, "libpng warning: %s", warning_message);
|
|
||||||
fprintf(stderr, PNG_STRING_NEWLINE);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
PNG_UNUSED(warning_message) /* Make compiler happy */
|
|
||||||
#endif
|
|
||||||
PNG_UNUSED(png_ptr) /* Make compiler happy */
|
|
||||||
}
|
|
||||||
#endif /* WARNINGS */
|
|
||||||
|
|
||||||
/* This function is called when the application wants to use another method
|
|
||||||
* of handling errors and warnings. Note that the error function MUST NOT
|
|
||||||
* return to the calling routine or serious problems will occur. The return
|
|
||||||
* method used in the default routine calls longjmp(png_ptr->jmp_buf_ptr, 1)
|
|
||||||
*/
|
|
||||||
void PNGAPI
|
|
||||||
png_set_error_fn(png_structrp png_ptr, png_voidp error_ptr,
|
|
||||||
png_error_ptr error_fn, png_error_ptr warning_fn)
|
|
||||||
{
|
|
||||||
if (png_ptr == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
png_ptr->error_ptr = error_ptr;
|
|
||||||
png_ptr->error_fn = error_fn;
|
|
||||||
#ifdef PNG_WARNINGS_SUPPORTED
|
|
||||||
png_ptr->warning_fn = warning_fn;
|
|
||||||
#else
|
|
||||||
PNG_UNUSED(warning_fn)
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* This function returns a pointer to the error_ptr associated with the user
|
|
||||||
* functions. The application should free any memory associated with this
|
|
||||||
* pointer before png_write_destroy and png_read_destroy are called.
|
|
||||||
*/
|
|
||||||
png_voidp PNGAPI
|
|
||||||
png_get_error_ptr(png_const_structrp png_ptr)
|
|
||||||
{
|
|
||||||
if (png_ptr == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return ((png_voidp)png_ptr->error_ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef PNG_ERROR_NUMBERS_SUPPORTED
|
|
||||||
void PNGAPI
|
|
||||||
png_set_strip_error_numbers(png_structrp png_ptr, png_uint_32 strip_mode)
|
|
||||||
{
|
|
||||||
if (png_ptr != NULL)
|
|
||||||
{
|
|
||||||
png_ptr->flags &=
|
|
||||||
((~(PNG_FLAG_STRIP_ERROR_NUMBERS |
|
|
||||||
PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
|
|
||||||
defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
|
|
||||||
/* Currently the above both depend on SETJMP_SUPPORTED, however it would be
|
|
||||||
* possible to implement without setjmp support just so long as there is some
|
|
||||||
* way to handle the error return here:
|
|
||||||
*/
|
|
||||||
PNG_FUNCTION(void /* PRIVATE */, (PNGCBAPI
|
|
||||||
png_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message),
|
|
||||||
PNG_NORETURN)
|
|
||||||
{
|
|
||||||
png_const_structrp png_ptr = png_nonconst_ptr;
|
|
||||||
png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr);
|
|
||||||
|
|
||||||
/* An error is always logged here, overwriting anything (typically a warning)
|
|
||||||
* that is already there:
|
|
||||||
*/
|
|
||||||
if (image != NULL)
|
|
||||||
{
|
|
||||||
png_safecat(image->message, (sizeof image->message), 0, error_message);
|
|
||||||
image->warning_or_error |= PNG_IMAGE_ERROR;
|
|
||||||
|
|
||||||
/* Retrieve the jmp_buf from within the png_control, making this work for
|
|
||||||
* C++ compilation too is pretty tricky: C++ wants a pointer to the first
|
|
||||||
* element of a jmp_buf, but C doesn't tell us the type of that.
|
|
||||||
*/
|
|
||||||
if (image->opaque != NULL && image->opaque->error_buf != NULL)
|
|
||||||
longjmp(png_control_jmp_buf(image->opaque), 1);
|
|
||||||
|
|
||||||
/* Missing longjmp buffer, the following is to help debugging: */
|
|
||||||
{
|
|
||||||
size_t pos = png_safecat(image->message, (sizeof image->message), 0,
|
|
||||||
"bad longjmp: ");
|
|
||||||
png_safecat(image->message, (sizeof image->message), pos,
|
|
||||||
error_message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Here on an internal programming error. */
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef PNG_WARNINGS_SUPPORTED
|
|
||||||
void /* PRIVATE */ PNGCBAPI
|
|
||||||
png_safe_warning(png_structp png_nonconst_ptr, png_const_charp warning_message)
|
|
||||||
{
|
|
||||||
png_const_structrp png_ptr = png_nonconst_ptr;
|
|
||||||
png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr);
|
|
||||||
|
|
||||||
/* A warning is only logged if there is no prior warning or error. */
|
|
||||||
if (image->warning_or_error == 0)
|
|
||||||
{
|
|
||||||
png_safecat(image->message, (sizeof image->message), 0, warning_message);
|
|
||||||
image->warning_or_error |= PNG_IMAGE_WARNING;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int /* PRIVATE */
|
|
||||||
png_safe_execute(png_imagep image_in, int (*function)(png_voidp), png_voidp arg)
|
|
||||||
{
|
|
||||||
volatile png_imagep image = image_in;
|
|
||||||
volatile int result;
|
|
||||||
volatile png_voidp saved_error_buf;
|
|
||||||
jmp_buf safe_jmpbuf;
|
|
||||||
|
|
||||||
/* Safely execute function(arg) with png_error returning to this function. */
|
|
||||||
saved_error_buf = image->opaque->error_buf;
|
|
||||||
result = setjmp(safe_jmpbuf) == 0;
|
|
||||||
|
|
||||||
if (result != 0)
|
|
||||||
{
|
|
||||||
|
|
||||||
image->opaque->error_buf = safe_jmpbuf;
|
|
||||||
result = function(arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
image->opaque->error_buf = saved_error_buf;
|
|
||||||
|
|
||||||
/* And do the cleanup prior to any failure return. */
|
|
||||||
if (result == 0)
|
|
||||||
png_image_free(image);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
#endif /* SIMPLIFIED READ || SIMPLIFIED_WRITE */
|
|
||||||
#endif /* READ || WRITE */
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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 */
|
|
|
@ -1,219 +0,0 @@
|
||||||
/* pnglibconf.h - library build configuration */
|
|
||||||
|
|
||||||
/* libpng version 1.6.37 */
|
|
||||||
|
|
||||||
/* Copyright (c) 2018-2019 Cosmin Truta */
|
|
||||||
/* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson */
|
|
||||||
|
|
||||||
/* This code is released under the libpng license. */
|
|
||||||
/* For conditions of distribution and use, see the disclaimer */
|
|
||||||
/* and license in png.h */
|
|
||||||
|
|
||||||
/* pnglibconf.h */
|
|
||||||
/* Machine generated file: DO NOT EDIT */
|
|
||||||
/* Derived from: scripts/pnglibconf.dfa */
|
|
||||||
#ifndef PNGLCONF_H
|
|
||||||
#define PNGLCONF_H
|
|
||||||
/* options */
|
|
||||||
#define PNG_16BIT_SUPPORTED
|
|
||||||
#define PNG_ALIGNED_MEMORY_SUPPORTED
|
|
||||||
/*#undef PNG_ARM_NEON_API_SUPPORTED*/
|
|
||||||
/*#undef PNG_ARM_NEON_CHECK_SUPPORTED*/
|
|
||||||
#define PNG_BENIGN_ERRORS_SUPPORTED
|
|
||||||
#define PNG_BENIGN_READ_ERRORS_SUPPORTED
|
|
||||||
/*#undef PNG_BENIGN_WRITE_ERRORS_SUPPORTED*/
|
|
||||||
#define PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
|
|
||||||
#define PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
|
|
||||||
#define PNG_COLORSPACE_SUPPORTED
|
|
||||||
#define PNG_CONSOLE_IO_SUPPORTED
|
|
||||||
#define PNG_CONVERT_tIME_SUPPORTED
|
|
||||||
#define PNG_EASY_ACCESS_SUPPORTED
|
|
||||||
/*#undef PNG_ERROR_NUMBERS_SUPPORTED*/
|
|
||||||
#define PNG_ERROR_TEXT_SUPPORTED
|
|
||||||
#define PNG_FIXED_POINT_SUPPORTED
|
|
||||||
#define PNG_FLOATING_ARITHMETIC_SUPPORTED
|
|
||||||
#define PNG_FLOATING_POINT_SUPPORTED
|
|
||||||
#define PNG_FORMAT_AFIRST_SUPPORTED
|
|
||||||
#define PNG_FORMAT_BGR_SUPPORTED
|
|
||||||
#define PNG_GAMMA_SUPPORTED
|
|
||||||
#define PNG_GET_PALETTE_MAX_SUPPORTED
|
|
||||||
#define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
|
|
||||||
#define PNG_INCH_CONVERSIONS_SUPPORTED
|
|
||||||
#define PNG_INFO_IMAGE_SUPPORTED
|
|
||||||
#define PNG_IO_STATE_SUPPORTED
|
|
||||||
#define PNG_MNG_FEATURES_SUPPORTED
|
|
||||||
#define PNG_POINTER_INDEXING_SUPPORTED
|
|
||||||
/*#undef PNG_POWERPC_VSX_API_SUPPORTED*/
|
|
||||||
/*#undef PNG_POWERPC_VSX_CHECK_SUPPORTED*/
|
|
||||||
#define PNG_PROGRESSIVE_READ_SUPPORTED
|
|
||||||
#define PNG_READ_16BIT_SUPPORTED
|
|
||||||
#define PNG_READ_ALPHA_MODE_SUPPORTED
|
|
||||||
#define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
|
|
||||||
#define PNG_READ_BACKGROUND_SUPPORTED
|
|
||||||
#define PNG_READ_BGR_SUPPORTED
|
|
||||||
#define PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
|
|
||||||
#define PNG_READ_COMPOSITE_NODIV_SUPPORTED
|
|
||||||
#define PNG_READ_COMPRESSED_TEXT_SUPPORTED
|
|
||||||
#define PNG_READ_EXPAND_16_SUPPORTED
|
|
||||||
#define PNG_READ_EXPAND_SUPPORTED
|
|
||||||
#define PNG_READ_FILLER_SUPPORTED
|
|
||||||
#define PNG_READ_GAMMA_SUPPORTED
|
|
||||||
#define PNG_READ_GET_PALETTE_MAX_SUPPORTED
|
|
||||||
#define PNG_READ_GRAY_TO_RGB_SUPPORTED
|
|
||||||
#define PNG_READ_INTERLACING_SUPPORTED
|
|
||||||
#define PNG_READ_INT_FUNCTIONS_SUPPORTED
|
|
||||||
#define PNG_READ_INVERT_ALPHA_SUPPORTED
|
|
||||||
#define PNG_READ_INVERT_SUPPORTED
|
|
||||||
#define PNG_READ_OPT_PLTE_SUPPORTED
|
|
||||||
#define PNG_READ_PACKSWAP_SUPPORTED
|
|
||||||
#define PNG_READ_PACK_SUPPORTED
|
|
||||||
#define PNG_READ_QUANTIZE_SUPPORTED
|
|
||||||
#define PNG_READ_RGB_TO_GRAY_SUPPORTED
|
|
||||||
#define PNG_READ_SCALE_16_TO_8_SUPPORTED
|
|
||||||
#define PNG_READ_SHIFT_SUPPORTED
|
|
||||||
#define PNG_READ_STRIP_16_TO_8_SUPPORTED
|
|
||||||
#define PNG_READ_STRIP_ALPHA_SUPPORTED
|
|
||||||
#define PNG_READ_SUPPORTED
|
|
||||||
#define PNG_READ_SWAP_ALPHA_SUPPORTED
|
|
||||||
#define PNG_READ_SWAP_SUPPORTED
|
|
||||||
#define PNG_READ_TEXT_SUPPORTED
|
|
||||||
#define PNG_READ_TRANSFORMS_SUPPORTED
|
|
||||||
#define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
|
|
||||||
#define PNG_READ_USER_CHUNKS_SUPPORTED
|
|
||||||
#define PNG_READ_USER_TRANSFORM_SUPPORTED
|
|
||||||
#define PNG_READ_bKGD_SUPPORTED
|
|
||||||
#define PNG_READ_cHRM_SUPPORTED
|
|
||||||
#define PNG_READ_eXIf_SUPPORTED
|
|
||||||
#define PNG_READ_gAMA_SUPPORTED
|
|
||||||
#define PNG_READ_hIST_SUPPORTED
|
|
||||||
#define PNG_READ_iCCP_SUPPORTED
|
|
||||||
#define PNG_READ_iTXt_SUPPORTED
|
|
||||||
#define PNG_READ_oFFs_SUPPORTED
|
|
||||||
#define PNG_READ_pCAL_SUPPORTED
|
|
||||||
#define PNG_READ_pHYs_SUPPORTED
|
|
||||||
#define PNG_READ_sBIT_SUPPORTED
|
|
||||||
#define PNG_READ_sCAL_SUPPORTED
|
|
||||||
#define PNG_READ_sPLT_SUPPORTED
|
|
||||||
#define PNG_READ_sRGB_SUPPORTED
|
|
||||||
#define PNG_READ_tEXt_SUPPORTED
|
|
||||||
#define PNG_READ_tIME_SUPPORTED
|
|
||||||
#define PNG_READ_tRNS_SUPPORTED
|
|
||||||
#define PNG_READ_zTXt_SUPPORTED
|
|
||||||
#define PNG_SAVE_INT_32_SUPPORTED
|
|
||||||
#define PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
|
|
||||||
#define PNG_SEQUENTIAL_READ_SUPPORTED
|
|
||||||
#define PNG_SETJMP_SUPPORTED
|
|
||||||
#define PNG_SET_OPTION_SUPPORTED
|
|
||||||
#define PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
|
|
||||||
#define PNG_SET_USER_LIMITS_SUPPORTED
|
|
||||||
#define PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED
|
|
||||||
#define PNG_SIMPLIFIED_READ_BGR_SUPPORTED
|
|
||||||
#define PNG_SIMPLIFIED_READ_SUPPORTED
|
|
||||||
#define PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
|
|
||||||
#define PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED
|
|
||||||
#define PNG_SIMPLIFIED_WRITE_STDIO_SUPPORTED
|
|
||||||
#define PNG_SIMPLIFIED_WRITE_SUPPORTED
|
|
||||||
#define PNG_STDIO_SUPPORTED
|
|
||||||
#define PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
|
|
||||||
#define PNG_TEXT_SUPPORTED
|
|
||||||
#define PNG_TIME_RFC1123_SUPPORTED
|
|
||||||
#define PNG_UNKNOWN_CHUNKS_SUPPORTED
|
|
||||||
#define PNG_USER_CHUNKS_SUPPORTED
|
|
||||||
#define PNG_USER_LIMITS_SUPPORTED
|
|
||||||
#define PNG_USER_MEM_SUPPORTED
|
|
||||||
#define PNG_USER_TRANSFORM_INFO_SUPPORTED
|
|
||||||
#define PNG_USER_TRANSFORM_PTR_SUPPORTED
|
|
||||||
#define PNG_WARNINGS_SUPPORTED
|
|
||||||
#define PNG_WRITE_16BIT_SUPPORTED
|
|
||||||
#define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
|
|
||||||
#define PNG_WRITE_BGR_SUPPORTED
|
|
||||||
#define PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
|
|
||||||
#define PNG_WRITE_COMPRESSED_TEXT_SUPPORTED
|
|
||||||
#define PNG_WRITE_CUSTOMIZE_COMPRESSION_SUPPORTED
|
|
||||||
#define PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
|
|
||||||
#define PNG_WRITE_FILLER_SUPPORTED
|
|
||||||
#define PNG_WRITE_FILTER_SUPPORTED
|
|
||||||
#define PNG_WRITE_FLUSH_SUPPORTED
|
|
||||||
#define PNG_WRITE_GET_PALETTE_MAX_SUPPORTED
|
|
||||||
#define PNG_WRITE_INTERLACING_SUPPORTED
|
|
||||||
#define PNG_WRITE_INT_FUNCTIONS_SUPPORTED
|
|
||||||
#define PNG_WRITE_INVERT_ALPHA_SUPPORTED
|
|
||||||
#define PNG_WRITE_INVERT_SUPPORTED
|
|
||||||
#define PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
|
|
||||||
#define PNG_WRITE_PACKSWAP_SUPPORTED
|
|
||||||
#define PNG_WRITE_PACK_SUPPORTED
|
|
||||||
#define PNG_WRITE_SHIFT_SUPPORTED
|
|
||||||
#define PNG_WRITE_SUPPORTED
|
|
||||||
#define PNG_WRITE_SWAP_ALPHA_SUPPORTED
|
|
||||||
#define PNG_WRITE_SWAP_SUPPORTED
|
|
||||||
#define PNG_WRITE_TEXT_SUPPORTED
|
|
||||||
#define PNG_WRITE_TRANSFORMS_SUPPORTED
|
|
||||||
#define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
|
|
||||||
#define PNG_WRITE_USER_TRANSFORM_SUPPORTED
|
|
||||||
#define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
|
|
||||||
#define PNG_WRITE_bKGD_SUPPORTED
|
|
||||||
#define PNG_WRITE_cHRM_SUPPORTED
|
|
||||||
#define PNG_WRITE_eXIf_SUPPORTED
|
|
||||||
#define PNG_WRITE_gAMA_SUPPORTED
|
|
||||||
#define PNG_WRITE_hIST_SUPPORTED
|
|
||||||
#define PNG_WRITE_iCCP_SUPPORTED
|
|
||||||
#define PNG_WRITE_iTXt_SUPPORTED
|
|
||||||
#define PNG_WRITE_oFFs_SUPPORTED
|
|
||||||
#define PNG_WRITE_pCAL_SUPPORTED
|
|
||||||
#define PNG_WRITE_pHYs_SUPPORTED
|
|
||||||
#define PNG_WRITE_sBIT_SUPPORTED
|
|
||||||
#define PNG_WRITE_sCAL_SUPPORTED
|
|
||||||
#define PNG_WRITE_sPLT_SUPPORTED
|
|
||||||
#define PNG_WRITE_sRGB_SUPPORTED
|
|
||||||
#define PNG_WRITE_tEXt_SUPPORTED
|
|
||||||
#define PNG_WRITE_tIME_SUPPORTED
|
|
||||||
#define PNG_WRITE_tRNS_SUPPORTED
|
|
||||||
#define PNG_WRITE_zTXt_SUPPORTED
|
|
||||||
#define PNG_bKGD_SUPPORTED
|
|
||||||
#define PNG_cHRM_SUPPORTED
|
|
||||||
#define PNG_eXIf_SUPPORTED
|
|
||||||
#define PNG_gAMA_SUPPORTED
|
|
||||||
#define PNG_hIST_SUPPORTED
|
|
||||||
#define PNG_iCCP_SUPPORTED
|
|
||||||
#define PNG_iTXt_SUPPORTED
|
|
||||||
#define PNG_oFFs_SUPPORTED
|
|
||||||
#define PNG_pCAL_SUPPORTED
|
|
||||||
#define PNG_pHYs_SUPPORTED
|
|
||||||
#define PNG_sBIT_SUPPORTED
|
|
||||||
#define PNG_sCAL_SUPPORTED
|
|
||||||
#define PNG_sPLT_SUPPORTED
|
|
||||||
#define PNG_sRGB_SUPPORTED
|
|
||||||
#define PNG_tEXt_SUPPORTED
|
|
||||||
#define PNG_tIME_SUPPORTED
|
|
||||||
#define PNG_tRNS_SUPPORTED
|
|
||||||
#define PNG_zTXt_SUPPORTED
|
|
||||||
/* end of options */
|
|
||||||
/* settings */
|
|
||||||
#define PNG_API_RULE 0
|
|
||||||
#define PNG_DEFAULT_READ_MACROS 1
|
|
||||||
#define PNG_GAMMA_THRESHOLD_FIXED 5000
|
|
||||||
#define PNG_IDAT_READ_SIZE PNG_ZBUF_SIZE
|
|
||||||
#define PNG_INFLATE_BUF_SIZE 1024
|
|
||||||
#define PNG_LINKAGE_API extern
|
|
||||||
#define PNG_LINKAGE_CALLBACK extern
|
|
||||||
#define PNG_LINKAGE_DATA extern
|
|
||||||
#define PNG_LINKAGE_FUNCTION extern
|
|
||||||
#define PNG_MAX_GAMMA_8 11
|
|
||||||
#define PNG_QUANTIZE_BLUE_BITS 5
|
|
||||||
#define PNG_QUANTIZE_GREEN_BITS 5
|
|
||||||
#define PNG_QUANTIZE_RED_BITS 5
|
|
||||||
#define PNG_TEXT_Z_DEFAULT_COMPRESSION (-1)
|
|
||||||
#define PNG_TEXT_Z_DEFAULT_STRATEGY 0
|
|
||||||
#define PNG_USER_CHUNK_CACHE_MAX 1000
|
|
||||||
#define PNG_USER_CHUNK_MALLOC_MAX 8000000
|
|
||||||
#define PNG_USER_HEIGHT_MAX 1000000
|
|
||||||
#define PNG_USER_WIDTH_MAX 1000000
|
|
||||||
#define PNG_ZBUF_SIZE 8192
|
|
||||||
#define PNG_ZLIB_VERNUM 0 /* unknown */
|
|
||||||
#define PNG_Z_DEFAULT_COMPRESSION (-1)
|
|
||||||
#define PNG_Z_DEFAULT_NOFILTER_STRATEGY 0
|
|
||||||
#define PNG_Z_DEFAULT_STRATEGY 1
|
|
||||||
#define PNG_sCAL_PRECISION 5
|
|
||||||
#define PNG_sRGB_PROFILE_CHECKS 2
|
|
||||||
/* end of settings */
|
|
||||||
#endif /* PNGLCONF_H */
|
|
|
@ -1,284 +0,0 @@
|
||||||
|
|
||||||
/* pngmem.c - stub functions for memory allocation
|
|
||||||
*
|
|
||||||
* Copyright (c) 2018 Cosmin Truta
|
|
||||||
* Copyright (c) 1998-2002,2004,2006-2014,2016 Glenn Randers-Pehrson
|
|
||||||
* Copyright (c) 1996-1997 Andreas Dilger
|
|
||||||
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
|
|
||||||
*
|
|
||||||
* This code is released under the libpng license.
|
|
||||||
* For conditions of distribution and use, see the disclaimer
|
|
||||||
* and license in png.h
|
|
||||||
*
|
|
||||||
* This file provides a location for all memory allocation. Users who
|
|
||||||
* need special memory handling are expected to supply replacement
|
|
||||||
* functions for png_malloc() and png_free(), and to use
|
|
||||||
* png_create_read_struct_2() and png_create_write_struct_2() to
|
|
||||||
* identify the replacement functions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "pngpriv.h"
|
|
||||||
|
|
||||||
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
|
|
||||||
/* Free a png_struct */
|
|
||||||
void /* PRIVATE */
|
|
||||||
png_destroy_png_struct(png_structrp png_ptr)
|
|
||||||
{
|
|
||||||
if (png_ptr != NULL)
|
|
||||||
{
|
|
||||||
/* png_free might call png_error and may certainly call
|
|
||||||
* png_get_mem_ptr, so fake a temporary png_struct to support this.
|
|
||||||
*/
|
|
||||||
png_struct dummy_struct = *png_ptr;
|
|
||||||
memset(png_ptr, 0, (sizeof *png_ptr));
|
|
||||||
png_free(&dummy_struct, png_ptr);
|
|
||||||
|
|
||||||
# ifdef PNG_SETJMP_SUPPORTED
|
|
||||||
/* We may have a jmp_buf left to deallocate. */
|
|
||||||
png_free_jmpbuf(&dummy_struct);
|
|
||||||
# endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate memory. For reasonable files, size should never exceed
|
|
||||||
* 64K. However, zlib may allocate more than 64K if you don't tell
|
|
||||||
* it not to. See zconf.h and png.h for more information. zlib does
|
|
||||||
* need to allocate exactly 64K, so whatever you call here must
|
|
||||||
* have the ability to do that.
|
|
||||||
*/
|
|
||||||
PNG_FUNCTION(png_voidp,PNGAPI
|
|
||||||
png_calloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
|
|
||||||
{
|
|
||||||
png_voidp ret;
|
|
||||||
|
|
||||||
ret = png_malloc(png_ptr, size);
|
|
||||||
|
|
||||||
if (ret != NULL)
|
|
||||||
memset(ret, 0, size);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* png_malloc_base, an internal function added at libpng 1.6.0, does the work of
|
|
||||||
* allocating memory, taking into account limits and PNG_USER_MEM_SUPPORTED.
|
|
||||||
* Checking and error handling must happen outside this routine; it returns NULL
|
|
||||||
* if the allocation cannot be done (for any reason.)
|
|
||||||
*/
|
|
||||||
PNG_FUNCTION(png_voidp /* PRIVATE */,
|
|
||||||
png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size),
|
|
||||||
PNG_ALLOCATED)
|
|
||||||
{
|
|
||||||
/* Moved to png_malloc_base from png_malloc_default in 1.6.0; the DOS
|
|
||||||
* allocators have also been removed in 1.6.0, so any 16-bit system now has
|
|
||||||
* to implement a user memory handler. This checks to be sure it isn't
|
|
||||||
* called with big numbers.
|
|
||||||
*/
|
|
||||||
#ifndef PNG_USER_MEM_SUPPORTED
|
|
||||||
PNG_UNUSED(png_ptr)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Some compilers complain that this is always true. However, it
|
|
||||||
* can be false when integer overflow happens.
|
|
||||||
*/
|
|
||||||
if (size > 0 && size <= PNG_SIZE_MAX
|
|
||||||
# ifdef PNG_MAX_MALLOC_64K
|
|
||||||
&& size <= 65536U
|
|
||||||
# endif
|
|
||||||
)
|
|
||||||
{
|
|
||||||
#ifdef PNG_USER_MEM_SUPPORTED
|
|
||||||
if (png_ptr != NULL && png_ptr->malloc_fn != NULL)
|
|
||||||
return png_ptr->malloc_fn(png_constcast(png_structrp,png_ptr), size);
|
|
||||||
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
return malloc((size_t)size); /* checked for truncation above */
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) ||\
|
|
||||||
defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED)
|
|
||||||
/* This is really here only to work round a spurious warning in GCC 4.6 and 4.7
|
|
||||||
* that arises because of the checks in png_realloc_array that are repeated in
|
|
||||||
* png_malloc_array.
|
|
||||||
*/
|
|
||||||
static png_voidp
|
|
||||||
png_malloc_array_checked(png_const_structrp png_ptr, int nelements,
|
|
||||||
size_t element_size)
|
|
||||||
{
|
|
||||||
png_alloc_size_t req = (png_alloc_size_t)nelements; /* known to be > 0 */
|
|
||||||
|
|
||||||
if (req <= PNG_SIZE_MAX/element_size)
|
|
||||||
return png_malloc_base(png_ptr, req * element_size);
|
|
||||||
|
|
||||||
/* The failure case when the request is too large */
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
PNG_FUNCTION(png_voidp /* PRIVATE */,
|
|
||||||
png_malloc_array,(png_const_structrp png_ptr, int nelements,
|
|
||||||
size_t element_size),PNG_ALLOCATED)
|
|
||||||
{
|
|
||||||
if (nelements <= 0 || element_size == 0)
|
|
||||||
png_error(png_ptr, "internal error: array alloc");
|
|
||||||
|
|
||||||
return png_malloc_array_checked(png_ptr, nelements, element_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
PNG_FUNCTION(png_voidp /* PRIVATE */,
|
|
||||||
png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array,
|
|
||||||
int old_elements, int add_elements, size_t element_size),PNG_ALLOCATED)
|
|
||||||
{
|
|
||||||
/* These are internal errors: */
|
|
||||||
if (add_elements <= 0 || element_size == 0 || old_elements < 0 ||
|
|
||||||
(old_array == NULL && old_elements > 0))
|
|
||||||
png_error(png_ptr, "internal error: array realloc");
|
|
||||||
|
|
||||||
/* Check for overflow on the elements count (so the caller does not have to
|
|
||||||
* check.)
|
|
||||||
*/
|
|
||||||
if (add_elements <= INT_MAX - old_elements)
|
|
||||||
{
|
|
||||||
png_voidp new_array = png_malloc_array_checked(png_ptr,
|
|
||||||
old_elements+add_elements, element_size);
|
|
||||||
|
|
||||||
if (new_array != NULL)
|
|
||||||
{
|
|
||||||
/* Because png_malloc_array worked the size calculations below cannot
|
|
||||||
* overflow.
|
|
||||||
*/
|
|
||||||
if (old_elements > 0)
|
|
||||||
memcpy(new_array, old_array, element_size*(unsigned)old_elements);
|
|
||||||
|
|
||||||
memset((char*)new_array + element_size*(unsigned)old_elements, 0,
|
|
||||||
element_size*(unsigned)add_elements);
|
|
||||||
|
|
||||||
return new_array;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL; /* error */
|
|
||||||
}
|
|
||||||
#endif /* TEXT || sPLT || STORE_UNKNOWN_CHUNKS */
|
|
||||||
|
|
||||||
/* Various functions that have different error handling are derived from this.
|
|
||||||
* png_malloc always exists, but if PNG_USER_MEM_SUPPORTED is defined a separate
|
|
||||||
* function png_malloc_default is also provided.
|
|
||||||
*/
|
|
||||||
PNG_FUNCTION(png_voidp,PNGAPI
|
|
||||||
png_malloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
|
|
||||||
{
|
|
||||||
png_voidp ret;
|
|
||||||
|
|
||||||
if (png_ptr == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
ret = png_malloc_base(png_ptr, size);
|
|
||||||
|
|
||||||
if (ret == NULL)
|
|
||||||
png_error(png_ptr, "Out of memory"); /* 'm' means png_malloc */
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef PNG_USER_MEM_SUPPORTED
|
|
||||||
PNG_FUNCTION(png_voidp,PNGAPI
|
|
||||||
png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size),
|
|
||||||
PNG_ALLOCATED PNG_DEPRECATED)
|
|
||||||
{
|
|
||||||
png_voidp ret;
|
|
||||||
|
|
||||||
if (png_ptr == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* Passing 'NULL' here bypasses the application provided memory handler. */
|
|
||||||
ret = png_malloc_base(NULL/*use malloc*/, size);
|
|
||||||
|
|
||||||
if (ret == NULL)
|
|
||||||
png_error(png_ptr, "Out of Memory"); /* 'M' means png_malloc_default */
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif /* USER_MEM */
|
|
||||||
|
|
||||||
/* This function was added at libpng version 1.2.3. The png_malloc_warn()
|
|
||||||
* function will issue a png_warning and return NULL instead of issuing a
|
|
||||||
* png_error, if it fails to allocate the requested memory.
|
|
||||||
*/
|
|
||||||
PNG_FUNCTION(png_voidp,PNGAPI
|
|
||||||
png_malloc_warn,(png_const_structrp png_ptr, png_alloc_size_t size),
|
|
||||||
PNG_ALLOCATED)
|
|
||||||
{
|
|
||||||
if (png_ptr != NULL)
|
|
||||||
{
|
|
||||||
png_voidp ret = png_malloc_base(png_ptr, size);
|
|
||||||
|
|
||||||
if (ret != NULL)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
png_warning(png_ptr, "Out of memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Free a pointer allocated by png_malloc(). If ptr is NULL, return
|
|
||||||
* without taking any action.
|
|
||||||
*/
|
|
||||||
void PNGAPI
|
|
||||||
png_free(png_const_structrp png_ptr, png_voidp ptr)
|
|
||||||
{
|
|
||||||
if (png_ptr == NULL || ptr == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
#ifdef PNG_USER_MEM_SUPPORTED
|
|
||||||
if (png_ptr->free_fn != NULL)
|
|
||||||
png_ptr->free_fn(png_constcast(png_structrp,png_ptr), ptr);
|
|
||||||
|
|
||||||
else
|
|
||||||
png_free_default(png_ptr, ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
PNG_FUNCTION(void,PNGAPI
|
|
||||||
png_free_default,(png_const_structrp png_ptr, png_voidp ptr),PNG_DEPRECATED)
|
|
||||||
{
|
|
||||||
if (png_ptr == NULL || ptr == NULL)
|
|
||||||
return;
|
|
||||||
#endif /* USER_MEM */
|
|
||||||
|
|
||||||
free(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef PNG_USER_MEM_SUPPORTED
|
|
||||||
/* This function is called when the application wants to use another method
|
|
||||||
* of allocating and freeing memory.
|
|
||||||
*/
|
|
||||||
void PNGAPI
|
|
||||||
png_set_mem_fn(png_structrp png_ptr, png_voidp mem_ptr, png_malloc_ptr
|
|
||||||
malloc_fn, png_free_ptr free_fn)
|
|
||||||
{
|
|
||||||
if (png_ptr != NULL)
|
|
||||||
{
|
|
||||||
png_ptr->mem_ptr = mem_ptr;
|
|
||||||
png_ptr->malloc_fn = malloc_fn;
|
|
||||||
png_ptr->free_fn = free_fn;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This function returns a pointer to the mem_ptr associated with the user
|
|
||||||
* functions. The application should free any memory associated with this
|
|
||||||
* pointer before png_write_destroy and png_read_destroy are called.
|
|
||||||
*/
|
|
||||||
png_voidp PNGAPI
|
|
||||||
png_get_mem_ptr(png_const_structrp png_ptr)
|
|
||||||
{
|
|
||||||
if (png_ptr == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return png_ptr->mem_ptr;
|
|
||||||
}
|
|
||||||
#endif /* USER_MEM */
|
|
||||||
#endif /* READ || WRITE */
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,120 +0,0 @@
|
||||||
|
|
||||||
/* pngrio.c - functions for data input
|
|
||||||
*
|
|
||||||
* Copyright (c) 2018 Cosmin Truta
|
|
||||||
* Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson
|
|
||||||
* Copyright (c) 1996-1997 Andreas Dilger
|
|
||||||
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
|
|
||||||
*
|
|
||||||
* This code is released under the libpng license.
|
|
||||||
* For conditions of distribution and use, see the disclaimer
|
|
||||||
* and license in png.h
|
|
||||||
*
|
|
||||||
* This file provides a location for all input. Users who need
|
|
||||||
* special handling are expected to write a function that has the same
|
|
||||||
* arguments as this and performs a similar function, but that possibly
|
|
||||||
* has a different input method. Note that you shouldn't change this
|
|
||||||
* function, but rather write a replacement function and then make
|
|
||||||
* libpng use it at run time with png_set_read_fn(...).
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "pngpriv.h"
|
|
||||||
|
|
||||||
#ifdef PNG_READ_SUPPORTED
|
|
||||||
|
|
||||||
/* Read the data from whatever input you are using. The default routine
|
|
||||||
* reads from a file pointer. Note that this routine sometimes gets called
|
|
||||||
* with very small lengths, so you should implement some kind of simple
|
|
||||||
* buffering if you are using unbuffered reads. This should never be asked
|
|
||||||
* to read more than 64K on a 16-bit machine.
|
|
||||||
*/
|
|
||||||
void /* PRIVATE */
|
|
||||||
png_read_data(png_structrp png_ptr, png_bytep data, size_t length)
|
|
||||||
{
|
|
||||||
png_debug1(4, "reading %d bytes", (int)length);
|
|
||||||
|
|
||||||
if (png_ptr->read_data_fn != NULL)
|
|
||||||
(*(png_ptr->read_data_fn))(png_ptr, data, length);
|
|
||||||
|
|
||||||
else
|
|
||||||
png_error(png_ptr, "Call to NULL read function");
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef PNG_STDIO_SUPPORTED
|
|
||||||
/* This is the function that does the actual reading of data. If you are
|
|
||||||
* not reading from a standard C stream, you should create a replacement
|
|
||||||
* read_data function and use it at run time with png_set_read_fn(), rather
|
|
||||||
* than changing the library.
|
|
||||||
*/
|
|
||||||
void PNGCBAPI
|
|
||||||
png_default_read_data(png_structp png_ptr, png_bytep data, size_t length)
|
|
||||||
{
|
|
||||||
size_t check;
|
|
||||||
|
|
||||||
if (png_ptr == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* fread() returns 0 on error, so it is OK to store this in a size_t
|
|
||||||
* instead of an int, which is what fread() actually returns.
|
|
||||||
*/
|
|
||||||
check = fread(data, 1, length, png_voidcast(png_FILE_p, png_ptr->io_ptr));
|
|
||||||
|
|
||||||
if (check != length)
|
|
||||||
png_error(png_ptr, "Read Error");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* This function allows the application to supply a new input function
|
|
||||||
* for libpng if standard C streams aren't being used.
|
|
||||||
*
|
|
||||||
* This function takes as its arguments:
|
|
||||||
*
|
|
||||||
* png_ptr - pointer to a png input data structure
|
|
||||||
*
|
|
||||||
* io_ptr - pointer to user supplied structure containing info about
|
|
||||||
* the input functions. May be NULL.
|
|
||||||
*
|
|
||||||
* read_data_fn - pointer to a new input function that takes as its
|
|
||||||
* arguments a pointer to a png_struct, a pointer to
|
|
||||||
* a location where input data can be stored, and a 32-bit
|
|
||||||
* unsigned int that is the number of bytes to be read.
|
|
||||||
* To exit and output any fatal error messages the new write
|
|
||||||
* function should call png_error(png_ptr, "Error msg").
|
|
||||||
* May be NULL, in which case libpng's default function will
|
|
||||||
* be used.
|
|
||||||
*/
|
|
||||||
void PNGAPI
|
|
||||||
png_set_read_fn(png_structrp png_ptr, png_voidp io_ptr,
|
|
||||||
png_rw_ptr read_data_fn)
|
|
||||||
{
|
|
||||||
if (png_ptr == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
png_ptr->io_ptr = io_ptr;
|
|
||||||
|
|
||||||
#ifdef PNG_STDIO_SUPPORTED
|
|
||||||
if (read_data_fn != NULL)
|
|
||||||
png_ptr->read_data_fn = read_data_fn;
|
|
||||||
|
|
||||||
else
|
|
||||||
png_ptr->read_data_fn = png_default_read_data;
|
|
||||||
#else
|
|
||||||
png_ptr->read_data_fn = read_data_fn;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PNG_WRITE_SUPPORTED
|
|
||||||
/* It is an error to write to a read device */
|
|
||||||
if (png_ptr->write_data_fn != NULL)
|
|
||||||
{
|
|
||||||
png_ptr->write_data_fn = NULL;
|
|
||||||
png_warning(png_ptr,
|
|
||||||
"Can't set both read_data_fn and write_data_fn in the"
|
|
||||||
" same structure");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PNG_WRITE_FLUSH_SUPPORTED
|
|
||||||
png_ptr->output_flush_fn = NULL;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif /* READ */
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,489 +0,0 @@
|
||||||
|
|
||||||
/* pngstruct.h - header file for PNG reference library
|
|
||||||
*
|
|
||||||
* Copyright (c) 2018-2019 Cosmin Truta
|
|
||||||
* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
|
|
||||||
* Copyright (c) 1996-1997 Andreas Dilger
|
|
||||||
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
|
|
||||||
*
|
|
||||||
* This code is released under the libpng license.
|
|
||||||
* For conditions of distribution and use, see the disclaimer
|
|
||||||
* and license in png.h
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* The structure that holds the information to read and write PNG files.
|
|
||||||
* The only people who need to care about what is inside of this are the
|
|
||||||
* people who will be modifying the library for their own special needs.
|
|
||||||
* It should NOT be accessed directly by an application.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef PNGSTRUCT_H
|
|
||||||
#define PNGSTRUCT_H
|
|
||||||
/* zlib.h defines the structure z_stream, an instance of which is included
|
|
||||||
* in this structure and is required for decompressing the LZ compressed
|
|
||||||
* data in PNG files.
|
|
||||||
*/
|
|
||||||
#ifndef ZLIB_CONST
|
|
||||||
/* We must ensure that zlib uses 'const' in declarations. */
|
|
||||||
# define ZLIB_CONST
|
|
||||||
#endif
|
|
||||||
#include "zlib.h"
|
|
||||||
#ifdef const
|
|
||||||
/* zlib.h sometimes #defines const to nothing, undo this. */
|
|
||||||
# undef const
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* zlib.h has mediocre z_const use before 1.2.6, this stuff is for compatibility
|
|
||||||
* with older builds.
|
|
||||||
*/
|
|
||||||
#if ZLIB_VERNUM < 0x1260
|
|
||||||
# define PNGZ_MSG_CAST(s) png_constcast(char*,s)
|
|
||||||
# define PNGZ_INPUT_CAST(b) png_constcast(png_bytep,b)
|
|
||||||
#else
|
|
||||||
# define PNGZ_MSG_CAST(s) (s)
|
|
||||||
# define PNGZ_INPUT_CAST(b) (b)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* zlib.h declares a magic type 'uInt' that limits the amount of data that zlib
|
|
||||||
* can handle at once. This type need be no larger than 16 bits (so maximum of
|
|
||||||
* 65535), this define allows us to discover how big it is, but limited by the
|
|
||||||
* maximum for size_t. The value can be overridden in a library build
|
|
||||||
* (pngusr.h, or set it in CPPFLAGS) and it works to set it to a considerably
|
|
||||||
* lower value (e.g. 255 works). A lower value may help memory usage (slightly)
|
|
||||||
* and may even improve performance on some systems (and degrade it on others.)
|
|
||||||
*/
|
|
||||||
#ifndef ZLIB_IO_MAX
|
|
||||||
# define ZLIB_IO_MAX ((uInt)-1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PNG_WRITE_SUPPORTED
|
|
||||||
/* The type of a compression buffer list used by the write code. */
|
|
||||||
typedef struct png_compression_buffer
|
|
||||||
{
|
|
||||||
struct png_compression_buffer *next;
|
|
||||||
png_byte output[1]; /* actually zbuf_size */
|
|
||||||
} png_compression_buffer, *png_compression_bufferp;
|
|
||||||
|
|
||||||
#define PNG_COMPRESSION_BUFFER_SIZE(pp)\
|
|
||||||
(offsetof(png_compression_buffer, output) + (pp)->zbuffer_size)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Colorspace support; structures used in png_struct, png_info and in internal
|
|
||||||
* functions to hold and communicate information about the color space.
|
|
||||||
*
|
|
||||||
* PNG_COLORSPACE_SUPPORTED is only required if the application will perform
|
|
||||||
* colorspace corrections, otherwise all the colorspace information can be
|
|
||||||
* skipped and the size of libpng can be reduced (significantly) by compiling
|
|
||||||
* out the colorspace support.
|
|
||||||
*/
|
|
||||||
#ifdef PNG_COLORSPACE_SUPPORTED
|
|
||||||
/* The chromaticities of the red, green and blue colorants and the chromaticity
|
|
||||||
* of the corresponding white point (i.e. of rgb(1.0,1.0,1.0)).
|
|
||||||
*/
|
|
||||||
typedef struct png_xy
|
|
||||||
{
|
|
||||||
png_fixed_point redx, redy;
|
|
||||||
png_fixed_point greenx, greeny;
|
|
||||||
png_fixed_point bluex, bluey;
|
|
||||||
png_fixed_point whitex, whitey;
|
|
||||||
} png_xy;
|
|
||||||
|
|
||||||
/* The same data as above but encoded as CIE XYZ values. When this data comes
|
|
||||||
* from chromaticities the sum of the Y values is assumed to be 1.0
|
|
||||||
*/
|
|
||||||
typedef struct png_XYZ
|
|
||||||
{
|
|
||||||
png_fixed_point red_X, red_Y, red_Z;
|
|
||||||
png_fixed_point green_X, green_Y, green_Z;
|
|
||||||
png_fixed_point blue_X, blue_Y, blue_Z;
|
|
||||||
} png_XYZ;
|
|
||||||
#endif /* COLORSPACE */
|
|
||||||
|
|
||||||
#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED)
|
|
||||||
/* A colorspace is all the above plus, potentially, profile information;
|
|
||||||
* however at present libpng does not use the profile internally so it is only
|
|
||||||
* stored in the png_info struct (if iCCP is supported.) The rendering intent
|
|
||||||
* is retained here and is checked.
|
|
||||||
*
|
|
||||||
* The file gamma encoding information is also stored here and gamma correction
|
|
||||||
* is done by libpng, whereas color correction must currently be done by the
|
|
||||||
* application.
|
|
||||||
*/
|
|
||||||
typedef struct png_colorspace
|
|
||||||
{
|
|
||||||
#ifdef PNG_GAMMA_SUPPORTED
|
|
||||||
png_fixed_point gamma; /* File gamma */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PNG_COLORSPACE_SUPPORTED
|
|
||||||
png_xy end_points_xy; /* End points as chromaticities */
|
|
||||||
png_XYZ end_points_XYZ; /* End points as CIE XYZ colorant values */
|
|
||||||
png_uint_16 rendering_intent; /* Rendering intent of a profile */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Flags are always defined to simplify the code. */
|
|
||||||
png_uint_16 flags; /* As defined below */
|
|
||||||
} png_colorspace, * PNG_RESTRICT png_colorspacerp;
|
|
||||||
|
|
||||||
typedef const png_colorspace * PNG_RESTRICT png_const_colorspacerp;
|
|
||||||
|
|
||||||
/* General flags for the 'flags' field */
|
|
||||||
#define PNG_COLORSPACE_HAVE_GAMMA 0x0001
|
|
||||||
#define PNG_COLORSPACE_HAVE_ENDPOINTS 0x0002
|
|
||||||
#define PNG_COLORSPACE_HAVE_INTENT 0x0004
|
|
||||||
#define PNG_COLORSPACE_FROM_gAMA 0x0008
|
|
||||||
#define PNG_COLORSPACE_FROM_cHRM 0x0010
|
|
||||||
#define PNG_COLORSPACE_FROM_sRGB 0x0020
|
|
||||||
#define PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB 0x0040
|
|
||||||
#define PNG_COLORSPACE_MATCHES_sRGB 0x0080 /* exact match on profile */
|
|
||||||
#define PNG_COLORSPACE_INVALID 0x8000
|
|
||||||
#define PNG_COLORSPACE_CANCEL(flags) (0xffff ^ (flags))
|
|
||||||
#endif /* COLORSPACE || GAMMA */
|
|
||||||
|
|
||||||
struct png_struct_def
|
|
||||||
{
|
|
||||||
#ifdef PNG_SETJMP_SUPPORTED
|
|
||||||
jmp_buf jmp_buf_local; /* New name in 1.6.0 for jmp_buf in png_struct */
|
|
||||||
png_longjmp_ptr longjmp_fn;/* setjmp non-local goto function. */
|
|
||||||
jmp_buf *jmp_buf_ptr; /* passed to longjmp_fn */
|
|
||||||
size_t jmp_buf_size; /* size of the above, if allocated */
|
|
||||||
#endif
|
|
||||||
png_error_ptr error_fn; /* function for printing errors and aborting */
|
|
||||||
#ifdef PNG_WARNINGS_SUPPORTED
|
|
||||||
png_error_ptr warning_fn; /* function for printing warnings */
|
|
||||||
#endif
|
|
||||||
png_voidp error_ptr; /* user supplied struct for error functions */
|
|
||||||
png_rw_ptr write_data_fn; /* function for writing output data */
|
|
||||||
png_rw_ptr read_data_fn; /* function for reading input data */
|
|
||||||
png_voidp io_ptr; /* ptr to application struct for I/O functions */
|
|
||||||
|
|
||||||
#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
|
|
||||||
png_user_transform_ptr read_user_transform_fn; /* user read transform */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
|
|
||||||
png_user_transform_ptr write_user_transform_fn; /* user write transform */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* These were added in libpng-1.0.2 */
|
|
||||||
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
|
|
||||||
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
|
|
||||||
defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
|
|
||||||
png_voidp user_transform_ptr; /* user supplied struct for user transform */
|
|
||||||
png_byte user_transform_depth; /* bit depth of user transformed pixels */
|
|
||||||
png_byte user_transform_channels; /* channels in user transformed pixels */
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
png_uint_32 mode; /* tells us where we are in the PNG file */
|
|
||||||
png_uint_32 flags; /* flags indicating various things to libpng */
|
|
||||||
png_uint_32 transformations; /* which transformations to perform */
|
|
||||||
|
|
||||||
png_uint_32 zowner; /* ID (chunk type) of zstream owner, 0 if none */
|
|
||||||
z_stream zstream; /* decompression structure */
|
|
||||||
|
|
||||||
#ifdef PNG_WRITE_SUPPORTED
|
|
||||||
png_compression_bufferp zbuffer_list; /* Created on demand during write */
|
|
||||||
uInt zbuffer_size; /* size of the actual buffer */
|
|
||||||
|
|
||||||
int zlib_level; /* holds zlib compression level */
|
|
||||||
int zlib_method; /* holds zlib compression method */
|
|
||||||
int zlib_window_bits; /* holds zlib compression window bits */
|
|
||||||
int zlib_mem_level; /* holds zlib compression memory level */
|
|
||||||
int zlib_strategy; /* holds zlib compression strategy */
|
|
||||||
#endif
|
|
||||||
/* Added at libpng 1.5.4 */
|
|
||||||
#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
|
|
||||||
int zlib_text_level; /* holds zlib compression level */
|
|
||||||
int zlib_text_method; /* holds zlib compression method */
|
|
||||||
int zlib_text_window_bits; /* holds zlib compression window bits */
|
|
||||||
int zlib_text_mem_level; /* holds zlib compression memory level */
|
|
||||||
int zlib_text_strategy; /* holds zlib compression strategy */
|
|
||||||
#endif
|
|
||||||
/* End of material added at libpng 1.5.4 */
|
|
||||||
/* Added at libpng 1.6.0 */
|
|
||||||
#ifdef PNG_WRITE_SUPPORTED
|
|
||||||
int zlib_set_level; /* Actual values set into the zstream on write */
|
|
||||||
int zlib_set_method;
|
|
||||||
int zlib_set_window_bits;
|
|
||||||
int zlib_set_mem_level;
|
|
||||||
int zlib_set_strategy;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
png_uint_32 width; /* width of image in pixels */
|
|
||||||
png_uint_32 height; /* height of image in pixels */
|
|
||||||
png_uint_32 num_rows; /* number of rows in current pass */
|
|
||||||
png_uint_32 usr_width; /* width of row at start of write */
|
|
||||||
size_t rowbytes; /* size of row in bytes */
|
|
||||||
png_uint_32 iwidth; /* width of current interlaced row in pixels */
|
|
||||||
png_uint_32 row_number; /* current row in interlace pass */
|
|
||||||
png_uint_32 chunk_name; /* PNG_CHUNK() id of current chunk */
|
|
||||||
png_bytep prev_row; /* buffer to save previous (unfiltered) row.
|
|
||||||
* While reading this is a pointer into
|
|
||||||
* big_prev_row; while writing it is separately
|
|
||||||
* allocated if needed.
|
|
||||||
*/
|
|
||||||
png_bytep row_buf; /* buffer to save current (unfiltered) row.
|
|
||||||
* While reading, this is a pointer into
|
|
||||||
* big_row_buf; while writing it is separately
|
|
||||||
* allocated.
|
|
||||||
*/
|
|
||||||
#ifdef PNG_WRITE_FILTER_SUPPORTED
|
|
||||||
png_bytep try_row; /* buffer to save trial row when filtering */
|
|
||||||
png_bytep tst_row; /* buffer to save best trial row when filtering */
|
|
||||||
#endif
|
|
||||||
size_t info_rowbytes; /* Added in 1.5.4: cache of updated row bytes */
|
|
||||||
|
|
||||||
png_uint_32 idat_size; /* current IDAT size for read */
|
|
||||||
png_uint_32 crc; /* current chunk CRC value */
|
|
||||||
png_colorp palette; /* palette from the input file */
|
|
||||||
png_uint_16 num_palette; /* number of color entries in palette */
|
|
||||||
|
|
||||||
/* Added at libpng-1.5.10 */
|
|
||||||
#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
|
|
||||||
int num_palette_max; /* maximum palette index found in IDAT */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
png_uint_16 num_trans; /* number of transparency values */
|
|
||||||
png_byte compression; /* file compression type (always 0) */
|
|
||||||
png_byte filter; /* file filter type (always 0) */
|
|
||||||
png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
|
|
||||||
png_byte pass; /* current interlace pass (0 - 6) */
|
|
||||||
png_byte do_filter; /* row filter flags (see PNG_FILTER_ in png.h ) */
|
|
||||||
png_byte color_type; /* color type of file */
|
|
||||||
png_byte bit_depth; /* bit depth of file */
|
|
||||||
png_byte usr_bit_depth; /* bit depth of users row: write only */
|
|
||||||
png_byte pixel_depth; /* number of bits per pixel */
|
|
||||||
png_byte channels; /* number of channels in file */
|
|
||||||
#ifdef PNG_WRITE_SUPPORTED
|
|
||||||
png_byte usr_channels; /* channels at start of write: write only */
|
|
||||||
#endif
|
|
||||||
png_byte sig_bytes; /* magic bytes read/written from start of file */
|
|
||||||
png_byte maximum_pixel_depth;
|
|
||||||
/* pixel depth used for the row buffers */
|
|
||||||
png_byte transformed_pixel_depth;
|
|
||||||
/* pixel depth after read/write transforms */
|
|
||||||
#if ZLIB_VERNUM >= 0x1240
|
|
||||||
png_byte zstream_start; /* at start of an input zlib stream */
|
|
||||||
#endif /* Zlib >= 1.2.4 */
|
|
||||||
#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
|
|
||||||
png_uint_16 filler; /* filler bytes for pixel expansion */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
|
|
||||||
defined(PNG_READ_ALPHA_MODE_SUPPORTED)
|
|
||||||
png_byte background_gamma_type;
|
|
||||||
png_fixed_point background_gamma;
|
|
||||||
png_color_16 background; /* background color in screen gamma space */
|
|
||||||
#ifdef PNG_READ_GAMMA_SUPPORTED
|
|
||||||
png_color_16 background_1; /* background normalized to gamma 1.0 */
|
|
||||||
#endif
|
|
||||||
#endif /* bKGD */
|
|
||||||
|
|
||||||
#ifdef PNG_WRITE_FLUSH_SUPPORTED
|
|
||||||
png_flush_ptr output_flush_fn; /* Function for flushing output */
|
|
||||||
png_uint_32 flush_dist; /* how many rows apart to flush, 0 - no flush */
|
|
||||||
png_uint_32 flush_rows; /* number of rows written since last flush */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PNG_READ_GAMMA_SUPPORTED
|
|
||||||
int gamma_shift; /* number of "insignificant" bits in 16-bit gamma */
|
|
||||||
png_fixed_point screen_gamma; /* screen gamma value (display_exponent) */
|
|
||||||
|
|
||||||
png_bytep gamma_table; /* gamma table for 8-bit depth files */
|
|
||||||
png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */
|
|
||||||
#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
|
|
||||||
defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
|
|
||||||
defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
|
|
||||||
png_bytep gamma_from_1; /* converts from 1.0 to screen */
|
|
||||||
png_bytep gamma_to_1; /* converts from file to 1.0 */
|
|
||||||
png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */
|
|
||||||
png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */
|
|
||||||
#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED)
|
|
||||||
png_color_8 sig_bit; /* significant bits in each available channel */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
|
|
||||||
png_color_8 shift; /* shift for significant bit transformation */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \
|
|
||||||
|| defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
|
|
||||||
png_bytep trans_alpha; /* alpha values for paletted files */
|
|
||||||
png_color_16 trans_color; /* transparent color for non-paletted files */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
png_read_status_ptr read_row_fn; /* called after each row is decoded */
|
|
||||||
png_write_status_ptr write_row_fn; /* called after each row is encoded */
|
|
||||||
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
|
|
||||||
png_progressive_info_ptr info_fn; /* called after header data fully read */
|
|
||||||
png_progressive_row_ptr row_fn; /* called after a prog. row is decoded */
|
|
||||||
png_progressive_end_ptr end_fn; /* called after image is complete */
|
|
||||||
png_bytep save_buffer_ptr; /* current location in save_buffer */
|
|
||||||
png_bytep save_buffer; /* buffer for previously read data */
|
|
||||||
png_bytep current_buffer_ptr; /* current location in current_buffer */
|
|
||||||
png_bytep current_buffer; /* buffer for recently used data */
|
|
||||||
png_uint_32 push_length; /* size of current input chunk */
|
|
||||||
png_uint_32 skip_length; /* bytes to skip in input data */
|
|
||||||
size_t save_buffer_size; /* amount of data now in save_buffer */
|
|
||||||
size_t save_buffer_max; /* total size of save_buffer */
|
|
||||||
size_t buffer_size; /* total amount of available input data */
|
|
||||||
size_t current_buffer_size; /* amount of data now in current_buffer */
|
|
||||||
int process_mode; /* what push library is currently doing */
|
|
||||||
int cur_palette; /* current push library palette index */
|
|
||||||
|
|
||||||
#endif /* PROGRESSIVE_READ */
|
|
||||||
|
|
||||||
#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
|
|
||||||
/* For the Borland special 64K segment handler */
|
|
||||||
png_bytepp offset_table_ptr;
|
|
||||||
png_bytep offset_table;
|
|
||||||
png_uint_16 offset_table_number;
|
|
||||||
png_uint_16 offset_table_count;
|
|
||||||
png_uint_16 offset_table_count_free;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PNG_READ_QUANTIZE_SUPPORTED
|
|
||||||
png_bytep palette_lookup; /* lookup table for quantizing */
|
|
||||||
png_bytep quantize_index; /* index translation for palette files */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Options */
|
|
||||||
#ifdef PNG_SET_OPTION_SUPPORTED
|
|
||||||
png_uint_32 options; /* On/off state (up to 16 options) */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if PNG_LIBPNG_VER < 10700
|
|
||||||
/* To do: remove this from libpng-1.7 */
|
|
||||||
#ifdef PNG_TIME_RFC1123_SUPPORTED
|
|
||||||
char time_buffer[29]; /* String to hold RFC 1123 time text */
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* New members added in libpng-1.0.6 */
|
|
||||||
|
|
||||||
png_uint_32 free_me; /* flags items libpng is responsible for freeing */
|
|
||||||
|
|
||||||
#ifdef PNG_USER_CHUNKS_SUPPORTED
|
|
||||||
png_voidp user_chunk_ptr;
|
|
||||||
#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
|
|
||||||
png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
|
|
||||||
int unknown_default; /* As PNG_HANDLE_* */
|
|
||||||
unsigned int num_chunk_list; /* Number of entries in the list */
|
|
||||||
png_bytep chunk_list; /* List of png_byte[5]; the textual chunk name
|
|
||||||
* followed by a PNG_HANDLE_* byte */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* New members added in libpng-1.0.3 */
|
|
||||||
#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
|
|
||||||
png_byte rgb_to_gray_status;
|
|
||||||
/* Added in libpng 1.5.5 to record setting of coefficients: */
|
|
||||||
png_byte rgb_to_gray_coefficients_set;
|
|
||||||
/* These were changed from png_byte in libpng-1.0.6 */
|
|
||||||
png_uint_16 rgb_to_gray_red_coeff;
|
|
||||||
png_uint_16 rgb_to_gray_green_coeff;
|
|
||||||
/* deleted in 1.5.5: rgb_to_gray_blue_coeff; */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* New member added in libpng-1.6.36 */
|
|
||||||
#if defined(PNG_READ_EXPAND_SUPPORTED) && \
|
|
||||||
defined(PNG_ARM_NEON_IMPLEMENTATION)
|
|
||||||
png_bytep riffled_palette; /* buffer for accelerated palette expansion */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* New member added in libpng-1.0.4 (renamed in 1.0.9) */
|
|
||||||
#if defined(PNG_MNG_FEATURES_SUPPORTED)
|
|
||||||
/* Changed from png_byte to png_uint_32 at version 1.2.0 */
|
|
||||||
png_uint_32 mng_features_permitted;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */
|
|
||||||
#ifdef PNG_MNG_FEATURES_SUPPORTED
|
|
||||||
png_byte filter_type;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* New members added in libpng-1.2.0 */
|
|
||||||
|
|
||||||
/* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */
|
|
||||||
#ifdef PNG_USER_MEM_SUPPORTED
|
|
||||||
png_voidp mem_ptr; /* user supplied struct for mem functions */
|
|
||||||
png_malloc_ptr malloc_fn; /* function for allocating memory */
|
|
||||||
png_free_ptr free_fn; /* function for freeing memory */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* New member added in libpng-1.0.13 and 1.2.0 */
|
|
||||||
png_bytep big_row_buf; /* buffer to save current (unfiltered) row */
|
|
||||||
|
|
||||||
#ifdef PNG_READ_QUANTIZE_SUPPORTED
|
|
||||||
/* The following three members were added at version 1.0.14 and 1.2.4 */
|
|
||||||
png_bytep quantize_sort; /* working sort array */
|
|
||||||
png_bytep index_to_palette; /* where the original index currently is
|
|
||||||
in the palette */
|
|
||||||
png_bytep palette_to_index; /* which original index points to this
|
|
||||||
palette color */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* New members added in libpng-1.0.16 and 1.2.6 */
|
|
||||||
png_byte compression_type;
|
|
||||||
|
|
||||||
#ifdef PNG_USER_LIMITS_SUPPORTED
|
|
||||||
png_uint_32 user_width_max;
|
|
||||||
png_uint_32 user_height_max;
|
|
||||||
|
|
||||||
/* Added in libpng-1.4.0: Total number of sPLT, text, and unknown
|
|
||||||
* chunks that can be stored (0 means unlimited).
|
|
||||||
*/
|
|
||||||
png_uint_32 user_chunk_cache_max;
|
|
||||||
|
|
||||||
/* Total memory that a zTXt, sPLT, iTXt, iCCP, or unknown chunk
|
|
||||||
* can occupy when decompressed. 0 means unlimited.
|
|
||||||
*/
|
|
||||||
png_alloc_size_t user_chunk_malloc_max;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* New member added in libpng-1.0.25 and 1.2.17 */
|
|
||||||
#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
|
|
||||||
/* Temporary storage for unknown chunk that the library doesn't recognize,
|
|
||||||
* used while reading the chunk.
|
|
||||||
*/
|
|
||||||
png_unknown_chunk unknown_chunk;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* New member added in libpng-1.2.26 */
|
|
||||||
size_t old_big_row_buf_size;
|
|
||||||
|
|
||||||
#ifdef PNG_READ_SUPPORTED
|
|
||||||
/* New member added in libpng-1.2.30 */
|
|
||||||
png_bytep read_buffer; /* buffer for reading chunk data */
|
|
||||||
png_alloc_size_t read_buffer_size; /* current size of the buffer */
|
|
||||||
#endif
|
|
||||||
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
|
|
||||||
uInt IDAT_read_size; /* limit on read buffer size for IDAT */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PNG_IO_STATE_SUPPORTED
|
|
||||||
/* New member added in libpng-1.4.0 */
|
|
||||||
png_uint_32 io_state;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* New member added in libpng-1.5.6 */
|
|
||||||
png_bytep big_prev_row;
|
|
||||||
|
|
||||||
/* New member added in libpng-1.5.7 */
|
|
||||||
void (*read_filter[PNG_FILTER_VALUE_LAST-1])(png_row_infop row_info,
|
|
||||||
png_bytep row, png_const_bytep prev_row);
|
|
||||||
|
|
||||||
#ifdef PNG_READ_SUPPORTED
|
|
||||||
#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED)
|
|
||||||
png_colorspace colorspace;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
#endif /* PNGSTRUCT_H */
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,864 +0,0 @@
|
||||||
|
|
||||||
/* pngtrans.c - transforms the data in a row (used by both readers and writers)
|
|
||||||
*
|
|
||||||
* Copyright (c) 2018 Cosmin Truta
|
|
||||||
* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
|
|
||||||
* Copyright (c) 1996-1997 Andreas Dilger
|
|
||||||
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
|
|
||||||
*
|
|
||||||
* This code is released under the libpng license.
|
|
||||||
* For conditions of distribution and use, see the disclaimer
|
|
||||||
* and license in png.h
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "pngpriv.h"
|
|
||||||
|
|
||||||
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
|
|
||||||
|
|
||||||
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
|
|
||||||
/* Turn on BGR-to-RGB mapping */
|
|
||||||
void PNGAPI
|
|
||||||
png_set_bgr(png_structrp png_ptr)
|
|
||||||
{
|
|
||||||
png_debug(1, "in png_set_bgr");
|
|
||||||
|
|
||||||
if (png_ptr == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
png_ptr->transformations |= PNG_BGR;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
|
|
||||||
/* Turn on 16-bit byte swapping */
|
|
||||||
void PNGAPI
|
|
||||||
png_set_swap(png_structrp png_ptr)
|
|
||||||
{
|
|
||||||
png_debug(1, "in png_set_swap");
|
|
||||||
|
|
||||||
if (png_ptr == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (png_ptr->bit_depth == 16)
|
|
||||||
png_ptr->transformations |= PNG_SWAP_BYTES;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
|
|
||||||
/* Turn on pixel packing */
|
|
||||||
void PNGAPI
|
|
||||||
png_set_packing(png_structrp png_ptr)
|
|
||||||
{
|
|
||||||
png_debug(1, "in png_set_packing");
|
|
||||||
|
|
||||||
if (png_ptr == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (png_ptr->bit_depth < 8)
|
|
||||||
{
|
|
||||||
png_ptr->transformations |= PNG_PACK;
|
|
||||||
# ifdef PNG_WRITE_SUPPORTED
|
|
||||||
png_ptr->usr_bit_depth = 8;
|
|
||||||
# endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
|
|
||||||
/* Turn on packed pixel swapping */
|
|
||||||
void PNGAPI
|
|
||||||
png_set_packswap(png_structrp png_ptr)
|
|
||||||
{
|
|
||||||
png_debug(1, "in png_set_packswap");
|
|
||||||
|
|
||||||
if (png_ptr == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (png_ptr->bit_depth < 8)
|
|
||||||
png_ptr->transformations |= PNG_PACKSWAP;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
|
|
||||||
void PNGAPI
|
|
||||||
png_set_shift(png_structrp png_ptr, png_const_color_8p true_bits)
|
|
||||||
{
|
|
||||||
png_debug(1, "in png_set_shift");
|
|
||||||
|
|
||||||
if (png_ptr == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
png_ptr->transformations |= PNG_SHIFT;
|
|
||||||
png_ptr->shift = *true_bits;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
|
|
||||||
defined(PNG_WRITE_INTERLACING_SUPPORTED)
|
|
||||||
int PNGAPI
|
|
||||||
png_set_interlace_handling(png_structrp png_ptr)
|
|
||||||
{
|
|
||||||
png_debug(1, "in png_set_interlace handling");
|
|
||||||
|
|
||||||
if (png_ptr != 0 && png_ptr->interlaced != 0)
|
|
||||||
{
|
|
||||||
png_ptr->transformations |= PNG_INTERLACE;
|
|
||||||
return (7);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
|
|
||||||
/* Add a filler byte on read, or remove a filler or alpha byte on write.
|
|
||||||
* The filler type has changed in v0.95 to allow future 2-byte fillers
|
|
||||||
* for 48-bit input data, as well as to avoid problems with some compilers
|
|
||||||
* that don't like bytes as parameters.
|
|
||||||
*/
|
|
||||||
void PNGAPI
|
|
||||||
png_set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
|
|
||||||
{
|
|
||||||
png_debug(1, "in png_set_filler");
|
|
||||||
|
|
||||||
if (png_ptr == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* In libpng 1.6 it is possible to determine whether this is a read or write
|
|
||||||
* operation and therefore to do more checking here for a valid call.
|
|
||||||
*/
|
|
||||||
if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0)
|
|
||||||
{
|
|
||||||
# ifdef PNG_READ_FILLER_SUPPORTED
|
|
||||||
/* On read png_set_filler is always valid, regardless of the base PNG
|
|
||||||
* format, because other transformations can give a format where the
|
|
||||||
* filler code can execute (basically an 8 or 16-bit component RGB or G
|
|
||||||
* format.)
|
|
||||||
*
|
|
||||||
* NOTE: usr_channels is not used by the read code! (This has led to
|
|
||||||
* confusion in the past.) The filler is only used in the read code.
|
|
||||||
*/
|
|
||||||
png_ptr->filler = (png_uint_16)filler;
|
|
||||||
# else
|
|
||||||
png_app_error(png_ptr, "png_set_filler not supported on read");
|
|
||||||
PNG_UNUSED(filler) /* not used in the write case */
|
|
||||||
return;
|
|
||||||
# endif
|
|
||||||
}
|
|
||||||
|
|
||||||
else /* write */
|
|
||||||
{
|
|
||||||
# ifdef PNG_WRITE_FILLER_SUPPORTED
|
|
||||||
/* On write the usr_channels parameter must be set correctly at the
|
|
||||||
* start to record the number of channels in the app-supplied data.
|
|
||||||
*/
|
|
||||||
switch (png_ptr->color_type)
|
|
||||||
{
|
|
||||||
case PNG_COLOR_TYPE_RGB:
|
|
||||||
png_ptr->usr_channels = 4;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PNG_COLOR_TYPE_GRAY:
|
|
||||||
if (png_ptr->bit_depth >= 8)
|
|
||||||
{
|
|
||||||
png_ptr->usr_channels = 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* There simply isn't any code in libpng to strip out bits
|
|
||||||
* from bytes when the components are less than a byte in
|
|
||||||
* size!
|
|
||||||
*/
|
|
||||||
png_app_error(png_ptr,
|
|
||||||
"png_set_filler is invalid for"
|
|
||||||
" low bit depth gray output");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
png_app_error(png_ptr,
|
|
||||||
"png_set_filler: inappropriate color type");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
# else
|
|
||||||
png_app_error(png_ptr, "png_set_filler not supported on write");
|
|
||||||
return;
|
|
||||||
# endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Here on success - libpng supports the operation, set the transformation
|
|
||||||
* and the flag to say where the filler channel is.
|
|
||||||
*/
|
|
||||||
png_ptr->transformations |= PNG_FILLER;
|
|
||||||
|
|
||||||
if (filler_loc == PNG_FILLER_AFTER)
|
|
||||||
png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
|
|
||||||
|
|
||||||
else
|
|
||||||
png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Added to libpng-1.2.7 */
|
|
||||||
void PNGAPI
|
|
||||||
png_set_add_alpha(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
|
|
||||||
{
|
|
||||||
png_debug(1, "in png_set_add_alpha");
|
|
||||||
|
|
||||||
if (png_ptr == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
png_set_filler(png_ptr, filler, filler_loc);
|
|
||||||
/* The above may fail to do anything. */
|
|
||||||
if ((png_ptr->transformations & PNG_FILLER) != 0)
|
|
||||||
png_ptr->transformations |= PNG_ADD_ALPHA;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
|
|
||||||
defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
|
|
||||||
void PNGAPI
|
|
||||||
png_set_swap_alpha(png_structrp png_ptr)
|
|
||||||
{
|
|
||||||
png_debug(1, "in png_set_swap_alpha");
|
|
||||||
|
|
||||||
if (png_ptr == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
png_ptr->transformations |= PNG_SWAP_ALPHA;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
|
|
||||||
defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
|
|
||||||
void PNGAPI
|
|
||||||
png_set_invert_alpha(png_structrp png_ptr)
|
|
||||||
{
|
|
||||||
png_debug(1, "in png_set_invert_alpha");
|
|
||||||
|
|
||||||
if (png_ptr == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
png_ptr->transformations |= PNG_INVERT_ALPHA;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
|
|
||||||
void PNGAPI
|
|
||||||
png_set_invert_mono(png_structrp png_ptr)
|
|
||||||
{
|
|
||||||
png_debug(1, "in png_set_invert_mono");
|
|
||||||
|
|
||||||
if (png_ptr == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
png_ptr->transformations |= PNG_INVERT_MONO;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Invert monochrome grayscale data */
|
|
||||||
void /* PRIVATE */
|
|
||||||
png_do_invert(png_row_infop row_info, png_bytep row)
|
|
||||||
{
|
|
||||||
png_debug(1, "in png_do_invert");
|
|
||||||
|
|
||||||
/* This test removed from libpng version 1.0.13 and 1.2.0:
|
|
||||||
* if (row_info->bit_depth == 1 &&
|
|
||||||
*/
|
|
||||||
if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
|
|
||||||
{
|
|
||||||
png_bytep rp = row;
|
|
||||||
size_t i;
|
|
||||||
size_t istop = row_info->rowbytes;
|
|
||||||
|
|
||||||
for (i = 0; i < istop; i++)
|
|
||||||
{
|
|
||||||
*rp = (png_byte)(~(*rp));
|
|
||||||
rp++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
|
|
||||||
row_info->bit_depth == 8)
|
|
||||||
{
|
|
||||||
png_bytep rp = row;
|
|
||||||
size_t i;
|
|
||||||
size_t istop = row_info->rowbytes;
|
|
||||||
|
|
||||||
for (i = 0; i < istop; i += 2)
|
|
||||||
{
|
|
||||||
*rp = (png_byte)(~(*rp));
|
|
||||||
rp += 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef PNG_16BIT_SUPPORTED
|
|
||||||
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
|
|
||||||
row_info->bit_depth == 16)
|
|
||||||
{
|
|
||||||
png_bytep rp = row;
|
|
||||||
size_t i;
|
|
||||||
size_t istop = row_info->rowbytes;
|
|
||||||
|
|
||||||
for (i = 0; i < istop; i += 4)
|
|
||||||
{
|
|
||||||
*rp = (png_byte)(~(*rp));
|
|
||||||
*(rp + 1) = (png_byte)(~(*(rp + 1)));
|
|
||||||
rp += 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PNG_16BIT_SUPPORTED
|
|
||||||
#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
|
|
||||||
/* Swaps byte order on 16-bit depth images */
|
|
||||||
void /* PRIVATE */
|
|
||||||
png_do_swap(png_row_infop row_info, png_bytep row)
|
|
||||||
{
|
|
||||||
png_debug(1, "in png_do_swap");
|
|
||||||
|
|
||||||
if (row_info->bit_depth == 16)
|
|
||||||
{
|
|
||||||
png_bytep rp = row;
|
|
||||||
png_uint_32 i;
|
|
||||||
png_uint_32 istop= row_info->width * row_info->channels;
|
|
||||||
|
|
||||||
for (i = 0; i < istop; i++, rp += 2)
|
|
||||||
{
|
|
||||||
#ifdef PNG_BUILTIN_BSWAP16_SUPPORTED
|
|
||||||
/* Feature added to libpng-1.6.11 for testing purposes, not
|
|
||||||
* enabled by default.
|
|
||||||
*/
|
|
||||||
*(png_uint_16*)rp = __builtin_bswap16(*(png_uint_16*)rp);
|
|
||||||
#else
|
|
||||||
png_byte t = *rp;
|
|
||||||
*rp = *(rp + 1);
|
|
||||||
*(rp + 1) = t;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
|
|
||||||
static const png_byte onebppswaptable[256] = {
|
|
||||||
0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
|
|
||||||
0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
|
|
||||||
0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
|
|
||||||
0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
|
|
||||||
0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
|
|
||||||
0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
|
|
||||||
0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
|
|
||||||
0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
|
|
||||||
0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
|
|
||||||
0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
|
|
||||||
0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
|
|
||||||
0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
|
|
||||||
0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
|
|
||||||
0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
|
|
||||||
0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
|
|
||||||
0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
|
|
||||||
0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
|
|
||||||
0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
|
|
||||||
0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
|
|
||||||
0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
|
|
||||||
0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
|
|
||||||
0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
|
|
||||||
0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
|
|
||||||
0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
|
|
||||||
0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
|
|
||||||
0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
|
|
||||||
0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
|
|
||||||
0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
|
|
||||||
0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
|
|
||||||
0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
|
|
||||||
0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
|
|
||||||
0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
|
|
||||||
};
|
|
||||||
|
|
||||||
static const png_byte twobppswaptable[256] = {
|
|
||||||
0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
|
|
||||||
0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
|
|
||||||
0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
|
|
||||||
0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
|
|
||||||
0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
|
|
||||||
0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
|
|
||||||
0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
|
|
||||||
0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
|
|
||||||
0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
|
|
||||||
0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
|
|
||||||
0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
|
|
||||||
0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
|
|
||||||
0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
|
|
||||||
0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
|
|
||||||
0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
|
|
||||||
0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
|
|
||||||
0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
|
|
||||||
0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
|
|
||||||
0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
|
|
||||||
0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
|
|
||||||
0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
|
|
||||||
0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
|
|
||||||
0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
|
|
||||||
0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
|
|
||||||
0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
|
|
||||||
0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
|
|
||||||
0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
|
|
||||||
0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
|
|
||||||
0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
|
|
||||||
0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
|
|
||||||
0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
|
|
||||||
0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
|
|
||||||
};
|
|
||||||
|
|
||||||
static const png_byte fourbppswaptable[256] = {
|
|
||||||
0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
|
|
||||||
0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
|
|
||||||
0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
|
|
||||||
0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
|
|
||||||
0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
|
|
||||||
0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
|
|
||||||
0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
|
|
||||||
0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
|
|
||||||
0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
|
|
||||||
0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
|
|
||||||
0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
|
|
||||||
0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
|
|
||||||
0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
|
|
||||||
0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
|
|
||||||
0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
|
|
||||||
0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
|
|
||||||
0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
|
|
||||||
0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
|
|
||||||
0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
|
|
||||||
0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
|
|
||||||
0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
|
|
||||||
0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
|
|
||||||
0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
|
|
||||||
0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
|
|
||||||
0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
|
|
||||||
0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
|
|
||||||
0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
|
|
||||||
0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
|
|
||||||
0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
|
|
||||||
0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
|
|
||||||
0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
|
|
||||||
0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Swaps pixel packing order within bytes */
|
|
||||||
void /* PRIVATE */
|
|
||||||
png_do_packswap(png_row_infop row_info, png_bytep row)
|
|
||||||
{
|
|
||||||
png_debug(1, "in png_do_packswap");
|
|
||||||
|
|
||||||
if (row_info->bit_depth < 8)
|
|
||||||
{
|
|
||||||
png_bytep rp;
|
|
||||||
png_const_bytep end, table;
|
|
||||||
|
|
||||||
end = row + row_info->rowbytes;
|
|
||||||
|
|
||||||
if (row_info->bit_depth == 1)
|
|
||||||
table = onebppswaptable;
|
|
||||||
|
|
||||||
else if (row_info->bit_depth == 2)
|
|
||||||
table = twobppswaptable;
|
|
||||||
|
|
||||||
else if (row_info->bit_depth == 4)
|
|
||||||
table = fourbppswaptable;
|
|
||||||
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (rp = row; rp < end; rp++)
|
|
||||||
*rp = table[*rp];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* PACKSWAP || WRITE_PACKSWAP */
|
|
||||||
|
|
||||||
#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
|
|
||||||
defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
|
|
||||||
/* Remove a channel - this used to be 'png_do_strip_filler' but it used a
|
|
||||||
* somewhat weird combination of flags to determine what to do. All the calls
|
|
||||||
* to png_do_strip_filler are changed in 1.5.2 to call this instead with the
|
|
||||||
* correct arguments.
|
|
||||||
*
|
|
||||||
* The routine isn't general - the channel must be the channel at the start or
|
|
||||||
* end (not in the middle) of each pixel.
|
|
||||||
*/
|
|
||||||
void /* PRIVATE */
|
|
||||||
png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
|
|
||||||
{
|
|
||||||
png_bytep sp = row; /* source pointer */
|
|
||||||
png_bytep dp = row; /* destination pointer */
|
|
||||||
png_bytep ep = row + row_info->rowbytes; /* One beyond end of row */
|
|
||||||
|
|
||||||
/* At the start sp will point to the first byte to copy and dp to where
|
|
||||||
* it is copied to. ep always points just beyond the end of the row, so
|
|
||||||
* the loop simply copies (channels-1) channels until sp reaches ep.
|
|
||||||
*
|
|
||||||
* at_start: 0 -- convert AG, XG, ARGB, XRGB, AAGG, XXGG, etc.
|
|
||||||
* nonzero -- convert GA, GX, RGBA, RGBX, GGAA, RRGGBBXX, etc.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* GA, GX, XG cases */
|
|
||||||
if (row_info->channels == 2)
|
|
||||||
{
|
|
||||||
if (row_info->bit_depth == 8)
|
|
||||||
{
|
|
||||||
if (at_start != 0) /* Skip initial filler */
|
|
||||||
++sp;
|
|
||||||
else /* Skip initial channel and, for sp, the filler */
|
|
||||||
{
|
|
||||||
sp += 2; ++dp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* For a 1 pixel wide image there is nothing to do */
|
|
||||||
while (sp < ep)
|
|
||||||
{
|
|
||||||
*dp++ = *sp; sp += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
row_info->pixel_depth = 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (row_info->bit_depth == 16)
|
|
||||||
{
|
|
||||||
if (at_start != 0) /* Skip initial filler */
|
|
||||||
sp += 2;
|
|
||||||
else /* Skip initial channel and, for sp, the filler */
|
|
||||||
{
|
|
||||||
sp += 4; dp += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (sp < ep)
|
|
||||||
{
|
|
||||||
*dp++ = *sp++; *dp++ = *sp; sp += 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
row_info->pixel_depth = 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
return; /* bad bit depth */
|
|
||||||
|
|
||||||
row_info->channels = 1;
|
|
||||||
|
|
||||||
/* Finally fix the color type if it records an alpha channel */
|
|
||||||
if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
|
||||||
row_info->color_type = PNG_COLOR_TYPE_GRAY;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* RGBA, RGBX, XRGB cases */
|
|
||||||
else if (row_info->channels == 4)
|
|
||||||
{
|
|
||||||
if (row_info->bit_depth == 8)
|
|
||||||
{
|
|
||||||
if (at_start != 0) /* Skip initial filler */
|
|
||||||
++sp;
|
|
||||||
else /* Skip initial channels and, for sp, the filler */
|
|
||||||
{
|
|
||||||
sp += 4; dp += 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Note that the loop adds 3 to dp and 4 to sp each time. */
|
|
||||||
while (sp < ep)
|
|
||||||
{
|
|
||||||
*dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp; sp += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
row_info->pixel_depth = 24;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (row_info->bit_depth == 16)
|
|
||||||
{
|
|
||||||
if (at_start != 0) /* Skip initial filler */
|
|
||||||
sp += 2;
|
|
||||||
else /* Skip initial channels and, for sp, the filler */
|
|
||||||
{
|
|
||||||
sp += 8; dp += 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (sp < ep)
|
|
||||||
{
|
|
||||||
/* Copy 6 bytes, skip 2 */
|
|
||||||
*dp++ = *sp++; *dp++ = *sp++;
|
|
||||||
*dp++ = *sp++; *dp++ = *sp++;
|
|
||||||
*dp++ = *sp++; *dp++ = *sp; sp += 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
row_info->pixel_depth = 48;
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
return; /* bad bit depth */
|
|
||||||
|
|
||||||
row_info->channels = 3;
|
|
||||||
|
|
||||||
/* Finally fix the color type if it records an alpha channel */
|
|
||||||
if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
|
|
||||||
row_info->color_type = PNG_COLOR_TYPE_RGB;
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
return; /* The filler channel has gone already */
|
|
||||||
|
|
||||||
/* Fix the rowbytes value. */
|
|
||||||
row_info->rowbytes = (size_t)(dp-row);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
|
|
||||||
/* Swaps red and blue bytes within a pixel */
|
|
||||||
void /* PRIVATE */
|
|
||||||
png_do_bgr(png_row_infop row_info, png_bytep row)
|
|
||||||
{
|
|
||||||
png_debug(1, "in png_do_bgr");
|
|
||||||
|
|
||||||
if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
|
|
||||||
{
|
|
||||||
png_uint_32 row_width = row_info->width;
|
|
||||||
if (row_info->bit_depth == 8)
|
|
||||||
{
|
|
||||||
if (row_info->color_type == PNG_COLOR_TYPE_RGB)
|
|
||||||
{
|
|
||||||
png_bytep rp;
|
|
||||||
png_uint_32 i;
|
|
||||||
|
|
||||||
for (i = 0, rp = row; i < row_width; i++, rp += 3)
|
|
||||||
{
|
|
||||||
png_byte save = *rp;
|
|
||||||
*rp = *(rp + 2);
|
|
||||||
*(rp + 2) = save;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
|
|
||||||
{
|
|
||||||
png_bytep rp;
|
|
||||||
png_uint_32 i;
|
|
||||||
|
|
||||||
for (i = 0, rp = row; i < row_width; i++, rp += 4)
|
|
||||||
{
|
|
||||||
png_byte save = *rp;
|
|
||||||
*rp = *(rp + 2);
|
|
||||||
*(rp + 2) = save;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef PNG_16BIT_SUPPORTED
|
|
||||||
else if (row_info->bit_depth == 16)
|
|
||||||
{
|
|
||||||
if (row_info->color_type == PNG_COLOR_TYPE_RGB)
|
|
||||||
{
|
|
||||||
png_bytep rp;
|
|
||||||
png_uint_32 i;
|
|
||||||
|
|
||||||
for (i = 0, rp = row; i < row_width; i++, rp += 6)
|
|
||||||
{
|
|
||||||
png_byte save = *rp;
|
|
||||||
*rp = *(rp + 4);
|
|
||||||
*(rp + 4) = save;
|
|
||||||
save = *(rp + 1);
|
|
||||||
*(rp + 1) = *(rp + 5);
|
|
||||||
*(rp + 5) = save;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
|
|
||||||
{
|
|
||||||
png_bytep rp;
|
|
||||||
png_uint_32 i;
|
|
||||||
|
|
||||||
for (i = 0, rp = row; i < row_width; i++, rp += 8)
|
|
||||||
{
|
|
||||||
png_byte save = *rp;
|
|
||||||
*rp = *(rp + 4);
|
|
||||||
*(rp + 4) = save;
|
|
||||||
save = *(rp + 1);
|
|
||||||
*(rp + 1) = *(rp + 5);
|
|
||||||
*(rp + 5) = save;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* READ_BGR || WRITE_BGR */
|
|
||||||
|
|
||||||
#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \
|
|
||||||
defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED)
|
|
||||||
/* Added at libpng-1.5.10 */
|
|
||||||
void /* PRIVATE */
|
|
||||||
png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info)
|
|
||||||
{
|
|
||||||
if (png_ptr->num_palette < (1 << row_info->bit_depth) &&
|
|
||||||
png_ptr->num_palette > 0) /* num_palette can be 0 in MNG files */
|
|
||||||
{
|
|
||||||
/* Calculations moved outside switch in an attempt to stop different
|
|
||||||
* compiler warnings. 'padding' is in *bits* within the last byte, it is
|
|
||||||
* an 'int' because pixel_depth becomes an 'int' in the expression below,
|
|
||||||
* and this calculation is used because it avoids warnings that other
|
|
||||||
* forms produced on either GCC or MSVC.
|
|
||||||
*/
|
|
||||||
int padding = PNG_PADBITS(row_info->pixel_depth, row_info->width);
|
|
||||||
png_bytep rp = png_ptr->row_buf + row_info->rowbytes - 1;
|
|
||||||
|
|
||||||
switch (row_info->bit_depth)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
/* in this case, all bytes must be 0 so we don't need
|
|
||||||
* to unpack the pixels except for the rightmost one.
|
|
||||||
*/
|
|
||||||
for (; rp > png_ptr->row_buf; rp--)
|
|
||||||
{
|
|
||||||
if ((*rp >> padding) != 0)
|
|
||||||
png_ptr->num_palette_max = 1;
|
|
||||||
padding = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
{
|
|
||||||
for (; rp > png_ptr->row_buf; rp--)
|
|
||||||
{
|
|
||||||
int i = ((*rp >> padding) & 0x03);
|
|
||||||
|
|
||||||
if (i > png_ptr->num_palette_max)
|
|
||||||
png_ptr->num_palette_max = i;
|
|
||||||
|
|
||||||
i = (((*rp >> padding) >> 2) & 0x03);
|
|
||||||
|
|
||||||
if (i > png_ptr->num_palette_max)
|
|
||||||
png_ptr->num_palette_max = i;
|
|
||||||
|
|
||||||
i = (((*rp >> padding) >> 4) & 0x03);
|
|
||||||
|
|
||||||
if (i > png_ptr->num_palette_max)
|
|
||||||
png_ptr->num_palette_max = i;
|
|
||||||
|
|
||||||
i = (((*rp >> padding) >> 6) & 0x03);
|
|
||||||
|
|
||||||
if (i > png_ptr->num_palette_max)
|
|
||||||
png_ptr->num_palette_max = i;
|
|
||||||
|
|
||||||
padding = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 4:
|
|
||||||
{
|
|
||||||
for (; rp > png_ptr->row_buf; rp--)
|
|
||||||
{
|
|
||||||
int i = ((*rp >> padding) & 0x0f);
|
|
||||||
|
|
||||||
if (i > png_ptr->num_palette_max)
|
|
||||||
png_ptr->num_palette_max = i;
|
|
||||||
|
|
||||||
i = (((*rp >> padding) >> 4) & 0x0f);
|
|
||||||
|
|
||||||
if (i > png_ptr->num_palette_max)
|
|
||||||
png_ptr->num_palette_max = i;
|
|
||||||
|
|
||||||
padding = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 8:
|
|
||||||
{
|
|
||||||
for (; rp > png_ptr->row_buf; rp--)
|
|
||||||
{
|
|
||||||
if (*rp > png_ptr->num_palette_max)
|
|
||||||
png_ptr->num_palette_max = (int) *rp;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* CHECK_FOR_INVALID_INDEX */
|
|
||||||
|
|
||||||
#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
|
|
||||||
defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
|
|
||||||
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
|
|
||||||
void PNGAPI
|
|
||||||
png_set_user_transform_info(png_structrp png_ptr, png_voidp
|
|
||||||
user_transform_ptr, int user_transform_depth, int user_transform_channels)
|
|
||||||
{
|
|
||||||
png_debug(1, "in png_set_user_transform_info");
|
|
||||||
|
|
||||||
if (png_ptr == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
|
|
||||||
if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
|
|
||||||
(png_ptr->flags & PNG_FLAG_ROW_INIT) != 0)
|
|
||||||
{
|
|
||||||
png_app_error(png_ptr,
|
|
||||||
"info change after png_start_read_image or png_read_update_info");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
png_ptr->user_transform_ptr = user_transform_ptr;
|
|
||||||
png_ptr->user_transform_depth = (png_byte)user_transform_depth;
|
|
||||||
png_ptr->user_transform_channels = (png_byte)user_transform_channels;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* This function returns a pointer to the user_transform_ptr associated with
|
|
||||||
* the user transform functions. The application should free any memory
|
|
||||||
* associated with this pointer before png_write_destroy and png_read_destroy
|
|
||||||
* are called.
|
|
||||||
*/
|
|
||||||
#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
|
|
||||||
png_voidp PNGAPI
|
|
||||||
png_get_user_transform_ptr(png_const_structrp png_ptr)
|
|
||||||
{
|
|
||||||
if (png_ptr == NULL)
|
|
||||||
return (NULL);
|
|
||||||
|
|
||||||
return png_ptr->user_transform_ptr;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED
|
|
||||||
png_uint_32 PNGAPI
|
|
||||||
png_get_current_row_number(png_const_structrp png_ptr)
|
|
||||||
{
|
|
||||||
/* See the comments in png.h - this is the sub-image row when reading an
|
|
||||||
* interlaced image.
|
|
||||||
*/
|
|
||||||
if (png_ptr != NULL)
|
|
||||||
return png_ptr->row_number;
|
|
||||||
|
|
||||||
return PNG_UINT_32_MAX; /* help the app not to fail silently */
|
|
||||||
}
|
|
||||||
|
|
||||||
png_byte PNGAPI
|
|
||||||
png_get_current_pass_number(png_const_structrp png_ptr)
|
|
||||||
{
|
|
||||||
if (png_ptr != NULL)
|
|
||||||
return png_ptr->pass;
|
|
||||||
return 8; /* invalid */
|
|
||||||
}
|
|
||||||
#endif /* USER_TRANSFORM_INFO */
|
|
||||||
#endif /* READ_USER_TRANSFORM || WRITE_USER_TRANSFORM */
|
|
||||||
#endif /* READ || WRITE */
|
|
|
@ -1,168 +0,0 @@
|
||||||
|
|
||||||
/* pngwio.c - functions for data output
|
|
||||||
*
|
|
||||||
* Copyright (c) 2018 Cosmin Truta
|
|
||||||
* Copyright (c) 1998-2002,2004,2006-2014,2016,2018 Glenn Randers-Pehrson
|
|
||||||
* Copyright (c) 1996-1997 Andreas Dilger
|
|
||||||
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
|
|
||||||
*
|
|
||||||
* This code is released under the libpng license.
|
|
||||||
* For conditions of distribution and use, see the disclaimer
|
|
||||||
* and license in png.h
|
|
||||||
*
|
|
||||||
* This file provides a location for all output. Users who need
|
|
||||||
* special handling are expected to write functions that have the same
|
|
||||||
* arguments as these and perform similar functions, but that possibly
|
|
||||||
* use different output methods. Note that you shouldn't change these
|
|
||||||
* functions, but rather write replacement functions and then change
|
|
||||||
* them at run time with png_set_write_fn(...).
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "pngpriv.h"
|
|
||||||
|
|
||||||
#ifdef PNG_WRITE_SUPPORTED
|
|
||||||
|
|
||||||
/* Write the data to whatever output you are using. The default routine
|
|
||||||
* writes to a file pointer. Note that this routine sometimes gets called
|
|
||||||
* with very small lengths, so you should implement some kind of simple
|
|
||||||
* buffering if you are using unbuffered writes. This should never be asked
|
|
||||||
* to write more than 64K on a 16-bit machine.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void /* PRIVATE */
|
|
||||||
png_write_data(png_structrp png_ptr, png_const_bytep data, size_t length)
|
|
||||||
{
|
|
||||||
/* NOTE: write_data_fn must not change the buffer! */
|
|
||||||
if (png_ptr->write_data_fn != NULL )
|
|
||||||
(*(png_ptr->write_data_fn))(png_ptr, png_constcast(png_bytep,data),
|
|
||||||
length);
|
|
||||||
|
|
||||||
else
|
|
||||||
png_error(png_ptr, "Call to NULL write function");
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef PNG_STDIO_SUPPORTED
|
|
||||||
/* This is the function that does the actual writing of data. If you are
|
|
||||||
* not writing to a standard C stream, you should create a replacement
|
|
||||||
* write_data function and use it at run time with png_set_write_fn(), rather
|
|
||||||
* than changing the library.
|
|
||||||
*/
|
|
||||||
void PNGCBAPI
|
|
||||||
png_default_write_data(png_structp png_ptr, png_bytep data, size_t length)
|
|
||||||
{
|
|
||||||
size_t check;
|
|
||||||
|
|
||||||
if (png_ptr == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr));
|
|
||||||
|
|
||||||
if (check != length)
|
|
||||||
png_error(png_ptr, "Write Error");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* This function is called to output any data pending writing (normally
|
|
||||||
* to disk). After png_flush is called, there should be no data pending
|
|
||||||
* writing in any buffers.
|
|
||||||
*/
|
|
||||||
#ifdef PNG_WRITE_FLUSH_SUPPORTED
|
|
||||||
void /* PRIVATE */
|
|
||||||
png_flush(png_structrp png_ptr)
|
|
||||||
{
|
|
||||||
if (png_ptr->output_flush_fn != NULL)
|
|
||||||
(*(png_ptr->output_flush_fn))(png_ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
# ifdef PNG_STDIO_SUPPORTED
|
|
||||||
void PNGCBAPI
|
|
||||||
png_default_flush(png_structp png_ptr)
|
|
||||||
{
|
|
||||||
png_FILE_p io_ptr;
|
|
||||||
|
|
||||||
if (png_ptr == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
io_ptr = png_voidcast(png_FILE_p, (png_ptr->io_ptr));
|
|
||||||
fflush(io_ptr);
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* This function allows the application to supply new output functions for
|
|
||||||
* libpng if standard C streams aren't being used.
|
|
||||||
*
|
|
||||||
* This function takes as its arguments:
|
|
||||||
* png_ptr - pointer to a png output data structure
|
|
||||||
* io_ptr - pointer to user supplied structure containing info about
|
|
||||||
* the output functions. May be NULL.
|
|
||||||
* write_data_fn - pointer to a new output function that takes as its
|
|
||||||
* arguments a pointer to a png_struct, a pointer to
|
|
||||||
* data to be written, and a 32-bit unsigned int that is
|
|
||||||
* the number of bytes to be written. The new write
|
|
||||||
* function should call png_error(png_ptr, "Error msg")
|
|
||||||
* to exit and output any fatal error messages. May be
|
|
||||||
* NULL, in which case libpng's default function will
|
|
||||||
* be used.
|
|
||||||
* flush_data_fn - pointer to a new flush function that takes as its
|
|
||||||
* arguments a pointer to a png_struct. After a call to
|
|
||||||
* the flush function, there should be no data in any buffers
|
|
||||||
* or pending transmission. If the output method doesn't do
|
|
||||||
* any buffering of output, a function prototype must still be
|
|
||||||
* supplied although it doesn't have to do anything. If
|
|
||||||
* PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile
|
|
||||||
* time, output_flush_fn will be ignored, although it must be
|
|
||||||
* supplied for compatibility. May be NULL, in which case
|
|
||||||
* libpng's default function will be used, if
|
|
||||||
* PNG_WRITE_FLUSH_SUPPORTED is defined. This is not
|
|
||||||
* a good idea if io_ptr does not point to a standard
|
|
||||||
* *FILE structure.
|
|
||||||
*/
|
|
||||||
void PNGAPI
|
|
||||||
png_set_write_fn(png_structrp png_ptr, png_voidp io_ptr,
|
|
||||||
png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)
|
|
||||||
{
|
|
||||||
if (png_ptr == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
png_ptr->io_ptr = io_ptr;
|
|
||||||
|
|
||||||
#ifdef PNG_STDIO_SUPPORTED
|
|
||||||
if (write_data_fn != NULL)
|
|
||||||
png_ptr->write_data_fn = write_data_fn;
|
|
||||||
|
|
||||||
else
|
|
||||||
png_ptr->write_data_fn = png_default_write_data;
|
|
||||||
#else
|
|
||||||
png_ptr->write_data_fn = write_data_fn;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PNG_WRITE_FLUSH_SUPPORTED
|
|
||||||
# ifdef PNG_STDIO_SUPPORTED
|
|
||||||
|
|
||||||
if (output_flush_fn != NULL)
|
|
||||||
png_ptr->output_flush_fn = output_flush_fn;
|
|
||||||
|
|
||||||
else
|
|
||||||
png_ptr->output_flush_fn = png_default_flush;
|
|
||||||
|
|
||||||
# else
|
|
||||||
png_ptr->output_flush_fn = output_flush_fn;
|
|
||||||
# endif
|
|
||||||
#else
|
|
||||||
PNG_UNUSED(output_flush_fn)
|
|
||||||
#endif /* WRITE_FLUSH */
|
|
||||||
|
|
||||||
#ifdef PNG_READ_SUPPORTED
|
|
||||||
/* It is an error to read while writing a png file */
|
|
||||||
if (png_ptr->read_data_fn != NULL)
|
|
||||||
{
|
|
||||||
png_ptr->read_data_fn = NULL;
|
|
||||||
|
|
||||||
png_warning(png_ptr,
|
|
||||||
"Can't set both read_data_fn and write_data_fn in the"
|
|
||||||
" same structure");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif /* WRITE */
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,575 +0,0 @@
|
||||||
|
|
||||||
/* pngwtran.c - transforms the data in a row for PNG writers
|
|
||||||
*
|
|
||||||
* Copyright (c) 2018 Cosmin Truta
|
|
||||||
* Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson
|
|
||||||
* Copyright (c) 1996-1997 Andreas Dilger
|
|
||||||
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
|
|
||||||
*
|
|
||||||
* This code is released under the libpng license.
|
|
||||||
* For conditions of distribution and use, see the disclaimer
|
|
||||||
* and license in png.h
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "pngpriv.h"
|
|
||||||
|
|
||||||
#ifdef PNG_WRITE_SUPPORTED
|
|
||||||
#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
|
|
||||||
|
|
||||||
#ifdef PNG_WRITE_PACK_SUPPORTED
|
|
||||||
/* Pack pixels into bytes. Pass the true bit depth in bit_depth. The
|
|
||||||
* row_info bit depth should be 8 (one pixel per byte). The channels
|
|
||||||
* should be 1 (this only happens on grayscale and paletted images).
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
|
|
||||||
{
|
|
||||||
png_debug(1, "in png_do_pack");
|
|
||||||
|
|
||||||
if (row_info->bit_depth == 8 &&
|
|
||||||
row_info->channels == 1)
|
|
||||||
{
|
|
||||||
switch ((int)bit_depth)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
png_bytep sp, dp;
|
|
||||||
int mask, v;
|
|
||||||
png_uint_32 i;
|
|
||||||
png_uint_32 row_width = row_info->width;
|
|
||||||
|
|
||||||
sp = row;
|
|
||||||
dp = row;
|
|
||||||
mask = 0x80;
|
|
||||||
v = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < row_width; i++)
|
|
||||||
{
|
|
||||||
if (*sp != 0)
|
|
||||||
v |= mask;
|
|
||||||
|
|
||||||
sp++;
|
|
||||||
|
|
||||||
if (mask > 1)
|
|
||||||
mask >>= 1;
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mask = 0x80;
|
|
||||||
*dp = (png_byte)v;
|
|
||||||
dp++;
|
|
||||||
v = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mask != 0x80)
|
|
||||||
*dp = (png_byte)v;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
{
|
|
||||||
png_bytep sp, dp;
|
|
||||||
unsigned int shift;
|
|
||||||
int v;
|
|
||||||
png_uint_32 i;
|
|
||||||
png_uint_32 row_width = row_info->width;
|
|
||||||
|
|
||||||
sp = row;
|
|
||||||
dp = row;
|
|
||||||
shift = 6;
|
|
||||||
v = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < row_width; i++)
|
|
||||||
{
|
|
||||||
png_byte value;
|
|
||||||
|
|
||||||
value = (png_byte)(*sp & 0x03);
|
|
||||||
v |= (value << shift);
|
|
||||||
|
|
||||||
if (shift == 0)
|
|
||||||
{
|
|
||||||
shift = 6;
|
|
||||||
*dp = (png_byte)v;
|
|
||||||
dp++;
|
|
||||||
v = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
shift -= 2;
|
|
||||||
|
|
||||||
sp++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shift != 6)
|
|
||||||
*dp = (png_byte)v;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 4:
|
|
||||||
{
|
|
||||||
png_bytep sp, dp;
|
|
||||||
unsigned int shift;
|
|
||||||
int v;
|
|
||||||
png_uint_32 i;
|
|
||||||
png_uint_32 row_width = row_info->width;
|
|
||||||
|
|
||||||
sp = row;
|
|
||||||
dp = row;
|
|
||||||
shift = 4;
|
|
||||||
v = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < row_width; i++)
|
|
||||||
{
|
|
||||||
png_byte value;
|
|
||||||
|
|
||||||
value = (png_byte)(*sp & 0x0f);
|
|
||||||
v |= (value << shift);
|
|
||||||
|
|
||||||
if (shift == 0)
|
|
||||||
{
|
|
||||||
shift = 4;
|
|
||||||
*dp = (png_byte)v;
|
|
||||||
dp++;
|
|
||||||
v = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
shift -= 4;
|
|
||||||
|
|
||||||
sp++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shift != 4)
|
|
||||||
*dp = (png_byte)v;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
row_info->bit_depth = (png_byte)bit_depth;
|
|
||||||
row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
|
|
||||||
row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
|
|
||||||
row_info->width);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PNG_WRITE_SHIFT_SUPPORTED
|
|
||||||
/* Shift pixel values to take advantage of whole range. Pass the
|
|
||||||
* true number of bits in bit_depth. The row should be packed
|
|
||||||
* according to row_info->bit_depth. Thus, if you had a row of
|
|
||||||
* bit depth 4, but the pixels only had values from 0 to 7, you
|
|
||||||
* would pass 3 as bit_depth, and this routine would translate the
|
|
||||||
* data to 0 to 15.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
png_do_shift(png_row_infop row_info, png_bytep row,
|
|
||||||
png_const_color_8p bit_depth)
|
|
||||||
{
|
|
||||||
png_debug(1, "in png_do_shift");
|
|
||||||
|
|
||||||
if (row_info->color_type != PNG_COLOR_TYPE_PALETTE)
|
|
||||||
{
|
|
||||||
int shift_start[4], shift_dec[4];
|
|
||||||
unsigned int channels = 0;
|
|
||||||
|
|
||||||
if ((row_info->color_type & PNG_COLOR_MASK_COLOR) != 0)
|
|
||||||
{
|
|
||||||
shift_start[channels] = row_info->bit_depth - bit_depth->red;
|
|
||||||
shift_dec[channels] = bit_depth->red;
|
|
||||||
channels++;
|
|
||||||
|
|
||||||
shift_start[channels] = row_info->bit_depth - bit_depth->green;
|
|
||||||
shift_dec[channels] = bit_depth->green;
|
|
||||||
channels++;
|
|
||||||
|
|
||||||
shift_start[channels] = row_info->bit_depth - bit_depth->blue;
|
|
||||||
shift_dec[channels] = bit_depth->blue;
|
|
||||||
channels++;
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
shift_start[channels] = row_info->bit_depth - bit_depth->gray;
|
|
||||||
shift_dec[channels] = bit_depth->gray;
|
|
||||||
channels++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0)
|
|
||||||
{
|
|
||||||
shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
|
|
||||||
shift_dec[channels] = bit_depth->alpha;
|
|
||||||
channels++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* With low row depths, could only be grayscale, so one channel */
|
|
||||||
if (row_info->bit_depth < 8)
|
|
||||||
{
|
|
||||||
png_bytep bp = row;
|
|
||||||
size_t i;
|
|
||||||
unsigned int mask;
|
|
||||||
size_t row_bytes = row_info->rowbytes;
|
|
||||||
|
|
||||||
if (bit_depth->gray == 1 && row_info->bit_depth == 2)
|
|
||||||
mask = 0x55;
|
|
||||||
|
|
||||||
else if (row_info->bit_depth == 4 && bit_depth->gray == 3)
|
|
||||||
mask = 0x11;
|
|
||||||
|
|
||||||
else
|
|
||||||
mask = 0xff;
|
|
||||||
|
|
||||||
for (i = 0; i < row_bytes; i++, bp++)
|
|
||||||
{
|
|
||||||
int j;
|
|
||||||
unsigned int v, out;
|
|
||||||
|
|
||||||
v = *bp;
|
|
||||||
out = 0;
|
|
||||||
|
|
||||||
for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
|
|
||||||
{
|
|
||||||
if (j > 0)
|
|
||||||
out |= v << j;
|
|
||||||
|
|
||||||
else
|
|
||||||
out |= (v >> (-j)) & mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
*bp = (png_byte)(out & 0xff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (row_info->bit_depth == 8)
|
|
||||||
{
|
|
||||||
png_bytep bp = row;
|
|
||||||
png_uint_32 i;
|
|
||||||
png_uint_32 istop = channels * row_info->width;
|
|
||||||
|
|
||||||
for (i = 0; i < istop; i++, bp++)
|
|
||||||
{
|
|
||||||
unsigned int c = i%channels;
|
|
||||||
int j;
|
|
||||||
unsigned int v, out;
|
|
||||||
|
|
||||||
v = *bp;
|
|
||||||
out = 0;
|
|
||||||
|
|
||||||
for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
|
|
||||||
{
|
|
||||||
if (j > 0)
|
|
||||||
out |= v << j;
|
|
||||||
|
|
||||||
else
|
|
||||||
out |= v >> (-j);
|
|
||||||
}
|
|
||||||
|
|
||||||
*bp = (png_byte)(out & 0xff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
png_bytep bp;
|
|
||||||
png_uint_32 i;
|
|
||||||
png_uint_32 istop = channels * row_info->width;
|
|
||||||
|
|
||||||
for (bp = row, i = 0; i < istop; i++)
|
|
||||||
{
|
|
||||||
unsigned int c = i%channels;
|
|
||||||
int j;
|
|
||||||
unsigned int value, v;
|
|
||||||
|
|
||||||
v = png_get_uint_16(bp);
|
|
||||||
value = 0;
|
|
||||||
|
|
||||||
for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
|
|
||||||
{
|
|
||||||
if (j > 0)
|
|
||||||
value |= v << j;
|
|
||||||
|
|
||||||
else
|
|
||||||
value |= v >> (-j);
|
|
||||||
}
|
|
||||||
*bp++ = (png_byte)((value >> 8) & 0xff);
|
|
||||||
*bp++ = (png_byte)(value & 0xff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
|
|
||||||
static void
|
|
||||||
png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
|
|
||||||
{
|
|
||||||
png_debug(1, "in png_do_write_swap_alpha");
|
|
||||||
|
|
||||||
{
|
|
||||||
if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
|
|
||||||
{
|
|
||||||
if (row_info->bit_depth == 8)
|
|
||||||
{
|
|
||||||
/* This converts from ARGB to RGBA */
|
|
||||||
png_bytep sp, dp;
|
|
||||||
png_uint_32 i;
|
|
||||||
png_uint_32 row_width = row_info->width;
|
|
||||||
|
|
||||||
for (i = 0, sp = dp = row; i < row_width; i++)
|
|
||||||
{
|
|
||||||
png_byte save = *(sp++);
|
|
||||||
*(dp++) = *(sp++);
|
|
||||||
*(dp++) = *(sp++);
|
|
||||||
*(dp++) = *(sp++);
|
|
||||||
*(dp++) = save;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef PNG_WRITE_16BIT_SUPPORTED
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* This converts from AARRGGBB to RRGGBBAA */
|
|
||||||
png_bytep sp, dp;
|
|
||||||
png_uint_32 i;
|
|
||||||
png_uint_32 row_width = row_info->width;
|
|
||||||
|
|
||||||
for (i = 0, sp = dp = row; i < row_width; i++)
|
|
||||||
{
|
|
||||||
png_byte save[2];
|
|
||||||
save[0] = *(sp++);
|
|
||||||
save[1] = *(sp++);
|
|
||||||
*(dp++) = *(sp++);
|
|
||||||
*(dp++) = *(sp++);
|
|
||||||
*(dp++) = *(sp++);
|
|
||||||
*(dp++) = *(sp++);
|
|
||||||
*(dp++) = *(sp++);
|
|
||||||
*(dp++) = *(sp++);
|
|
||||||
*(dp++) = save[0];
|
|
||||||
*(dp++) = save[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* WRITE_16BIT */
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
|
||||||
{
|
|
||||||
if (row_info->bit_depth == 8)
|
|
||||||
{
|
|
||||||
/* This converts from AG to GA */
|
|
||||||
png_bytep sp, dp;
|
|
||||||
png_uint_32 i;
|
|
||||||
png_uint_32 row_width = row_info->width;
|
|
||||||
|
|
||||||
for (i = 0, sp = dp = row; i < row_width; i++)
|
|
||||||
{
|
|
||||||
png_byte save = *(sp++);
|
|
||||||
*(dp++) = *(sp++);
|
|
||||||
*(dp++) = save;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef PNG_WRITE_16BIT_SUPPORTED
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* This converts from AAGG to GGAA */
|
|
||||||
png_bytep sp, dp;
|
|
||||||
png_uint_32 i;
|
|
||||||
png_uint_32 row_width = row_info->width;
|
|
||||||
|
|
||||||
for (i = 0, sp = dp = row; i < row_width; i++)
|
|
||||||
{
|
|
||||||
png_byte save[2];
|
|
||||||
save[0] = *(sp++);
|
|
||||||
save[1] = *(sp++);
|
|
||||||
*(dp++) = *(sp++);
|
|
||||||
*(dp++) = *(sp++);
|
|
||||||
*(dp++) = save[0];
|
|
||||||
*(dp++) = save[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* WRITE_16BIT */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
|
|
||||||
static void
|
|
||||||
png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
|
|
||||||
{
|
|
||||||
png_debug(1, "in png_do_write_invert_alpha");
|
|
||||||
|
|
||||||
{
|
|
||||||
if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
|
|
||||||
{
|
|
||||||
if (row_info->bit_depth == 8)
|
|
||||||
{
|
|
||||||
/* This inverts the alpha channel in RGBA */
|
|
||||||
png_bytep sp, dp;
|
|
||||||
png_uint_32 i;
|
|
||||||
png_uint_32 row_width = row_info->width;
|
|
||||||
|
|
||||||
for (i = 0, sp = dp = row; i < row_width; i++)
|
|
||||||
{
|
|
||||||
/* Does nothing
|
|
||||||
*(dp++) = *(sp++);
|
|
||||||
*(dp++) = *(sp++);
|
|
||||||
*(dp++) = *(sp++);
|
|
||||||
*/
|
|
||||||
sp+=3; dp = sp;
|
|
||||||
*dp = (png_byte)(255 - *(sp++));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef PNG_WRITE_16BIT_SUPPORTED
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* This inverts the alpha channel in RRGGBBAA */
|
|
||||||
png_bytep sp, dp;
|
|
||||||
png_uint_32 i;
|
|
||||||
png_uint_32 row_width = row_info->width;
|
|
||||||
|
|
||||||
for (i = 0, sp = dp = row; i < row_width; i++)
|
|
||||||
{
|
|
||||||
/* Does nothing
|
|
||||||
*(dp++) = *(sp++);
|
|
||||||
*(dp++) = *(sp++);
|
|
||||||
*(dp++) = *(sp++);
|
|
||||||
*(dp++) = *(sp++);
|
|
||||||
*(dp++) = *(sp++);
|
|
||||||
*(dp++) = *(sp++);
|
|
||||||
*/
|
|
||||||
sp+=6; dp = sp;
|
|
||||||
*(dp++) = (png_byte)(255 - *(sp++));
|
|
||||||
*dp = (png_byte)(255 - *(sp++));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* WRITE_16BIT */
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
|
||||||
{
|
|
||||||
if (row_info->bit_depth == 8)
|
|
||||||
{
|
|
||||||
/* This inverts the alpha channel in GA */
|
|
||||||
png_bytep sp, dp;
|
|
||||||
png_uint_32 i;
|
|
||||||
png_uint_32 row_width = row_info->width;
|
|
||||||
|
|
||||||
for (i = 0, sp = dp = row; i < row_width; i++)
|
|
||||||
{
|
|
||||||
*(dp++) = *(sp++);
|
|
||||||
*(dp++) = (png_byte)(255 - *(sp++));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef PNG_WRITE_16BIT_SUPPORTED
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* This inverts the alpha channel in GGAA */
|
|
||||||
png_bytep sp, dp;
|
|
||||||
png_uint_32 i;
|
|
||||||
png_uint_32 row_width = row_info->width;
|
|
||||||
|
|
||||||
for (i = 0, sp = dp = row; i < row_width; i++)
|
|
||||||
{
|
|
||||||
/* Does nothing
|
|
||||||
*(dp++) = *(sp++);
|
|
||||||
*(dp++) = *(sp++);
|
|
||||||
*/
|
|
||||||
sp+=2; dp = sp;
|
|
||||||
*(dp++) = (png_byte)(255 - *(sp++));
|
|
||||||
*dp = (png_byte)(255 - *(sp++));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* WRITE_16BIT */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Transform the data according to the user's wishes. The order of
|
|
||||||
* transformations is significant.
|
|
||||||
*/
|
|
||||||
void /* PRIVATE */
|
|
||||||
png_do_write_transformations(png_structrp png_ptr, png_row_infop row_info)
|
|
||||||
{
|
|
||||||
png_debug(1, "in png_do_write_transformations");
|
|
||||||
|
|
||||||
if (png_ptr == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
|
|
||||||
if ((png_ptr->transformations & PNG_USER_TRANSFORM) != 0)
|
|
||||||
if (png_ptr->write_user_transform_fn != NULL)
|
|
||||||
(*(png_ptr->write_user_transform_fn)) /* User write transform
|
|
||||||
function */
|
|
||||||
(png_ptr, /* png_ptr */
|
|
||||||
row_info, /* row_info: */
|
|
||||||
/* png_uint_32 width; width of row */
|
|
||||||
/* size_t rowbytes; number of bytes in row */
|
|
||||||
/* png_byte color_type; color type of pixels */
|
|
||||||
/* png_byte bit_depth; bit depth of samples */
|
|
||||||
/* png_byte channels; number of channels (1-4) */
|
|
||||||
/* png_byte pixel_depth; bits per pixel (depth*channels) */
|
|
||||||
png_ptr->row_buf + 1); /* start of pixel data for row */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PNG_WRITE_FILLER_SUPPORTED
|
|
||||||
if ((png_ptr->transformations & PNG_FILLER) != 0)
|
|
||||||
png_do_strip_channel(row_info, png_ptr->row_buf + 1,
|
|
||||||
!(png_ptr->flags & PNG_FLAG_FILLER_AFTER));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PNG_WRITE_PACKSWAP_SUPPORTED
|
|
||||||
if ((png_ptr->transformations & PNG_PACKSWAP) != 0)
|
|
||||||
png_do_packswap(row_info, png_ptr->row_buf + 1);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PNG_WRITE_PACK_SUPPORTED
|
|
||||||
if ((png_ptr->transformations & PNG_PACK) != 0)
|
|
||||||
png_do_pack(row_info, png_ptr->row_buf + 1,
|
|
||||||
(png_uint_32)png_ptr->bit_depth);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PNG_WRITE_SWAP_SUPPORTED
|
|
||||||
# ifdef PNG_16BIT_SUPPORTED
|
|
||||||
if ((png_ptr->transformations & PNG_SWAP_BYTES) != 0)
|
|
||||||
png_do_swap(row_info, png_ptr->row_buf + 1);
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PNG_WRITE_SHIFT_SUPPORTED
|
|
||||||
if ((png_ptr->transformations & PNG_SHIFT) != 0)
|
|
||||||
png_do_shift(row_info, png_ptr->row_buf + 1,
|
|
||||||
&(png_ptr->shift));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
|
|
||||||
if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0)
|
|
||||||
png_do_write_swap_alpha(row_info, png_ptr->row_buf + 1);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
|
|
||||||
if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0)
|
|
||||||
png_do_write_invert_alpha(row_info, png_ptr->row_buf + 1);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PNG_WRITE_BGR_SUPPORTED
|
|
||||||
if ((png_ptr->transformations & PNG_BGR) != 0)
|
|
||||||
png_do_bgr(row_info, png_ptr->row_buf + 1);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PNG_WRITE_INVERT_SUPPORTED
|
|
||||||
if ((png_ptr->transformations & PNG_INVERT_MONO) != 0)
|
|
||||||
png_do_invert(row_info, png_ptr->row_buf + 1);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif /* WRITE_TRANSFORMS */
|
|
||||||
#endif /* WRITE */
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,768 +0,0 @@
|
||||||
/* filter_vsx_intrinsics.c - PowerPC optimised filter functions
|
|
||||||
*
|
|
||||||
* Copyright (c) 2018 Cosmin Truta
|
|
||||||
* Copyright (c) 2017 Glenn Randers-Pehrson
|
|
||||||
* Written by Vadim Barkov, 2017.
|
|
||||||
*
|
|
||||||
* This code is released under the libpng license.
|
|
||||||
* For conditions of distribution and use, see the disclaimer
|
|
||||||
* and license in png.h
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "../pngpriv.h"
|
|
||||||
|
|
||||||
#ifdef PNG_READ_SUPPORTED
|
|
||||||
|
|
||||||
/* This code requires -maltivec and -mvsx on the command line: */
|
|
||||||
#if PNG_POWERPC_VSX_IMPLEMENTATION == 1 /* intrinsics code from pngpriv.h */
|
|
||||||
|
|
||||||
#include <altivec.h>
|
|
||||||
|
|
||||||
#if PNG_POWERPC_VSX_OPT > 0
|
|
||||||
|
|
||||||
#ifndef __VSX__
|
|
||||||
# error "This code requires VSX support (POWER7 and later). Please provide -mvsx compiler flag."
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define vec_ld_unaligned(vec,data) vec = vec_vsx_ld(0,data)
|
|
||||||
#define vec_st_unaligned(vec,data) vec_vsx_st(vec,0,data)
|
|
||||||
|
|
||||||
|
|
||||||
/* 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.
|
|
||||||
* ( this is taken from ../intel/filter_sse2_intrinsics.c )
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define vsx_declare_common_vars(row_info,row,prev_row,offset) \
|
|
||||||
png_byte i;\
|
|
||||||
png_bytep rp = row + offset;\
|
|
||||||
png_const_bytep pp = prev_row;\
|
|
||||||
size_t unaligned_top = 16 - (((size_t)rp % 16));\
|
|
||||||
size_t istop;\
|
|
||||||
if(unaligned_top == 16)\
|
|
||||||
unaligned_top = 0;\
|
|
||||||
istop = row_info->rowbytes;\
|
|
||||||
if((unaligned_top < istop))\
|
|
||||||
istop -= unaligned_top;\
|
|
||||||
else{\
|
|
||||||
unaligned_top = istop;\
|
|
||||||
istop = 0;\
|
|
||||||
}
|
|
||||||
|
|
||||||
void png_read_filter_row_up_vsx(png_row_infop row_info, png_bytep row,
|
|
||||||
png_const_bytep prev_row)
|
|
||||||
{
|
|
||||||
vector unsigned char rp_vec;
|
|
||||||
vector unsigned char pp_vec;
|
|
||||||
vsx_declare_common_vars(row_info,row,prev_row,0)
|
|
||||||
|
|
||||||
/* Altivec operations require 16-byte aligned data
|
|
||||||
* but input can be unaligned. So we calculate
|
|
||||||
* unaligned part as usual.
|
|
||||||
*/
|
|
||||||
for (i = 0; i < unaligned_top; i++)
|
|
||||||
{
|
|
||||||
*rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
|
|
||||||
rp++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Using SIMD while we can */
|
|
||||||
while( istop >= 16 )
|
|
||||||
{
|
|
||||||
rp_vec = vec_ld(0,rp);
|
|
||||||
vec_ld_unaligned(pp_vec,pp);
|
|
||||||
|
|
||||||
rp_vec = vec_add(rp_vec,pp_vec);
|
|
||||||
|
|
||||||
vec_st(rp_vec,0,rp);
|
|
||||||
|
|
||||||
pp += 16;
|
|
||||||
rp += 16;
|
|
||||||
istop -= 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(istop > 0)
|
|
||||||
{
|
|
||||||
/* If byte count of row is not divisible by 16
|
|
||||||
* we will process remaining part as usual
|
|
||||||
*/
|
|
||||||
for (i = 0; i < istop; i++)
|
|
||||||
{
|
|
||||||
*rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
|
|
||||||
rp++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static const vector unsigned char VSX_LEFTSHIFTED1_4 = {16,16,16,16, 0, 1, 2, 3,16,16,16,16,16,16,16,16};
|
|
||||||
static const vector unsigned char VSX_LEFTSHIFTED2_4 = {16,16,16,16,16,16,16,16, 4, 5, 6, 7,16,16,16,16};
|
|
||||||
static const vector unsigned char VSX_LEFTSHIFTED3_4 = {16,16,16,16,16,16,16,16,16,16,16,16, 8, 9,10,11};
|
|
||||||
|
|
||||||
static const vector unsigned char VSX_LEFTSHIFTED1_3 = {16,16,16, 0, 1, 2,16,16,16,16,16,16,16,16,16,16};
|
|
||||||
static const vector unsigned char VSX_LEFTSHIFTED2_3 = {16,16,16,16,16,16, 3, 4, 5,16,16,16,16,16,16,16};
|
|
||||||
static const vector unsigned char VSX_LEFTSHIFTED3_3 = {16,16,16,16,16,16,16,16,16, 6, 7, 8,16,16,16,16};
|
|
||||||
static const vector unsigned char VSX_LEFTSHIFTED4_3 = {16,16,16,16,16,16,16,16,16,16,16,16, 9,10,11,16};
|
|
||||||
|
|
||||||
static const vector unsigned char VSX_NOT_SHIFTED1_4 = {16,16,16,16, 4, 5, 6, 7,16,16,16,16,16,16,16,16};
|
|
||||||
static const vector unsigned char VSX_NOT_SHIFTED2_4 = {16,16,16,16,16,16,16,16, 8, 9,10,11,16,16,16,16};
|
|
||||||
static const vector unsigned char VSX_NOT_SHIFTED3_4 = {16,16,16,16,16,16,16,16,16,16,16,16,12,13,14,15};
|
|
||||||
|
|
||||||
static const vector unsigned char VSX_NOT_SHIFTED1_3 = {16,16,16, 3, 4, 5,16,16,16,16,16,16,16,16,16,16};
|
|
||||||
static const vector unsigned char VSX_NOT_SHIFTED2_3 = {16,16,16,16,16,16, 6, 7, 8,16,16,16,16,16,16,16};
|
|
||||||
static const vector unsigned char VSX_NOT_SHIFTED3_3 = {16,16,16,16,16,16,16,16,16, 9,10,11,16,16,16,16};
|
|
||||||
static const vector unsigned char VSX_NOT_SHIFTED4_3 = {16,16,16,16,16,16,16,16,16,16,16,16,12,13,14,16};
|
|
||||||
|
|
||||||
static const vector unsigned char VSX_CHAR_ZERO = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
|
||||||
#ifdef __LITTLE_ENDIAN__
|
|
||||||
|
|
||||||
static const vector unsigned char VSX_CHAR_TO_SHORT1_4 = { 4,16, 5,16, 6,16, 7,16,16,16,16,16,16,16,16,16};
|
|
||||||
static const vector unsigned char VSX_CHAR_TO_SHORT2_4 = { 8,16, 9,16,10,16,11,16,16,16,16,16,16,16,16,16};
|
|
||||||
static const vector unsigned char VSX_CHAR_TO_SHORT3_4 = {12,16,13,16,14,16,15,16,16,16,16,16,16,16,16,16};
|
|
||||||
|
|
||||||
static const vector unsigned char VSX_SHORT_TO_CHAR1_4 = {16,16,16,16, 0, 2, 4, 6,16,16,16,16,16,16,16,16};
|
|
||||||
static const vector unsigned char VSX_SHORT_TO_CHAR2_4 = {16,16,16,16,16,16,16,16, 0, 2, 4, 6,16,16,16,16};
|
|
||||||
static const vector unsigned char VSX_SHORT_TO_CHAR3_4 = {16,16,16,16,16,16,16,16,16,16,16,16, 0, 2, 4, 6};
|
|
||||||
|
|
||||||
static const vector unsigned char VSX_CHAR_TO_SHORT1_3 = { 3,16, 4,16, 5,16,16,16,16,16,16,16,16,16,16,16};
|
|
||||||
static const vector unsigned char VSX_CHAR_TO_SHORT2_3 = { 6,16, 7,16, 8,16,16,16,16,16,16,16,16,16,16,16};
|
|
||||||
static const vector unsigned char VSX_CHAR_TO_SHORT3_3 = { 9,16,10,16,11,16,16,16,16,16,16,16,16,16,16,16};
|
|
||||||
static const vector unsigned char VSX_CHAR_TO_SHORT4_3 = {12,16,13,16,14,16,16,16,16,16,16,16,16,16,16,16};
|
|
||||||
|
|
||||||
static const vector unsigned char VSX_SHORT_TO_CHAR1_3 = {16,16,16, 0, 2, 4,16,16,16,16,16,16,16,16,16,16};
|
|
||||||
static const vector unsigned char VSX_SHORT_TO_CHAR2_3 = {16,16,16,16,16,16, 0, 2, 4,16,16,16,16,16,16,16};
|
|
||||||
static const vector unsigned char VSX_SHORT_TO_CHAR3_3 = {16,16,16,16,16,16,16,16,16, 0, 2, 4,16,16,16,16};
|
|
||||||
static const vector unsigned char VSX_SHORT_TO_CHAR4_3 = {16,16,16,16,16,16,16,16,16,16,16,16, 0, 2, 4,16};
|
|
||||||
|
|
||||||
#elif defined(__BIG_ENDIAN__)
|
|
||||||
|
|
||||||
static const vector unsigned char VSX_CHAR_TO_SHORT1_4 = {16, 4,16, 5,16, 6,16, 7,16,16,16,16,16,16,16,16};
|
|
||||||
static const vector unsigned char VSX_CHAR_TO_SHORT2_4 = {16, 8,16, 9,16,10,16,11,16,16,16,16,16,16,16,16};
|
|
||||||
static const vector unsigned char VSX_CHAR_TO_SHORT3_4 = {16,12,16,13,16,14,16,15,16,16,16,16,16,16,16,16};
|
|
||||||
|
|
||||||
static const vector unsigned char VSX_SHORT_TO_CHAR1_4 = {16,16,16,16, 1, 3, 5, 7,16,16,16,16,16,16,16,16};
|
|
||||||
static const vector unsigned char VSX_SHORT_TO_CHAR2_4 = {16,16,16,16,16,16,16,16, 1, 3, 5, 7,16,16,16,16};
|
|
||||||
static const vector unsigned char VSX_SHORT_TO_CHAR3_4 = {16,16,16,16,16,16,16,16,16,16,16,16, 1, 3, 5, 7};
|
|
||||||
|
|
||||||
static const vector unsigned char VSX_CHAR_TO_SHORT1_3 = {16, 3,16, 4,16, 5,16,16,16,16,16,16,16,16,16,16};
|
|
||||||
static const vector unsigned char VSX_CHAR_TO_SHORT2_3 = {16, 6,16, 7,16, 8,16,16,16,16,16,16,16,16,16,16};
|
|
||||||
static const vector unsigned char VSX_CHAR_TO_SHORT3_3 = {16, 9,16,10,16,11,16,16,16,16,16,16,16,16,16,16};
|
|
||||||
static const vector unsigned char VSX_CHAR_TO_SHORT4_3 = {16,12,16,13,16,14,16,16,16,16,16,16,16,16,16,16};
|
|
||||||
|
|
||||||
static const vector unsigned char VSX_SHORT_TO_CHAR1_3 = {16,16,16, 1, 3, 5,16,16,16,16,16,16,16,16,16,16};
|
|
||||||
static const vector unsigned char VSX_SHORT_TO_CHAR2_3 = {16,16,16,16,16,16, 1, 3, 5,16,16,16,16,16,16,16};
|
|
||||||
static const vector unsigned char VSX_SHORT_TO_CHAR3_3 = {16,16,16,16,16,16,16,16,16, 1, 3, 5,16,16,16,16};
|
|
||||||
static const vector unsigned char VSX_SHORT_TO_CHAR4_3 = {16,16,16,16,16,16,16,16,16,16,16,16, 1, 3, 5,16};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define vsx_char_to_short(vec,offset,bpp) (vector unsigned short)vec_perm((vec),VSX_CHAR_ZERO,VSX_CHAR_TO_SHORT##offset##_##bpp)
|
|
||||||
#define vsx_short_to_char(vec,offset,bpp) vec_perm(((vector unsigned char)(vec)),VSX_CHAR_ZERO,VSX_SHORT_TO_CHAR##offset##_##bpp)
|
|
||||||
|
|
||||||
#ifdef PNG_USE_ABS
|
|
||||||
# define vsx_abs(number) abs(number)
|
|
||||||
#else
|
|
||||||
# define vsx_abs(number) (number > 0) ? (number) : -(number)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void png_read_filter_row_sub4_vsx(png_row_infop row_info, png_bytep row,
|
|
||||||
png_const_bytep prev_row)
|
|
||||||
{
|
|
||||||
png_byte bpp = 4;
|
|
||||||
|
|
||||||
vector unsigned char rp_vec;
|
|
||||||
vector unsigned char part_vec;
|
|
||||||
|
|
||||||
vsx_declare_common_vars(row_info,row,prev_row,bpp)
|
|
||||||
|
|
||||||
PNG_UNUSED(pp)
|
|
||||||
|
|
||||||
/* Altivec operations require 16-byte aligned data
|
|
||||||
* but input can be unaligned. So we calculate
|
|
||||||
* unaligned part as usual.
|
|
||||||
*/
|
|
||||||
for (i = 0; i < unaligned_top; i++)
|
|
||||||
{
|
|
||||||
*rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff);
|
|
||||||
rp++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Using SIMD while we can */
|
|
||||||
while( istop >= 16 )
|
|
||||||
{
|
|
||||||
for(i=0;i < bpp ; i++)
|
|
||||||
{
|
|
||||||
*rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff);
|
|
||||||
rp++;
|
|
||||||
}
|
|
||||||
rp -= bpp;
|
|
||||||
|
|
||||||
rp_vec = vec_ld(0,rp);
|
|
||||||
part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED1_4);
|
|
||||||
rp_vec = vec_add(rp_vec,part_vec);
|
|
||||||
|
|
||||||
part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED2_4);
|
|
||||||
rp_vec = vec_add(rp_vec,part_vec);
|
|
||||||
|
|
||||||
part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED3_4);
|
|
||||||
rp_vec = vec_add(rp_vec,part_vec);
|
|
||||||
|
|
||||||
vec_st(rp_vec,0,rp);
|
|
||||||
|
|
||||||
rp += 16;
|
|
||||||
istop -= 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(istop > 0)
|
|
||||||
for (i = 0; i < istop % 16; i++)
|
|
||||||
{
|
|
||||||
*rp = (png_byte)(((int)(*rp) + (int)(*(rp - bpp))) & 0xff);
|
|
||||||
rp++;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void png_read_filter_row_sub3_vsx(png_row_infop row_info, png_bytep row,
|
|
||||||
png_const_bytep prev_row)
|
|
||||||
{
|
|
||||||
png_byte bpp = 3;
|
|
||||||
|
|
||||||
vector unsigned char rp_vec;
|
|
||||||
vector unsigned char part_vec;
|
|
||||||
|
|
||||||
vsx_declare_common_vars(row_info,row,prev_row,bpp)
|
|
||||||
|
|
||||||
PNG_UNUSED(pp)
|
|
||||||
|
|
||||||
/* Altivec operations require 16-byte aligned data
|
|
||||||
* but input can be unaligned. So we calculate
|
|
||||||
* unaligned part as usual.
|
|
||||||
*/
|
|
||||||
for (i = 0; i < unaligned_top; i++)
|
|
||||||
{
|
|
||||||
*rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff);
|
|
||||||
rp++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Using SIMD while we can */
|
|
||||||
while( istop >= 16 )
|
|
||||||
{
|
|
||||||
for(i=0;i < bpp ; i++)
|
|
||||||
{
|
|
||||||
*rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff);
|
|
||||||
rp++;
|
|
||||||
}
|
|
||||||
rp -= bpp;
|
|
||||||
|
|
||||||
rp_vec = vec_ld(0,rp);
|
|
||||||
part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED1_3);
|
|
||||||
rp_vec = vec_add(rp_vec,part_vec);
|
|
||||||
|
|
||||||
part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED2_3);
|
|
||||||
rp_vec = vec_add(rp_vec,part_vec);
|
|
||||||
|
|
||||||
part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED3_3);
|
|
||||||
rp_vec = vec_add(rp_vec,part_vec);
|
|
||||||
|
|
||||||
part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED4_3);
|
|
||||||
rp_vec = vec_add(rp_vec,part_vec);
|
|
||||||
|
|
||||||
vec_st(rp_vec,0,rp);
|
|
||||||
rp += 15;
|
|
||||||
istop -= 16;
|
|
||||||
|
|
||||||
/* Since 16 % bpp = 16 % 3 = 1, last element of array must
|
|
||||||
* be proceeded manually
|
|
||||||
*/
|
|
||||||
*rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff);
|
|
||||||
rp++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(istop > 0)
|
|
||||||
for (i = 0; i < istop % 16; i++)
|
|
||||||
{
|
|
||||||
*rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff);
|
|
||||||
rp++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void png_read_filter_row_avg4_vsx(png_row_infop row_info, png_bytep row,
|
|
||||||
png_const_bytep prev_row)
|
|
||||||
{
|
|
||||||
png_byte bpp = 4;
|
|
||||||
|
|
||||||
vector unsigned char rp_vec;
|
|
||||||
vector unsigned char pp_vec;
|
|
||||||
vector unsigned char pp_part_vec;
|
|
||||||
vector unsigned char rp_part_vec;
|
|
||||||
vector unsigned char avg_vec;
|
|
||||||
|
|
||||||
vsx_declare_common_vars(row_info,row,prev_row,bpp)
|
|
||||||
rp -= bpp;
|
|
||||||
if(istop >= bpp)
|
|
||||||
istop -= bpp;
|
|
||||||
|
|
||||||
for (i = 0; i < bpp; i++)
|
|
||||||
{
|
|
||||||
*rp = (png_byte)(((int)(*rp) +
|
|
||||||
((int)(*pp++) / 2 )) & 0xff);
|
|
||||||
|
|
||||||
rp++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Altivec operations require 16-byte aligned data
|
|
||||||
* but input can be unaligned. So we calculate
|
|
||||||
* unaligned part as usual.
|
|
||||||
*/
|
|
||||||
for (i = 0; i < unaligned_top; i++)
|
|
||||||
{
|
|
||||||
*rp = (png_byte)(((int)(*rp) +
|
|
||||||
(int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
|
|
||||||
|
|
||||||
rp++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Using SIMD while we can */
|
|
||||||
while( istop >= 16 )
|
|
||||||
{
|
|
||||||
for(i=0;i < bpp ; i++)
|
|
||||||
{
|
|
||||||
*rp = (png_byte)(((int)(*rp) +
|
|
||||||
(int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
|
|
||||||
|
|
||||||
rp++;
|
|
||||||
}
|
|
||||||
rp -= bpp;
|
|
||||||
pp -= bpp;
|
|
||||||
|
|
||||||
vec_ld_unaligned(pp_vec,pp);
|
|
||||||
rp_vec = vec_ld(0,rp);
|
|
||||||
|
|
||||||
rp_part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED1_4);
|
|
||||||
pp_part_vec = vec_perm(pp_vec,VSX_CHAR_ZERO,VSX_NOT_SHIFTED1_4);
|
|
||||||
avg_vec = vec_avg(rp_part_vec,pp_part_vec);
|
|
||||||
avg_vec = vec_sub(avg_vec, vec_and(vec_xor(rp_part_vec,pp_part_vec),vec_splat_u8(1)));
|
|
||||||
rp_vec = vec_add(rp_vec,avg_vec);
|
|
||||||
|
|
||||||
rp_part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED2_4);
|
|
||||||
pp_part_vec = vec_perm(pp_vec,VSX_CHAR_ZERO,VSX_NOT_SHIFTED2_4);
|
|
||||||
avg_vec = vec_avg(rp_part_vec,pp_part_vec);
|
|
||||||
avg_vec = vec_sub(avg_vec, vec_and(vec_xor(rp_part_vec,pp_part_vec),vec_splat_u8(1)));
|
|
||||||
rp_vec = vec_add(rp_vec,avg_vec);
|
|
||||||
|
|
||||||
rp_part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED3_4);
|
|
||||||
pp_part_vec = vec_perm(pp_vec,VSX_CHAR_ZERO,VSX_NOT_SHIFTED3_4);
|
|
||||||
avg_vec = vec_avg(rp_part_vec,pp_part_vec);
|
|
||||||
avg_vec = vec_sub(avg_vec, vec_and(vec_xor(rp_part_vec,pp_part_vec),vec_splat_u8(1)));
|
|
||||||
rp_vec = vec_add(rp_vec,avg_vec);
|
|
||||||
|
|
||||||
vec_st(rp_vec,0,rp);
|
|
||||||
|
|
||||||
rp += 16;
|
|
||||||
pp += 16;
|
|
||||||
istop -= 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(istop > 0)
|
|
||||||
for (i = 0; i < istop % 16; i++)
|
|
||||||
{
|
|
||||||
*rp = (png_byte)(((int)(*rp) +
|
|
||||||
(int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
|
|
||||||
|
|
||||||
rp++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void png_read_filter_row_avg3_vsx(png_row_infop row_info, png_bytep row,
|
|
||||||
png_const_bytep prev_row)
|
|
||||||
{
|
|
||||||
png_byte bpp = 3;
|
|
||||||
|
|
||||||
vector unsigned char rp_vec;
|
|
||||||
vector unsigned char pp_vec;
|
|
||||||
vector unsigned char pp_part_vec;
|
|
||||||
vector unsigned char rp_part_vec;
|
|
||||||
vector unsigned char avg_vec;
|
|
||||||
|
|
||||||
vsx_declare_common_vars(row_info,row,prev_row,bpp)
|
|
||||||
rp -= bpp;
|
|
||||||
if(istop >= bpp)
|
|
||||||
istop -= bpp;
|
|
||||||
|
|
||||||
for (i = 0; i < bpp; i++)
|
|
||||||
{
|
|
||||||
*rp = (png_byte)(((int)(*rp) +
|
|
||||||
((int)(*pp++) / 2 )) & 0xff);
|
|
||||||
|
|
||||||
rp++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Altivec operations require 16-byte aligned data
|
|
||||||
* but input can be unaligned. So we calculate
|
|
||||||
* unaligned part as usual.
|
|
||||||
*/
|
|
||||||
for (i = 0; i < unaligned_top; i++)
|
|
||||||
{
|
|
||||||
*rp = (png_byte)(((int)(*rp) +
|
|
||||||
(int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
|
|
||||||
|
|
||||||
rp++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Using SIMD while we can */
|
|
||||||
while( istop >= 16 )
|
|
||||||
{
|
|
||||||
for(i=0;i < bpp ; i++)
|
|
||||||
{
|
|
||||||
*rp = (png_byte)(((int)(*rp) +
|
|
||||||
(int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
|
|
||||||
|
|
||||||
rp++;
|
|
||||||
}
|
|
||||||
rp -= bpp;
|
|
||||||
pp -= bpp;
|
|
||||||
|
|
||||||
vec_ld_unaligned(pp_vec,pp);
|
|
||||||
rp_vec = vec_ld(0,rp);
|
|
||||||
|
|
||||||
rp_part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED1_3);
|
|
||||||
pp_part_vec = vec_perm(pp_vec,VSX_CHAR_ZERO,VSX_NOT_SHIFTED1_3);
|
|
||||||
avg_vec = vec_avg(rp_part_vec,pp_part_vec);
|
|
||||||
avg_vec = vec_sub(avg_vec, vec_and(vec_xor(rp_part_vec,pp_part_vec),vec_splat_u8(1)));
|
|
||||||
rp_vec = vec_add(rp_vec,avg_vec);
|
|
||||||
|
|
||||||
rp_part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED2_3);
|
|
||||||
pp_part_vec = vec_perm(pp_vec,VSX_CHAR_ZERO,VSX_NOT_SHIFTED2_3);
|
|
||||||
avg_vec = vec_avg(rp_part_vec,pp_part_vec);
|
|
||||||
avg_vec = vec_sub(avg_vec, vec_and(vec_xor(rp_part_vec,pp_part_vec),vec_splat_u8(1)));
|
|
||||||
rp_vec = vec_add(rp_vec,avg_vec);
|
|
||||||
|
|
||||||
rp_part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED3_3);
|
|
||||||
pp_part_vec = vec_perm(pp_vec,VSX_CHAR_ZERO,VSX_NOT_SHIFTED3_3);
|
|
||||||
avg_vec = vec_avg(rp_part_vec,pp_part_vec);
|
|
||||||
avg_vec = vec_sub(avg_vec, vec_and(vec_xor(rp_part_vec,pp_part_vec),vec_splat_u8(1)));
|
|
||||||
rp_vec = vec_add(rp_vec,avg_vec);
|
|
||||||
|
|
||||||
rp_part_vec = vec_perm(rp_vec,VSX_CHAR_ZERO,VSX_LEFTSHIFTED4_3);
|
|
||||||
pp_part_vec = vec_perm(pp_vec,VSX_CHAR_ZERO,VSX_NOT_SHIFTED4_3);
|
|
||||||
avg_vec = vec_avg(rp_part_vec,pp_part_vec);
|
|
||||||
avg_vec = vec_sub(avg_vec, vec_and(vec_xor(rp_part_vec,pp_part_vec),vec_splat_u8(1)));
|
|
||||||
rp_vec = vec_add(rp_vec,avg_vec);
|
|
||||||
|
|
||||||
vec_st(rp_vec,0,rp);
|
|
||||||
|
|
||||||
rp += 15;
|
|
||||||
pp += 15;
|
|
||||||
istop -= 16;
|
|
||||||
|
|
||||||
/* Since 16 % bpp = 16 % 3 = 1, last element of array must
|
|
||||||
* be proceeded manually
|
|
||||||
*/
|
|
||||||
*rp = (png_byte)(((int)(*rp) +
|
|
||||||
(int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
|
|
||||||
rp++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(istop > 0)
|
|
||||||
for (i = 0; i < istop % 16; i++)
|
|
||||||
{
|
|
||||||
*rp = (png_byte)(((int)(*rp) +
|
|
||||||
(int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
|
|
||||||
|
|
||||||
rp++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Bytewise c ? t : e. */
|
|
||||||
#define if_then_else(c,t,e) vec_sel(e,t,c)
|
|
||||||
|
|
||||||
#define vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp) {\
|
|
||||||
c = *(pp - bpp);\
|
|
||||||
a = *(rp - bpp);\
|
|
||||||
b = *pp++;\
|
|
||||||
p = b - c;\
|
|
||||||
pc = a - c;\
|
|
||||||
pa = vsx_abs(p);\
|
|
||||||
pb = vsx_abs(pc);\
|
|
||||||
pc = vsx_abs(p + pc);\
|
|
||||||
if (pb < pa) pa = pb, a = b;\
|
|
||||||
if (pc < pa) a = c;\
|
|
||||||
a += *rp;\
|
|
||||||
*rp++ = (png_byte)a;\
|
|
||||||
}
|
|
||||||
|
|
||||||
void png_read_filter_row_paeth4_vsx(png_row_infop row_info, png_bytep row,
|
|
||||||
png_const_bytep prev_row)
|
|
||||||
{
|
|
||||||
png_byte bpp = 4;
|
|
||||||
|
|
||||||
int a, b, c, pa, pb, pc, p;
|
|
||||||
vector unsigned char rp_vec;
|
|
||||||
vector unsigned char pp_vec;
|
|
||||||
vector unsigned short a_vec,b_vec,c_vec,nearest_vec;
|
|
||||||
vector signed short pa_vec,pb_vec,pc_vec,smallest_vec;
|
|
||||||
|
|
||||||
vsx_declare_common_vars(row_info,row,prev_row,bpp)
|
|
||||||
rp -= bpp;
|
|
||||||
if(istop >= bpp)
|
|
||||||
istop -= bpp;
|
|
||||||
|
|
||||||
/* Process the first pixel in the row completely (this is the same as 'up'
|
|
||||||
* because there is only one candidate predictor for the first row).
|
|
||||||
*/
|
|
||||||
for(i = 0; i < bpp ; i++)
|
|
||||||
{
|
|
||||||
*rp = (png_byte)( *rp + *pp);
|
|
||||||
rp++;
|
|
||||||
pp++;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(i = 0; i < unaligned_top ; i++)
|
|
||||||
{
|
|
||||||
vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp)
|
|
||||||
}
|
|
||||||
|
|
||||||
while( istop >= 16)
|
|
||||||
{
|
|
||||||
for(i = 0; i < bpp ; i++)
|
|
||||||
{
|
|
||||||
vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp)
|
|
||||||
}
|
|
||||||
|
|
||||||
rp -= bpp;
|
|
||||||
pp -= bpp;
|
|
||||||
rp_vec = vec_ld(0,rp);
|
|
||||||
vec_ld_unaligned(pp_vec,pp);
|
|
||||||
|
|
||||||
a_vec = vsx_char_to_short(vec_perm(rp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED1_4),1,4);
|
|
||||||
b_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_NOT_SHIFTED1_4),1,4);
|
|
||||||
c_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED1_4),1,4);
|
|
||||||
pa_vec = (vector signed short) vec_sub(b_vec,c_vec);
|
|
||||||
pb_vec = (vector signed short) vec_sub(a_vec , c_vec);
|
|
||||||
pc_vec = vec_add(pa_vec,pb_vec);
|
|
||||||
pa_vec = vec_abs(pa_vec);
|
|
||||||
pb_vec = vec_abs(pb_vec);
|
|
||||||
pc_vec = vec_abs(pc_vec);
|
|
||||||
smallest_vec = vec_min(pc_vec, vec_min(pa_vec,pb_vec));
|
|
||||||
nearest_vec = if_then_else(
|
|
||||||
vec_cmpeq(pa_vec,smallest_vec),
|
|
||||||
a_vec,
|
|
||||||
if_then_else(
|
|
||||||
vec_cmpeq(pb_vec,smallest_vec),
|
|
||||||
b_vec,
|
|
||||||
c_vec
|
|
||||||
)
|
|
||||||
);
|
|
||||||
rp_vec = vec_add(rp_vec,(vsx_short_to_char(nearest_vec,1,4)));
|
|
||||||
|
|
||||||
a_vec = vsx_char_to_short(vec_perm(rp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED2_4),2,4);
|
|
||||||
b_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_NOT_SHIFTED2_4),2,4);
|
|
||||||
c_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED2_4),2,4);
|
|
||||||
pa_vec = (vector signed short) vec_sub(b_vec,c_vec);
|
|
||||||
pb_vec = (vector signed short) vec_sub(a_vec , c_vec);
|
|
||||||
pc_vec = vec_add(pa_vec,pb_vec);
|
|
||||||
pa_vec = vec_abs(pa_vec);
|
|
||||||
pb_vec = vec_abs(pb_vec);
|
|
||||||
pc_vec = vec_abs(pc_vec);
|
|
||||||
smallest_vec = vec_min(pc_vec, vec_min(pa_vec,pb_vec));
|
|
||||||
nearest_vec = if_then_else(
|
|
||||||
vec_cmpeq(pa_vec,smallest_vec),
|
|
||||||
a_vec,
|
|
||||||
if_then_else(
|
|
||||||
vec_cmpeq(pb_vec,smallest_vec),
|
|
||||||
b_vec,
|
|
||||||
c_vec
|
|
||||||
)
|
|
||||||
);
|
|
||||||
rp_vec = vec_add(rp_vec,(vsx_short_to_char(nearest_vec,2,4)));
|
|
||||||
|
|
||||||
a_vec = vsx_char_to_short(vec_perm(rp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED3_4),3,4);
|
|
||||||
b_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_NOT_SHIFTED3_4),3,4);
|
|
||||||
c_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED3_4),3,4);
|
|
||||||
pa_vec = (vector signed short) vec_sub(b_vec,c_vec);
|
|
||||||
pb_vec = (vector signed short) vec_sub(a_vec , c_vec);
|
|
||||||
pc_vec = vec_add(pa_vec,pb_vec);
|
|
||||||
pa_vec = vec_abs(pa_vec);
|
|
||||||
pb_vec = vec_abs(pb_vec);
|
|
||||||
pc_vec = vec_abs(pc_vec);
|
|
||||||
smallest_vec = vec_min(pc_vec, vec_min(pa_vec,pb_vec));
|
|
||||||
nearest_vec = if_then_else(
|
|
||||||
vec_cmpeq(pa_vec,smallest_vec),
|
|
||||||
a_vec,
|
|
||||||
if_then_else(
|
|
||||||
vec_cmpeq(pb_vec,smallest_vec),
|
|
||||||
b_vec,
|
|
||||||
c_vec
|
|
||||||
)
|
|
||||||
);
|
|
||||||
rp_vec = vec_add(rp_vec,(vsx_short_to_char(nearest_vec,3,4)));
|
|
||||||
|
|
||||||
vec_st(rp_vec,0,rp);
|
|
||||||
|
|
||||||
rp += 16;
|
|
||||||
pp += 16;
|
|
||||||
istop -= 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(istop > 0)
|
|
||||||
for (i = 0; i < istop % 16; i++)
|
|
||||||
{
|
|
||||||
vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void png_read_filter_row_paeth3_vsx(png_row_infop row_info, png_bytep row,
|
|
||||||
png_const_bytep prev_row)
|
|
||||||
{
|
|
||||||
png_byte bpp = 3;
|
|
||||||
|
|
||||||
int a, b, c, pa, pb, pc, p;
|
|
||||||
vector unsigned char rp_vec;
|
|
||||||
vector unsigned char pp_vec;
|
|
||||||
vector unsigned short a_vec,b_vec,c_vec,nearest_vec;
|
|
||||||
vector signed short pa_vec,pb_vec,pc_vec,smallest_vec;
|
|
||||||
|
|
||||||
vsx_declare_common_vars(row_info,row,prev_row,bpp)
|
|
||||||
rp -= bpp;
|
|
||||||
if(istop >= bpp)
|
|
||||||
istop -= bpp;
|
|
||||||
|
|
||||||
/* Process the first pixel in the row completely (this is the same as 'up'
|
|
||||||
* because there is only one candidate predictor for the first row).
|
|
||||||
*/
|
|
||||||
for(i = 0; i < bpp ; i++)
|
|
||||||
{
|
|
||||||
*rp = (png_byte)( *rp + *pp);
|
|
||||||
rp++;
|
|
||||||
pp++;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(i = 0; i < unaligned_top ; i++)
|
|
||||||
{
|
|
||||||
vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp)
|
|
||||||
}
|
|
||||||
|
|
||||||
while( istop >= 16)
|
|
||||||
{
|
|
||||||
for(i = 0; i < bpp ; i++)
|
|
||||||
{
|
|
||||||
vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp)
|
|
||||||
}
|
|
||||||
|
|
||||||
rp -= bpp;
|
|
||||||
pp -= bpp;
|
|
||||||
rp_vec = vec_ld(0,rp);
|
|
||||||
vec_ld_unaligned(pp_vec,pp);
|
|
||||||
|
|
||||||
a_vec = vsx_char_to_short(vec_perm(rp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED1_3),1,3);
|
|
||||||
b_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_NOT_SHIFTED1_3),1,3);
|
|
||||||
c_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED1_3),1,3);
|
|
||||||
pa_vec = (vector signed short) vec_sub(b_vec,c_vec);
|
|
||||||
pb_vec = (vector signed short) vec_sub(a_vec , c_vec);
|
|
||||||
pc_vec = vec_add(pa_vec,pb_vec);
|
|
||||||
pa_vec = vec_abs(pa_vec);
|
|
||||||
pb_vec = vec_abs(pb_vec);
|
|
||||||
pc_vec = vec_abs(pc_vec);
|
|
||||||
smallest_vec = vec_min(pc_vec, vec_min(pa_vec,pb_vec));
|
|
||||||
nearest_vec = if_then_else(
|
|
||||||
vec_cmpeq(pa_vec,smallest_vec),
|
|
||||||
a_vec,
|
|
||||||
if_then_else(
|
|
||||||
vec_cmpeq(pb_vec,smallest_vec),
|
|
||||||
b_vec,
|
|
||||||
c_vec
|
|
||||||
)
|
|
||||||
);
|
|
||||||
rp_vec = vec_add(rp_vec,(vsx_short_to_char(nearest_vec,1,3)));
|
|
||||||
|
|
||||||
a_vec = vsx_char_to_short(vec_perm(rp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED2_3),2,3);
|
|
||||||
b_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_NOT_SHIFTED2_3),2,3);
|
|
||||||
c_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED2_3),2,3);
|
|
||||||
pa_vec = (vector signed short) vec_sub(b_vec,c_vec);
|
|
||||||
pb_vec = (vector signed short) vec_sub(a_vec , c_vec);
|
|
||||||
pc_vec = vec_add(pa_vec,pb_vec);
|
|
||||||
pa_vec = vec_abs(pa_vec);
|
|
||||||
pb_vec = vec_abs(pb_vec);
|
|
||||||
pc_vec = vec_abs(pc_vec);
|
|
||||||
smallest_vec = vec_min(pc_vec, vec_min(pa_vec,pb_vec));
|
|
||||||
nearest_vec = if_then_else(
|
|
||||||
vec_cmpeq(pa_vec,smallest_vec),
|
|
||||||
a_vec,
|
|
||||||
if_then_else(
|
|
||||||
vec_cmpeq(pb_vec,smallest_vec),
|
|
||||||
b_vec,
|
|
||||||
c_vec
|
|
||||||
)
|
|
||||||
);
|
|
||||||
rp_vec = vec_add(rp_vec,(vsx_short_to_char(nearest_vec,2,3)));
|
|
||||||
|
|
||||||
a_vec = vsx_char_to_short(vec_perm(rp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED3_3),3,3);
|
|
||||||
b_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_NOT_SHIFTED3_3),3,3);
|
|
||||||
c_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED3_3),3,3);
|
|
||||||
pa_vec = (vector signed short) vec_sub(b_vec,c_vec);
|
|
||||||
pb_vec = (vector signed short) vec_sub(a_vec , c_vec);
|
|
||||||
pc_vec = vec_add(pa_vec,pb_vec);
|
|
||||||
pa_vec = vec_abs(pa_vec);
|
|
||||||
pb_vec = vec_abs(pb_vec);
|
|
||||||
pc_vec = vec_abs(pc_vec);
|
|
||||||
smallest_vec = vec_min(pc_vec, vec_min(pa_vec,pb_vec));
|
|
||||||
nearest_vec = if_then_else(
|
|
||||||
vec_cmpeq(pa_vec,smallest_vec),
|
|
||||||
a_vec,
|
|
||||||
if_then_else(
|
|
||||||
vec_cmpeq(pb_vec,smallest_vec),
|
|
||||||
b_vec,
|
|
||||||
c_vec
|
|
||||||
)
|
|
||||||
);
|
|
||||||
rp_vec = vec_add(rp_vec,(vsx_short_to_char(nearest_vec,3,3)));
|
|
||||||
|
|
||||||
a_vec = vsx_char_to_short(vec_perm(rp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED4_3),4,3);
|
|
||||||
b_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_NOT_SHIFTED4_3),4,3);
|
|
||||||
c_vec = vsx_char_to_short(vec_perm(pp_vec , VSX_CHAR_ZERO , VSX_LEFTSHIFTED4_3),4,3);
|
|
||||||
pa_vec = (vector signed short) vec_sub(b_vec,c_vec);
|
|
||||||
pb_vec = (vector signed short) vec_sub(a_vec , c_vec);
|
|
||||||
pc_vec = vec_add(pa_vec,pb_vec);
|
|
||||||
pa_vec = vec_abs(pa_vec);
|
|
||||||
pb_vec = vec_abs(pb_vec);
|
|
||||||
pc_vec = vec_abs(pc_vec);
|
|
||||||
smallest_vec = vec_min(pc_vec, vec_min(pa_vec,pb_vec));
|
|
||||||
nearest_vec = if_then_else(
|
|
||||||
vec_cmpeq(pa_vec,smallest_vec),
|
|
||||||
a_vec,
|
|
||||||
if_then_else(
|
|
||||||
vec_cmpeq(pb_vec,smallest_vec),
|
|
||||||
b_vec,
|
|
||||||
c_vec
|
|
||||||
)
|
|
||||||
);
|
|
||||||
rp_vec = vec_add(rp_vec,(vsx_short_to_char(nearest_vec,4,3)));
|
|
||||||
|
|
||||||
vec_st(rp_vec,0,rp);
|
|
||||||
|
|
||||||
rp += 15;
|
|
||||||
pp += 15;
|
|
||||||
istop -= 16;
|
|
||||||
|
|
||||||
/* Since 16 % bpp = 16 % 3 = 1, last element of array must
|
|
||||||
* be proceeded manually
|
|
||||||
*/
|
|
||||||
vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp)
|
|
||||||
}
|
|
||||||
|
|
||||||
if(istop > 0)
|
|
||||||
for (i = 0; i < istop % 16; i++)
|
|
||||||
{
|
|
||||||
vsx_paeth_process(rp,pp,a,b,c,pa,pb,pc,bpp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* PNG_POWERPC_VSX_OPT > 0 */
|
|
||||||
#endif /* PNG_POWERPC_VSX_IMPLEMENTATION == 1 (intrinsics) */
|
|
||||||
#endif /* READ */
|
|
|
@ -1,126 +0,0 @@
|
||||||
|
|
||||||
/* powerpc_init.c - POWERPC optimised filter functions
|
|
||||||
*
|
|
||||||
* Copyright (c) 2018 Cosmin Truta
|
|
||||||
* Copyright (c) 2017 Glenn Randers-Pehrson
|
|
||||||
* Written by Vadim Barkov, 2017.
|
|
||||||
*
|
|
||||||
* 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_POWERPC_VSX_OPT > 0
|
|
||||||
#ifdef PNG_POWERPC_VSX_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 PowerPC
|
|
||||||
* VSX 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_POWERPC_VSX_FILE to the file name of file containing
|
|
||||||
* a fragment of C source code which defines the png_have_vsx function. There
|
|
||||||
* are a number of implementations in contrib/powerpc-vsx, but the only one that
|
|
||||||
* has partial support is contrib/powerpc-vsx/linux.c - a generic Linux
|
|
||||||
* implementation which reads /proc/cpufino.
|
|
||||||
*/
|
|
||||||
#ifndef PNG_POWERPC_VSX_FILE
|
|
||||||
# ifdef __linux__
|
|
||||||
# define PNG_POWERPC_VSX_FILE "contrib/powerpc-vsx/linux_aux.c"
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef PNG_POWERPC_VSX_FILE
|
|
||||||
|
|
||||||
#include <signal.h> /* for sig_atomic_t */
|
|
||||||
static int png_have_vsx(png_structp png_ptr);
|
|
||||||
#include PNG_POWERPC_VSX_FILE
|
|
||||||
|
|
||||||
#else /* PNG_POWERPC_VSX_FILE */
|
|
||||||
# error "PNG_POWERPC_VSX_FILE undefined: no support for run-time POWERPC VSX checks"
|
|
||||||
#endif /* PNG_POWERPC_VSX_FILE */
|
|
||||||
#endif /* PNG_POWERPC_VSX_CHECK_SUPPORTED */
|
|
||||||
|
|
||||||
void
|
|
||||||
png_init_filter_functions_vsx(png_structp pp, unsigned int bpp)
|
|
||||||
{
|
|
||||||
/* The switch statement is compiled in for POWERPC_VSX_API, the call to
|
|
||||||
* png_have_vsx is compiled in for POWERPC_VSX_CHECK. If both are defined
|
|
||||||
* the check is only performed if the API has not set the PowerPC option on
|
|
||||||
* or off explicitly. In this case the check controls what happens.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef PNG_POWERPC_VSX_API_SUPPORTED
|
|
||||||
switch ((pp->options >> PNG_POWERPC_VSX) & 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_POWERPC_VSX_API_SUPPORTED */
|
|
||||||
#ifdef PNG_POWERPC_VSX_CHECK_SUPPORTED
|
|
||||||
{
|
|
||||||
static volatile sig_atomic_t no_vsx = -1; /* not checked */
|
|
||||||
|
|
||||||
if (no_vsx < 0)
|
|
||||||
no_vsx = !png_have_vsx(pp);
|
|
||||||
|
|
||||||
if (no_vsx)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#ifdef PNG_POWERPC_VSX_API_SUPPORTED
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#endif /* PNG_POWERPC_VSX_CHECK_SUPPORTED */
|
|
||||||
|
|
||||||
#ifdef PNG_POWERPC_VSX_API_SUPPORTED
|
|
||||||
default: /* OFF or INVALID */
|
|
||||||
return;
|
|
||||||
|
|
||||||
case PNG_OPTION_ON:
|
|
||||||
/* Option turned on */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* IMPORTANT: any new internal 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_vsx;
|
|
||||||
|
|
||||||
if (bpp == 3)
|
|
||||||
{
|
|
||||||
pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_vsx;
|
|
||||||
pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_vsx;
|
|
||||||
pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = png_read_filter_row_paeth3_vsx;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (bpp == 4)
|
|
||||||
{
|
|
||||||
pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_vsx;
|
|
||||||
pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_vsx;
|
|
||||||
pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = png_read_filter_row_paeth4_vsx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* PNG_POWERPC_VSX_OPT > 0 */
|
|
||||||
#endif /* READ */
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
cmake_minimum_required(VERSION 3.0)
|
||||||
|
|
||||||
|
project(spng C)
|
||||||
|
|
||||||
|
add_library(spng STATIC ${CMAKE_CURRENT_LIST_DIR}/libspng/spng/spng.c)
|
||||||
|
target_compile_definitions(spng PUBLIC SPNG_STATIC)
|
||||||
|
target_link_libraries(spng PUBLIC ZLIB::ZLIB)
|
||||||
|
target_include_directories(spng PUBLIC ${CMAKE_CURRENT_LIST_DIR}/libspng/spng/)
|
||||||
|
dolphin_disable_warnings_msvc(spng)
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit dc5b1032c08efac68ad30170f7ccbf0aa8dd55c9
|
|
@ -0,0 +1,35 @@
|
||||||
|
<?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>{447B7B1E-1D74-4AEF-B2B9-6EB41C5D5313}</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" />
|
||||||
|
<ItemDefinitionGroup>
|
||||||
|
<ClCompile>
|
||||||
|
<AdditionalIncludeDirectories>libspng\spng;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="libspng\spng\spng.c" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Text Include="CMakeLists.txt" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="libspng\spng\spng.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
|
@ -15,13 +15,13 @@ Dolphin includes or links code of the following third-party software projects:
|
||||||
- [ENet](http://enet.bespin.org/):
|
- [ENet](http://enet.bespin.org/):
|
||||||
[MIT](http://enet.bespin.org/License.html)
|
[MIT](http://enet.bespin.org/License.html)
|
||||||
- [FatFs](http://elm-chan.org/fsw/ff/00index_e.html):
|
- [FatFs](http://elm-chan.org/fsw/ff/00index_e.html):
|
||||||
[BSD-1-Clause](http://elm-chan.org/fsw/ff/doc/appnote.html#license)
|
[BSD 1-Clause](http://elm-chan.org/fsw/ff/doc/appnote.html#license)
|
||||||
- [GCEmu](http://sourceforge.net/projects/gcemu-project/):
|
- [GCEmu](http://sourceforge.net/projects/gcemu-project/):
|
||||||
GPLv2+
|
GPLv2+
|
||||||
- [gettext](https://www.gnu.org/software/gettext/):
|
- [gettext](https://www.gnu.org/software/gettext/):
|
||||||
[GPLv3+](http://git.savannah.gnu.org/cgit/gettext.git/tree/COPYING)
|
[GPLv3+](http://git.savannah.gnu.org/cgit/gettext.git/tree/COPYING)
|
||||||
- [googletest](https://github.com/google/googletest):
|
- [googletest](https://github.com/google/googletest):
|
||||||
[3-clause BSD](https://github.com/google/googletest/blob/master/LICENSE)
|
[BSD 3-Clause](https://github.com/google/googletest/blob/master/LICENSE)
|
||||||
- [libao](https://www.xiph.org/ao/):
|
- [libao](https://www.xiph.org/ao/):
|
||||||
[GPLv2+](https://trac.xiph.org/browser/trunk/ao/README)
|
[GPLv2+](https://trac.xiph.org/browser/trunk/ao/README)
|
||||||
- [libav](https://libav.org/):
|
- [libav](https://libav.org/):
|
||||||
|
@ -32,8 +32,8 @@ Dolphin includes or links code of the following third-party software projects:
|
||||||
[LGPLv2+](http://git.savannah.gnu.org/cgit/libiconv.git/tree/COPYING.LIB)
|
[LGPLv2+](http://git.savannah.gnu.org/cgit/libiconv.git/tree/COPYING.LIB)
|
||||||
- [liblzma](https://tukaani.org/xz/):
|
- [liblzma](https://tukaani.org/xz/):
|
||||||
[Public domain](https://git.tukaani.org/?p=xz.git;a=blob_plain;f=COPYING;hb=HEAD)
|
[Public domain](https://git.tukaani.org/?p=xz.git;a=blob_plain;f=COPYING;hb=HEAD)
|
||||||
- [libpng](http://www.libpng.org/pub/png/libpng.html):
|
- [libspng](https://github.com/randy408/libspng):
|
||||||
[libpng license](http://www.libpng.org/pub/png/src/libpng-LICENSE.txt)
|
[BSD 2-Clause](https://github.com/randy408/libspng/blob/master/LICENSE)
|
||||||
- [libusb](http://libusb.info/):
|
- [libusb](http://libusb.info/):
|
||||||
[LGPLv2.1+](https://github.com/libusb/libusb/blob/master/COPYING)
|
[LGPLv2.1+](https://github.com/libusb/libusb/blob/master/COPYING)
|
||||||
- [LLVM](http://llvm.org/):
|
- [LLVM](http://llvm.org/):
|
||||||
|
@ -43,7 +43,7 @@ Dolphin includes or links code of the following third-party software projects:
|
||||||
- [mGBA](http://mgba.io)
|
- [mGBA](http://mgba.io)
|
||||||
[MPL 2.0](https://github.com/mgba-emu/mgba/blob/master/LICENSE)
|
[MPL 2.0](https://github.com/mgba-emu/mgba/blob/master/LICENSE)
|
||||||
- [MiniUPnPc](http://miniupnp.free.fr/):
|
- [MiniUPnPc](http://miniupnp.free.fr/):
|
||||||
[3-clause BSD](https://github.com/miniupnp/miniupnp/blob/master/miniupnpc/LICENSE)
|
[BSD 3-Clause](https://github.com/miniupnp/miniupnp/blob/master/miniupnpc/LICENSE)
|
||||||
- [Microsoft Visual C++ Runtime Library](http://www.microsoft.com/en-us/download/details.aspx?id=40784):
|
- [Microsoft Visual C++ Runtime Library](http://www.microsoft.com/en-us/download/details.aspx?id=40784):
|
||||||
[System Library if not distributed](https://www.gnu.org/licenses/gpl-faq.html#WindowsRuntimeAndGPL)
|
[System Library if not distributed](https://www.gnu.org/licenses/gpl-faq.html#WindowsRuntimeAndGPL)
|
||||||
- [OpenAL Soft](http://kcat.strangesoft.net/openal.html):
|
- [OpenAL Soft](http://kcat.strangesoft.net/openal.html):
|
||||||
|
@ -73,8 +73,8 @@ Dolphin includes or links code of the following third-party software projects:
|
||||||
- [Windows Implementation Libraries](https://github.com/microsoft/wil):
|
- [Windows Implementation Libraries](https://github.com/microsoft/wil):
|
||||||
[MIT](https://github.com/microsoft/wil/blob/master/LICENSE)
|
[MIT](https://github.com/microsoft/wil/blob/master/LICENSE)
|
||||||
- [xxHash](https://github.com/Cyan4973/xxHash):
|
- [xxHash](https://github.com/Cyan4973/xxHash):
|
||||||
[2-clause BSD](https://github.com/Cyan4973/xxHash/blob/master/LICENSE)
|
[BSD 2-Clause](https://github.com/Cyan4973/xxHash/blob/master/LICENSE)
|
||||||
- [zlib-ng](https://github.com/zlib-ng/zlib-ng):
|
- [zlib-ng](https://github.com/zlib-ng/zlib-ng):
|
||||||
[zlib license](https://github.com/zlib-ng/zlib-ng/blob/develop/LICENSE.md)
|
[zlib license](https://github.com/zlib-ng/zlib-ng/blob/develop/LICENSE.md)
|
||||||
- [Zstandard](https://facebook.github.io/zstd/):
|
- [Zstandard](https://facebook.github.io/zstd/):
|
||||||
[3-clause BSD](https://github.com/facebook/zstd/blob/dev/LICENSE) or [GPLv2](https://github.com/facebook/zstd/blob/dev/COPYING)
|
[BSD 3-Clause](https://github.com/facebook/zstd/blob/dev/LICENSE) or [GPLv2](https://github.com/facebook/zstd/blob/dev/COPYING)
|
||||||
|
|
|
@ -64,8 +64,6 @@ add_library(common
|
||||||
HttpRequest.h
|
HttpRequest.h
|
||||||
Image.cpp
|
Image.cpp
|
||||||
Image.h
|
Image.h
|
||||||
ImageC.c
|
|
||||||
ImageC.h
|
|
||||||
IniFile.cpp
|
IniFile.cpp
|
||||||
IniFile.h
|
IniFile.h
|
||||||
Inline.h
|
Inline.h
|
||||||
|
@ -148,7 +146,7 @@ PRIVATE
|
||||||
${CURL_LIBRARIES}
|
${CURL_LIBRARIES}
|
||||||
FatFs
|
FatFs
|
||||||
${ICONV_LIBRARIES}
|
${ICONV_LIBRARIES}
|
||||||
png
|
spng
|
||||||
${VTUNE_LIBRARIES}
|
${VTUNE_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -315,9 +313,4 @@ endif()
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
# Add precompiled header
|
# Add precompiled header
|
||||||
target_link_libraries(common PRIVATE use_pch)
|
target_link_libraries(common PRIVATE use_pch)
|
||||||
|
|
||||||
# We need to disable PCH for this one file, because it's C and our PCH is C++
|
|
||||||
set_source_files_properties(
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/ImageC.c
|
|
||||||
PROPERTIES COMPILE_FLAGS "/Y- /I${CMAKE_SOURCE_DIR}/Source/PCH/nopch")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -3,159 +3,121 @@
|
||||||
|
|
||||||
#include "Common/Image.h"
|
#include "Common/Image.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <png.h>
|
#include <spng.h>
|
||||||
|
|
||||||
#include "Common/Assert.h"
|
#include "Common/Assert.h"
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
#include "Common/IOFile.h"
|
#include "Common/IOFile.h"
|
||||||
#include "Common/ImageC.h"
|
|
||||||
#include "Common/Logging/Log.h"
|
#include "Common/Logging/Log.h"
|
||||||
#include "Common/Timer.h"
|
#include "Common/Timer.h"
|
||||||
|
|
||||||
namespace Common
|
namespace Common
|
||||||
{
|
{
|
||||||
|
static void spng_free(spng_ctx* ctx)
|
||||||
|
{
|
||||||
|
if (ctx)
|
||||||
|
spng_ctx_free(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static auto make_spng_ctx(int flags)
|
||||||
|
{
|
||||||
|
return std::unique_ptr<spng_ctx, decltype(&spng_free)>(spng_ctx_new(flags), spng_free);
|
||||||
|
}
|
||||||
|
|
||||||
bool LoadPNG(const std::vector<u8>& input, std::vector<u8>* data_out, u32* width_out,
|
bool LoadPNG(const std::vector<u8>& input, std::vector<u8>* data_out, u32* width_out,
|
||||||
u32* height_out)
|
u32* height_out)
|
||||||
{
|
{
|
||||||
// Using the 'Simplified API' of libpng; see section V in the libpng manual.
|
auto ctx = make_spng_ctx(0);
|
||||||
|
if (!ctx)
|
||||||
// Read header
|
|
||||||
png_image png = {};
|
|
||||||
png.version = PNG_IMAGE_VERSION;
|
|
||||||
if (!png_image_begin_read_from_memory(&png, input.data(), input.size()))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Prepare output vector
|
if (spng_set_png_buffer(ctx.get(), input.data(), input.size()))
|
||||||
png.format = PNG_FORMAT_RGBA;
|
|
||||||
size_t png_size = PNG_IMAGE_SIZE(png);
|
|
||||||
data_out->resize(png_size);
|
|
||||||
|
|
||||||
// Convert to RGBA and write into output vector
|
|
||||||
if (!png_image_finish_read(&png, nullptr, data_out->data(), 0, nullptr))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
*width_out = png.width;
|
spng_ihdr ihdr{};
|
||||||
*height_out = png.height;
|
if (spng_get_ihdr(ctx.get(), &ihdr))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const int format = SPNG_FMT_RGBA8;
|
||||||
|
size_t decoded_len = 0;
|
||||||
|
if (spng_decoded_image_size(ctx.get(), format, &decoded_len))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
data_out->resize(decoded_len);
|
||||||
|
if (spng_decode_image(ctx.get(), data_out->data(), decoded_len, format, SPNG_DECODE_TRNS))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*width_out = ihdr.width;
|
||||||
|
*height_out = ihdr.height;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WriteCallback(png_structp png_ptr, png_bytep data, size_t length)
|
|
||||||
{
|
|
||||||
std::vector<u8>* buffer = static_cast<std::vector<u8>*>(png_get_io_ptr(png_ptr));
|
|
||||||
buffer->insert(buffer->end(), data, data + length);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ErrorCallback(ErrorHandler* self, const char* msg)
|
|
||||||
{
|
|
||||||
std::vector<std::string>* errors = static_cast<std::vector<std::string>*>(self->error_list);
|
|
||||||
errors->emplace_back(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void WarningCallback(ErrorHandler* self, const char* msg)
|
|
||||||
{
|
|
||||||
std::vector<std::string>* warnings = static_cast<std::vector<std::string>*>(self->warning_list);
|
|
||||||
warnings->emplace_back(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SavePNG(const std::string& path, const u8* input, ImageByteFormat format, u32 width,
|
bool SavePNG(const std::string& path, const u8* input, ImageByteFormat format, u32 width,
|
||||||
u32 height, int stride, int level)
|
u32 height, u32 stride, int level)
|
||||||
{
|
{
|
||||||
Common::Timer timer;
|
Common::Timer timer;
|
||||||
timer.Start();
|
timer.Start();
|
||||||
|
|
||||||
size_t byte_per_pixel;
|
spng_color_type color_type;
|
||||||
int color_type;
|
|
||||||
switch (format)
|
switch (format)
|
||||||
{
|
{
|
||||||
case ImageByteFormat::RGB:
|
case ImageByteFormat::RGB:
|
||||||
color_type = PNG_COLOR_TYPE_RGB;
|
color_type = SPNG_COLOR_TYPE_TRUECOLOR;
|
||||||
byte_per_pixel = 3;
|
|
||||||
break;
|
break;
|
||||||
case ImageByteFormat::RGBA:
|
case ImageByteFormat::RGBA:
|
||||||
color_type = PNG_COLOR_TYPE_RGBA;
|
color_type = SPNG_COLOR_TYPE_TRUECOLOR_ALPHA;
|
||||||
byte_per_pixel = 4;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ASSERT_MSG(FRAMEDUMP, false, "Invalid format {}", static_cast<int>(format));
|
ASSERT_MSG(FRAMEDUMP, false, "Invalid format {}", static_cast<int>(format));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// libpng doesn't handle non-ASCII characters in path, so write in two steps:
|
auto ctx = make_spng_ctx(SPNG_CTX_ENCODER);
|
||||||
// first to memory, then to file
|
if (!ctx)
|
||||||
std::vector<u8> buffer;
|
return false;
|
||||||
buffer.reserve(byte_per_pixel * width * height);
|
|
||||||
|
|
||||||
std::vector<std::string> warnings;
|
auto outfile = File::IOFile(path, "wb");
|
||||||
std::vector<std::string> errors;
|
if (spng_set_png_file(ctx.get(), outfile.GetHandle()))
|
||||||
ErrorHandler error_handler;
|
return false;
|
||||||
error_handler.error_list = &errors;
|
|
||||||
error_handler.warning_list = &warnings;
|
|
||||||
error_handler.StoreError = ErrorCallback;
|
|
||||||
error_handler.StoreWarning = WarningCallback;
|
|
||||||
|
|
||||||
std::vector<const u8*> rows;
|
if (spng_set_option(ctx.get(), SPNG_IMG_COMPRESSION_LEVEL, level))
|
||||||
rows.reserve(height);
|
return false;
|
||||||
|
|
||||||
|
spng_ihdr ihdr{};
|
||||||
|
ihdr.width = width;
|
||||||
|
ihdr.height = height;
|
||||||
|
ihdr.color_type = color_type;
|
||||||
|
ihdr.bit_depth = 8;
|
||||||
|
if (spng_set_ihdr(ctx.get(), &ihdr))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (spng_encode_image(ctx.get(), nullptr, 0, SPNG_FMT_PNG, SPNG_ENCODE_PROGRESSIVE))
|
||||||
|
return false;
|
||||||
for (u32 row = 0; row < height; row++)
|
for (u32 row = 0; row < height; row++)
|
||||||
{
|
{
|
||||||
rows.push_back(&input[row * stride]);
|
const int err = spng_encode_row(ctx.get(), &input[row * stride], stride);
|
||||||
}
|
if (err == SPNG_EOI)
|
||||||
|
break;
|
||||||
png_structp png_ptr =
|
if (err)
|
||||||
png_create_write_struct(PNG_LIBPNG_VER_STRING, &error_handler, PngError, PngWarning);
|
|
||||||
png_infop info_ptr = png_create_info_struct(png_ptr);
|
|
||||||
|
|
||||||
bool success = false;
|
|
||||||
if (png_ptr != nullptr && info_ptr != nullptr)
|
|
||||||
{
|
|
||||||
success = SavePNG0(png_ptr, info_ptr, color_type, width, height, level, &buffer, WriteCallback,
|
|
||||||
const_cast<u8**>(rows.data()));
|
|
||||||
}
|
|
||||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
|
||||||
|
|
||||||
if (success)
|
|
||||||
{
|
|
||||||
File::IOFile outfile(path, "wb");
|
|
||||||
if (!outfile)
|
|
||||||
return false;
|
|
||||||
success = outfile.WriteBytes(buffer.data(), buffer.size());
|
|
||||||
|
|
||||||
timer.Stop();
|
|
||||||
INFO_LOG_FMT(FRAMEDUMP, "{} byte {} by {} image saved to {} at level {} in {}", buffer.size(),
|
|
||||||
width, height, path, level, timer.GetTimeElapsedFormatted());
|
|
||||||
ASSERT(errors.size() == 0);
|
|
||||||
if (warnings.size() != 0)
|
|
||||||
{
|
{
|
||||||
WARN_LOG_FMT(FRAMEDUMP, "Saved with {} warnings:", warnings.size());
|
ERROR_LOG_FMT(FRAMEDUMP, "Failed to save {} by {} image to {} at level {}: error {}", width,
|
||||||
for (auto& warning : warnings)
|
height, path, level, err);
|
||||||
WARN_LOG_FMT(FRAMEDUMP, "libpng warning: {}", warning);
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
ERROR_LOG_FMT(FRAMEDUMP,
|
|
||||||
"Failed to save {} by {} image to {} at level {}: {} warnings, {} errors", width,
|
|
||||||
height, path, level, warnings.size(), errors.size());
|
|
||||||
for (auto& error : errors)
|
|
||||||
ERROR_LOG_FMT(FRAMEDUMP, "libpng error: {}", error);
|
|
||||||
for (auto& warning : warnings)
|
|
||||||
WARN_LOG_FMT(FRAMEDUMP, "libpng warning: {}", warning);
|
|
||||||
}
|
|
||||||
|
|
||||||
return success;
|
size_t image_len = 0;
|
||||||
|
spng_decoded_image_size(ctx.get(), SPNG_FMT_PNG, &image_len);
|
||||||
|
INFO_LOG_FMT(FRAMEDUMP, "{} byte {} by {} image saved to {} at level {} in {}", image_len, width,
|
||||||
|
height, path, level, timer.GetTimeElapsedFormatted());
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConvertRGBAToRGBAndSavePNG(const std::string& path, const u8* input, u32 width, u32 height,
|
static std::vector<u8> RGBAToRGB(const u8* input, u32 width, u32 height, u32 row_stride)
|
||||||
int stride, int level)
|
|
||||||
{
|
|
||||||
const std::vector<u8> data = RGBAToRGB(input, width, height, stride);
|
|
||||||
return SavePNG(path, data.data(), ImageByteFormat::RGB, width, height, width * 3, level);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<u8> RGBAToRGB(const u8* input, u32 width, u32 height, int row_stride)
|
|
||||||
{
|
{
|
||||||
std::vector<u8> buffer;
|
std::vector<u8> buffer;
|
||||||
buffer.reserve(width * height * 3);
|
buffer.reserve(width * height * 3);
|
||||||
|
@ -172,4 +134,11 @@ std::vector<u8> RGBAToRGB(const u8* input, u32 width, u32 height, int row_stride
|
||||||
}
|
}
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ConvertRGBAToRGBAndSavePNG(const std::string& path, const u8* input, u32 width, u32 height,
|
||||||
|
u32 stride, int level)
|
||||||
|
{
|
||||||
|
const std::vector<u8> data = RGBAToRGB(input, width, height, stride);
|
||||||
|
return SavePNG(path, data.data(), ImageByteFormat::RGB, width, height, width * 3, level);
|
||||||
|
}
|
||||||
} // namespace Common
|
} // namespace Common
|
||||||
|
|
|
@ -20,10 +20,7 @@ enum class ImageByteFormat
|
||||||
};
|
};
|
||||||
|
|
||||||
bool SavePNG(const std::string& path, const u8* input, ImageByteFormat format, u32 width,
|
bool SavePNG(const std::string& path, const u8* input, ImageByteFormat format, u32 width,
|
||||||
u32 height, int stride, int level = 6);
|
u32 height, u32 stride, int level = 6);
|
||||||
bool ConvertRGBAToRGBAndSavePNG(const std::string& path, const u8* input, u32 width, u32 height,
|
bool ConvertRGBAToRGBAndSavePNG(const std::string& path, const u8* input, u32 width, u32 height,
|
||||||
int stride, int level);
|
u32 stride, int level);
|
||||||
|
|
||||||
std::vector<u8> RGBAToRGB(const u8* input, u32 width, u32 height, int row_stride = 0);
|
|
||||||
|
|
||||||
} // namespace Common
|
} // namespace Common
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
// Copyright 2021 Dolphin Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#include "Common/ImageC.h"
|
|
||||||
|
|
||||||
// Since libpng requires use of setjmp, and setjmp interacts poorly with destructors and other C++
|
|
||||||
// features, this is in a separate C file.
|
|
||||||
|
|
||||||
// The main purpose of this function is to allow specifying the compression level, which
|
|
||||||
// png_image_write_to_memory does not allow. row_pointers is not modified by libpng, but also isn't
|
|
||||||
// const for some reason.
|
|
||||||
bool SavePNG0(png_structp png_ptr, png_infop info_ptr, int color_type, png_uint_32 width,
|
|
||||||
png_uint_32 height, int level, png_voidp io_ptr, png_rw_ptr write_fn,
|
|
||||||
png_bytepp row_pointers)
|
|
||||||
{
|
|
||||||
if (setjmp(png_jmpbuf(png_ptr)) != 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
png_set_compression_level(png_ptr, level);
|
|
||||||
png_set_IHDR(png_ptr, info_ptr, width, height, 8, color_type, PNG_INTERLACE_NONE,
|
|
||||||
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
|
|
||||||
png_set_rows(png_ptr, info_ptr, row_pointers);
|
|
||||||
png_set_write_fn(png_ptr, io_ptr, write_fn, NULL);
|
|
||||||
png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// pngerror.c says: "Note that the error function MUST NOT return to the calling routine or serious
|
|
||||||
// problems will occur. The return method used in the default routine calls
|
|
||||||
// longjmp(png_ptr->jmp_buf_ptr, 1)"
|
|
||||||
void PngError(png_structp png_ptr, png_const_charp msg)
|
|
||||||
{
|
|
||||||
struct ErrorHandler* error_logger = (struct ErrorHandler*)png_get_error_ptr(png_ptr);
|
|
||||||
error_logger->StoreError(error_logger, msg);
|
|
||||||
png_longjmp(png_ptr, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PngWarning(png_structp png_ptr, png_const_charp msg)
|
|
||||||
{
|
|
||||||
struct ErrorHandler* error_logger = (struct ErrorHandler*)png_get_error_ptr(png_ptr);
|
|
||||||
error_logger->StoreWarning(error_logger, msg);
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
// Copyright 2021 Dolphin Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <png.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
struct ErrorHandler
|
|
||||||
{
|
|
||||||
void* error_list; // std::vector<std::string>*
|
|
||||||
void* warning_list; // std::vector<std::string>*
|
|
||||||
void (*StoreError)(struct ErrorHandler* self, const char* msg);
|
|
||||||
void (*StoreWarning)(struct ErrorHandler* self, const char* msg);
|
|
||||||
};
|
|
||||||
|
|
||||||
bool SavePNG0(png_structp png_ptr, png_infop info_ptr, int color_type, png_uint_32 width,
|
|
||||||
png_uint_32 height, int level, png_voidp io_ptr, png_rw_ptr write_fn,
|
|
||||||
png_bytepp row_pointers);
|
|
||||||
|
|
||||||
void PngError(png_structp png_ptr, png_const_charp msg);
|
|
||||||
void PngWarning(png_structp png_ptr, png_const_charp msg);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -111,7 +111,6 @@
|
||||||
<ClInclude Include="Common\HRWrap.h" />
|
<ClInclude Include="Common\HRWrap.h" />
|
||||||
<ClInclude Include="Common\HttpRequest.h" />
|
<ClInclude Include="Common\HttpRequest.h" />
|
||||||
<ClInclude Include="Common\Image.h" />
|
<ClInclude Include="Common\Image.h" />
|
||||||
<ClInclude Include="Common\ImageC.h" />
|
|
||||||
<ClInclude Include="Common\IniFile.h" />
|
<ClInclude Include="Common\IniFile.h" />
|
||||||
<ClInclude Include="Common\Inline.h" />
|
<ClInclude Include="Common\Inline.h" />
|
||||||
<ClInclude Include="Common\Intrinsics.h" />
|
<ClInclude Include="Common\Intrinsics.h" />
|
||||||
|
@ -740,11 +739,6 @@
|
||||||
<ClCompile Include="Common\HRWrap.cpp" />
|
<ClCompile Include="Common\HRWrap.cpp" />
|
||||||
<ClCompile Include="Common\HttpRequest.cpp" />
|
<ClCompile Include="Common\HttpRequest.cpp" />
|
||||||
<ClCompile Include="Common\Image.cpp" />
|
<ClCompile Include="Common\Image.cpp" />
|
||||||
<ClCompile Include="Common\ImageC.c">
|
|
||||||
<!-- This is a C file, not a C++ file, so we can't use the C++ pre-compiled header -->
|
|
||||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
|
||||||
<ForcedIncludeFiles />
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Common\IniFile.cpp" />
|
<ClCompile Include="Common\IniFile.cpp" />
|
||||||
<ClCompile Include="Common\IOFile.cpp" />
|
<ClCompile Include="Common\IOFile.cpp" />
|
||||||
<ClCompile Include="Common\JitRegister.cpp" />
|
<ClCompile Include="Common\JitRegister.cpp" />
|
||||||
|
|
|
@ -79,7 +79,7 @@ PUBLIC
|
||||||
|
|
||||||
PRIVATE
|
PRIVATE
|
||||||
fmt::fmt
|
fmt::fmt
|
||||||
png
|
spng
|
||||||
)
|
)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
|
|
|
@ -164,7 +164,7 @@ PUBLIC
|
||||||
core
|
core
|
||||||
PRIVATE
|
PRIVATE
|
||||||
fmt::fmt
|
fmt::fmt
|
||||||
png
|
spng
|
||||||
xxhash
|
xxhash
|
||||||
imgui
|
imgui
|
||||||
glslang
|
glslang
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
<AdditionalIncludeDirectories>$(ExternalsDir)spirv_cross\SPIRV-Cross;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>$(ExternalsDir)spirv_cross\SPIRV-Cross;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<AdditionalIncludeDirectories>$(ExternalsDir)imgui;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>$(ExternalsDir)imgui;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<AdditionalIncludeDirectories>$(ExternalsDir)liblzma\api;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>$(ExternalsDir)liblzma\api;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<AdditionalIncludeDirectories>$(ExternalsDir)libpng;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>$(ExternalsDir)libspng\libspng\spng;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<AdditionalIncludeDirectories>$(ExternalsDir)libusb\libusb\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>$(ExternalsDir)libusb\libusb\libusb;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<AdditionalIncludeDirectories>$(ExternalsDir)LZO;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>$(ExternalsDir)LZO;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<AdditionalIncludeDirectories>$(ExternalsDir)mGBA\mgba\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>$(ExternalsDir)mGBA\mgba\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
@ -94,6 +94,7 @@
|
||||||
<PreprocessorDefinitions>AUTOUPDATE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>AUTOUPDATE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<PreprocessorDefinitions>SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<PreprocessorDefinitions>HAVE_SDL2=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>HAVE_SDL2=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<PreprocessorDefinitions>SPNG_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<!--
|
<!--
|
||||||
Make sure we include a clean version of windows.h.
|
Make sure we include a clean version of windows.h.
|
||||||
-->
|
-->
|
||||||
|
|
|
@ -27,8 +27,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LZO", "..\Externals\LZO\LZO
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniupnpc", "..\Externals\miniupnpc\miniupnpc.vcxproj", "{31643FDB-1BB8-4965-9DE7-000FC88D35AE}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniupnpc", "..\Externals\miniupnpc\miniupnpc.vcxproj", "{31643FDB-1BB8-4965-9DE7-000FC88D35AE}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "png", "..\Externals\libpng\png\png.vcxproj", "{4C9F135B-A85E-430C-BAD4-4C67EF5FC12C}"
|
|
||||||
EndProject
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xxhash", "..\Externals\xxhash\xxhash.vcxproj", "{677EA016-1182-440C-9345-DC88D1E98C0C}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xxhash", "..\Externals\xxhash\xxhash.vcxproj", "{677EA016-1182-440C-9345-DC88D1E98C0C}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib-ng", "..\Externals\zlib-ng\zlib-ng.vcxproj", "{F6EA7144-8D64-4EBB-A13E-76DFBD911EAE}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib-ng", "..\Externals\zlib-ng\zlib-ng.vcxproj", "{F6EA7144-8D64-4EBB-A13E-76DFBD911EAE}"
|
||||||
|
@ -85,6 +83,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDL2", "..\Externals\SDL\SD
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FatFs", "..\Externals\FatFs\FatFs.vcxproj", "{3F17D282-A77D-4931-B844-903AD0809A5E}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FatFs", "..\Externals\FatFs\FatFs.vcxproj", "{3F17D282-A77D-4931-B844-903AD0809A5E}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "spng", "..\Externals\libspng\spng.vcxproj", "{447B7B1E-1D74-4AEF-B2B9-6EB41C5D5313}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|ARM64 = Debug|ARM64
|
Debug|ARM64 = Debug|ARM64
|
||||||
|
@ -177,14 +177,6 @@ Global
|
||||||
{31643FDB-1BB8-4965-9DE7-000FC88D35AE}.Release|ARM64.Build.0 = Release|ARM64
|
{31643FDB-1BB8-4965-9DE7-000FC88D35AE}.Release|ARM64.Build.0 = Release|ARM64
|
||||||
{31643FDB-1BB8-4965-9DE7-000FC88D35AE}.Release|x64.ActiveCfg = Release|x64
|
{31643FDB-1BB8-4965-9DE7-000FC88D35AE}.Release|x64.ActiveCfg = Release|x64
|
||||||
{31643FDB-1BB8-4965-9DE7-000FC88D35AE}.Release|x64.Build.0 = Release|x64
|
{31643FDB-1BB8-4965-9DE7-000FC88D35AE}.Release|x64.Build.0 = Release|x64
|
||||||
{4C9F135B-A85E-430C-BAD4-4C67EF5FC12C}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
|
||||||
{4C9F135B-A85E-430C-BAD4-4C67EF5FC12C}.Debug|ARM64.Build.0 = Debug|ARM64
|
|
||||||
{4C9F135B-A85E-430C-BAD4-4C67EF5FC12C}.Debug|x64.ActiveCfg = Debug|x64
|
|
||||||
{4C9F135B-A85E-430C-BAD4-4C67EF5FC12C}.Debug|x64.Build.0 = Debug|x64
|
|
||||||
{4C9F135B-A85E-430C-BAD4-4C67EF5FC12C}.Release|ARM64.ActiveCfg = Release|ARM64
|
|
||||||
{4C9F135B-A85E-430C-BAD4-4C67EF5FC12C}.Release|ARM64.Build.0 = Release|ARM64
|
|
||||||
{4C9F135B-A85E-430C-BAD4-4C67EF5FC12C}.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{4C9F135B-A85E-430C-BAD4-4C67EF5FC12C}.Release|x64.Build.0 = Release|x64
|
|
||||||
{677EA016-1182-440C-9345-DC88D1E98C0C}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
{677EA016-1182-440C-9345-DC88D1E98C0C}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||||
{677EA016-1182-440C-9345-DC88D1E98C0C}.Debug|ARM64.Build.0 = Debug|ARM64
|
{677EA016-1182-440C-9345-DC88D1E98C0C}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||||
{677EA016-1182-440C-9345-DC88D1E98C0C}.Debug|x64.ActiveCfg = Debug|x64
|
{677EA016-1182-440C-9345-DC88D1E98C0C}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
@ -409,6 +401,14 @@ Global
|
||||||
{3F17D282-A77D-4931-B844-903AD0809A5E}.Release|ARM64.Build.0 = Release|ARM64
|
{3F17D282-A77D-4931-B844-903AD0809A5E}.Release|ARM64.Build.0 = Release|ARM64
|
||||||
{3F17D282-A77D-4931-B844-903AD0809A5E}.Release|x64.ActiveCfg = Release|x64
|
{3F17D282-A77D-4931-B844-903AD0809A5E}.Release|x64.ActiveCfg = Release|x64
|
||||||
{3F17D282-A77D-4931-B844-903AD0809A5E}.Release|x64.Build.0 = Release|x64
|
{3F17D282-A77D-4931-B844-903AD0809A5E}.Release|x64.Build.0 = Release|x64
|
||||||
|
{447B7B1E-1D74-4AEF-B2B9-6EB41C5D5313}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||||
|
{447B7B1E-1D74-4AEF-B2B9-6EB41C5D5313}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||||
|
{447B7B1E-1D74-4AEF-B2B9-6EB41C5D5313}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{447B7B1E-1D74-4AEF-B2B9-6EB41C5D5313}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{447B7B1E-1D74-4AEF-B2B9-6EB41C5D5313}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||||
|
{447B7B1E-1D74-4AEF-B2B9-6EB41C5D5313}.Release|ARM64.Build.0 = Release|ARM64
|
||||||
|
{447B7B1E-1D74-4AEF-B2B9-6EB41C5D5313}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{447B7B1E-1D74-4AEF-B2B9-6EB41C5D5313}.Release|x64.Build.0 = Release|x64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@ -417,7 +417,6 @@ Global
|
||||||
{8ADA04D7-6DB1-4DA4-AB55-64FB12A0997B} = {87ADDFF9-5768-4DA2-A33B-2477593D6677}
|
{8ADA04D7-6DB1-4DA4-AB55-64FB12A0997B} = {87ADDFF9-5768-4DA2-A33B-2477593D6677}
|
||||||
{AB993F38-C31D-4897-B139-A620C42BC565} = {87ADDFF9-5768-4DA2-A33B-2477593D6677}
|
{AB993F38-C31D-4897-B139-A620C42BC565} = {87ADDFF9-5768-4DA2-A33B-2477593D6677}
|
||||||
{31643FDB-1BB8-4965-9DE7-000FC88D35AE} = {87ADDFF9-5768-4DA2-A33B-2477593D6677}
|
{31643FDB-1BB8-4965-9DE7-000FC88D35AE} = {87ADDFF9-5768-4DA2-A33B-2477593D6677}
|
||||||
{4C9F135B-A85E-430C-BAD4-4C67EF5FC12C} = {87ADDFF9-5768-4DA2-A33B-2477593D6677}
|
|
||||||
{677EA016-1182-440C-9345-DC88D1E98C0C} = {87ADDFF9-5768-4DA2-A33B-2477593D6677}
|
{677EA016-1182-440C-9345-DC88D1E98C0C} = {87ADDFF9-5768-4DA2-A33B-2477593D6677}
|
||||||
{F6EA7144-8D64-4EBB-A13E-76DFBD911EAE} = {87ADDFF9-5768-4DA2-A33B-2477593D6677}
|
{F6EA7144-8D64-4EBB-A13E-76DFBD911EAE} = {87ADDFF9-5768-4DA2-A33B-2477593D6677}
|
||||||
{EC082900-B4D8-42E9-9663-77F02F6936AE} = {87ADDFF9-5768-4DA2-A33B-2477593D6677}
|
{EC082900-B4D8-42E9-9663-77F02F6936AE} = {87ADDFF9-5768-4DA2-A33B-2477593D6677}
|
||||||
|
@ -444,6 +443,7 @@ Global
|
||||||
{3D780617-EC8C-4721-B9FD-DFC9BB658C7C} = {87ADDFF9-5768-4DA2-A33B-2477593D6677}
|
{3D780617-EC8C-4721-B9FD-DFC9BB658C7C} = {87ADDFF9-5768-4DA2-A33B-2477593D6677}
|
||||||
{8DC244EE-A0BD-4038-BAF7-CFAFA5EB2BAA} = {87ADDFF9-5768-4DA2-A33B-2477593D6677}
|
{8DC244EE-A0BD-4038-BAF7-CFAFA5EB2BAA} = {87ADDFF9-5768-4DA2-A33B-2477593D6677}
|
||||||
{3F17D282-A77D-4931-B844-903AD0809A5E} = {87ADDFF9-5768-4DA2-A33B-2477593D6677}
|
{3F17D282-A77D-4931-B844-903AD0809A5E} = {87ADDFF9-5768-4DA2-A33B-2477593D6677}
|
||||||
|
{447B7B1E-1D74-4AEF-B2B9-6EB41C5D5313} = {87ADDFF9-5768-4DA2-A33B-2477593D6677}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {64B0A343-3B94-4522-9C24-6937FE5EFB22}
|
SolutionGuid = {64B0A343-3B94-4522-9C24-6937FE5EFB22}
|
||||||
|
|
Loading…
Reference in New Issue