Skip to content

Commit

Permalink
libpng: New version 1.6.27
Browse files Browse the repository at this point in the history
Warning: libpng 1.6 is strict about iCCp chunks being incorrect,
solution is to fix the profile. On *nix ImageMagicks "convert" works
on windows optiPNG.
  • Loading branch information
J08nY committed Jun 22, 2016
1 parent 842e7bf commit f0290e6
Show file tree
Hide file tree
Showing 26 changed files with 15,549 additions and 8,680 deletions.
151 changes: 27 additions & 124 deletions drivers/png/arm/arm_init.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@

/* arm_init.c - NEON optimised filter functions
*
* Copyright (c) 2013 Glenn Randers-Pehrson
* Copyright (c) 2014,2016 Glenn Randers-Pehrson
* Written by Mans Rullgard, 2011.
* Last changed in libpng 1.6.8 [December 19, 2013]
* Last changed in libpng 1.6.22 [June 9, 2016]
*
* This code is released under the libpng license.
* For conditions of distribution and use, see the disclaimer
Expand All @@ -17,134 +17,36 @@
#include "../pngpriv.h"

#ifdef PNG_READ_SUPPORTED

#if PNG_ARM_NEON_OPT > 0
#ifdef PNG_ARM_NEON_CHECK_SUPPORTED /* Do run-time checks */
#include <signal.h> /* for sig_atomic_t */

#ifdef __ANDROID__
/* Linux provides access to information about CPU capabilites via
* /proc/self/auxv, however Android blocks this while still claiming to be
* Linux. The Andoid NDK, however, provides appropriate support.
/* 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.
*
* Documentation: http://www.kandroid.org/ndk/docs/CPU-ARM-NEON.html
*/
#include <cpu-features.h>

static int
png_have_neon(png_structp png_ptr)
{
/* This is a whole lot easier than the mess below, however it is probably
* implemented as below, therefore it is better to cache the result (these
* function calls may be slow!)
*/
PNG_UNUSED(png_ptr)
return android_getCpuFamily() == ANDROID_CPU_FAMILY_ARM &&
(android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0;
}
#elif defined(__linux__)
/* The generic __linux__ implementation requires reading /proc/self/auxv and
* looking at each element for one that records NEON capabilities.
*/
#include <unistd.h> /* for POSIX 1003.1 */
#include <errno.h> /* for EINTR */

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <elf.h>
#include <asm/hwcap.h>

/* A read call may be interrupted, in which case it returns -1 and sets errno to
* EINTR if nothing was done, otherwise (if something was done) a partial read
* may result.
* 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.
*/
static size_t
safe_read(png_structp png_ptr, int fd, void *buffer_in, size_t nbytes)
{
size_t ntotal = 0;
char *buffer = png_voidcast(char*, buffer_in);

while (nbytes > 0)
{
unsigned int nread;
int iread;

/* Passing nread > INT_MAX to read is implementation defined in POSIX
* 1003.1, therefore despite the unsigned argument portable code must
* limit the value to INT_MAX!
*/
if (nbytes > INT_MAX)
nread = INT_MAX;

else
nread = (unsigned int)/*SAFE*/nbytes;

iread = read(fd, buffer, nread);

if (iread == -1)
{
/* This is the devil in the details, a read can terminate early with 0
* bytes read because of EINTR, yet it still returns -1 otherwise end
* of file cannot be distinguished.
*/
if (errno != EINTR)
{
png_warning(png_ptr, "/proc read failed");
return 0; /* I.e., a permanent failure */
}
}

else if (iread < 0)
{
/* Not a valid 'read' result: */
png_warning(png_ptr, "OS /proc read bug");
return 0;
}

else if (iread > 0)
{
/* Continue reading until a permanent failure, or EOF */
buffer += iread;
nbytes -= (unsigned int)/*SAFE*/iread;
ntotal += (unsigned int)/*SAFE*/iread;
}

else
return ntotal;
}

return ntotal; /* nbytes == 0 */
}
#ifndef PNG_ARM_NEON_FILE
# ifdef __linux__
# define PNG_ARM_NEON_FILE "contrib/arm-neon/linux.c"
# endif
#endif

static int
png_have_neon(png_structp png_ptr)
{
int fd = open("/proc/self/auxv", O_RDONLY);
Elf32_auxv_t aux;
#ifdef PNG_ARM_NEON_FILE

/* Failsafe: failure to open means no NEON */
if (fd == -1)
{
png_warning(png_ptr, "/proc/self/auxv open failed");
return 0;
}

while (safe_read(png_ptr, fd, &aux, sizeof aux) == sizeof aux)
{
if (aux.a_type == AT_HWCAP && (aux.a_un.a_val & HWCAP_NEON) != 0)
{
close(fd);
return 1;
}
}
#include <signal.h> /* for sig_atomic_t */
static int png_have_neon(png_structp png_ptr);
#include PNG_ARM_NEON_FILE

close(fd);
return 0;
}
#else
/* We don't know how to do a run-time check on this system */
# error "no support for run-time ARM NEON checks"
#endif /* OS checks */
#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
Expand All @@ -164,6 +66,7 @@ png_init_filter_functions_neon(png_structp pp, unsigned int bpp)
* 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)
{
Expand Down Expand Up @@ -229,4 +132,4 @@ png_init_filter_functions_neon(png_structp pp, unsigned int bpp)
}
}
#endif /* PNG_ARM_NEON_OPT > 0 */
#endif /* PNG_READ_SUPPORTED */
#endif /* READ */
26 changes: 22 additions & 4 deletions drivers/png/arm/filter_neon.S
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@

/* filter_neon.S - NEON optimised filter functions
*
* Copyright (c) 2013 Glenn Randers-Pehrson
* Copyright (c) 2014 Glenn Randers-Pehrson
* Written by Mans Rullgard, 2011.
* Last changed in libpng 1.5.17 [June 27, 2013]
* Last changed in libpng 1.6.16 [December 22, 2014]
*
* 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 also
* includes the definition (or not) of PNG_ARM_NEON_OPT.
/* 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"
Expand All @@ -20,6 +20,15 @@
.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__
Expand All @@ -38,6 +47,13 @@ ELF .size \name, . - \name
.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
Expand Down Expand Up @@ -233,3 +249,5 @@ func png_read_filter_row_paeth3_neon, export=1
pop {r4,pc}
endfunc
#endif /* PNG_ARM_NEON_OPT > 0 */
#endif /* PNG_ARM_NEON_IMPLEMENTATION == 2 (assembler) */
#endif /* READ */
Loading

1 comment on commit f0290e6

@akien-mga
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the reference, this was libpng 1.6.23 and not 1.6.27 :)

Please sign in to comment.