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