float.h (2860B)
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 callback(i, src[stride * i] * scale); 66 } 67 return true; 68 69 case JXL_TYPE_UINT16: 70 if (little_endian) { 71 for (size_t i = 0; i < count; ++i) { 72 callback(i, LoadLE16(src + stride * i) * scale); 73 } 74 } else { 75 for (size_t i = 0; i < count; ++i) { 76 callback(i, LoadBE16(src + stride * i) * scale); 77 } 78 } 79 return true; 80 81 case JXL_TYPE_FLOAT16: 82 if (little_endian) { 83 for (size_t i = 0; i < count; ++i) { 84 callback(i, detail::LoadFloat16(LoadLE16(src + stride * i))); 85 } 86 } else { 87 for (size_t i = 0; i < count; ++i) { 88 callback(i, detail::LoadFloat16(LoadBE16(src + stride * i))); 89 } 90 } 91 return true; 92 93 default: 94 return JXL_FAILURE("Unsupported sample format"); 95 } 96 } 97 98 } // namespace jxl 99 100 #endif // LIB_JXL_BASE_FLOAT_H_