float.h (3019B)
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 static JXL_INLINE float LoadFloat16(uint16_t bits16) { 23 const uint32_t sign = bits16 >> 15; 24 const uint32_t biased_exp = (bits16 >> 10) & 0x1F; 25 const uint32_t mantissa = bits16 & 0x3FF; 26 27 // Subnormal or zero 28 if (biased_exp == 0) { 29 const float subnormal = 30 (1.0f / 16384) * (static_cast<float>(mantissa) * (1.0f / 1024)); 31 return sign ? -subnormal : subnormal; 32 } 33 34 // Normalized: convert the representation directly (faster than ldexp/tables). 35 const uint32_t biased_exp32 = biased_exp + (127 - 15); 36 const uint32_t mantissa32 = mantissa << (23 - 10); 37 const uint32_t bits32 = (sign << 31) | (biased_exp32 << 23) | mantissa32; 38 39 float result; 40 memcpy(&result, &bits32, 4); 41 return result; 42 } 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 SaveFloatAtFn callback) { 50 switch (type) { 51 case JXL_TYPE_FLOAT: 52 if (little_endian) { 53 for (size_t i = 0; i < count; ++i) { 54 callback(i, LoadLEFloat(src + stride * i)); 55 } 56 } else { 57 for (size_t i = 0; i < count; ++i) { 58 callback(i, LoadBEFloat(src + stride * i)); 59 } 60 } 61 return true; 62 63 case JXL_TYPE_UINT8: 64 for (size_t i = 0; i < count; ++i) { 65 // Integer multiply uint8 value before scaling so that the UINT8 value 66 // and the corresponding UINT16 value convert to the same float 67 callback(i, (src[stride * i] * 257) * scale); 68 } 69 return true; 70 71 case JXL_TYPE_UINT16: 72 if (little_endian) { 73 for (size_t i = 0; i < count; ++i) { 74 callback(i, LoadLE16(src + stride * i) * scale); 75 } 76 } else { 77 for (size_t i = 0; i < count; ++i) { 78 callback(i, LoadBE16(src + stride * i) * scale); 79 } 80 } 81 return true; 82 83 case JXL_TYPE_FLOAT16: 84 if (little_endian) { 85 for (size_t i = 0; i < count; ++i) { 86 callback(i, detail::LoadFloat16(LoadLE16(src + stride * i))); 87 } 88 } else { 89 for (size_t i = 0; i < count; ++i) { 90 callback(i, detail::LoadFloat16(LoadBE16(src + stride * i))); 91 } 92 } 93 return true; 94 95 default: 96 return JXL_FAILURE("Unsupported sample format"); 97 } 98 } 99 100 } // namespace jxl 101 102 #endif // LIB_JXL_BASE_FLOAT_H_