Skip to content

Commit

Permalink
Migrate lookup tables to codegen crate
Browse files Browse the repository at this point in the history
  • Loading branch information
BuildTools committed Aug 26, 2024
1 parent a9949d5 commit a2e8ae7
Show file tree
Hide file tree
Showing 9 changed files with 68,821 additions and 488 deletions.
787 changes: 313 additions & 474 deletions codegen/src/lut.rs

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions codegen/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use anyhow::{Context, Result};

mod codegen_file;
mod lut;
mod named;

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

Ok(())
}
9 changes: 2 additions & 7 deletions palette/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,15 @@ categories = ["graphics", "multimedia::images", "no-std"]
rust-version = "1.61.0"

[features]
default = ["named_from_str", "std", "approx", "float_u8_lut"]
default = ["named_from_str", "std", "approx"]
named_from_str = ["named", "phf"]
named = []
random = ["rand"]
serializing = ["serde", "std"]
find-crate = ["palette_derive/find-crate"]
std = ["alloc", "approx?/std"]
alloc = []
float_u8_lut = ["rec_oetf_lut", "adobe_rgb_lut", "p3_gamma_lut"]
rec_oetf_lut = []
adobe_rgb_lut = []
p3_gamma_lut = []
float_u16_lut = ["prophoto_lut"]
prophoto_lut = []
gamma_lut_u16 = []

[lib]
bench = false
Expand Down
1 change: 0 additions & 1 deletion palette/src/encoding/adobe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,6 @@ mod test {
}
}

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

Expand Down
74 changes: 73 additions & 1 deletion palette/src/encoding/lut.rs
Original file line number Diff line number Diff line change
@@ -1 +1,73 @@
include!(concat!(env!("OUT_DIR"), "/lut.rs"));
mod codegen;

const MAX_FLOAT_BITS: u32 = 0x3f7fffff; // 1.0 - f32::EPSILON

// SAFETY: Only use this macro if `input` is clamped between `min_float` and `max_float`.
macro_rules! linear_float_to_encoded_uint {
($enc:ty, $lut:ty, $input:ident, $min_float_bits:ident, $table:ident, $bit_width:expr, $man_index_width:expr) => {{
let input_bits = $input.to_bits();
#[cfg(test)]
{
debug_assert!(($min_float_bits..=MAX_FLOAT_BITS).contains(&$input.to_bits()));
}
let entry = {
let i = ((input_bits - $min_float_bits) >> (23 - $man_index_width)) as usize;
#[cfg(test)]
{
debug_assert!($table.get(i).is_some());
}
unsafe { *$table.get_unchecked(i) }
};

let bias = (entry >> (2 * $bit_width)) << ($bit_width + 1);
let scale = entry & ((1 << (2 * $bit_width)) - 1);
let t =
(input_bits as $lut >> (23 - $man_index_width - $bit_width)) & ((1 << $bit_width) - 1);
let res = (bias + scale * t) >> (2 * $bit_width);
#[cfg(test)]
{
debug_assert!(res < ((<$enc>::MAX as $lut) + 1), "{}", res);
}
res as $enc
}};
}

#[inline]
fn linear_f32_to_encoded_u8(linear: f32, min_float_bits: u32, table: &[u32]) -> u8 {
let min_float = f32::from_bits(min_float_bits);
let max_float = f32::from_bits(MAX_FLOAT_BITS);

let mut input = linear;
if input.partial_cmp(&min_float) != Some(core::cmp::Ordering::Greater) {
input = min_float;
} else if input > max_float {
input = max_float;
}

linear_float_to_encoded_uint!(u8, u32, input, min_float_bits, table, 8, 3)
}

#[cfg(feature = "gamma_lut_u16")]
#[inline]
fn linear_f32_to_encoded_u16_with_linear_scale(
linear: f32,
linear_scale: f32,
min_float_bits: u32,
table: &[u64],
) -> u16 {
let min_float = f32::from_bits(min_float_bits);
let max_float = f32::from_bits(MAX_FLOAT_BITS);

let mut input = linear;
if input.partial_cmp(&0.0) != Some(core::cmp::Ordering::Greater) {
input = 0.0;
} else if input > max_float {
input = max_float;
}

if input < min_float {
return ((linear_scale * input + 8388608.0).to_bits() & 65535) as u16;
}

linear_float_to_encoded_uint!(u16, u64, input, min_float_bits, table, 16, 7)
}
Loading

0 comments on commit a2e8ae7

Please sign in to comment.