/src/libjxl/lib/jxl/base/float.h
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) the JPEG XL Project Authors. All rights reserved. |
2 | | // |
3 | | // Use of this source code is governed by a BSD-style |
4 | | // license that can be found in the LICENSE file. |
5 | | |
6 | | #ifndef LIB_JXL_BASE_FLOAT_H_ |
7 | | #define LIB_JXL_BASE_FLOAT_H_ |
8 | | |
9 | | #include <jxl/types.h> |
10 | | #include <stddef.h> |
11 | | #include <stdint.h> |
12 | | #include <string.h> |
13 | | |
14 | | #include "lib/jxl/base/byte_order.h" |
15 | | #include "lib/jxl/base/compiler_specific.h" |
16 | | #include "lib/jxl/base/status.h" |
17 | | |
18 | | namespace jxl { |
19 | | |
20 | | namespace detail { |
21 | | // Based on highway scalar implementation, for testing |
22 | 0 | static JXL_INLINE float LoadFloat16(uint16_t bits16) { |
23 | 0 | const uint32_t sign = bits16 >> 15; |
24 | 0 | const uint32_t biased_exp = (bits16 >> 10) & 0x1F; |
25 | 0 | const uint32_t mantissa = bits16 & 0x3FF; |
26 | | |
27 | | // Subnormal or zero |
28 | 0 | if (biased_exp == 0) { |
29 | 0 | const float subnormal = |
30 | 0 | (1.0f / 16384) * (static_cast<float>(mantissa) * (1.0f / 1024)); |
31 | 0 | return sign ? -subnormal : subnormal; |
32 | 0 | } |
33 | | |
34 | | // Normalized: convert the representation directly (faster than ldexp/tables). |
35 | 0 | const uint32_t biased_exp32 = biased_exp + (127 - 15); |
36 | 0 | const uint32_t mantissa32 = mantissa << (23 - 10); |
37 | 0 | const uint32_t bits32 = (sign << 31) | (biased_exp32 << 23) | mantissa32; |
38 | |
|
39 | 0 | float result; |
40 | 0 | memcpy(&result, &bits32, 4); |
41 | 0 | return result; |
42 | 0 | } |
43 | | } // namespace detail |
44 | | |
45 | | template <typename SaveFloatAtFn> |
46 | | static Status JXL_INLINE LoadFloatRow(const uint8_t* src, size_t count, |
47 | | size_t stride, JxlDataType type, |
48 | | bool little_endian, float scale, |
49 | 191k | SaveFloatAtFn callback) { |
50 | 191k | switch (type) { |
51 | 18.9k | case JXL_TYPE_FLOAT: |
52 | 18.9k | if (little_endian) { |
53 | 1.59M | for (size_t i = 0; i < count; ++i) { |
54 | 1.58M | callback(i, LoadLEFloat(src + stride * i)); |
55 | 1.58M | } |
56 | 18.9k | } else { |
57 | 0 | for (size_t i = 0; i < count; ++i) { |
58 | 0 | callback(i, LoadBEFloat(src + stride * i)); |
59 | 0 | } |
60 | 0 | } |
61 | 18.9k | return true; |
62 | | |
63 | 164k | case JXL_TYPE_UINT8: |
64 | 72.6M | for (size_t i = 0; i < count; ++i) { |
65 | 72.4M | callback(i, src[stride * i] * scale); |
66 | 72.4M | } |
67 | 164k | return true; |
68 | | |
69 | 8.57k | case JXL_TYPE_UINT16: |
70 | 8.57k | if (little_endian) { |
71 | 2.45M | for (size_t i = 0; i < count; ++i) { |
72 | 2.44M | callback(i, LoadLE16(src + stride * i) * scale); |
73 | 2.44M | } |
74 | 8.57k | } else { |
75 | 0 | for (size_t i = 0; i < count; ++i) { |
76 | 0 | callback(i, LoadBE16(src + stride * i) * scale); |
77 | 0 | } |
78 | 0 | } |
79 | 8.57k | return true; |
80 | | |
81 | 0 | case JXL_TYPE_FLOAT16: |
82 | 0 | if (little_endian) { |
83 | 0 | for (size_t i = 0; i < count; ++i) { |
84 | 0 | callback(i, detail::LoadFloat16(LoadLE16(src + stride * i))); |
85 | 0 | } |
86 | 0 | } else { |
87 | 0 | for (size_t i = 0; i < count; ++i) { |
88 | 0 | callback(i, detail::LoadFloat16(LoadBE16(src + stride * i))); |
89 | 0 | } |
90 | 0 | } |
91 | 0 | return true; |
92 | | |
93 | 0 | default: |
94 | 0 | return JXL_FAILURE("Unsupported sample format"); |
95 | 191k | } |
96 | 191k | } |
97 | | |
98 | | } // namespace jxl |
99 | | |
100 | | #endif // LIB_JXL_BASE_FLOAT_H_ |