summaryrefslogtreecommitdiff
path: root/arm
diff options
context:
space:
mode:
authorJohn Bowler <jbowler@acm.org>2012-12-14 23:12:16 -0600
committerGlenn Randers-Pehrson <glennrp at users.sourceforge.net>2012-12-14 23:12:16 -0600
commit0f2a5bac645016cb5d2f5c3b9816767ee45d6143 (patch)
tree471d4b43070a3abd2ea42af80c110e350a95b74c /arm
parenteac85878bf93dfad3a90d34fe10178f317c9ec58 (diff)
downloadlibpng-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.c74
-rw-r--r--arm/filter_neon.S2
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