diff --git a/pngrutil.c b/pngrutil.c index fc450ea63..8ad1a67c5 100644 --- a/pngrutil.c +++ b/pngrutil.c @@ -3668,22 +3668,64 @@ png_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row, } #ifdef PNG_ARM_NEON + +#ifdef __linux__ +#include +#include +#include + +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__ */ + static void png_init_filter_functions_neon(png_structp pp, unsigned int bpp) { +#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) { + 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_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; + pp->read_filter[PNG_FILTER_VALUE_PAETH-1] = + png_read_filter_row_paeth4_neon; } } -#endif +#endif /* PNG_ARM_NEON */ static void png_init_filter_functions(png_structp pp)