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