/src/libjxl/lib/jxl/base/float.h
Line | Count | Source |
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 | | |
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 = |
36 | 0 | biased_exp == 0b11111 ? 0b11111111 : biased_exp + (127 - 15); |
37 | 0 | const uint32_t mantissa32 = mantissa << (23 - 10); |
38 | 0 | const uint32_t bits32 = (sign << 31) | (biased_exp32 << 23) | mantissa32; |
39 | |
|
40 | 0 | float result; |
41 | 0 | memcpy(&result, &bits32, 4); |
42 | 0 | return result; |
43 | 0 | } |
44 | | } // namespace detail |
45 | | |
46 | | template <typename SaveFloatAtFn> |
47 | | static Status JXL_INLINE LoadFloatRow(const uint8_t* src, size_t count, |
48 | | size_t stride, JxlDataType type, |
49 | | bool little_endian, float scale, |
50 | 2.73M | SaveFloatAtFn callback) { |
51 | 2.73M | switch (type) { |
52 | 278k | case JXL_TYPE_FLOAT: |
53 | 278k | if (little_endian) { |
54 | 33.4M | for (size_t i = 0; i < count; ++i) { |
55 | 33.1M | callback(i, LoadLEFloat(src + stride * i)); |
56 | 33.1M | } |
57 | 278k | } else { |
58 | 0 | for (size_t i = 0; i < count; ++i) { |
59 | 0 | callback(i, LoadBEFloat(src + stride * i)); |
60 | 0 | } |
61 | 0 | } |
62 | 278k | return true; |
63 | | |
64 | 2.23M | case JXL_TYPE_UINT8: |
65 | 892M | for (size_t i = 0; i < count; ++i) { |
66 | 889M | callback(i, src[stride * i] * scale); |
67 | 889M | } |
68 | 2.23M | return true; |
69 | | |
70 | 228k | case JXL_TYPE_UINT16: |
71 | 228k | if (little_endian) { |
72 | 37.4M | for (size_t i = 0; i < count; ++i) { |
73 | 37.2M | callback(i, LoadLE16(src + stride * i) * scale); |
74 | 37.2M | } |
75 | 228k | } else { |
76 | 0 | for (size_t i = 0; i < count; ++i) { |
77 | 0 | callback(i, LoadBE16(src + stride * i) * scale); |
78 | 0 | } |
79 | 0 | } |
80 | 228k | return true; |
81 | | |
82 | 0 | case JXL_TYPE_FLOAT16: |
83 | 0 | if (little_endian) { |
84 | 0 | for (size_t i = 0; i < count; ++i) { |
85 | 0 | callback(i, detail::LoadFloat16(LoadLE16(src + stride * i))); |
86 | 0 | } |
87 | 0 | } else { |
88 | 0 | for (size_t i = 0; i < count; ++i) { |
89 | 0 | callback(i, detail::LoadFloat16(LoadBE16(src + stride * i))); |
90 | 0 | } |
91 | 0 | } |
92 | 0 | return true; |
93 | | |
94 | 0 | default: |
95 | 0 | return JXL_FAILURE("Unsupported sample format"); |
96 | 2.73M | } |
97 | 2.73M | } |
98 | | |
99 | | } // namespace jxl |
100 | | |
101 | | #endif // LIB_JXL_BASE_FLOAT_H_ |