From b849eeff74f1bf3824fcf8bd065433712012b842 Mon Sep 17 00:00:00 2001 From: BuildTools Date: Mon, 6 Jan 2025 18:02:01 -0800 Subject: [PATCH] Reworked and reorganized lookup table generation and added documentation --- codegen/src/lut.rs | 320 ++--- codegen/src/lut/model.rs | 129 ++ palette/src/encoding/adobe.rs | 15 + palette/src/encoding/lut.rs | 8 +- palette/src/encoding/lut/codegen.rs | 1778 +++++++++++++++++++------ palette/src/encoding/p3.rs | 13 + palette/src/encoding/prophoto.rs | 9 + palette/src/encoding/rec_standards.rs | 29 +- palette/src/encoding/srgb.rs | 7 +- 9 files changed, 1689 insertions(+), 619 deletions(-) create mode 100644 codegen/src/lut/model.rs diff --git a/codegen/src/lut.rs b/codegen/src/lut.rs index 90bd8fa5..d3cc388e 100644 --- a/codegen/src/lut.rs +++ b/codegen/src/lut.rs @@ -2,28 +2,36 @@ use anyhow::Result; use proc_macro2::{Ident, TokenStream}; use quote::{format_ident, quote}; -use crate::codegen_file::CodegenFile; +use crate::{codegen_file::CodegenFile, lut::model::LinearModel}; + +mod model; pub fn generate() -> Result<()> { let mut file = CodegenFile::create("palette/src/encoding/lut/codegen.rs")?; let transfer_fn_u8 = vec![ - LutEntryU8::new("Srgb", "SRGB", Some((12.92, 0.0031308)), 2.4), + LutEntryU8::new( + "Srgb", + "SRGB", + TransferFn::new_with_linear(12.92, 0.0031308, 2.4), + ), LutEntryU8::new( "RecOetf", "REC_OETF", - Some((4.5, 0.018053968510807)), - 1.0 / 0.45, + TransferFn::new_with_linear(4.5, 0.018053968510807, 1.0 / 0.45), + ), + LutEntryU8::new( + "AdobeRgb", + "ADOBE_RGB", + TransferFn::new_pure_gamma(563.0 / 256.0), ), - LutEntryU8::new("AdobeRgb", "ADOBE_RGB", None, 563.0 / 256.0), - LutEntryU8::new("P3Gamma", "P3_GAMMA", None, 2.6), + LutEntryU8::new("P3Gamma", "P3_GAMMA", TransferFn::new_pure_gamma(2.6)), ]; let transfer_fn_u16 = vec![LutEntryU16::new( "ProPhotoRgb", "PROPHOTO_RGB", - Some((16.0, 0.001953125)), - 1.8, + TransferFn::new_with_linear(16.0, 0.001953125, 1.8), )]; let ident_u8 = transfer_fn_u8 @@ -49,88 +57,78 @@ pub fn generate() -> Result<()> { Ok(()) } -type TransferFn = Box f64>; - -struct LutEntryU8 { - fn_type: Ident, - fn_type_uppercase: String, - into_linear: TransferFn, +/// This struct is able to model a given transfer function. +/// +/// Any transfer function will have a linear part (optional) for input values +/// less than some value `beta` and an exponential part determined by the function's +/// `gamma` value. For transfer functions with a linear part, `alpha` is chosen to +/// preserve function continuity. +struct TransferFn { + into_linear: Box f64>, linear_scale: Option, alpha: f64, beta: f64, gamma: f64, } +impl TransferFn { + fn new_with_linear(linear_scale: f64, linear_end: f64, gamma: f64) -> Self { + let alpha = (linear_scale * linear_end - 1.0) / (linear_end.powf(gamma.recip()) - 1.0); + let beta = linear_end; + Self { + into_linear: Box::new(move |encoded| { + if encoded <= linear_scale * beta { + encoded / linear_scale + } else { + ((encoded + alpha - 1.0) / alpha).powf(gamma) + } + }), + linear_scale: Some(linear_scale), + alpha, + beta, + gamma, + } + } + + fn new_pure_gamma(gamma: f64) -> Self { + Self { + into_linear: Box::new(move |encoded| encoded.powf(gamma)), + linear_scale: None, + alpha: 1.0, + beta: 0.0, + gamma, + } + } +} + +struct LutEntryU8 { + fn_type: Ident, + fn_type_uppercase: String, + transfer_fn: TransferFn, +} + struct LutEntryU16 { fn_type: Ident, fn_type_uppercase: String, - into_linear: TransferFn, - linear_scale: Option, - alpha: f64, - beta: f64, - gamma: f64, + transfer_fn: TransferFn, } impl LutEntryU8 { - fn new( - fn_type: &str, - fn_type_uppercase: &str, - is_linear_as_until: Option<(f64, f64)>, - gamma: f64, - ) -> Self { - let (linear_scale, alpha, beta) = - if let Some((linear_scale, linear_end)) = is_linear_as_until { - ( - Some(linear_scale), - (linear_scale * linear_end - 1.0) / (linear_end.powf(gamma.recip()) - 1.0), - linear_end, - ) - } else { - (None, 1.0, 0.0) - }; + fn new(fn_type: &str, fn_type_uppercase: &str, transfer_fn: TransferFn) -> Self { Self { fn_type: format_ident!("{fn_type}"), fn_type_uppercase: fn_type_uppercase.to_owned(), - into_linear: Box::new(move |encoded| match linear_scale { - Some(scale) if encoded <= scale * beta => encoded / scale, - _ => ((encoded + alpha - 1.0) / alpha).powf(gamma), - }), - linear_scale, - alpha, - beta, - gamma, + transfer_fn, } } } impl LutEntryU16 { - fn new( - fn_type: &str, - fn_type_uppercase: &str, - is_linear_as_until: Option<(f64, f64)>, - gamma: f64, - ) -> Self { - let (linear_scale, alpha, beta) = - if let Some((linear_scale, linear_end)) = is_linear_as_until { - ( - Some(linear_scale), - (linear_scale * linear_end - 1.0) / (linear_end.powf(gamma.recip()) - 1.0), - linear_end, - ) - } else { - (None, 1.0, 0.0) - }; + fn new(fn_type: &str, fn_type_uppercase: &str, transfer_fn: TransferFn) -> Self { Self { fn_type: format_ident!("{fn_type}"), fn_type_uppercase: fn_type_uppercase.to_owned(), - into_linear: Box::new(move |encoded| match linear_scale { - Some(scale) if encoded <= scale * beta => encoded / scale, - _ => ((encoded + alpha - 1.0) / alpha).powf(gamma), - }), - linear_scale, - alpha, - beta, - gamma, + transfer_fn, } } } @@ -140,16 +138,21 @@ fn build_u8_to_f64_lut(entries: &[LutEntryU8]) -> TokenStream { |LutEntryU8 { fn_type, fn_type_uppercase, - into_linear, - .. + transfer_fn, }| { - let table = (0..=u8::MAX).map(|i| into_linear((i as f64) / 255.0)); + let table = (0..=u8::MAX).map(|i| (transfer_fn.into_linear)((i as f64) / 255.0)); let table_ident = format_ident!("{fn_type_uppercase}_U8_TO_F64"); + let table_f32 = table.clone().map(|f| f as f32); + let table_f32_ident = format_ident!("{fn_type_uppercase}_U8_TO_F32"); quote! { const #table_ident: [f64; 256] = [ #(#table),* ]; + const #table_f32_ident: [f32; 256] = [ + #(#table_f32),* + ]; + impl IntoLinear for #fn_type { #[inline] fn into_linear(encoded: u8) -> f64 { @@ -160,7 +163,7 @@ fn build_u8_to_f64_lut(entries: &[LutEntryU8]) -> TokenStream { impl IntoLinear for #fn_type { #[inline] fn into_linear(encoded: u8) -> f32 { - #table_ident[encoded as usize] as f32 + #table_f32_ident[encoded as usize] } } } @@ -177,10 +180,9 @@ fn build_u16_to_f64_lut(entries: &[LutEntryU16]) -> TokenStream { |LutEntryU16 { fn_type, fn_type_uppercase, - into_linear, - .. + transfer_fn, }| { - let table = (0..=u16::MAX).map(|i| into_linear((i as f64) / 65535.0)); + let table = (0..=u16::MAX).map(|i| (transfer_fn.into_linear)((i as f64) / 65535.0)); let table_ident = format_ident!("{fn_type_uppercase}_U16_TO_F64"); quote! { #[cfg(feature = "gamma_lut_u16")] @@ -212,69 +214,34 @@ fn build_u16_to_f64_lut(entries: &[LutEntryU16]) -> TokenStream { } } -fn integrate_linear( - (start_x, start_t): (f64, f64), - (end_x, end_t): (f64, f64), - linear_scale: f64, - exp_scale: f64, -) -> (f64, f64) { - let antiderive_y = |x: f64| 0.5 * linear_scale * exp_scale * x * x; - let antiderive_ty = - |x: f64, t: f64| 0.5 * linear_scale * exp_scale * x * x * (t - exp_scale * x / 3.0); - - ( - antiderive_y(end_x) - antiderive_y(start_x), - antiderive_ty(end_x, end_t) - antiderive_ty(start_x, start_t), - ) -} - -fn integrate_exponential( - (start_x, start_t): (f64, f64), - (end_x, end_t): (f64, f64), - alpha: f64, - gamma: f64, - exp_scale: f64, -) -> (f64, f64) { - let antiderive_y = |x: f64, t: f64| { - alpha * gamma * exp_scale * x * x.powf(gamma.recip()) / (1.0 + gamma) + (1.0 - alpha) * t - }; - let antiderive_ty = |x: f64, t: f64| { - alpha - * gamma - * exp_scale - * x - * x.powf(gamma.recip()) - * (t - gamma * exp_scale * x / (1.0 + 2.0 * gamma)) - / (1.0 + gamma) - + 0.5 * (1.0 - alpha) * t * t - }; - - ( - antiderive_y(end_x, end_t) - antiderive_y(start_x, start_t), - antiderive_ty(end_x, end_t) - antiderive_ty(start_x, start_t), - ) -} - +/// This algorithm is an adaptation of (this C++ code)[https://gist.github.com/rygorous/2203834] +/// by Fabian "ryg" Giesen, which utilizes simple linear regression on +/// sub-intervals of the transfer function's domain and stores the resulting +/// models' scales and biases into a lookup table. +/// +/// The algorithm linked above calculates the transfer function for every +/// potential `f32` input and feeds that into the regression model. In +/// contrast, this algorithm replaces the discrete sums in the model with +/// continuous integrals in order to reduce the time it takes to generate +/// the tables. We are able to do this since transfer functions follow a +/// predictable pattern for which the anti-derivative is known. fn build_f32_to_u8_lut(entries: &[LutEntryU8]) -> TokenStream { // 1.0 - f32::EPSILON const MAX_FLOAT_BITS: u32 = 0x3f7fffff; // The number of mantissa bits used to index into the lookup table const MAN_INDEX_WIDTH: u32 = 3; // The number of bits in the remainder of the mantissa - const BUCKET_INDEX_WIDTH: i32 = 20; + const BUCKET_INDEX_WIDTH: u32 = 20; const BUCKET_SIZE: u32 = 1 << BUCKET_INDEX_WIDTH; let tables = entries.iter().map( |LutEntryU8 { fn_type, fn_type_uppercase, - into_linear, - linear_scale, - alpha, - beta, - gamma, + transfer_fn, }| { // Any input less than or equal to this maps to 0 - let min_float_bits = ((into_linear(0.5 / 255.0) as f32).to_bits() - 1) & 0xff800000; + let min_float_bits = + (((transfer_fn.into_linear)(0.5 / 255.0) as f32).to_bits() - 1) & 0xff800000; let exp_table_size = ((MAX_FLOAT_BITS - min_float_bits) >> 23) + 1; let table_size = exp_table_size << MAN_INDEX_WIDTH; @@ -282,55 +249,8 @@ fn build_f32_to_u8_lut(entries: &[LutEntryU8]) -> TokenStream { let table = (0..table_size).map(|i| { let start = min_float_bits + (i << BUCKET_INDEX_WIDTH); let end = start + BUCKET_SIZE; - let start_x = f32::from_bits(start) as f64; - let end_x = f32::from_bits(end) as f64; - - let beta_bits = (*beta as f32).to_bits(); - let exp_scale = 2.0f64.powi(158 - ((start >> 23) as i32) - BUCKET_INDEX_WIDTH); - let (integral_y, integral_ty) = match linear_scale { - Some(linear_scale) if end <= beta_bits => { - integrate_linear((start_x, 0.0), (end_x, 256.0), *linear_scale, exp_scale) - } - Some(linear_scale) if start < beta_bits => { - let beta_t = (beta_bits & (BUCKET_SIZE - 1)) as f64 - * 2.0f64.powi(8 - BUCKET_INDEX_WIDTH); - let integral_linear = integrate_linear( - (start_x, 0.0), - (*beta, beta_t), - *linear_scale, - exp_scale, - ); - let integral_exponential = integrate_exponential( - (*beta, beta_t), - (end_x, 256.0), - *alpha, - *gamma, - exp_scale, - ); - ( - integral_linear.0 + integral_exponential.0, - integral_linear.1 + integral_exponential.1, - ) - } - _ => integrate_exponential( - (start_x, 0.0), - (end_x, 256.0), - *alpha, - *gamma, - exp_scale, - ), - }; - - const INTEGRAL_T: f64 = 32768.0; - const INTEGRAL_T2: f64 = 16777216.0 / 3.0; - - let scale = (256.0 * integral_ty - INTEGRAL_T * integral_y) - / (256.0 * INTEGRAL_T2 - INTEGRAL_T * INTEGRAL_T); - let bias = (integral_y - scale * INTEGRAL_T) / 256.0; - let scale_uint = (255.0 * scale * 65536.0 + 0.5) as u32; - let bias_uint = (((255.0 * bias + 0.5) * 128.0 + 0.5) as u32) << 9; - (bias_uint << 7) | scale_uint + LinearModel::new(transfer_fn, start, end, MAN_INDEX_WIDTH, 8).into_u8_lookup() }); let table_ident = format_ident!("TO_{fn_type_uppercase}_U8"); @@ -371,15 +291,8 @@ fn build_f32_to_u16_lut(entries: &[LutEntryU16]) -> TokenStream { const BUCKET_INDEX_WIDTH: i32 = 16; const BUCKET_SIZE: u32 = 1 << BUCKET_INDEX_WIDTH; let tables = entries.iter().map( - |LutEntryU16 { - fn_type, - fn_type_uppercase, - into_linear, - linear_scale, - alpha, - beta, - gamma, - }| { + |LutEntryU16 { fn_type, fn_type_uppercase, transfer_fn }| { + let TransferFn { into_linear, linear_scale, beta, .. } = transfer_fn; let min_float_bits = (*beta as f32) .to_bits() .max((into_linear(0.5 / 65535.0) as f32).to_bits() - 1) @@ -389,51 +302,8 @@ fn build_f32_to_u16_lut(entries: &[LutEntryU16]) -> TokenStream { let table = (0..table_size).map(|i| { let start = min_float_bits + (i << BUCKET_INDEX_WIDTH); let end = start + BUCKET_SIZE; - let start_x = f32::from_bits(start) as f64; - let end_x = f32::from_bits(end) as f64; - let beta_bits = (*beta as f32).to_bits(); - let exp_scale = 2.0f64.powi(166 - ((start >> 23) as i32) - BUCKET_INDEX_WIDTH); - - let (integral_y, integral_ty) = match linear_scale { - Some(linear_scale) if end <= beta_bits => { - integrate_linear((start_x, 0.0), (end_x, 65536.0), *linear_scale, exp_scale) - } - Some(linear_scale) if start < beta_bits => { - let beta_t = (beta_bits & (BUCKET_SIZE - 1)) as f64 - * 2.0f64.powi(16 - BUCKET_INDEX_WIDTH); - let integral_linear = - integrate_linear((start_x, 0.0), (*beta, beta_t), *linear_scale, exp_scale); - let integral_exponential = integrate_exponential( - (*beta, beta_t), - (end_x, 65536.0), - *alpha, - *gamma, - exp_scale, - ); - ( - integral_linear.0 + integral_exponential.0, - integral_linear.1 + integral_exponential.1, - ) - } - _ => integrate_exponential( - (start_x, 0.0), - (end_x, 65536.0), - *alpha, - *gamma, - exp_scale, - ), - }; - - const INTEGRAL_T: f64 = 2147483648.0; - const INTEGRAL_T2: f64 = 281474976710656.0 / 3.0; - - let scale = (65536.0 * integral_ty - INTEGRAL_T * integral_y) - / (65536.0 * INTEGRAL_T2 - INTEGRAL_T * INTEGRAL_T); - let bias = (integral_y - scale * INTEGRAL_T) / 65536.0; - let scale_uint = (65535.0 * scale * 4294967296.0 + 0.5) as u64; - let bias_uint = (((65535.0 * bias + 0.5) * 32768.0 + 0.5) as u64) << 17; - (bias_uint << 15) | scale_uint + LinearModel::new(transfer_fn, start, end, MAN_INDEX_WIDTH, 16).into_u16_lookup() }); let table_ident = format_ident!("TO_{fn_type_uppercase}_U16"); diff --git a/codegen/src/lut/model.rs b/codegen/src/lut/model.rs new file mode 100644 index 00000000..3cb9e1d5 --- /dev/null +++ b/codegen/src/lut/model.rs @@ -0,0 +1,129 @@ +use super::TransferFn; + +/// This struct contains the scale and bias for a linear +/// regression model of a transfer function on a given interval. +/// +/// This model is calculated by using simple linear regression with +/// integration instead of summation. +pub(super) struct LinearModel { + scale: f64, + bias: f64, +} + +impl LinearModel { + pub(super) fn new( + transfer_fn: &TransferFn, + start: u32, + end: u32, + man_index_width: u32, + t_width: u32, + ) -> Self { + let TransferFn { + linear_scale, + alpha, + beta, + gamma, + .. + } = *transfer_fn; + + let beta_bits = (beta as f32).to_bits(); + // Corresponds to the scale between differentials. Specifically, + // `dx = exp_scale * dt` + let exp_scale = f32::from_bits(((start >> 23) - man_index_width - t_width) << 23) as f64; + let start_x = f32::from_bits(start) as f64; + let end_x = f32::from_bits(end) as f64; + + // If the transfer function is purely linear on a given interval, + // integration is unnecessary. + if let Some(linear_scale) = linear_scale { + if end <= beta_bits { + return Self { + scale: linear_scale * exp_scale, + bias: linear_scale * start_x, + }; + } + } + + let max_t = 2.0f64.powi(t_width as i32); + + let (integral_y, integral_ty) = match linear_scale { + Some(linear_scale) if start < beta_bits => { + let beta_t = + (beta_bits << (9 + man_index_width)) as f64 * 2.0f64.powi(t_width as i32 - 32); + let int_linear = + integrate_linear((start_x, beta), (0.0, beta_t), linear_scale, exp_scale); + let int_exponential = + integrate_exponential((beta, end_x), (beta_t, max_t), alpha, gamma, exp_scale); + ( + int_linear.0 + int_exponential.0, + int_linear.1 + int_exponential.1, + ) + } + _ => integrate_exponential((start_x, end_x), (0.0, max_t), alpha, gamma, exp_scale), + }; + let max_t2 = max_t * max_t; + let integral_t = max_t2 * 0.5; + let integral_t2 = max_t2 * max_t / 3.0; + + let scale = (max_t * integral_ty - integral_t * integral_y) + / (max_t * integral_t2 - integral_t * integral_t); + Self { + scale, + bias: (integral_y - scale * integral_t) / max_t, + } + } + + pub(super) fn into_u8_lookup(self) -> u32 { + let scale_uint = (255.0 * self.scale * 65536.0 + 0.5) as u32; + let bias_uint = (((255.0 * self.bias + 0.5) * 128.0 + 0.5) as u32) << 9; + (bias_uint << 7) | scale_uint + } + + pub(super) fn into_u16_lookup(self) -> u64 { + let scale_uint = (65535.0 * self.scale * 4294967296.0 + 0.5) as u64; + let bias_uint = (((65535.0 * self.bias + 0.5) * 32768.0 + 0.5) as u64) << 17; + (bias_uint << 15) | scale_uint + } +} + +fn integrate_linear( + (start_x, end_x): (f64, f64), + (start_t, end_t): (f64, f64), + linear_scale: f64, + exp_scale: f64, +) -> (f64, f64) { + let antiderive_y = |x: f64| 0.5 * linear_scale * x * x / exp_scale; + let antiderive_ty = + |x: f64, t: f64| 0.5 * linear_scale * x * x * (t - x / (3.0 * exp_scale)) / exp_scale; + + ( + antiderive_y(end_x) - antiderive_y(start_x), + antiderive_ty(end_x, end_t) - antiderive_ty(start_x, start_t), + ) +} + +fn integrate_exponential( + (start_x, end_x): (f64, f64), + (start_t, end_t): (f64, f64), + alpha: f64, + gamma: f64, + exp_scale: f64, +) -> (f64, f64) { + let one_plus_gamma_inv = 1.0 + gamma.recip(); + let antiderive_y = |x: f64, t: f64| { + alpha * gamma * x.powf(one_plus_gamma_inv) / (exp_scale * (1.0 + gamma)) + (1.0 - alpha) * t + }; + let antiderive_ty = |x: f64, t: f64| { + alpha + * gamma + * x.powf(one_plus_gamma_inv) + * (t - gamma * x / (exp_scale * (1.0 + 2.0 * gamma))) + / (exp_scale * (1.0 + gamma)) + + 0.5 * (1.0 - alpha) * t * t + }; + + ( + antiderive_y(end_x, end_t) - antiderive_y(start_x, start_t), + antiderive_ty(end_x, end_t) - antiderive_ty(start_x, start_t), + ) +} diff --git a/palette/src/encoding/adobe.rs b/palette/src/encoding/adobe.rs index ba185f25..d64ffd66 100644 --- a/palette/src/encoding/adobe.rs +++ b/palette/src/encoding/adobe.rs @@ -17,6 +17,21 @@ use super::{FromLinear, IntoLinear}; /// in cyan-green hues. /// /// The Adobe RGB standard uses a gamma 2.2 transfer function. +/// +///# As transfer function +/// +/// `AdobeRgb` will not use any kind of approximation when converting from `T` to +/// `T`. This involves calls to `powf`, which may make it too slow for certain +/// applications. +/// +/// There are some specialized cases where it has been optimized: +/// +/// * When converting from `u8` to `f32` or `f64`, while converting to linear +/// space. This uses lookup tables with precomputed values. +/// * When converting from `f32` or `f64` to `u8`, while converting from linear +/// space. This uses a fast algorithm that guarantees a maximum error in the +/// result of less than 0.6 in line with [this DirectX spec] +/// (https://microsoft.github.io/DirectX-Specs/d3d/archive/D3D11_3_FunctionalSpec.htm#FLOATtoSRGB). #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct AdobeRgb; diff --git a/palette/src/encoding/lut.rs b/palette/src/encoding/lut.rs index b5179fd3..7a174e15 100644 --- a/palette/src/encoding/lut.rs +++ b/palette/src/encoding/lut.rs @@ -3,7 +3,7 @@ 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 { +macro_rules! unsafe_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)] @@ -16,7 +16,7 @@ macro_rules! linear_float_to_encoded_uint { { debug_assert!($table.get(i).is_some()); } - unsafe { *$table.get_unchecked(i) } + *$table.get_unchecked(i) }; let bias = (entry >> (2 * $bit_width)) << ($bit_width + 1); @@ -44,7 +44,7 @@ fn linear_f32_to_encoded_u8(linear: f32, min_float_bits: u32, table: &[u32]) -> input = max_float; } - linear_float_to_encoded_uint!(u8, u32, input, min_float_bits, table, 8, 3) + unsafe { unsafe_linear_float_to_encoded_uint!(u8, u32, input, min_float_bits, table, 8, 3) } } #[cfg(feature = "gamma_lut_u16")] @@ -69,5 +69,5 @@ fn linear_f32_to_encoded_u16_with_linear_scale( 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) + unsafe { unsafe_linear_float_to_encoded_uint!(u16, u64, input, min_float_bits, table, 16, 7) } } diff --git a/palette/src/encoding/lut/codegen.rs b/palette/src/encoding/lut/codegen.rs index 73b9274f..ac15904c 100644 --- a/palette/src/encoding/lut/codegen.rs +++ b/palette/src/encoding/lut/codegen.rs @@ -265,6 +265,264 @@ const SRGB_U8_TO_F64: [f64; 256] = [ 0.991102096850078f64, 1f64, ]; +const SRGB_U8_TO_F32: [f32; 256] = [ + 0f32, + 0.000303527f32, + 0.000607054f32, + 0.000910581f32, + 0.001214108f32, + 0.001517635f32, + 0.001821162f32, + 0.0021246888f32, + 0.002428216f32, + 0.0027317428f32, + 0.00303527f32, + 0.0033465335f32, + 0.0036765048f32, + 0.004024714f32, + 0.0043914393f32, + 0.0047769505f32, + 0.0051815137f32, + 0.0056053884f32, + 0.0060488298f32, + 0.0065120873f32, + 0.006995407f32, + 0.0074990285f32, + 0.008023189f32, + 0.008568122f32, + 0.009134055f32, + 0.009721213f32, + 0.010329818f32, + 0.01096009f32, + 0.011612241f32, + 0.012286483f32, + 0.012983028f32, + 0.013702078f32, + 0.014443839f32, + 0.01520851f32, + 0.015996289f32, + 0.01680737f32, + 0.017641949f32, + 0.018500214f32, + 0.019382356f32, + 0.020288557f32, + 0.021219004f32, + 0.022173878f32, + 0.02315336f32, + 0.024157627f32, + 0.025186853f32, + 0.026241215f32, + 0.027320884f32, + 0.028426033f32, + 0.029556828f32, + 0.030713437f32, + 0.031896025f32, + 0.03310476f32, + 0.0343398f32, + 0.035601307f32, + 0.03688944f32, + 0.038204364f32, + 0.03954623f32, + 0.040915187f32, + 0.042311404f32, + 0.04373502f32, + 0.045186196f32, + 0.046665076f32, + 0.048171815f32, + 0.049706556f32, + 0.05126945f32, + 0.052860636f32, + 0.054480266f32, + 0.05612848f32, + 0.05780542f32, + 0.05951123f32, + 0.061246045f32, + 0.06301001f32, + 0.06480326f32, + 0.06662593f32, + 0.06847816f32, + 0.07036009f32, + 0.07227184f32, + 0.07421356f32, + 0.07618537f32, + 0.07818741f32, + 0.08021981f32, + 0.0822827f32, + 0.0843762f32, + 0.08650045f32, + 0.088655576f32, + 0.0908417f32, + 0.09305895f32, + 0.095307454f32, + 0.09758733f32, + 0.09989872f32, + 0.102241725f32, + 0.10461647f32, + 0.10702309f32, + 0.1094617f32, + 0.11193242f32, + 0.11443536f32, + 0.11697066f32, + 0.11953842f32, + 0.12213876f32, + 0.1247718f32, + 0.12743767f32, + 0.13013646f32, + 0.1328683f32, + 0.13563332f32, + 0.13843161f32, + 0.14126328f32, + 0.14412846f32, + 0.14702725f32, + 0.14995977f32, + 0.15292613f32, + 0.15592645f32, + 0.15896082f32, + 0.16202936f32, + 0.16513218f32, + 0.16826938f32, + 0.1714411f32, + 0.17464739f32, + 0.17788841f32, + 0.18116423f32, + 0.18447497f32, + 0.18782076f32, + 0.19120167f32, + 0.19461782f32, + 0.1980693f32, + 0.20155624f32, + 0.20507872f32, + 0.20863685f32, + 0.21223074f32, + 0.21586049f32, + 0.21952619f32, + 0.22322795f32, + 0.22696586f32, + 0.23074004f32, + 0.23455057f32, + 0.23839755f32, + 0.24228111f32, + 0.2462013f32, + 0.25015828f32, + 0.2541521f32, + 0.25818285f32, + 0.26225063f32, + 0.2663556f32, + 0.27049777f32, + 0.2746773f32, + 0.27889425f32, + 0.28314874f32, + 0.28744084f32, + 0.29177064f32, + 0.29613826f32, + 0.30054379f32, + 0.3049873f32, + 0.3094689f32, + 0.3139887f32, + 0.31854677f32, + 0.32314318f32, + 0.32777807f32, + 0.33245152f32, + 0.3371636f32, + 0.34191442f32, + 0.34670404f32, + 0.35153258f32, + 0.35640013f32, + 0.36130676f32, + 0.36625257f32, + 0.37123767f32, + 0.3762621f32, + 0.381326f32, + 0.38642943f32, + 0.39157248f32, + 0.39675522f32, + 0.40197778f32, + 0.4072402f32, + 0.4125426f32, + 0.41788507f32, + 0.42326766f32, + 0.4286905f32, + 0.43415362f32, + 0.43965715f32, + 0.4452012f32, + 0.45078576f32, + 0.456411f32, + 0.462077f32, + 0.46778378f32, + 0.47353148f32, + 0.47932017f32, + 0.48514992f32, + 0.49102083f32, + 0.49693298f32, + 0.5028865f32, + 0.50888133f32, + 0.5149177f32, + 0.52099556f32, + 0.5271151f32, + 0.5332764f32, + 0.5394795f32, + 0.54572445f32, + 0.5520114f32, + 0.5583404f32, + 0.5647115f32, + 0.5711248f32, + 0.57758045f32, + 0.58407843f32, + 0.59061885f32, + 0.59720176f32, + 0.60382736f32, + 0.61049557f32, + 0.6172066f32, + 0.6239604f32, + 0.63075715f32, + 0.63759685f32, + 0.6444797f32, + 0.65140563f32, + 0.6583748f32, + 0.6653873f32, + 0.67244315f32, + 0.6795425f32, + 0.6866853f32, + 0.69387174f32, + 0.7011019f32, + 0.70837575f32, + 0.7156935f32, + 0.7230551f32, + 0.7304607f32, + 0.7379104f32, + 0.7454042f32, + 0.7529422f32, + 0.7605245f32, + 0.76815116f32, + 0.7758222f32, + 0.7835378f32, + 0.7912979f32, + 0.7991027f32, + 0.80695224f32, + 0.8148466f32, + 0.82278574f32, + 0.8307699f32, + 0.838799f32, + 0.8468732f32, + 0.8549926f32, + 0.8631572f32, + 0.8713671f32, + 0.8796224f32, + 0.8879231f32, + 0.8962693f32, + 0.9046612f32, + 0.91309863f32, + 0.92158186f32, + 0.9301109f32, + 0.9386857f32, + 0.9473065f32, + 0.9559733f32, + 0.9646863f32, + 0.9734453f32, + 0.9822506f32, + 0.9911021f32, + 1f32, +]; impl IntoLinear for Srgb { #[inline] fn into_linear(encoded: u8) -> f64 { @@ -274,7 +532,7 @@ impl IntoLinear for Srgb { impl IntoLinear for Srgb { #[inline] fn into_linear(encoded: u8) -> f32 { - SRGB_U8_TO_F64[encoded as usize] as f32 + SRGB_U8_TO_F32[encoded as usize] } } const REC_OETF_U8_TO_F64: [f64; 256] = [ @@ -535,6 +793,264 @@ const REC_OETF_U8_TO_F64: [f64; 256] = [ 0.9920898491044691f64, 1f64, ]; +const REC_OETF_U8_TO_F32: [f32; 256] = [ + 0f32, + 0.0008714597f32, + 0.0017429194f32, + 0.0026143792f32, + 0.0034858389f32, + 0.0043572984f32, + 0.0052287583f32, + 0.006100218f32, + 0.0069716778f32, + 0.007843138f32, + 0.008714597f32, + 0.009586057f32, + 0.010457517f32, + 0.011328976f32, + 0.012200436f32, + 0.013071896f32, + 0.0139433555f32, + 0.014814815f32, + 0.015686275f32, + 0.016557734f32, + 0.017429193f32, + 0.01830158f32, + 0.019191196f32, + 0.02010409f32, + 0.021040367f32, + 0.02200014f32, + 0.022983508f32, + 0.023990577f32, + 0.02502145f32, + 0.026076226f32, + 0.027155004f32, + 0.028257882f32, + 0.029384954f32, + 0.030536318f32, + 0.031712066f32, + 0.03291229f32, + 0.03413708f32, + 0.035386533f32, + 0.036660727f32, + 0.03795976f32, + 0.039283708f32, + 0.040632665f32, + 0.042006712f32, + 0.04340593f32, + 0.04483041f32, + 0.046280228f32, + 0.047755465f32, + 0.0492562f32, + 0.050782517f32, + 0.052334487f32, + 0.05391219f32, + 0.055515707f32, + 0.057145108f32, + 0.05880047f32, + 0.060481865f32, + 0.062189374f32, + 0.06392306f32, + 0.065683f32, + 0.06746927f32, + 0.069281936f32, + 0.07112107f32, + 0.07298673f32, + 0.074879f32, + 0.07679794f32, + 0.07874362f32, + 0.08071611f32, + 0.08271547f32, + 0.08474177f32, + 0.08679508f32, + 0.08887545f32, + 0.09098296f32, + 0.09311766f32, + 0.09527963f32, + 0.09746892f32, + 0.099685594f32, + 0.10192971f32, + 0.10420134f32, + 0.106500536f32, + 0.10882736f32, + 0.11118188f32, + 0.11356414f32, + 0.11597421f32, + 0.118412144f32, + 0.120877996f32, + 0.12337184f32, + 0.12589371f32, + 0.12844369f32, + 0.13102181f32, + 0.13362813f32, + 0.13626273f32, + 0.13892564f32, + 0.14161693f32, + 0.14433663f32, + 0.14708483f32, + 0.14986156f32, + 0.15266687f32, + 0.15550083f32, + 0.15836348f32, + 0.16125488f32, + 0.16417508f32, + 0.16712414f32, + 0.17010209f32, + 0.173109f32, + 0.1761449f32, + 0.17920986f32, + 0.18230394f32, + 0.18542716f32, + 0.18857959f32, + 0.19176127f32, + 0.19497225f32, + 0.19821258f32, + 0.20148233f32, + 0.2047815f32, + 0.20811018f32, + 0.2114684f32, + 0.2148562f32, + 0.21827365f32, + 0.22172078f32, + 0.22519766f32, + 0.22870429f32, + 0.23224077f32, + 0.23580709f32, + 0.23940334f32, + 0.24302955f32, + 0.24668576f32, + 0.25037202f32, + 0.25408837f32, + 0.25783488f32, + 0.26161155f32, + 0.26541847f32, + 0.26925564f32, + 0.27312312f32, + 0.27702096f32, + 0.2809492f32, + 0.2849079f32, + 0.2888971f32, + 0.29291677f32, + 0.29696706f32, + 0.30104795f32, + 0.30515948f32, + 0.30930173f32, + 0.3134747f32, + 0.31767845f32, + 0.32191303f32, + 0.32617846f32, + 0.3304748f32, + 0.33480206f32, + 0.33916032f32, + 0.3435496f32, + 0.34796995f32, + 0.3524214f32, + 0.35690397f32, + 0.36141774f32, + 0.3659627f32, + 0.37053898f32, + 0.3751465f32, + 0.3797854f32, + 0.38445562f32, + 0.3891573f32, + 0.3938904f32, + 0.39865503f32, + 0.40345114f32, + 0.40827885f32, + 0.41313815f32, + 0.4180291f32, + 0.4229517f32, + 0.42790604f32, + 0.4328921f32, + 0.43791f32, + 0.4429597f32, + 0.44804123f32, + 0.45315468f32, + 0.45830008f32, + 0.46347743f32, + 0.46868682f32, + 0.4739282f32, + 0.4792017f32, + 0.4845073f32, + 0.48984504f32, + 0.49521497f32, + 0.5006171f32, + 0.50605154f32, + 0.5115182f32, + 0.51701725f32, + 0.52254856f32, + 0.52811235f32, + 0.5337085f32, + 0.53933716f32, + 0.54499835f32, + 0.550692f32, + 0.55641824f32, + 0.56217706f32, + 0.56796855f32, + 0.57379264f32, + 0.57964945f32, + 0.58553904f32, + 0.59146136f32, + 0.59741646f32, + 0.6034044f32, + 0.6094252f32, + 0.6154789f32, + 0.6215655f32, + 0.62768507f32, + 0.63383764f32, + 0.64002323f32, + 0.6462419f32, + 0.65249366f32, + 0.6587785f32, + 0.6650965f32, + 0.6714477f32, + 0.6778321f32, + 0.68424976f32, + 0.6907007f32, + 0.6971849f32, + 0.7037025f32, + 0.7102535f32, + 0.7168378f32, + 0.7234556f32, + 0.73010683f32, + 0.73679155f32, + 0.7435098f32, + 0.75026166f32, + 0.75704706f32, + 0.76386607f32, + 0.77071875f32, + 0.7776051f32, + 0.78452516f32, + 0.79147893f32, + 0.7984665f32, + 0.8054878f32, + 0.812543f32, + 0.819632f32, + 0.8267549f32, + 0.8339117f32, + 0.8411025f32, + 0.8483272f32, + 0.855586f32, + 0.86287874f32, + 0.8702055f32, + 0.87756646f32, + 0.8849615f32, + 0.89239067f32, + 0.899854f32, + 0.90735155f32, + 0.9148833f32, + 0.92244935f32, + 0.93004966f32, + 0.9376843f32, + 0.94535327f32, + 0.9530566f32, + 0.9607943f32, + 0.96856654f32, + 0.97637314f32, + 0.98421425f32, + 0.99208987f32, + 1f32, +]; impl IntoLinear for RecOetf { #[inline] fn into_linear(encoded: u8) -> f64 { @@ -544,150 +1060,150 @@ impl IntoLinear for RecOetf { impl IntoLinear for RecOetf { #[inline] fn into_linear(encoded: u8) -> f32 { - REC_OETF_U8_TO_F64[encoded as usize] as f32 + REC_OETF_U8_TO_F32[encoded as usize] } } const ADOBE_RGB_U8_TO_F64: [f64; 256] = [ 0f64, - 0.000005099078671483772f64, - 0.000023416529145944588f64, - 0.00005711967424262004f64, - 0.00010753586531413795f64, - 0.00017566273965992924f64, - 0.00026231101790786116f64, - 0.0003681689574752952f64, - 0.000493837590395549f64, - 0.0006398522940681912f64, - 0.0008066970384487725f64, - 0.000994814328511686f64, - 0.001204612439202574f64, - 0.0014364708566854964f64, - 0.0016907444812660011f64, - 0.0019677669462239726f64, + 0.000005099078671483812f64, + 0.00002341652914594477f64, + 0.00005711967424262048f64, + 0.00010753586531413878f64, + 0.0001756627396599306f64, + 0.00026231101790786317f64, + 0.00036816895747529804f64, + 0.0004938375903955528f64, + 0.0006398522940681874f64, + 0.0008066970384487688f64, + 0.0009948143285116826f64, + 0.0012046124392025709f64, + 0.0014364708566854938f64, + 0.0016907444812659992f64, + 0.0019677669462239717f64, 0.0022678532876009793f64, - 0.0025913021261326904f64, - 0.002938397475006459f64, - 0.003309410255569632f64, - 0.003704599581572246f64, - 0.004124213857464298f64, - 0.004568491725509789f64, - 0.005037662888651392f64, - 0.005531948830267081f64, - 0.006051563447608712f64, - 0.006596713612400081f64, - 0.007167599669516955f64, - 0.007764415882681342f64, - 0.008387350834533198f64, - 0.00903658778719564f64, - 0.009712305008449064f64, + 0.0025913021261326917f64, + 0.0029383974750064614f64, + 0.003309410255569636f64, + 0.0037045995815722516f64, + 0.004124213857464306f64, + 0.004568491725509799f64, + 0.005037662888651404f64, + 0.005531948830267067f64, + 0.006051563447608699f64, + 0.006596713612400069f64, + 0.007167599669516945f64, + 0.007764415882681334f64, + 0.00838735083453319f64, + 0.009036587787195637f64, + 0.009712305008449062f64, 0.010414676067820225f64, - 0.011143870106232962f64, - 0.011900052082325955f64, - 0.012683382998095918f64, - 0.013494020106153153f64, - 0.014332117100565749f64, - 0.015197824293007839f64, - 0.016091288775706775f64, - 0.01701265457249706f64, - 0.01796206277912936f64, - 0.01893965169384599f64, - 0.019945556939117915f64, - 0.020979911575335148f64, - 0.022042846207156474f64, - 0.023134489083147004f64, + 0.011143870106232967f64, + 0.01190005208232596f64, + 0.01268338299809593f64, + 0.013494020106153163f64, + 0.014332117100565768f64, + 0.015197824293007858f64, + 0.0160912887757068f64, + 0.017012654572497087f64, + 0.01796206277912934f64, + 0.01893965169384597f64, + 0.0199455569391179f64, + 0.020979911575335134f64, + 0.022042846207156467f64, + 0.023134489083146997f64, 0.02425496618926588f64, 0.025404401336708245f64, - 0.026582916244554385f64, - 0.027790630617634104f64, - 0.029027662219974645f64, - 0.030294126944165375f64, - 0.03159013887694136f64, - 0.03291581036126015f64, - 0.03427125205512166f64, - 0.03565657298735822f64, - 0.03707188061060401f64, - 0.03851728085163244f64, - 0.03999287815923697f64, - 0.041498775549814945f64, - 0.043035074650801364f64, - 0.04460187574208815f64, + 0.026582916244554392f64, + 0.027790630617634114f64, + 0.029027662219974663f64, + 0.030294126944165393f64, + 0.031590138876941384f64, + 0.03291581036126018f64, + 0.03427125205512162f64, + 0.035656572987358186f64, + 0.037071880610603986f64, + 0.03851728085163241f64, + 0.03999287815923695f64, + 0.041498775549814924f64, + 0.04303507465080135f64, + 0.04460187574208813f64, 0.04619927779555348f64, 0.0478273785128165f64, 0.0494862743613236f64, - 0.051176060608865086f64, - 0.052896831356613154f64, - 0.054648679570766086f64, - 0.05643169711287717f64, - 0.05824597476894142f64, - 0.06009160227730828f64, - 0.06196866835548356f64, - 0.06387726072587985f64, - 0.06581746614057067f64, - 0.06778937040509941f64, - 0.06979305840139281f64, - 0.07182861410982208f64, + 0.05117606060886511f64, + 0.052896831356613175f64, + 0.054648679570766114f64, + 0.0564316971128772f64, + 0.05824597476894147f64, + 0.06009160227730833f64, + 0.06196866835548361f64, + 0.0638772607258799f64, + 0.06581746614057064f64, + 0.06778937040509939f64, + 0.06979305840139277f64, + 0.07182861410982205f64, 0.07389612063045584f64, 0.07599566020354347f64, 0.0781273142292669f64, 0.08029116328679532f64, - 0.08248728715267618f64, - 0.08471576481859312f64, - 0.08697667450852041f64, - 0.08927009369530113f64, - 0.09159609911667517f64, - 0.09395476679078107f64, - 0.09634617203115636f64, - 0.09877038946125596f64, - 0.10122749302851121f64, - 0.10371755601794813f64, - 0.1062406510653839f64, - 0.10879685017021867f64, + 0.08248728715267621f64, + 0.08471576481859315f64, + 0.08697667450852045f64, + 0.08927009369530116f64, + 0.09159609911667511f64, + 0.093954766790781f64, + 0.0963461720311563f64, + 0.0987703894612559f64, + 0.10122749302851117f64, + 0.1037175560179481f64, + 0.10624065106538386f64, + 0.10879685017021863f64, 0.11138622470783986f64, 0.11400884544165421f64, 0.11666478253476295f64, 0.11935410556129411f64, - 0.12207688351740557f64, - 0.1248331848319717f64, - 0.12762307737696574f64, - 0.1304466284775496f64, - 0.13330390492188232f64, - 0.13619497297065736f64, - 0.1391198983663791f64, - 0.14207874634238815f64, - 0.1450715816316445f64, - 0.14809846847527655f64, - 0.1511594706309067f64, - 0.1542546513807582f64, + 0.12207688351740562f64, + 0.12483318483197174f64, + 0.12762307737696577f64, + 0.13044662847754965f64, + 0.1333039049218824f64, + 0.13619497297065744f64, + 0.1391198983663792f64, + 0.14207874634238823f64, + 0.14507158163164446f64, + 0.14809846847527652f64, + 0.15115947063090668f64, + 0.15425465138075814f64, 0.1573840735395531f64, 0.16054779946220837f64, 0.1637458910513361f64, 0.16697840976455555f64, - 0.17024541662162285f64, - 0.17354697221138468f64, - 0.1768831366985615f64, - 0.18025396983036632f64, - 0.18365953094296436f64, - 0.18709987896777752f64, - 0.19057507243764182f64, - 0.19408516949281832f64, - 0.1976302278868651f64, - 0.20121030499237388f64, - 0.20482545780657502f64, - 0.20847574295681542f64, + 0.1702454166216229f64, + 0.17354697221138474f64, + 0.17688313669856154f64, + 0.18025396983036637f64, + 0.18365953094296425f64, + 0.1870998789677774f64, + 0.19057507243764174f64, + 0.1940851694928182f64, + 0.19763022788686505f64, + 0.20121030499237383f64, + 0.20482545780657496f64, + 0.20847574295681537f64, 0.21216121670591326f64, 0.21588193495739272f64, 0.2196379532606032f64, 0.22342932681572564f64, 0.22725611047866973f64, 0.23111835876586506f64, - 0.23501612585894965f64, - 0.23894946560935806f64, - 0.24291843154281278f64, - 0.24692307686372134f64, - 0.2509634544594814f64, - 0.25503961690469745f64, - 0.25915161646531004f64, - 0.26329950510264183f64, + 0.23501612585894976f64, + 0.23894946560935817f64, + 0.2429184315428129f64, + 0.24692307686372145f64, + 0.25096345445948154f64, + 0.25503961690469756f64, + 0.25915161646531015f64, + 0.26329950510264194f64, 0.26748333447736095f64, 0.2717031559533646f64, 0.27595902060158656f64, @@ -696,14 +1212,14 @@ const ADOBE_RGB_U8_TO_F64: [f64; 256] = [ 0.2889433799722819f64, 0.293343922288497f64, 0.29778075886520106f64, - 0.30225393909139636f64, - 0.306763512087763f64, - 0.31130952670991674f64, - 0.31589203155160284f64, - 0.3205110749478321f64, - 0.325166704977958f64, - 0.32985896946869814f64, - 0.33458791599709964f64, + 0.3022539390913962f64, + 0.30676351208776287f64, + 0.3113095267099166f64, + 0.3158920315516027f64, + 0.320511074947832f64, + 0.3251667049779579f64, + 0.329858969468698f64, + 0.3345879159970995f64, 0.3393535918934514f64, 0.3441560442441435f64, 0.34899531989447563f64, @@ -712,14 +1228,14 @@ const ADOBE_RGB_U8_TO_F64: [f64; 256] = [ 0.36373455153753737f64, 0.3687215841131433f64, 0.3737456706933901f64, - 0.3788068567332928f64, - 0.38390518746509966f64, - 0.3890407079007324f64, - 0.39421346283418496f64, - 0.3994234968438819f64, - 0.40467085429499766f64, - 0.4099555793417367f64, - 0.4152777159295765f64, + 0.37880685673329295f64, + 0.38390518746509983f64, + 0.38904070790073253f64, + 0.39421346283418507f64, + 0.39942349684388206f64, + 0.40467085429499783f64, + 0.4099555793417369f64, + 0.4152777159295767f64, 0.42063730779747355f64, 0.426034398480032f64, 0.43146903130964015f64, @@ -728,14 +1244,14 @@ const ADOBE_RGB_U8_TO_F64: [f64; 256] = [ 0.44799861301525684f64, 0.45358384378540717f64, 0.45920683040363275f64, - 0.46486761503196766f64, - 0.4705662396442454f64, - 0.4763027460279797f64, - 0.4820771757862125f64, - 0.4878895703393362f64, - 0.4937399709268865f64, - 0.49962841860930873f64, - 0.5055549542696978f64, + 0.4648676150319675f64, + 0.47056623964424527f64, + 0.4763027460279795f64, + 0.48207717578621234f64, + 0.48788957033933605f64, + 0.4937399709268863f64, + 0.49962841860930857f64, + 0.5055549542696977f64, 0.511519618615511f64, 0.5175224521802562f64, 0.5235634953251542f64, @@ -744,14 +1260,14 @@ const ADOBE_RGB_U8_TO_F64: [f64; 256] = [ 0.5419162833029051f64, 0.5481105649917183f64, 0.5543432555389864f64, - 0.5606143943057827f64, - 0.5669240204918702f64, - 0.5732721731371813f64, - 0.5796588911232757f64, - 0.5860842131747781f64, - 0.592548177860795f64, - 0.5990508235963127f64, - 0.6055921886435751f64, + 0.5606143943057829f64, + 0.5669240204918703f64, + 0.5732721731371814f64, + 0.5796588911232758f64, + 0.5860842131747783f64, + 0.5925481778607952f64, + 0.5990508235963129f64, + 0.6055921886435752f64, 0.6121723111134431f64, 0.6187912289667334f64, 0.625448980015543f64, @@ -760,14 +1276,14 @@ const ADOBE_RGB_U8_TO_F64: [f64; 256] = [ 0.6456556082524908f64, 0.6524690672751842f64, 0.6593215463680848f64, - 0.666213082477736f64, - 0.6731437124107257f64, - 0.680113472834875f64, - 0.6871224002804079f64, - 0.6941705311411074f64, - 0.7012579016754557f64, - 0.7083845480077609f64, - 0.7155505061292678f64, + 0.6662130824777358f64, + 0.6731437124107256f64, + 0.6801134728348749f64, + 0.6871224002804077f64, + 0.6941705311411072f64, + 0.7012579016754554f64, + 0.7083845480077606f64, + 0.7155505061292676f64, 0.7227558118992558f64, 0.7300005010461207f64, 0.7372846091684455f64, @@ -776,14 +1292,14 @@ const ADOBE_RGB_U8_TO_F64: [f64; 256] = [ 0.7593738014488893f64, 0.766815938899294f64, 0.7742976714073675f64, - 0.7818190338145282f64, - 0.789380060839501f64, - 0.7969807870792837f64, - 0.804621247010104f64, - 0.8123014749883621f64, - 0.8200215052515643f64, - 0.8277813719192433f64, - 0.8355811089938693f64, + 0.7818190338145284f64, + 0.7893800608395011f64, + 0.7969807870792839f64, + 0.8046212470101042f64, + 0.8123014749883624f64, + 0.8200215052515645f64, + 0.8277813719192435f64, + 0.8355811089938695f64, 0.8434207503617492f64, 0.8513003297939138f64, 0.8592198809469983f64, @@ -792,19 +1308,277 @@ const ADOBE_RGB_U8_TO_F64: [f64; 256] = [ 0.8832186996003203f64, 0.8912984719456563f64, 0.8994183826091531f64, - 0.907578464578937f64, - 0.915778750734602f64, - 0.9240192738480124f64, - 0.9323000665840909f64, - 0.9406211615016012f64, - 0.9489825910539206f64, - 0.9573843875898036f64, - 0.9658265833541383f64, + 0.9075784645789368f64, + 0.9157787507346018f64, + 0.9240192738480122f64, + 0.9323000665840907f64, + 0.9406211615016009f64, + 0.9489825910539202f64, + 0.9573843875898034f64, + 0.9658265833541381f64, 0.9743092104886921f64, 0.9828323010328516f64, 0.9913958869243519f64, 1f64, ]; +const ADOBE_RGB_U8_TO_F32: [f32; 256] = [ + 0f32, + 0.000005099079f32, + 0.000023416529f32, + 0.000057119676f32, + 0.00010753587f32, + 0.00017566275f32, + 0.00026231102f32, + 0.00036816896f32, + 0.0004938376f32, + 0.0006398523f32, + 0.00080669706f32, + 0.0009948143f32, + 0.0012046124f32, + 0.0014364709f32, + 0.0016907445f32, + 0.001967767f32, + 0.0022678534f32, + 0.0025913022f32, + 0.0029383975f32, + 0.0033094103f32, + 0.0037045996f32, + 0.004124214f32, + 0.0045684916f32, + 0.005037663f32, + 0.005531949f32, + 0.0060515637f32, + 0.006596714f32, + 0.0071675996f32, + 0.007764416f32, + 0.0083873505f32, + 0.009036588f32, + 0.009712305f32, + 0.010414676f32, + 0.01114387f32, + 0.011900052f32, + 0.012683383f32, + 0.01349402f32, + 0.0143321175f32, + 0.015197825f32, + 0.016091289f32, + 0.017012654f32, + 0.017962063f32, + 0.018939652f32, + 0.019945556f32, + 0.020979911f32, + 0.022042846f32, + 0.023134489f32, + 0.024254967f32, + 0.025404401f32, + 0.026582915f32, + 0.02779063f32, + 0.029027661f32, + 0.030294128f32, + 0.031590138f32, + 0.032915812f32, + 0.03427125f32, + 0.03565657f32, + 0.03707188f32, + 0.03851728f32, + 0.039992876f32, + 0.041498777f32, + 0.043035075f32, + 0.044601876f32, + 0.046199277f32, + 0.047827378f32, + 0.049486276f32, + 0.05117606f32, + 0.05289683f32, + 0.05464868f32, + 0.056431696f32, + 0.058245976f32, + 0.060091604f32, + 0.06196867f32, + 0.06387726f32, + 0.06581747f32, + 0.06778937f32, + 0.06979306f32, + 0.07182861f32, + 0.07389612f32, + 0.07599566f32, + 0.07812732f32, + 0.08029117f32, + 0.082487285f32, + 0.08471576f32, + 0.08697668f32, + 0.08927009f32, + 0.0915961f32, + 0.093954764f32, + 0.09634617f32, + 0.09877039f32, + 0.10122749f32, + 0.10371756f32, + 0.10624065f32, + 0.10879685f32, + 0.111386225f32, + 0.114008844f32, + 0.11666478f32, + 0.11935411f32, + 0.122076884f32, + 0.12483318f32, + 0.12762308f32, + 0.13044663f32, + 0.13330391f32, + 0.13619497f32, + 0.1391199f32, + 0.14207874f32, + 0.14507158f32, + 0.14809847f32, + 0.15115947f32, + 0.15425465f32, + 0.15738407f32, + 0.1605478f32, + 0.1637459f32, + 0.1669784f32, + 0.17024542f32, + 0.17354697f32, + 0.17688313f32, + 0.18025397f32, + 0.18365952f32, + 0.18709987f32, + 0.19057508f32, + 0.19408517f32, + 0.19763023f32, + 0.2012103f32, + 0.20482546f32, + 0.20847574f32, + 0.21216121f32, + 0.21588193f32, + 0.21963796f32, + 0.22342932f32, + 0.2272561f32, + 0.23111837f32, + 0.23501612f32, + 0.23894946f32, + 0.24291843f32, + 0.24692307f32, + 0.25096345f32, + 0.2550396f32, + 0.2591516f32, + 0.2632995f32, + 0.26748332f32, + 0.27170315f32, + 0.275959f32, + 0.28025097f32, + 0.28457907f32, + 0.28894338f32, + 0.29334393f32, + 0.29778075f32, + 0.30225393f32, + 0.3067635f32, + 0.31130952f32, + 0.31589204f32, + 0.32051107f32, + 0.3251667f32, + 0.32985896f32, + 0.3345879f32, + 0.3393536f32, + 0.34415606f32, + 0.34899533f32, + 0.35387146f32, + 0.35878453f32, + 0.36373454f32, + 0.36872157f32, + 0.37374568f32, + 0.37880686f32, + 0.3839052f32, + 0.3890407f32, + 0.39421347f32, + 0.3994235f32, + 0.40467086f32, + 0.4099556f32, + 0.41527772f32, + 0.4206373f32, + 0.4260344f32, + 0.43146902f32, + 0.43694124f32, + 0.4424511f32, + 0.4479986f32, + 0.45358384f32, + 0.45920682f32, + 0.46486762f32, + 0.47056624f32, + 0.47630274f32, + 0.48207718f32, + 0.48788956f32, + 0.49373996f32, + 0.49962842f32, + 0.505555f32, + 0.5115196f32, + 0.51752245f32, + 0.5235635f32, + 0.52964276f32, + 0.53576034f32, + 0.5419163f32, + 0.54811054f32, + 0.5543433f32, + 0.5606144f32, + 0.56692404f32, + 0.57327217f32, + 0.57965887f32, + 0.5860842f32, + 0.5925482f32, + 0.5990508f32, + 0.6055922f32, + 0.6121723f32, + 0.6187912f32, + 0.625449f32, + 0.6321456f32, + 0.63888115f32, + 0.64565563f32, + 0.65246904f32, + 0.65932155f32, + 0.6662131f32, + 0.6731437f32, + 0.6801135f32, + 0.6871224f32, + 0.69417053f32, + 0.7012579f32, + 0.7083846f32, + 0.7155505f32, + 0.7227558f32, + 0.7300005f32, + 0.7372846f32, + 0.74460816f32, + 0.75197124f32, + 0.7593738f32, + 0.76681596f32, + 0.77429765f32, + 0.78181905f32, + 0.7893801f32, + 0.7969808f32, + 0.8046212f32, + 0.81230146f32, + 0.8200215f32, + 0.8277814f32, + 0.8355811f32, + 0.84342074f32, + 0.85130036f32, + 0.8592199f32, + 0.86717945f32, + 0.87517905f32, + 0.8832187f32, + 0.8912985f32, + 0.89941835f32, + 0.90757847f32, + 0.91577876f32, + 0.9240193f32, + 0.9323001f32, + 0.94062114f32, + 0.9489826f32, + 0.9573844f32, + 0.9658266f32, + 0.9743092f32, + 0.9828323f32, + 0.9913959f32, + 1f32, +]; impl IntoLinear for AdobeRgb { #[inline] fn into_linear(encoded: u8) -> f64 { @@ -814,150 +1588,150 @@ impl IntoLinear for AdobeRgb { impl IntoLinear for AdobeRgb { #[inline] fn into_linear(encoded: u8) -> f32 { - ADOBE_RGB_U8_TO_F64[encoded as usize] as f32 + ADOBE_RGB_U8_TO_F32[encoded as usize] } } const P3_GAMMA_U8_TO_F64: [f64; 256] = [ 0f64, - 0.0000005533444149690793f64, - 0.0000033548531870185513f64, - 0.000009627439389133453f64, - 0.0000203400262150969f64, - 0.00003633436228319558f64, - 0.00005836987750073729f64, - 0.00008714659739316771f64, - 0.00012331885878991266f64, - 0.00016750433669167724f64, - 0.0002202903793849237f64, - 0.0002822386669863676f64, - 0.0003538887612522046f64, - 0.0004357608875904013f64, - 0.0005283581655353502f64, - 0.0006321684310192821f64, + 0.0000005533444149690844f64, + 0.000003354853187018582f64, + 0.000009627439389133542f64, + 0.000020340026215097088f64, + 0.00003633436228319591f64, + 0.00005836987750073783f64, + 0.00008714659739316851f64, + 0.0001233188587899138f64, + 0.00016750433669167605f64, + 0.00022029037938492248f64, + 0.0002822386669863664f64, + 0.00035388876125220354f64, + 0.00043576088759040036f64, + 0.0005283581655353496f64, + 0.0006321684310192818f64, 0.0007476657489241151f64, - 0.0008753116856482296f64, - 0.0010155563923436347f64, - 0.001168839536437422f64, - 0.0013355911099063485f64, - 0.0015162321362163316f64, - 0.0017111752930441836f64, - 0.0019208254643317685f64, - 0.0021455802325272386f64, - 0.0023858303198023467f64, - 0.0026419599854321865f64, - 0.0029143473852649804f64, - 0.003203364898211895f64, - 0.0035093794238871927f64, - 0.003832752654883247f64, - 0.0041738413266387666f64, + 0.0008753116856482301f64, + 0.0010155563923436356f64, + 0.0011688395364374236f64, + 0.0013355911099063509f64, + 0.0015162321362163348f64, + 0.0017111752930441878f64, + 0.001920825464331774f64, + 0.0021455802325272316f64, + 0.0023858303198023407f64, + 0.002641959985432181f64, + 0.002914347385264975f64, + 0.0032033648982118905f64, + 0.0035093794238871896f64, + 0.003832752654883245f64, + 0.004173841326638766f64, 0.004532997447426741f64, - 0.004910568510631667f64, - 0.005306897691188655f64, - 0.005722324027808446f64, - 0.006157182592403123f64, - 0.0066118046479502f64, - 0.0070865177958821385f64, - 0.0075816461139596f64, - 0.008097510285476249f64, - 0.008634427720547658f64, - 0.00919271267015421f64, - 0.009772676333536906f64, - 0.010374626959481452f64, - 0.010998869941972439f64, - 0.011645707910650796f64, + 0.0049105685106316695f64, + 0.005306897691188657f64, + 0.005722324027808451f64, + 0.006157182592403129f64, + 0.006611804647950211f64, + 0.007086517795882149f64, + 0.0075816461139596135f64, + 0.008097510285476263f64, + 0.008634427720547646f64, + 0.009192712670154198f64, + 0.009772676333536897f64, + 0.010374626959481444f64, + 0.010998869941972435f64, + 0.01164570791065079f64, 0.012315440816465727f64, 0.01300836601287503f64, - 0.013724778332914616f64, - 0.014464970162428831f64, - 0.015229231509727017f64, - 0.016017850071908493f64, - 0.016831111298077323f64, - 0.017669298449649522f64, - 0.018532692657938707f64, - 0.019421572979190657f64, - 0.020336216447224754f64, - 0.02127689812382614f64, - 0.022243891147023107f64, - 0.023237466777372994f64, - 0.024257894442371072f64, - 0.025305441779088465f64, + 0.013724778332914621f64, + 0.014464970162428837f64, + 0.015229231509727027f64, + 0.016017850071908507f64, + 0.01683111129807734f64, + 0.01766929844964954f64, + 0.01853269265793868f64, + 0.019421572979190633f64, + 0.020336216447224734f64, + 0.021276898123826122f64, + 0.022243891147023093f64, + 0.02323746677737298f64, + 0.024257894442371062f64, + 0.02530544177908846f64, 0.02638037467513755f64, 0.027482957308056236f64, 0.028613452183196275f64, - 0.029772120170194837f64, - 0.030959220538103217f64, - 0.032175010989241706f64, - 0.033419747691845095f64, - 0.03469368531155907f64, - 0.03599707704184408f64, - 0.037330174633339416f64, - 0.03869322842223743f64, - 0.040086487357714355f64, - 0.041510199028461245f64, - 0.04296460968835732f64, - 0.044449964281323126f64, + 0.029772120170194854f64, + 0.030959220538103235f64, + 0.03217501098924172f64, + 0.03341974769184511f64, + 0.034693685311559114f64, + 0.035997077041844114f64, + 0.03733017463333945f64, + 0.03869322842223747f64, + 0.04008648735771434f64, + 0.041510199028461224f64, + 0.0429646096883573f64, + 0.044449964281323105f64, 0.04596650646539108f64, 0.04751447863602751f64, 0.04909412194873887f64, 0.050705676340992725f64, - 0.052349380553482705f64, - 0.05402547215076479f64, - 0.055734187541290996f64, - 0.05747576199686513f64, - 0.05925042967154394f64, - 0.06105842362000526f64, - 0.06289997581540575f64, - 0.064775317166746f64, - 0.06668467753576356f64, - 0.06862828575337131f64, - 0.07060636963565843f64, - 0.0726191559994701f64, + 0.05234938055348273f64, + 0.05402547215076481f64, + 0.05573418754129102f64, + 0.05747576199686516f64, + 0.05925042967154389f64, + 0.06105842362000521f64, + 0.0628999758154057f64, + 0.06477531716674595f64, + 0.06668467753576353f64, + 0.06862828575337128f64, + 0.0706063696356584f64, + 0.07261915599947007f64, 0.07466687067758179f64, 0.0767497385334826f64, 0.078867983475782f64, 0.08102182847225325f64, - 0.0832114955635266f64, - 0.08543720587644402f64, - 0.08769917963708794f64, - 0.08999763618349435f64, - 0.0923327939780616f64, - 0.09470487061966486f64, - 0.09711408285548591f64, - 0.09956064659256803f64, - 0.10204477690910467f64, - 0.10456668806546995f64, - 0.10712659351500124f64, - 0.10972470591453895f64, + 0.08321149556352662f64, + 0.08543720587644406f64, + 0.08769917963708797f64, + 0.08999763618349438f64, + 0.09233279397806167f64, + 0.09470487061966493f64, + 0.09711408285548598f64, + 0.09956064659256811f64, + 0.10204477690910463f64, + 0.10456668806546991f64, + 0.10712659351500121f64, + 0.10972470591453891f64, 0.11236123713473313f64, 0.11503639827012348f64, 0.1177503996489998f64, 0.12050345084304953f64, - 0.12329576067679901f64, - 0.12612753723685452f64, - 0.128998987880949f64, - 0.13191031924680052f64, - 0.13486173726078762f64, - 0.1378534471464465f64, - 0.14088565343279696f64, - 0.14395855996249937f64, - 0.1470723698998494f64, - 0.1502272857386142f64, - 0.15342350930971502f64, - 0.15666124178875954f64, + 0.12329576067679905f64, + 0.12612753723685455f64, + 0.12899898788094905f64, + 0.13191031924680055f64, + 0.13486173726078754f64, + 0.13785344714644643f64, + 0.14088565343279688f64, + 0.1439585599624993f64, + 0.14707236989984934f64, + 0.15022728573861419f64, + 0.15342350930971496f64, + 0.1566612417887595f64, 0.1599406837034294f64, 0.1632620349407254f64, 0.1666254947540754f64, 0.17003126177030786f64, 0.17347953399649485f64, 0.17697050882666807f64, - 0.18050438304841077f64, - 0.1840813528493295f64, - 0.18770161382340803f64, - 0.19136536097724682f64, - 0.19507278873619108f64, - 0.1988240909503498f64, - 0.202619460900509f64, - 0.2064590913039412f64, + 0.18050438304841088f64, + 0.1840813528493296f64, + 0.18770161382340814f64, + 0.19136536097724693f64, + 0.1950727887361912f64, + 0.19882409095034992f64, + 0.2026194609005091f64, + 0.2064590913039413f64, 0.21034317432011446f64, 0.21427190155630182f64, 0.21824546407309697f64, @@ -966,14 +1740,14 @@ const P3_GAMMA_U8_TO_F64: [f64; 256] = [ 0.23043706582605444f64, 0.2345918693254253f64, 0.23879245539473126f64, - 0.24303901192518917f64, - 0.24733172629743128f64, - 0.25167078538633014f64, - 0.25605637556574373f64, - 0.26048868271318537f64, - 0.2649678922144201f64, - 0.2694941889679877f64, - 0.2740677573896557f64, + 0.24303901192518904f64, + 0.24733172629743114f64, + 0.25167078538633003f64, + 0.2560563755657436f64, + 0.26048868271318526f64, + 0.26496789221441996f64, + 0.2694941889679876f64, + 0.27406775738965555f64, 0.2786887814168023f64, 0.2833574445127321f64, 0.2880739296709251f64, @@ -982,14 +1756,14 @@ const P3_GAMMA_U8_TO_F64: [f64; 256] = [ 0.30251214049394426f64, 0.3074217345846281f64, 0.31238005880186526f64, - 0.31738729340588406f64, - 0.32244361821509177f64, - 0.3275492126098414f64, - 0.3327042555361442f64, - 0.33790892550932883f64, - 0.343163400617647f64, - 0.348467858525829f64, - 0.3538224764785875f64, + 0.31738729340588423f64, + 0.32244361821509193f64, + 0.3275492126098415f64, + 0.33270425553614436f64, + 0.33790892550932894f64, + 0.34316340061764716f64, + 0.3484678585258291f64, + 0.35382247647858767f64, 0.35922743130407325f64, 0.3646828994172803f64, 0.37018905682340675f64, @@ -998,14 +1772,14 @@ const P3_GAMMA_U8_TO_F64: [f64; 256] = [ 0.3870134187735747f64, 0.3927240853224089f64, 0.3984863151575601f64, - 0.40430028189344247f64, - 0.4101661587569316f64, - 0.41608411859037775f64, - 0.4220543338545758f64, - 0.42807697663169686f64, - 0.4341522186281823f64, - 0.4402802311775992f64, - 0.4464611852434591f64, + 0.4043002818934423f64, + 0.4101661587569314f64, + 0.4160841185903776f64, + 0.42205433385457564f64, + 0.4280769766316967f64, + 0.43415221862818215f64, + 0.440280231177599f64, + 0.44646118524345896f64, 0.4526952514220008f64, 0.4589825999449365f64, 0.4653234006821642f64, @@ -1014,14 +1788,14 @@ const P3_GAMMA_U8_TO_F64: [f64; 256] = [ 0.4846682095073477f64, 0.49122451065743256f64, 0.49783510803661735f64, - 0.504500169398975f64, - 0.5112198621548164f64, - 0.517994353373143f64, - 0.5248238097840705f64, - 0.5317083977812223f64, - 0.5386482834240943f64, - 0.545643632440392f64, - 0.5526946102283391f64, + 0.5045001693989752f64, + 0.5112198621548165f64, + 0.5179943533731431f64, + 0.5248238097840706f64, + 0.5317083977812224f64, + 0.5386482834240944f64, + 0.5456436324403923f64, + 0.5526946102283393f64, 0.5598013818589584f64, 0.5669641120783259f64, 0.5741829653098001f64, @@ -1030,14 +1804,14 @@ const P3_GAMMA_U8_TO_F64: [f64; 256] = [ 0.5961779025157271f64, 0.60362288565137f64, 0.6111248091513098f64, - 0.6186838355479508f64, - 0.626300127065866f64, - 0.6339738456238317f64, - 0.6417051528368333f64, - 0.6494942100180511f64, - 0.6573411781808244f64, - 0.6652462180405926f64, - 0.6732094900168157f64, + 0.6186838355479506f64, + 0.6263001270658658f64, + 0.6339738456238315f64, + 0.641705152836833f64, + 0.6494942100180509f64, + 0.6573411781808242f64, + 0.6652462180405924f64, + 0.6732094900168155f64, 0.6812311542348733f64, 0.6893113705279428f64, 0.6974502984388571f64, @@ -1046,14 +1820,14 @@ const P3_GAMMA_U8_TO_F64: [f64; 256] = [ 0.7222209429902862f64, 0.7305963070579263f64, 0.7390311761660405f64, - 0.7475257081533022f64, - 0.7560800605804975f64, - 0.76469439073223f64, - 0.773368855618608f64, - 0.7821036119769139f64, - 0.790898816273256f64, - 0.7997546247042039f64, - 0.8086711931984062f64, + 0.7475257081533025f64, + 0.7560800605804978f64, + 0.7646943907322303f64, + 0.7733688556186084f64, + 0.7821036119769141f64, + 0.7908988162732563f64, + 0.7997546247042041f64, + 0.8086711931984065f64, 0.8176486774181934f64, 0.82668723276116f64, 0.8357870143617376f64, @@ -1062,19 +1836,277 @@ const P3_GAMMA_U8_TO_F64: [f64; 256] = [ 0.8634552641384868f64, 0.8728014969045629f64, 0.8822097277067559f64, - 0.8916801101325879f64, - 0.9012127975169663f64, - 0.9108079429436354f64, - 0.9204656992466088f64, - 0.9301862190115894f64, - 0.9399696545773759f64, - 0.9498161580372557f64, - 0.9597258812403842f64, + 0.8916801101325876f64, + 0.9012127975169659f64, + 0.9108079429436351f64, + 0.9204656992466086f64, + 0.930186219011589f64, + 0.9399696545773756f64, + 0.9498161580372555f64, + 0.9597258812403839f64, 0.9696989757931505f64, 0.9797355930605306f64, 0.9898358841674278f64, 1f64, ]; +const P3_GAMMA_U8_TO_F32: [f32; 256] = [ + 0f32, + 0.0000005533444f32, + 0.000003354853f32, + 0.00000962744f32, + 0.000020340027f32, + 0.00003633436f32, + 0.00005836988f32, + 0.000087146596f32, + 0.00012331885f32, + 0.00016750433f32, + 0.00022029039f32, + 0.00028223867f32, + 0.00035388875f32, + 0.00043576089f32, + 0.00052835816f32, + 0.00063216843f32, + 0.00074766576f32, + 0.00087531167f32, + 0.0010155564f32, + 0.0011688395f32, + 0.0013355911f32, + 0.0015162322f32, + 0.0017111753f32, + 0.0019208255f32, + 0.0021455802f32, + 0.0023858303f32, + 0.00264196f32, + 0.0029143475f32, + 0.0032033648f32, + 0.0035093795f32, + 0.0038327526f32, + 0.0041738413f32, + 0.0045329975f32, + 0.0049105687f32, + 0.0053068977f32, + 0.005722324f32, + 0.0061571826f32, + 0.0066118045f32, + 0.0070865178f32, + 0.007581646f32, + 0.00809751f32, + 0.008634428f32, + 0.009192713f32, + 0.009772676f32, + 0.010374627f32, + 0.01099887f32, + 0.011645708f32, + 0.012315441f32, + 0.013008366f32, + 0.013724779f32, + 0.01446497f32, + 0.015229232f32, + 0.01601785f32, + 0.016831111f32, + 0.017669298f32, + 0.018532693f32, + 0.019421574f32, + 0.020336216f32, + 0.021276899f32, + 0.02224389f32, + 0.023237467f32, + 0.024257895f32, + 0.025305443f32, + 0.026380375f32, + 0.027482957f32, + 0.028613452f32, + 0.02977212f32, + 0.03095922f32, + 0.032175012f32, + 0.033419747f32, + 0.034693684f32, + 0.035997078f32, + 0.037330173f32, + 0.038693227f32, + 0.04008649f32, + 0.0415102f32, + 0.04296461f32, + 0.044449963f32, + 0.045966506f32, + 0.04751448f32, + 0.049094122f32, + 0.050705675f32, + 0.05234938f32, + 0.05402547f32, + 0.055734187f32, + 0.05747576f32, + 0.05925043f32, + 0.061058424f32, + 0.06289998f32, + 0.06477532f32, + 0.06668468f32, + 0.06862829f32, + 0.07060637f32, + 0.072619155f32, + 0.07466687f32, + 0.07674974f32, + 0.07886799f32, + 0.08102183f32, + 0.0832115f32, + 0.08543721f32, + 0.08769918f32, + 0.089997634f32, + 0.092332795f32, + 0.094704874f32, + 0.097114086f32, + 0.09956065f32, + 0.102044776f32, + 0.104566686f32, + 0.10712659f32, + 0.10972471f32, + 0.11236124f32, + 0.1150364f32, + 0.1177504f32, + 0.12050345f32, + 0.12329576f32, + 0.12612754f32, + 0.128999f32, + 0.13191032f32, + 0.13486174f32, + 0.13785344f32, + 0.14088565f32, + 0.14395855f32, + 0.14707237f32, + 0.15022728f32, + 0.1534235f32, + 0.15666124f32, + 0.15994069f32, + 0.16326204f32, + 0.1666255f32, + 0.17003126f32, + 0.17347953f32, + 0.17697051f32, + 0.18050438f32, + 0.18408135f32, + 0.18770161f32, + 0.19136536f32, + 0.19507279f32, + 0.1988241f32, + 0.20261946f32, + 0.20645909f32, + 0.21034317f32, + 0.2142719f32, + 0.21824546f32, + 0.22226405f32, + 0.22632785f32, + 0.23043707f32, + 0.23459187f32, + 0.23879245f32, + 0.24303901f32, + 0.24733172f32, + 0.25167078f32, + 0.25605637f32, + 0.2604887f32, + 0.2649679f32, + 0.26949418f32, + 0.27406776f32, + 0.2786888f32, + 0.28335744f32, + 0.28807393f32, + 0.29283842f32, + 0.29765108f32, + 0.30251214f32, + 0.30742174f32, + 0.31238005f32, + 0.31738728f32, + 0.3224436f32, + 0.32754922f32, + 0.33270425f32, + 0.33790892f32, + 0.3431634f32, + 0.34846786f32, + 0.35382247f32, + 0.35922742f32, + 0.3646829f32, + 0.37018907f32, + 0.37574607f32, + 0.38135415f32, + 0.3870134f32, + 0.3927241f32, + 0.39848632f32, + 0.40430027f32, + 0.41016614f32, + 0.4160841f32, + 0.42205432f32, + 0.42807698f32, + 0.43415222f32, + 0.44028023f32, + 0.44646117f32, + 0.45269525f32, + 0.4589826f32, + 0.4653234f32, + 0.47171783f32, + 0.47816604f32, + 0.4846682f32, + 0.4912245f32, + 0.4978351f32, + 0.50450015f32, + 0.51121986f32, + 0.51799434f32, + 0.5248238f32, + 0.5317084f32, + 0.5386483f32, + 0.5456436f32, + 0.5526946f32, + 0.5598014f32, + 0.5669641f32, + 0.574183f32, + 0.5814581f32, + 0.5887897f32, + 0.5961779f32, + 0.6036229f32, + 0.6111248f32, + 0.6186838f32, + 0.62630016f32, + 0.63397384f32, + 0.64170516f32, + 0.64949423f32, + 0.6573412f32, + 0.6652462f32, + 0.6732095f32, + 0.68123114f32, + 0.6893114f32, + 0.6974503f32, + 0.7056481f32, + 0.7139049f32, + 0.72222096f32, + 0.7305963f32, + 0.7390312f32, + 0.7475257f32, + 0.75608003f32, + 0.7646944f32, + 0.77336884f32, + 0.7821036f32, + 0.7908988f32, + 0.7997546f32, + 0.8086712f32, + 0.81764865f32, + 0.8266872f32, + 0.835787f32, + 0.8449482f32, + 0.85417086f32, + 0.86345524f32, + 0.8728015f32, + 0.8822097f32, + 0.8916801f32, + 0.9012128f32, + 0.91080797f32, + 0.9204657f32, + 0.9301862f32, + 0.93996966f32, + 0.94981617f32, + 0.95972586f32, + 0.96969897f32, + 0.9797356f32, + 0.98983586f32, + 1f32, +]; impl IntoLinear for P3Gamma { #[inline] fn into_linear(encoded: u8) -> f64 { @@ -1084,7 +2116,7 @@ impl IntoLinear for P3Gamma { impl IntoLinear for P3Gamma { #[inline] fn into_linear(encoded: u8) -> f32 { - P3_GAMMA_U8_TO_F64[encoded as usize] as f32 + P3_GAMMA_U8_TO_F32[encoded as usize] } } @@ -67974,7 +69006,7 @@ const TO_PROPHOTO_RGB_U16: [u64; 1152usize] = [ 2574833890387642652u64, 2581770211031068172u64, 2588691658202747693u64, - 2595598330686929020u64, + 2595598330686929021u64, 2602490327267859963u64, 2609367755319722921u64, 2616230713626765700u64, @@ -68008,7 +69040,7 @@ const TO_PROPHOTO_RGB_U16: [u64; 1152usize] = [ 2802889558519058100u64, 2809371561816881403u64, 2815841620810654563u64, - 2822299812809788907u64, + 2822299812809788908u64, 2828746197943826581u64, 2835180857817146206u64, 2841603852559289927u64, @@ -68018,14 +69050,14 @@ const TO_PROPHOTO_RGB_U16: [u64; 1152usize] = [ 2867180563195575076u64, 2873546258779023016u64, 2879900692958220874u64, - 2886243930157678090u64, - 2892576034801904102u64, + 2886243930157678089u64, + 2892576034801904103u64, 2898897067020441057u64, 2905209814249992225u64, 2917797062019457377u64, 2930341016518579073u64, 2942842163078661756u64, - 2955300965556173391u64, + 2955300961261206095u64, 2967717887807581941u64, 2980093385099420779u64, 2992427908403255980u64, @@ -68035,7 +69067,7 @@ const TO_PROPHOTO_RGB_U16: [u64; 1152usize] = [ 3041364847378185057u64, 3053500891653338473u64, 3065598465906421800u64, - 3077657969569393562u64, + 3077657969569393563u64, 3089679784894343102u64, 3101664298428327056u64, 3113611875243565581u64, @@ -68055,7 +69087,7 @@ const TO_PROPHOTO_RGB_U16: [u64; 1152usize] = [ 3277195239538900797u64, 3288629722381092235u64, 3300032486889802845u64, - 3311403816532874161u64, + 3311403816532874162u64, 3322743990483180422u64, 3334053287913595866u64, 3345331979407060138u64, @@ -68070,7 +69102,7 @@ const TO_PROPHOTO_RGB_U16: [u64; 1152usize] = [ 3445505769394278591u64, 3456492484715994638u64, 3467451329994927047u64, - 3478382541454277098u64, + 3478382537159309802u64, 3489286333842409588u64, 3500162934792591204u64, 3511012567643121336u64, @@ -68083,7 +69115,7 @@ const TO_PROPHOTO_RGB_U16: [u64; 1152usize] = [ 3586222556007079068u64, 3596863951663230695u64, 3607480221760700812u64, - 3618071555278050440u64, + 3618071555278050441u64, 3628638141193840604u64, 3639180168486632326u64, 3649697821840019332u64, @@ -68104,7 +69136,7 @@ const TO_PROPHOTO_RGB_U16: [u64; 1152usize] = [ 3804656363524071560u64, 3814807338339531086u64, 3824936748124197466u64, - 3835044743201926058u64, + 3835044738906958762u64, 3845131465306637629u64, 3855197069057154835u64, 3865241687597463851u64, @@ -68224,7 +69256,7 @@ const TO_PROPHOTO_RGB_U16: [u64; 1152usize] = [ 5471279832458059259u64, 5486460763732943101u64, 5501608164198147183u64, - 5516722270076872783u64, + 5516722274371840078u64, 5531803326182255771u64, 5546851560147562835u64, 5561867203901027958u64, @@ -68241,8 +69273,8 @@ const TO_PROPHOTO_RGB_U16: [u64; 1152usize] = [ 5724951802234276097u64, 5739593435940639427u64, 5754205249689066720u64, - 5768787445343020888u64, - 5783340207586095658u64, + 5768787441048053592u64, + 5783340207586095657u64, 5797863729691819347u64, 5812358209228687573u64, 5826823830880294061u64, @@ -68253,7 +69285,7 @@ const TO_PROPHOTO_RGB_U16: [u64; 1152usize] = [ 5898725478950606039u64, 5913021780106502819u64, 5927290477507588287u64, - 5941531755837456171u64, + 5941531751542488875u64, 5955745769714929126u64, 5969932703823600878u64, 5984092712782294083u64, @@ -68262,10 +69294,10 @@ const TO_PROPHOTO_RGB_U16: [u64; 1152usize] = [ 6026412868090715145u64, 6040466834306870410u64, 6054494691416833365u64, - 6068496594039426663u64, + 6068496594039426664u64, 6082472701088440258u64, 6096423158592762211u64, - 6110348129761149771u64, + 6110348125466182475u64, 6124247756327523704u64, 6138122188615739370u64, 6151971581244619424u64, @@ -68300,7 +69332,7 @@ const TO_PROPHOTO_RGB_U16: [u64; 1152usize] = [ 6802645820785371818u64, 6828142709454446727u64, 6853563663101728697u64, - 6878909403281723448u64, + 6878909403281723449u64, 6904180651548936706u64, 6929378116572972303u64, 6954502494138532186u64, @@ -68317,7 +69349,7 @@ const TO_PROPHOTO_RGB_U16: [u64; 1152usize] = [ 7226235132106810746u64, 7250532917446455117u64, 7274765732815813158u64, - 7298934140855600640u64, + 7298934140855600639u64, 7323038695616598743u64, 7347079946854621353u64, 7371058422850645873u64, @@ -68351,15 +69383,15 @@ const TO_PROPHOTO_RGB_U16: [u64; 1152usize] = [ 8018934057400198019u64, 8041295632828107064u64, 8063607571318976404u64, - 8085870225060124308u64, + 8085870225060124307u64, 8108083954828803637u64, 8130249099927430775u64, 8152366008248356694u64, 8174435019093997778u64, - 8196456467471803112u64, + 8196456467471803113u64, 8218430684094254487u64, 8240357999673833693u64, - 8262238732038120631u64, + 8262238732038120632u64, 8284073207604629797u64, 8305861739905973797u64, 8327604642474765237u64, @@ -68375,24 +69407,24 @@ const TO_PROPHOTO_RGB_U16: [u64; 1152usize] = [ 8542590287037796576u64, 8563850907728921656u64, 8585069386200938510u64, - 8606245993036786784u64, + 8606245993036786785u64, 8627380994524438830u64, - 8648474656951866998u64, - 8669527242312076341u64, + 8648474656951866997u64, + 8669527242312076342u64, 8690539008303104621u64, 8711510208328022298u64, 8732441100084867132u64, - 8753331932681742290u64, + 8753331932681742289u64, 8774182955226750937u64, 8794994412533028946u64, 8815766545118744891u64, 8836499597797034643u64, - 8857193802496132184u64, + 8857193806791099480u64, 8877849404029173386u64, - 8898466630029424935u64, + 8898466625734457639u64, 8919045708130153519u64, 8939586870259593120u64, - 8960090339756043130u64, + 8960090344051010426u64, 8980556348547737530u64, 9000985111383041121u64, 9021376847305285997u64, @@ -68401,7 +69433,7 @@ const TO_PROPHOTO_RGB_U16: [u64; 1152usize] = [ 9082332062552152805u64, 9102577846895745403u64, 9122787673773135986u64, - 9142961745047787464u64, + 9142961745047787465u64, 9163100266878130045u64, 9183203441127626639u64, 9203271473954707454u64, diff --git a/palette/src/encoding/p3.rs b/palette/src/encoding/p3.rs index 283c9935..ba690650 100644 --- a/palette/src/encoding/p3.rs +++ b/palette/src/encoding/p3.rs @@ -159,6 +159,19 @@ impl LumaStandard for DciP3Plus { } /// A gamma 2.6 transfer function used by some P3 variants +/// +/// `P3Gamma` will not use any kind of approximation when converting from `T` to +/// `T`. This involves calls to `powf`, which may make it too slow for certain +/// applications. +/// +/// There are some specialized cases where it has been optimized: +/// +/// * When converting from `u8` to `f32` or `f64`, while converting to linear +/// space. This uses lookup tables with precomputed values. +/// * When converting from `f32` or `f64` to `u8`, while converting from linear +/// space. This uses a fast algorithm that guarantees a maximum error in the +/// result of less than 0.6 in line with [this DirectX spec] +/// (https://microsoft.github.io/DirectX-Specs/d3d/archive/D3D11_3_FunctionalSpec.htm#FLOATtoSRGB). #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct P3Gamma; diff --git a/palette/src/encoding/prophoto.rs b/palette/src/encoding/prophoto.rs index f3fba8bd..321bcde2 100644 --- a/palette/src/encoding/prophoto.rs +++ b/palette/src/encoding/prophoto.rs @@ -21,6 +21,15 @@ use crate::{ /// `ProPhotoRgb` will not use any kind of approximation when converting from `T` to /// `T`. This involves a call to `powf`, which may make it too slow for certain /// applications. +/// +/// Using the `gamma_lut_u16` feature allows certain specialized optimizations: +/// +/// * When converting from `u16` to `f32` or `f64`, while converting to linear +/// space. This uses lookup tables with precomputed values. +/// * When converting from `f32` or `f64` to `u16`, while converting from linear +/// space. This uses a fast algorithm that guarantees a maximum error in the +/// result of less than 0.6 in line with [this DirectX spec] +/// (https://microsoft.github.io/DirectX-Specs/d3d/archive/D3D11_3_FunctionalSpec.htm#FLOATtoSRGB). #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct ProPhotoRgb; diff --git a/palette/src/encoding/rec_standards.rs b/palette/src/encoding/rec_standards.rs index 2260507e..e61f751b 100644 --- a/palette/src/encoding/rec_standards.rs +++ b/palette/src/encoding/rec_standards.rs @@ -11,13 +11,7 @@ use crate::{ Mat3, Yxy, }; -/// The Rec. 2020 standard, color space, and transfer function. -/// -/// # As transfer function -/// -/// `Rec2020` will not use any kind of approximation when converting from `T` to -/// `T`. This involves calls to `powf`, which may make it too slow for certain -/// applications. +/// The Rec. 2020 standard, color space, and transfer function ([`RecOetf`]). #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct Rec2020; @@ -74,13 +68,7 @@ impl LumaStandard for Rec2020 { type TransferFn = RecOetf; } -/// The Rec. 709 standard, color space, and transfer function. -/// -/// # As transfer function -/// -/// `Rec709` will not use any kind of approximation when converting from `T` to -/// `T`. This involves calls to `powf`, which may make it too slow for certain -/// applications. +/// The Rec. 709 standard, color space, and transfer function ([`RecOetf`]). #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct Rec709; @@ -96,6 +84,19 @@ impl LumaStandard for Rec709 { /// The opto-electronic transfer function used in standard dynamic range (SDR) /// standards by the ITU-R such as [`Rec709`] and [`Rec2020`]. +/// +/// `RecOetf` will not use any kind of approximation when converting from `T` to +/// `T`. This involves calls to `powf`, which may make it too slow for certain +/// applications. +/// +/// There are some specialized cases where it has been optimized: +/// +/// * When converting from `u8` to `f32` or `f64`, while converting to linear +/// space. This uses lookup tables with precomputed values. +/// * When converting from `f32` or `f64` to `u8`, while converting from linear +/// space. This uses a fast algorithm that guarantees a maximum error in the +/// result of less than 0.6 in line with [this DirectX spec] +/// (https://microsoft.github.io/DirectX-Specs/d3d/archive/D3D11_3_FunctionalSpec.htm#FLOATtoSRGB). #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct RecOetf; diff --git a/palette/src/encoding/srgb.rs b/palette/src/encoding/srgb.rs index e5826ec3..3f8838d4 100644 --- a/palette/src/encoding/srgb.rs +++ b/palette/src/encoding/srgb.rs @@ -21,10 +21,11 @@ use crate::{ /// There are some specialized cases where it has been optimized: /// /// * When converting from `u8` to `f32` or `f64`, while converting to linear -/// space. This uses lookup tables with precomputed values provided that the -/// `float_lut` feature (enabled by default) is being used. +/// space. This uses lookup tables with precomputed values. /// * When converting from `f32` or `f64` to `u8`, while converting from linear -/// space if the `fast_uint_lut` feature (enabled by default) is being used. +/// space. This uses a fast algorithm that guarantees a maximum error in the +/// result of less than 0.6 in line with [this DirectX spec] +/// (https://microsoft.github.io/DirectX-Specs/d3d/archive/D3D11_3_FunctionalSpec.htm#FLOATtoSRGB). #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct Srgb;