diff options
author | John Bowler <jbowler@acm.org> | 2012-12-14 23:12:16 -0600 |
---|---|---|
committer | Glenn Randers-Pehrson <glennrp at users.sourceforge.net> | 2012-12-14 23:12:16 -0600 |
commit | 0f2a5bac645016cb5d2f5c3b9816767ee45d6143 (patch) | |
tree | 471d4b43070a3abd2ea42af80c110e350a95b74c /arm | |
parent | eac85878bf93dfad3a90d34fe10178f317c9ec58 (diff) | |
download | libpng-0f2a5bac645016cb5d2f5c3b9816767ee45d6143.tar.gz |
[libpng17] Rearranged ARM-NEON optimizations to isolate the machine specific
code to the hardware subdirectory, and add comments to pngrutil.c so that
implementors of other optimizations will know what to do.
Diffstat (limited to 'arm')
-rw-r--r-- | arm/arm_init.c | 74 | ||||
-rw-r--r-- | arm/filter_neon.S | 2 |
2 files changed, 76 insertions, 0 deletions
diff --git a/arm/arm_init.c b/arm/arm_init.c new file mode 100644 index 000000000..6b0a925f2 --- /dev/null +++ b/arm/arm_init.c @@ -0,0 +1,74 @@ + +/* filter_neon.S - NEON optimised filter functions + * + * Copyright (c) 2011 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 + */ +#include "../pngpriv.h" + +/* __arm__ is defined by GCC, MSVC defines _M_ARM to the ARM version number */ +#if defined __linux__ && defined __arm__ +#include <stdio.h> +#include <elf.h> +#include <asm/hwcap.h> + +static int png_have_hwcap(unsigned cap) +{ + FILE *f = fopen("/proc/self/auxv", "r"); + Elf32_auxv_t aux; + int have_cap = 0; + + if (!f) + return 0; + + while (fread(&aux, sizeof(aux), 1, f) > 0) + { + if (aux.a_type == AT_HWCAP && + aux.a_un.a_val & cap) + { + have_cap = 1; + break; + } + } + + fclose(f); + + return have_cap; +} +#endif /* __linux__ && __arm__ */ + +void +png_init_filter_functions_neon(png_structp pp, unsigned int bpp) +{ +#ifdef __arm__ +#ifdef __linux__ + if (!png_have_hwcap(HWCAP_NEON)) + return; +#endif + + 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; + } +#else + PNG_UNUSED(pp) + PNG_UNUSED(bpp) +#endif +} diff --git a/arm/filter_neon.S b/arm/filter_neon.S index 63a5d8c17..9ce04d3be 100644 --- a/arm/filter_neon.S +++ b/arm/filter_neon.S @@ -9,6 +9,7 @@ * and license in png.h */ +#ifdef __arm__ #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits /* mark stack as non-executable */ #endif @@ -223,3 +224,4 @@ func png_read_filter_row_paeth3_neon, export=1 pop {r4,pc} endfunc +#endif |