/src/astc-encoder/Source/astcenc_mathlib.h
Line | Count | Source |
1 | | // SPDX-License-Identifier: Apache-2.0 |
2 | | // ---------------------------------------------------------------------------- |
3 | | // Copyright 2011-2025 Arm Limited |
4 | | // |
5 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not |
6 | | // use this file except in compliance with the License. You may obtain a copy |
7 | | // of the License at: |
8 | | // |
9 | | // http://www.apache.org/licenses/LICENSE-2.0 |
10 | | // |
11 | | // Unless required by applicable law or agreed to in writing, software |
12 | | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
13 | | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
14 | | // License for the specific language governing permissions and limitations |
15 | | // under the License. |
16 | | // ---------------------------------------------------------------------------- |
17 | | |
18 | | /* |
19 | | * This module implements a variety of mathematical data types and library |
20 | | * functions used by the codec. |
21 | | */ |
22 | | |
23 | | #ifndef ASTC_MATHLIB_H_INCLUDED |
24 | | #define ASTC_MATHLIB_H_INCLUDED |
25 | | |
26 | | #include <cassert> |
27 | | #include <cstdint> |
28 | | #include <cmath> |
29 | | #include <cstring> |
30 | | |
31 | | #ifndef ASTCENC_POPCNT |
32 | | #if defined(__POPCNT__) |
33 | | #define ASTCENC_POPCNT 1 |
34 | | #else |
35 | | #define ASTCENC_POPCNT 0 |
36 | | #endif |
37 | | #endif |
38 | | |
39 | | #ifndef ASTCENC_F16C |
40 | | #if defined(__F16C__) |
41 | | #define ASTCENC_F16C 1 |
42 | | #else |
43 | | #define ASTCENC_F16C 0 |
44 | | #endif |
45 | | #endif |
46 | | |
47 | | #ifndef ASTCENC_SSE |
48 | | #if defined(__SSE4_2__) |
49 | | #define ASTCENC_SSE 42 |
50 | | #elif defined(__SSE4_1__) |
51 | | #define ASTCENC_SSE 41 |
52 | | #elif defined(__SSE2__) || (defined(_M_AMD64) && !defined(_M_ARM64EC)) |
53 | | #define ASTCENC_SSE 20 |
54 | | #else |
55 | | #define ASTCENC_SSE 0 |
56 | | #endif |
57 | | #endif |
58 | | |
59 | | #ifndef ASTCENC_AVX |
60 | | #if defined(__AVX2__) |
61 | | #define ASTCENC_AVX 2 |
62 | | #define ASTCENC_X86_GATHERS 1 |
63 | | #elif defined(__AVX__) |
64 | | #define ASTCENC_AVX 1 |
65 | | #define ASTCENC_X86_GATHERS 1 |
66 | | #else |
67 | | #define ASTCENC_AVX 0 |
68 | | #endif |
69 | | #endif |
70 | | |
71 | | #ifndef ASTCENC_NEON |
72 | | #if defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC) |
73 | | #define ASTCENC_NEON 1 |
74 | | #else |
75 | | #define ASTCENC_NEON 0 |
76 | | #endif |
77 | | #endif |
78 | | |
79 | | #ifndef ASTCENC_SVE |
80 | | #if defined(__ARM_FEATURE_SVE) |
81 | | #if defined(__ARM_FEATURE_SVE_BITS) && __ARM_FEATURE_SVE_BITS == 256 |
82 | | #define ASTCENC_SVE 8 |
83 | | // Auto-detected SVE can only assume vector width of 4 is available, but |
84 | | // must also allow for hardware being longer and so all use of intrinsics |
85 | | // must explicitly use predicate masks to limit to 4-wide. |
86 | | #else |
87 | | #define ASTCENC_SVE 4 |
88 | | #endif |
89 | | #else |
90 | | #define ASTCENC_SVE 0 |
91 | | #endif |
92 | | #endif |
93 | | |
94 | | // Force vector-sized SIMD alignment |
95 | | #if ASTCENC_AVX || ASTCENC_SVE == 8 |
96 | | #define ASTCENC_VECALIGN 32 |
97 | | #elif ASTCENC_SSE || ASTCENC_NEON || ASTCENC_SVE == 4 |
98 | | #define ASTCENC_VECALIGN 16 |
99 | | // Use default alignment for non-SIMD builds |
100 | | #else |
101 | | #define ASTCENC_VECALIGN 0 |
102 | | #endif |
103 | | |
104 | | // C++11 states that alignas(0) should be ignored but GCC doesn't do |
105 | | // this on some versions, so workaround and avoid emitting alignas(0) |
106 | | #if ASTCENC_VECALIGN > 0 |
107 | | #define ASTCENC_ALIGNAS alignas(ASTCENC_VECALIGN) |
108 | | #else |
109 | | #define ASTCENC_ALIGNAS |
110 | | #endif |
111 | | |
112 | | #if ASTCENC_SSE != 0 || ASTCENC_AVX != 0 || ASTCENC_POPCNT != 0 |
113 | | #include <immintrin.h> |
114 | | #endif |
115 | | |
116 | | /* ============================================================================ |
117 | | Fast math library; note that many of the higher-order functions in this set |
118 | | use approximations which are less accurate, but faster, than <cmath> standard |
119 | | library equivalents. |
120 | | |
121 | | Note: Many of these are not necessarily faster than simple C versions when |
122 | | used on a single scalar value, but are included for testing purposes as most |
123 | | have an option based on SSE intrinsics and therefore provide an obvious route |
124 | | to future vectorization. |
125 | | ============================================================================ */ |
126 | | |
127 | | // These are namespaced to avoid colliding with C standard library functions. |
128 | | namespace astc |
129 | | { |
130 | | |
131 | | static const float PI = 3.14159265358979323846f; |
132 | | static const float PI_OVER_TWO = 1.57079632679489661923f; |
133 | | |
134 | | /** |
135 | | * @brief SP float absolute value. |
136 | | * |
137 | | * @param v The value to make absolute. |
138 | | * |
139 | | * @return The absolute value. |
140 | | */ |
141 | | static inline float fabs(float v) |
142 | 0 | { |
143 | 0 | return std::fabs(v); |
144 | 0 | } Unexecuted instantiation: fuzz_astc_physical_to_symbolic.cpp:astc::fabs(float) Unexecuted instantiation: astcenc_block_sizes.cpp:astc::fabs(float) Unexecuted instantiation: astcenc_integer_sequence.cpp:astc::fabs(float) Unexecuted instantiation: astcenc_mathlib.cpp:astc::fabs(float) Unexecuted instantiation: astcenc_partition_tables.cpp:astc::fabs(float) Unexecuted instantiation: astcenc_percentile_tables.cpp:astc::fabs(float) Unexecuted instantiation: astcenc_symbolic_physical.cpp:astc::fabs(float) Unexecuted instantiation: astcenc_weight_quant_xfer_tables.cpp:astc::fabs(float) Unexecuted instantiation: astcenc_quantization.cpp:astc::fabs(float) |
145 | | |
146 | | /** |
147 | | * @brief Test if a float value is a nan. |
148 | | * |
149 | | * @param v The value test. |
150 | | * |
151 | | * @return Zero is not a NaN, non-zero otherwise. |
152 | | */ |
153 | | static inline bool isnan(float v) |
154 | 0 | { |
155 | 0 | return v != v; |
156 | 0 | } Unexecuted instantiation: fuzz_astc_physical_to_symbolic.cpp:astc::isnan(float) Unexecuted instantiation: astcenc_block_sizes.cpp:astc::isnan(float) Unexecuted instantiation: astcenc_integer_sequence.cpp:astc::isnan(float) Unexecuted instantiation: astcenc_mathlib.cpp:astc::isnan(float) Unexecuted instantiation: astcenc_partition_tables.cpp:astc::isnan(float) Unexecuted instantiation: astcenc_percentile_tables.cpp:astc::isnan(float) Unexecuted instantiation: astcenc_symbolic_physical.cpp:astc::isnan(float) Unexecuted instantiation: astcenc_weight_quant_xfer_tables.cpp:astc::isnan(float) Unexecuted instantiation: astcenc_quantization.cpp:astc::isnan(float) |
157 | | |
158 | | /** |
159 | | * @brief Return the minimum of two values. |
160 | | * |
161 | | * For floats, NaNs are turned into @c q. |
162 | | * |
163 | | * @param p The first value to compare. |
164 | | * @param q The second value to compare. |
165 | | * |
166 | | * @return The smallest value. |
167 | | */ |
168 | | template<typename T> |
169 | | static inline T min(T p, T q) |
170 | 13.2k | { |
171 | 13.2k | return p < q ? p : q; |
172 | 13.2k | } astcenc_partition_tables.cpp:unsigned char astc::min<unsigned char>(unsigned char, unsigned char) Line | Count | Source | 170 | 13.2k | { | 171 | 13.2k | return p < q ? p : q; | 172 | 13.2k | } |
Unexecuted instantiation: astcenc_symbolic_physical.cpp:int astc::min<int>(int, int) |
173 | | |
174 | | /** |
175 | | * @brief Return the minimum of three values. |
176 | | * |
177 | | * For floats, NaNs are turned into @c r. |
178 | | * |
179 | | * @param p The first value to compare. |
180 | | * @param q The second value to compare. |
181 | | * @param r The third value to compare. |
182 | | * |
183 | | * @return The smallest value. |
184 | | */ |
185 | | template<typename T> |
186 | | static inline T min(T p, T q, T r) |
187 | | { |
188 | | return min(min(p, q), r); |
189 | | } |
190 | | |
191 | | /** |
192 | | * @brief Return the minimum of four values. |
193 | | * |
194 | | * For floats, NaNs are turned into @c s. |
195 | | * |
196 | | * @param p The first value to compare. |
197 | | * @param q The second value to compare. |
198 | | * @param r The third value to compare. |
199 | | * @param s The fourth value to compare. |
200 | | * |
201 | | * @return The smallest value. |
202 | | */ |
203 | | template<typename T> |
204 | | static inline T min(T p, T q, T r, T s) |
205 | | { |
206 | | return min(min(p, q), min(r, s)); |
207 | | } |
208 | | |
209 | | /** |
210 | | * @brief Return the maximum of two values. |
211 | | * |
212 | | * For floats, NaNs are turned into @c q. |
213 | | * |
214 | | * @param p The first value to compare. |
215 | | * @param q The second value to compare. |
216 | | * |
217 | | * @return The largest value. |
218 | | */ |
219 | | template<typename T> |
220 | | static inline T max(T p, T q) |
221 | 110k | { |
222 | 110k | return p > q ? p : q; |
223 | 110k | } |
224 | | |
225 | | /** |
226 | | * @brief Return the maximum of three values. |
227 | | * |
228 | | * For floats, NaNs are turned into @c r. |
229 | | * |
230 | | * @param p The first value to compare. |
231 | | * @param q The second value to compare. |
232 | | * @param r The third value to compare. |
233 | | * |
234 | | * @return The largest value. |
235 | | */ |
236 | | template<typename T> |
237 | | static inline T max(T p, T q, T r) |
238 | | { |
239 | | return max(max(p, q), r); |
240 | | } |
241 | | |
242 | | /** |
243 | | * @brief Return the maximum of four values. |
244 | | * |
245 | | * For floats, NaNs are turned into @c s. |
246 | | * |
247 | | * @param p The first value to compare. |
248 | | * @param q The second value to compare. |
249 | | * @param r The third value to compare. |
250 | | * @param s The fourth value to compare. |
251 | | * |
252 | | * @return The largest value. |
253 | | */ |
254 | | template<typename T> |
255 | | static inline T max(T p, T q, T r, T s) |
256 | | { |
257 | | return max(max(p, q), max(r, s)); |
258 | | } |
259 | | |
260 | | /** |
261 | | * @brief Clamp a value value between @c mn and @c mx. |
262 | | * |
263 | | * For floats, NaNs are turned into @c mn. |
264 | | * |
265 | | * @param v The value to clamp. |
266 | | * @param mn The min value (inclusive). |
267 | | * @param mx The max value (inclusive). |
268 | | * |
269 | | * @return The clamped value. |
270 | | */ |
271 | | template<typename T> |
272 | | inline T clamp(T v, T mn, T mx) |
273 | 0 | { |
274 | 0 | // Do not reorder; correct NaN handling relies on the fact that comparison |
275 | 0 | // with NaN returns false and will fall-though to the "min" value. |
276 | 0 | if (v > mx) return mx; |
277 | 0 | if (v > mn) return v; |
278 | 0 | return mn; |
279 | 0 | } |
280 | | |
281 | | /** |
282 | | * @brief Clamp a float value between 0.0f and 1.0f. |
283 | | * |
284 | | * NaNs are turned into 0.0f. |
285 | | * |
286 | | * @param v The value to clamp. |
287 | | * |
288 | | * @return The clamped value. |
289 | | */ |
290 | | static inline float clamp1f(float v) |
291 | 0 | { |
292 | 0 | return astc::clamp(v, 0.0f, 1.0f); |
293 | 0 | } Unexecuted instantiation: fuzz_astc_physical_to_symbolic.cpp:astc::clamp1f(float) Unexecuted instantiation: astcenc_block_sizes.cpp:astc::clamp1f(float) Unexecuted instantiation: astcenc_integer_sequence.cpp:astc::clamp1f(float) Unexecuted instantiation: astcenc_mathlib.cpp:astc::clamp1f(float) Unexecuted instantiation: astcenc_partition_tables.cpp:astc::clamp1f(float) Unexecuted instantiation: astcenc_percentile_tables.cpp:astc::clamp1f(float) Unexecuted instantiation: astcenc_symbolic_physical.cpp:astc::clamp1f(float) Unexecuted instantiation: astcenc_weight_quant_xfer_tables.cpp:astc::clamp1f(float) Unexecuted instantiation: astcenc_quantization.cpp:astc::clamp1f(float) |
294 | | |
295 | | /** |
296 | | * @brief Clamp a float value between 0.0f and 255.0f. |
297 | | * |
298 | | * NaNs are turned into 0.0f. |
299 | | * |
300 | | * @param v The value to clamp. |
301 | | * |
302 | | * @return The clamped value. |
303 | | */ |
304 | | static inline float clamp255f(float v) |
305 | 0 | { |
306 | 0 | return astc::clamp(v, 0.0f, 255.0f); |
307 | 0 | } Unexecuted instantiation: fuzz_astc_physical_to_symbolic.cpp:astc::clamp255f(float) Unexecuted instantiation: astcenc_block_sizes.cpp:astc::clamp255f(float) Unexecuted instantiation: astcenc_integer_sequence.cpp:astc::clamp255f(float) Unexecuted instantiation: astcenc_mathlib.cpp:astc::clamp255f(float) Unexecuted instantiation: astcenc_partition_tables.cpp:astc::clamp255f(float) Unexecuted instantiation: astcenc_percentile_tables.cpp:astc::clamp255f(float) Unexecuted instantiation: astcenc_symbolic_physical.cpp:astc::clamp255f(float) Unexecuted instantiation: astcenc_weight_quant_xfer_tables.cpp:astc::clamp255f(float) Unexecuted instantiation: astcenc_quantization.cpp:astc::clamp255f(float) |
308 | | |
309 | | /** |
310 | | * @brief SP float round-down. |
311 | | * |
312 | | * @param v The value to round. |
313 | | * |
314 | | * @return The rounded value. |
315 | | */ |
316 | | static inline float flt_rd(float v) |
317 | 0 | { |
318 | 0 | return std::floor(v); |
319 | 0 | } Unexecuted instantiation: fuzz_astc_physical_to_symbolic.cpp:astc::flt_rd(float) Unexecuted instantiation: astcenc_block_sizes.cpp:astc::flt_rd(float) Unexecuted instantiation: astcenc_integer_sequence.cpp:astc::flt_rd(float) Unexecuted instantiation: astcenc_mathlib.cpp:astc::flt_rd(float) Unexecuted instantiation: astcenc_partition_tables.cpp:astc::flt_rd(float) Unexecuted instantiation: astcenc_percentile_tables.cpp:astc::flt_rd(float) Unexecuted instantiation: astcenc_symbolic_physical.cpp:astc::flt_rd(float) Unexecuted instantiation: astcenc_weight_quant_xfer_tables.cpp:astc::flt_rd(float) Unexecuted instantiation: astcenc_quantization.cpp:astc::flt_rd(float) |
320 | | |
321 | | /** |
322 | | * @brief SP float round-to-nearest and convert to integer. |
323 | | * |
324 | | * @param v The value to round. |
325 | | * |
326 | | * @return The rounded value. |
327 | | */ |
328 | | static inline int flt2int_rtn(float v) |
329 | 0 | { |
330 | 0 |
|
331 | 0 | return static_cast<int>(v + 0.5f); |
332 | 0 | } Unexecuted instantiation: fuzz_astc_physical_to_symbolic.cpp:astc::flt2int_rtn(float) Unexecuted instantiation: astcenc_block_sizes.cpp:astc::flt2int_rtn(float) Unexecuted instantiation: astcenc_integer_sequence.cpp:astc::flt2int_rtn(float) Unexecuted instantiation: astcenc_mathlib.cpp:astc::flt2int_rtn(float) Unexecuted instantiation: astcenc_partition_tables.cpp:astc::flt2int_rtn(float) Unexecuted instantiation: astcenc_percentile_tables.cpp:astc::flt2int_rtn(float) Unexecuted instantiation: astcenc_symbolic_physical.cpp:astc::flt2int_rtn(float) Unexecuted instantiation: astcenc_weight_quant_xfer_tables.cpp:astc::flt2int_rtn(float) Unexecuted instantiation: astcenc_quantization.cpp:astc::flt2int_rtn(float) |
333 | | |
334 | | /** |
335 | | * @brief SP float round down and convert to integer. |
336 | | * |
337 | | * @param v The value to round. |
338 | | * |
339 | | * @return The rounded value. |
340 | | */ |
341 | | static inline int flt2int_rd(float v) |
342 | 0 | { |
343 | 0 | return static_cast<int>(v); |
344 | 0 | } Unexecuted instantiation: fuzz_astc_physical_to_symbolic.cpp:astc::flt2int_rd(float) Unexecuted instantiation: astcenc_block_sizes.cpp:astc::flt2int_rd(float) Unexecuted instantiation: astcenc_integer_sequence.cpp:astc::flt2int_rd(float) Unexecuted instantiation: astcenc_mathlib.cpp:astc::flt2int_rd(float) Unexecuted instantiation: astcenc_partition_tables.cpp:astc::flt2int_rd(float) Unexecuted instantiation: astcenc_percentile_tables.cpp:astc::flt2int_rd(float) Unexecuted instantiation: astcenc_symbolic_physical.cpp:astc::flt2int_rd(float) Unexecuted instantiation: astcenc_weight_quant_xfer_tables.cpp:astc::flt2int_rd(float) Unexecuted instantiation: astcenc_quantization.cpp:astc::flt2int_rd(float) |
345 | | |
346 | | /** |
347 | | * @brief SP float bit-interpreted as an integer. |
348 | | * |
349 | | * @param v The value to bitcast. |
350 | | * |
351 | | * @return The converted value. |
352 | | */ |
353 | | static inline int float_as_int(float v) |
354 | 0 | { |
355 | 0 | // Future: Can use std:bit_cast with C++20 |
356 | 0 | int iv; |
357 | 0 | std::memcpy(&iv, &v, sizeof(float)); |
358 | 0 | return iv; |
359 | 0 | } Unexecuted instantiation: fuzz_astc_physical_to_symbolic.cpp:astc::float_as_int(float) Unexecuted instantiation: astcenc_block_sizes.cpp:astc::float_as_int(float) Unexecuted instantiation: astcenc_integer_sequence.cpp:astc::float_as_int(float) Unexecuted instantiation: astcenc_mathlib.cpp:astc::float_as_int(float) Unexecuted instantiation: astcenc_partition_tables.cpp:astc::float_as_int(float) Unexecuted instantiation: astcenc_percentile_tables.cpp:astc::float_as_int(float) Unexecuted instantiation: astcenc_symbolic_physical.cpp:astc::float_as_int(float) Unexecuted instantiation: astcenc_weight_quant_xfer_tables.cpp:astc::float_as_int(float) Unexecuted instantiation: astcenc_quantization.cpp:astc::float_as_int(float) |
360 | | |
361 | | /** |
362 | | * @brief Integer bit-interpreted as an SP float. |
363 | | * |
364 | | * @param v The value to bitcast. |
365 | | * |
366 | | * @return The converted value. |
367 | | */ |
368 | | static inline float int_as_float(int v) |
369 | 0 | { |
370 | 0 | // Future: Can use std:bit_cast with C++20 |
371 | 0 | float fv; |
372 | 0 | std::memcpy(&fv, &v, sizeof(int)); |
373 | 0 | return fv; |
374 | 0 | } Unexecuted instantiation: fuzz_astc_physical_to_symbolic.cpp:astc::int_as_float(int) Unexecuted instantiation: astcenc_block_sizes.cpp:astc::int_as_float(int) Unexecuted instantiation: astcenc_integer_sequence.cpp:astc::int_as_float(int) Unexecuted instantiation: astcenc_mathlib.cpp:astc::int_as_float(int) Unexecuted instantiation: astcenc_partition_tables.cpp:astc::int_as_float(int) Unexecuted instantiation: astcenc_percentile_tables.cpp:astc::int_as_float(int) Unexecuted instantiation: astcenc_symbolic_physical.cpp:astc::int_as_float(int) Unexecuted instantiation: astcenc_weight_quant_xfer_tables.cpp:astc::int_as_float(int) Unexecuted instantiation: astcenc_quantization.cpp:astc::int_as_float(int) |
375 | | |
376 | | /** |
377 | | * @brief SP float bit-interpreted as an unsigned integer. |
378 | | * |
379 | | * @param v The value to bitcast. |
380 | | * |
381 | | * @return The converted value. |
382 | | */ |
383 | | static inline unsigned int float_as_uint(float v) |
384 | 0 | { |
385 | 0 | // Future: Can use std:bit_cast with C++20 |
386 | 0 | unsigned int iv; |
387 | 0 | std::memcpy(&iv, &v, sizeof(float)); |
388 | 0 | return iv; |
389 | 0 | } Unexecuted instantiation: fuzz_astc_physical_to_symbolic.cpp:astc::float_as_uint(float) Unexecuted instantiation: astcenc_block_sizes.cpp:astc::float_as_uint(float) Unexecuted instantiation: astcenc_integer_sequence.cpp:astc::float_as_uint(float) Unexecuted instantiation: astcenc_mathlib.cpp:astc::float_as_uint(float) Unexecuted instantiation: astcenc_partition_tables.cpp:astc::float_as_uint(float) Unexecuted instantiation: astcenc_percentile_tables.cpp:astc::float_as_uint(float) Unexecuted instantiation: astcenc_symbolic_physical.cpp:astc::float_as_uint(float) Unexecuted instantiation: astcenc_weight_quant_xfer_tables.cpp:astc::float_as_uint(float) Unexecuted instantiation: astcenc_quantization.cpp:astc::float_as_uint(float) |
390 | | |
391 | | /** |
392 | | * @brief Unsigned integer bit-interpreted as an SP float. |
393 | | * |
394 | | * @param v The value to bitcast. |
395 | | * |
396 | | * @return The converted value. |
397 | | */ |
398 | | static inline float uint_as_float(unsigned int v) |
399 | 0 | { |
400 | 0 | // Future: Can use std:bit_cast with C++20 |
401 | 0 | float fv; |
402 | 0 | std::memcpy(&fv, &v, sizeof(unsigned int)); |
403 | 0 | return fv; |
404 | 0 | } Unexecuted instantiation: fuzz_astc_physical_to_symbolic.cpp:astc::uint_as_float(unsigned int) Unexecuted instantiation: astcenc_block_sizes.cpp:astc::uint_as_float(unsigned int) Unexecuted instantiation: astcenc_integer_sequence.cpp:astc::uint_as_float(unsigned int) Unexecuted instantiation: astcenc_mathlib.cpp:astc::uint_as_float(unsigned int) Unexecuted instantiation: astcenc_partition_tables.cpp:astc::uint_as_float(unsigned int) Unexecuted instantiation: astcenc_percentile_tables.cpp:astc::uint_as_float(unsigned int) Unexecuted instantiation: astcenc_symbolic_physical.cpp:astc::uint_as_float(unsigned int) Unexecuted instantiation: astcenc_weight_quant_xfer_tables.cpp:astc::uint_as_float(unsigned int) Unexecuted instantiation: astcenc_quantization.cpp:astc::uint_as_float(unsigned int) |
405 | | |
406 | | /** |
407 | | * @brief Signed int bit-interpreted as an unsigned integer. |
408 | | * |
409 | | * @param v The value to bitcast. |
410 | | * |
411 | | * @return The converted value. |
412 | | */ |
413 | | static inline unsigned int int_as_uint(int v) |
414 | 0 | { |
415 | 0 | // Future: Can use std:bit_cast with C++20 |
416 | 0 | unsigned int uv; |
417 | 0 | std::memcpy(&uv, &v, sizeof(int)); |
418 | 0 | return uv; |
419 | 0 | } Unexecuted instantiation: fuzz_astc_physical_to_symbolic.cpp:astc::int_as_uint(int) Unexecuted instantiation: astcenc_block_sizes.cpp:astc::int_as_uint(int) Unexecuted instantiation: astcenc_integer_sequence.cpp:astc::int_as_uint(int) Unexecuted instantiation: astcenc_mathlib.cpp:astc::int_as_uint(int) Unexecuted instantiation: astcenc_partition_tables.cpp:astc::int_as_uint(int) Unexecuted instantiation: astcenc_percentile_tables.cpp:astc::int_as_uint(int) Unexecuted instantiation: astcenc_symbolic_physical.cpp:astc::int_as_uint(int) Unexecuted instantiation: astcenc_weight_quant_xfer_tables.cpp:astc::int_as_uint(int) Unexecuted instantiation: astcenc_quantization.cpp:astc::int_as_uint(int) |
420 | | |
421 | | /** |
422 | | * @brief Unsigned integer bit-interpreted as a signed integer. |
423 | | * |
424 | | * @param v The value to bitcast. |
425 | | * |
426 | | * @return The converted value. |
427 | | */ |
428 | | static inline int uint_as_int(unsigned int v) |
429 | 0 | { |
430 | 0 | // Future: Can use std:bit_cast with C++20git p |
431 | 0 | int sv; |
432 | 0 | std::memcpy(&sv, &v, sizeof(unsigned int)); |
433 | 0 | return sv; |
434 | 0 | } Unexecuted instantiation: fuzz_astc_physical_to_symbolic.cpp:astc::uint_as_int(unsigned int) Unexecuted instantiation: astcenc_block_sizes.cpp:astc::uint_as_int(unsigned int) Unexecuted instantiation: astcenc_integer_sequence.cpp:astc::uint_as_int(unsigned int) Unexecuted instantiation: astcenc_mathlib.cpp:astc::uint_as_int(unsigned int) Unexecuted instantiation: astcenc_partition_tables.cpp:astc::uint_as_int(unsigned int) Unexecuted instantiation: astcenc_percentile_tables.cpp:astc::uint_as_int(unsigned int) Unexecuted instantiation: astcenc_symbolic_physical.cpp:astc::uint_as_int(unsigned int) Unexecuted instantiation: astcenc_weight_quant_xfer_tables.cpp:astc::uint_as_int(unsigned int) Unexecuted instantiation: astcenc_quantization.cpp:astc::uint_as_int(unsigned int) |
435 | | |
436 | | /** |
437 | | * @brief Fast approximation of 1.0 / sqrt(val). |
438 | | * |
439 | | * @param v The input value. |
440 | | * |
441 | | * @return The approximated result. |
442 | | */ |
443 | | static inline float rsqrt(float v) |
444 | 0 | { |
445 | 0 | return 1.0f / std::sqrt(v); |
446 | 0 | } Unexecuted instantiation: fuzz_astc_physical_to_symbolic.cpp:astc::rsqrt(float) Unexecuted instantiation: astcenc_block_sizes.cpp:astc::rsqrt(float) Unexecuted instantiation: astcenc_integer_sequence.cpp:astc::rsqrt(float) Unexecuted instantiation: astcenc_mathlib.cpp:astc::rsqrt(float) Unexecuted instantiation: astcenc_partition_tables.cpp:astc::rsqrt(float) Unexecuted instantiation: astcenc_percentile_tables.cpp:astc::rsqrt(float) Unexecuted instantiation: astcenc_symbolic_physical.cpp:astc::rsqrt(float) Unexecuted instantiation: astcenc_weight_quant_xfer_tables.cpp:astc::rsqrt(float) Unexecuted instantiation: astcenc_quantization.cpp:astc::rsqrt(float) |
447 | | |
448 | | /** |
449 | | * @brief Fast approximation of sqrt(val). |
450 | | * |
451 | | * @param v The input value. |
452 | | * |
453 | | * @return The approximated result. |
454 | | */ |
455 | | static inline float sqrt(float v) |
456 | 0 | { |
457 | 0 | return std::sqrt(v); |
458 | 0 | } Unexecuted instantiation: fuzz_astc_physical_to_symbolic.cpp:astc::sqrt(float) Unexecuted instantiation: astcenc_block_sizes.cpp:astc::sqrt(float) Unexecuted instantiation: astcenc_integer_sequence.cpp:astc::sqrt(float) Unexecuted instantiation: astcenc_mathlib.cpp:astc::sqrt(float) Unexecuted instantiation: astcenc_partition_tables.cpp:astc::sqrt(float) Unexecuted instantiation: astcenc_percentile_tables.cpp:astc::sqrt(float) Unexecuted instantiation: astcenc_symbolic_physical.cpp:astc::sqrt(float) Unexecuted instantiation: astcenc_weight_quant_xfer_tables.cpp:astc::sqrt(float) Unexecuted instantiation: astcenc_quantization.cpp:astc::sqrt(float) |
459 | | |
460 | | /** |
461 | | * @brief Extract mantissa and exponent of a float value. |
462 | | * |
463 | | * @param v The input value. |
464 | | * @param[out] expo The output exponent. |
465 | | * |
466 | | * @return The mantissa. |
467 | | */ |
468 | | static inline float frexp(float v, int* expo) |
469 | 0 | { |
470 | 0 | unsigned int iv = astc::float_as_uint(v); |
471 | 0 | *expo = ((iv >> 23) & 0xFF) - 126; |
472 | 0 | iv = (iv & 0x807fffff) | 0x3f000000; |
473 | 0 | return astc::uint_as_float(iv); |
474 | 0 | } Unexecuted instantiation: fuzz_astc_physical_to_symbolic.cpp:astc::frexp(float, int*) Unexecuted instantiation: astcenc_block_sizes.cpp:astc::frexp(float, int*) Unexecuted instantiation: astcenc_integer_sequence.cpp:astc::frexp(float, int*) Unexecuted instantiation: astcenc_mathlib.cpp:astc::frexp(float, int*) Unexecuted instantiation: astcenc_partition_tables.cpp:astc::frexp(float, int*) Unexecuted instantiation: astcenc_percentile_tables.cpp:astc::frexp(float, int*) Unexecuted instantiation: astcenc_symbolic_physical.cpp:astc::frexp(float, int*) Unexecuted instantiation: astcenc_weight_quant_xfer_tables.cpp:astc::frexp(float, int*) Unexecuted instantiation: astcenc_quantization.cpp:astc::frexp(float, int*) |
475 | | |
476 | | /** |
477 | | * @brief Initialize the seed structure for a random number generator. |
478 | | * |
479 | | * Important note: For the purposes of ASTC we want sets of random numbers to |
480 | | * use the codec, but we want the same seed value across instances and threads |
481 | | * to ensure that image output is stable across compressor runs and across |
482 | | * platforms. Every PRNG created by this call will therefore return the same |
483 | | * sequence of values ... |
484 | | * |
485 | | * @param state The state structure to initialize. |
486 | | */ |
487 | | void rand_init(uint64_t state[2]); |
488 | | |
489 | | /** |
490 | | * @brief Return the next random number from the generator. |
491 | | * |
492 | | * This RNG is an implementation of the "xoroshoro-128+ 1.0" PRNG, based on the |
493 | | * public-domain implementation given by David Blackman & Sebastiano Vigna at |
494 | | * http://vigna.di.unimi.it/xorshift/xoroshiro128plus.c |
495 | | * |
496 | | * @param state The state structure to use/update. |
497 | | */ |
498 | | uint64_t rand(uint64_t state[2]); |
499 | | |
500 | | } |
501 | | |
502 | | /* ============================================================================ |
503 | | Softfloat library with fp32 and fp16 conversion functionality. |
504 | | ============================================================================ */ |
505 | | #if (ASTCENC_F16C == 0) && (ASTCENC_NEON == 0) |
506 | | /* narrowing float->float conversions */ |
507 | | uint16_t float_to_sf16(float val); |
508 | | float sf16_to_float(uint16_t val); |
509 | | #endif |
510 | | |
511 | | /********************************* |
512 | | Vector library |
513 | | *********************************/ |
514 | | #include "astcenc_vecmathlib.h" |
515 | | |
516 | | /********************************* |
517 | | Declaration of line types |
518 | | *********************************/ |
519 | | // parametric line, 2D: The line is given by line = a + b * t. |
520 | | |
521 | | struct line2 |
522 | | { |
523 | | vfloat4 a; |
524 | | vfloat4 b; |
525 | | }; |
526 | | |
527 | | // parametric line, 3D |
528 | | struct line3 |
529 | | { |
530 | | vfloat4 a; |
531 | | vfloat4 b; |
532 | | }; |
533 | | |
534 | | struct line4 |
535 | | { |
536 | | vfloat4 a; |
537 | | vfloat4 b; |
538 | | }; |
539 | | |
540 | | |
541 | | struct processed_line2 |
542 | | { |
543 | | vfloat4 amod; |
544 | | vfloat4 bs; |
545 | | }; |
546 | | |
547 | | struct processed_line3 |
548 | | { |
549 | | vfloat4 amod; |
550 | | vfloat4 bs; |
551 | | }; |
552 | | |
553 | | struct processed_line4 |
554 | | { |
555 | | vfloat4 amod; |
556 | | vfloat4 bs; |
557 | | }; |
558 | | |
559 | | #endif |