1b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 2b50c217251b086440efcdb273c22f86a06c80cbaChris Craik/* arm_init.c - NEON optimised filter functions 3b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 47a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis * Copyright (c) 2014,2016 Glenn Randers-Pehrson 5b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * Written by Mans Rullgard, 2011. 67a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis * Last changed in libpng 1.6.22 [May 26, 2016] 7b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 8b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * This code is released under the libpng license. 9b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * For conditions of distribution and use, see the disclaimer 10b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * and license in png.h 11b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 12b50c217251b086440efcdb273c22f86a06c80cbaChris Craik/* Below, after checking __linux__, various non-C90 POSIX 1003.1 functions are 13b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * called. 14b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 15b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#define _POSIX_SOURCE 1 16b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 17b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#include "../pngpriv.h" 18b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 19b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_SUPPORTED 209b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett 21b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#if PNG_ARM_NEON_OPT > 0 22b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_ARM_NEON_CHECK_SUPPORTED /* Do run-time checks */ 23b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari/* WARNING: it is strongly recommended that you do not build libpng with 24b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * run-time checks for CPU features if at all possible. In the case of the ARM 25b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * NEON instructions there is no processor-specific way of detecting the 269b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett * presence of the required support, therefore run-time detection is extremely 27b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * OS specific. 28b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 29b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * You may set the macro PNG_ARM_NEON_FILE to the file name of file containing 30b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * a fragment of C source code which defines the png_have_neon function. There 31b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * are a number of implementations in contrib/arm-neon, but the only one that 32b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * has partial support is contrib/arm-neon/linux.c - a generic Linux 33b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * implementation which reads /proc/cpufino. 34b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 35b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifndef PNG_ARM_NEON_FILE 36b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari# ifdef __linux__ 37b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari# define PNG_ARM_NEON_FILE "contrib/arm-neon/linux.c" 38b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari# endif 39b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif 40b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 41b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#ifdef PNG_ARM_NEON_FILE 42b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 43b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#include <signal.h> /* for sig_atomic_t */ 44b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripuraristatic int png_have_neon(png_structp png_ptr); 45b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#include PNG_ARM_NEON_FILE 46b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 47b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#else /* PNG_ARM_NEON_FILE */ 48b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari# error "PNG_ARM_NEON_FILE undefined: no support for run-time ARM NEON checks" 49b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari#endif /* PNG_ARM_NEON_FILE */ 50b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif /* PNG_ARM_NEON_CHECK_SUPPORTED */ 51b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 52b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifndef PNG_ALIGNED_MEMORY_SUPPORTED 53b50c217251b086440efcdb273c22f86a06c80cbaChris Craik# error "ALIGNED_MEMORY is required; set: -DPNG_ALIGNED_MEMORY_SUPPORTED" 54b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif 55b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 56b50c217251b086440efcdb273c22f86a06c80cbaChris Craikvoid 57b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_init_filter_functions_neon(png_structp pp, unsigned int bpp) 58b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{ 59b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari /* The switch statement is compiled in for ARM_NEON_API, the call to 60b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * png_have_neon is compiled in for ARM_NEON_CHECK. If both are defined 61b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * the check is only performed if the API has not set the NEON option on 62b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * or off explicitly. In this case the check controls what happens. 63b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * 64b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * If the CHECK is not compiled in and the option is UNSET the behavior prior 65b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * to 1.6.7 was to use the NEON code - this was a bug caused by having the 66b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * wrong order of the 'ON' and 'default' cases. UNSET now defaults to OFF, 67b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * as documented in png.h 68b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari */ 697a055fdaacbcb54d3606638017fb3381f05d96acAlex Naidis png_debug(1, "in png_init_filter_functions_neon"); 70b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_ARM_NEON_API_SUPPORTED 71b50c217251b086440efcdb273c22f86a06c80cbaChris Craik switch ((pp->options >> PNG_ARM_NEON) & 3) 72b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 73b50c217251b086440efcdb273c22f86a06c80cbaChris Craik case PNG_OPTION_UNSET: 74b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Allow the run-time check to execute if it has been enabled - 75b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * thus both API and CHECK can be turned on. If it isn't supported 76b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * this case will fall through to the 'default' below, which just 77b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * returns. 78b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 79b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif /* PNG_ARM_NEON_API_SUPPORTED */ 80b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_ARM_NEON_CHECK_SUPPORTED 81b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 82b50c217251b086440efcdb273c22f86a06c80cbaChris Craik static volatile sig_atomic_t no_neon = -1; /* not checked */ 83b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 84b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (no_neon < 0) 85b50c217251b086440efcdb273c22f86a06c80cbaChris Craik no_neon = !png_have_neon(pp); 86b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 87b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (no_neon) 88b50c217251b086440efcdb273c22f86a06c80cbaChris Craik return; 89b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 90b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_ARM_NEON_API_SUPPORTED 91b50c217251b086440efcdb273c22f86a06c80cbaChris Craik break; 92b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif 93b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif /* PNG_ARM_NEON_CHECK_SUPPORTED */ 94b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 95b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_ARM_NEON_API_SUPPORTED 96b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari default: /* OFF or INVALID */ 97b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari return; 98b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 99b50c217251b086440efcdb273c22f86a06c80cbaChris Craik case PNG_OPTION_ON: 100b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Option turned on */ 101b50c217251b086440efcdb273c22f86a06c80cbaChris Craik break; 102b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 103b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif 104b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 105b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* IMPORTANT: any new external functions used here must be declared using 106b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * PNG_INTERNAL_FUNCTION in ../pngpriv.h. This is required so that the 107b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 'prefix' option to configure works: 108b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 109b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * ./configure --with-libpng-prefix=foobar_ 110b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 111b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * Verify you have got this right by running the above command, doing a build 112b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * and examining pngprefix.h; it must contain a #define for every external 113b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * function you add. (Notice that this happens automatically for the 114b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * initialization function.) 115b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 116b50c217251b086440efcdb273c22f86a06c80cbaChris Craik pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up_neon; 117b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 118b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (bpp == 3) 119b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 120b50c217251b086440efcdb273c22f86a06c80cbaChris Craik pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_neon; 121b50c217251b086440efcdb273c22f86a06c80cbaChris Craik pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_neon; 122b50c217251b086440efcdb273c22f86a06c80cbaChris Craik pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = 123b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_read_filter_row_paeth3_neon; 124b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 125b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 126b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (bpp == 4) 127b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 128b50c217251b086440efcdb273c22f86a06c80cbaChris Craik pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_neon; 129b50c217251b086440efcdb273c22f86a06c80cbaChris Craik pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_neon; 130b50c217251b086440efcdb273c22f86a06c80cbaChris Craik pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = 131b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_read_filter_row_paeth4_neon; 132b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 133b50c217251b086440efcdb273c22f86a06c80cbaChris Craik} 134b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif /* PNG_ARM_NEON_OPT > 0 */ 1359b1fe63dcc7ba076b9730b7bfa031cc0dbc25561Matt Sarett#endif /* READ */ 136