Skip to content

Commit a2e8ae7

Browse files
author
BuildTools
committed
Migrate lookup tables to codegen crate
1 parent a9949d5 commit a2e8ae7

File tree

9 files changed

+68821
-488
lines changed

9 files changed

+68821
-488
lines changed

codegen/src/lut.rs

+313-474
Large diffs are not rendered by default.

codegen/src/main.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
use anyhow::{Context, Result};
22

33
mod codegen_file;
4+
mod lut;
45
mod named;
56

67
fn main() -> Result<()> {
78
named::generate().context("could not generate named color constants")?;
9+
lut::generate().context("could not generate conversion lookup tables")?;
810

911
Ok(())
1012
}

palette/Cargo.toml

+2-7
Original file line numberDiff line numberDiff line change
@@ -27,20 +27,15 @@ categories = ["graphics", "multimedia::images", "no-std"]
2727
rust-version = "1.61.0"
2828

2929
[features]
30-
default = ["named_from_str", "std", "approx", "float_u8_lut"]
30+
default = ["named_from_str", "std", "approx"]
3131
named_from_str = ["named", "phf"]
3232
named = []
3333
random = ["rand"]
3434
serializing = ["serde", "std"]
3535
find-crate = ["palette_derive/find-crate"]
3636
std = ["alloc", "approx?/std"]
3737
alloc = []
38-
float_u8_lut = ["rec_oetf_lut", "adobe_rgb_lut", "p3_gamma_lut"]
39-
rec_oetf_lut = []
40-
adobe_rgb_lut = []
41-
p3_gamma_lut = []
42-
float_u16_lut = ["prophoto_lut"]
43-
prophoto_lut = []
38+
gamma_lut_u16 = []
4439

4540
[lib]
4641
bench = false

palette/src/encoding/adobe.rs

-1
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,6 @@ mod test {
157157
}
158158
}
159159

160-
#[cfg(feature = "adobe_rgb_lut")]
161160
mod lut {
162161
use crate::encoding::{AdobeRgb, FromLinear, IntoLinear};
163162

palette/src/encoding/lut.rs

+73-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,73 @@
1-
include!(concat!(env!("OUT_DIR"), "/lut.rs"));
1+
mod codegen;
2+
3+
const MAX_FLOAT_BITS: u32 = 0x3f7fffff; // 1.0 - f32::EPSILON
4+
5+
// SAFETY: Only use this macro if `input` is clamped between `min_float` and `max_float`.
6+
macro_rules! linear_float_to_encoded_uint {
7+
($enc:ty, $lut:ty, $input:ident, $min_float_bits:ident, $table:ident, $bit_width:expr, $man_index_width:expr) => {{
8+
let input_bits = $input.to_bits();
9+
#[cfg(test)]
10+
{
11+
debug_assert!(($min_float_bits..=MAX_FLOAT_BITS).contains(&$input.to_bits()));
12+
}
13+
let entry = {
14+
let i = ((input_bits - $min_float_bits) >> (23 - $man_index_width)) as usize;
15+
#[cfg(test)]
16+
{
17+
debug_assert!($table.get(i).is_some());
18+
}
19+
unsafe { *$table.get_unchecked(i) }
20+
};
21+
22+
let bias = (entry >> (2 * $bit_width)) << ($bit_width + 1);
23+
let scale = entry & ((1 << (2 * $bit_width)) - 1);
24+
let t =
25+
(input_bits as $lut >> (23 - $man_index_width - $bit_width)) & ((1 << $bit_width) - 1);
26+
let res = (bias + scale * t) >> (2 * $bit_width);
27+
#[cfg(test)]
28+
{
29+
debug_assert!(res < ((<$enc>::MAX as $lut) + 1), "{}", res);
30+
}
31+
res as $enc
32+
}};
33+
}
34+
35+
#[inline]
36+
fn linear_f32_to_encoded_u8(linear: f32, min_float_bits: u32, table: &[u32]) -> u8 {
37+
let min_float = f32::from_bits(min_float_bits);
38+
let max_float = f32::from_bits(MAX_FLOAT_BITS);
39+
40+
let mut input = linear;
41+
if input.partial_cmp(&min_float) != Some(core::cmp::Ordering::Greater) {
42+
input = min_float;
43+
} else if input > max_float {
44+
input = max_float;
45+
}
46+
47+
linear_float_to_encoded_uint!(u8, u32, input, min_float_bits, table, 8, 3)
48+
}
49+
50+
#[cfg(feature = "gamma_lut_u16")]
51+
#[inline]
52+
fn linear_f32_to_encoded_u16_with_linear_scale(
53+
linear: f32,
54+
linear_scale: f32,
55+
min_float_bits: u32,
56+
table: &[u64],
57+
) -> u16 {
58+
let min_float = f32::from_bits(min_float_bits);
59+
let max_float = f32::from_bits(MAX_FLOAT_BITS);
60+
61+
let mut input = linear;
62+
if input.partial_cmp(&0.0) != Some(core::cmp::Ordering::Greater) {
63+
input = 0.0;
64+
} else if input > max_float {
65+
input = max_float;
66+
}
67+
68+
if input < min_float {
69+
return ((linear_scale * input + 8388608.0).to_bits() & 65535) as u16;
70+
}
71+
72+
linear_float_to_encoded_uint!(u16, u64, input, min_float_bits, table, 16, 7)
73+
}

0 commit comments

Comments
 (0)