Bug 1555331. Use parametric inversion when building an output_lut. r=aosmond

Previously we didn't invert at all which was causing over saturation.

Differential Revision: https://phabricator.services.mozilla.com/D113226
This commit is contained in:
Jeff Muizelaar 2021-04-26 12:48:33 +00:00
parent bf77763c5d
commit 0fe884da2d
3 changed files with 16 additions and 13 deletions

View File

@ -897,9 +897,9 @@ fn modular_transform_create_output(out: &Profile) -> Option<Vec<Box<dyn ModularT
transforms.push(transform);
let mut transform = Box::new(GammaLut::default());
transform.output_gamma_lut_r = Some(build_output_lut(redTRC));
transform.output_gamma_lut_g = Some(build_output_lut(greenTRC));
transform.output_gamma_lut_b = Some(build_output_lut(blueTRC));
transform.output_gamma_lut_r = Some(build_output_lut(redTRC)?);
transform.output_gamma_lut_g = Some(build_output_lut(greenTRC)?);
transform.output_gamma_lut_b = Some(build_output_lut(blueTRC)?);
transforms.push(transform);
} else {
debug_assert!(false, "Unsupported output profile workflow.");

View File

@ -1350,9 +1350,9 @@ pub fn transform_create(
if output.redTRC.is_none() || output.greenTRC.is_none() || output.blueTRC.is_none() {
return None;
}
transform.output_gamma_lut_r = Some(build_output_lut(output.redTRC.as_deref().unwrap()));
transform.output_gamma_lut_g = Some(build_output_lut(output.greenTRC.as_deref().unwrap()));
transform.output_gamma_lut_b = Some(build_output_lut(output.blueTRC.as_deref().unwrap()));
transform.output_gamma_lut_r = build_output_lut(output.redTRC.as_deref().unwrap());
transform.output_gamma_lut_g = build_output_lut(output.greenTRC.as_deref().unwrap());
transform.output_gamma_lut_b = build_output_lut(output.blueTRC.as_deref().unwrap());
if transform.output_gamma_lut_r.is_none()
|| transform.output_gamma_lut_g.is_none()

View File

@ -534,22 +534,25 @@ fn build_pow_table(gamma: f32, length: i32) -> Vec<u16> {
output
}
pub(crate) fn build_output_lut(trc: &curveType) -> Vec<u16> {
pub(crate) fn build_output_lut(trc: &curveType) -> Option<Vec<u16>> {
match trc {
curveType::Parametric(params) => {
let params = Param::new(params);
let inv_params = params.invert()?;
let mut output = Vec::with_capacity(256);
let gamma_table = compute_curve_gamma_table_type_parametric(params);
for i in 0..256 {
output.push((gamma_table[i as usize] * 65535f32) as u16);
let X = i as f32 / 255.;
output.push((inv_params.eval(X) * 65535.) as u16);
}
output
Some(output)
}
curveType::Curve(data) => {
match data.len() {
0 => build_linear_table(4096),
0 => Some(build_linear_table(4096)),
1 => {
let gamma = 1. / u8Fixed8Number_to_float(data[0]);
build_pow_table(gamma, 4096)
Some(build_pow_table(gamma, 4096))
}
_ => {
//XXX: the choice of a minimum of 256 here is not backed by any theory,
@ -558,7 +561,7 @@ pub(crate) fn build_output_lut(trc: &curveType) -> Vec<u16> {
if output_gamma_lut_length < 256 {
output_gamma_lut_length = 256
}
invert_lut(data, output_gamma_lut_length as i32)
Some(invert_lut(data, output_gamma_lut_length as i32))
}
}
}