From a458bf18ffbb83da4512b4c9c3c3c96d355069e7 Mon Sep 17 00:00:00 2001 From: Butkovits Atila Date: Thu, 5 Nov 2020 16:22:51 +0200 Subject: [PATCH] Backed out changeset 0cb7e54c81fd (bug 1675425) for bustages complaining about calling unsafe function. CLOSED TREE --- gfx/qcms/src/chain.rs | 60 +++++++++++++-------- gfx/qcms/src/transform.rs | 79 +++++++++++++++++++--------- gfx/qcms/src/transform_util.rs | 96 ++++++++++++++++++++++++---------- 3 files changed, 160 insertions(+), 75 deletions(-) diff --git a/gfx/qcms/src/chain.rs b/gfx/qcms/src/chain.rs index b971aa3aad94..83a2478ab0c1 100644 --- a/gfx/qcms/src/chain.rs +++ b/gfx/qcms/src/chain.rs @@ -54,9 +54,9 @@ pub struct qcms_modular_transform { pub output_clut_table_g: *mut f32, pub output_clut_table_b: *mut f32, pub output_clut_table_length: u16, - pub output_gamma_lut_r: Option>, - pub output_gamma_lut_g: Option>, - pub output_gamma_lut_b: Option>, + pub output_gamma_lut_r: *mut u16, + pub output_gamma_lut_g: *mut u16, + pub output_gamma_lut_b: *mut u16, pub output_gamma_lut_r_length: usize, pub output_gamma_lut_g_length: usize, pub output_gamma_lut_b_length: usize, @@ -584,15 +584,24 @@ unsafe extern "C" fn qcms_transform_module_gamma_lut( let mut in_b: f32 = *fresh32; out_r = lut_interp_linear( in_r as f64, - &(*transform).output_gamma_lut_r.as_ref().unwrap(), + std::slice::from_raw_parts( + (*transform).output_gamma_lut_r, + (*transform).output_gamma_lut_r_length, + ), ); out_g = lut_interp_linear( in_g as f64, - &(*transform).output_gamma_lut_g.as_ref().unwrap(), + std::slice::from_raw_parts( + (*transform).output_gamma_lut_g, + (*transform).output_gamma_lut_g_length, + ), ); out_b = lut_interp_linear( in_b as f64, - &(*transform).output_gamma_lut_b.as_ref().unwrap(), + std::slice::from_raw_parts( + (*transform).output_gamma_lut_b, + (*transform).output_gamma_lut_b_length, + ), ); let fresh33 = dest; dest = dest.offset(1); @@ -756,14 +765,14 @@ unsafe extern "C" fn qcms_modular_transform_release(mut transform: *mut qcms_mod free((*transform).output_clut_table_b as *mut libc::c_void); } } - if !(*transform).output_gamma_lut_r.is_none() { - (*transform).output_gamma_lut_r = None; + if !(*transform).output_gamma_lut_r.is_null() { + free((*transform).output_gamma_lut_r as *mut libc::c_void); } - if !(*transform).output_gamma_lut_g.is_none() { - (*transform).output_gamma_lut_g = None; + if !(*transform).output_gamma_lut_g.is_null() { + free((*transform).output_gamma_lut_g as *mut libc::c_void); } - if !(*transform).output_gamma_lut_b.is_none() { - (*transform).output_gamma_lut_b = None; + if !(*transform).output_gamma_lut_b.is_null() { + free((*transform).output_gamma_lut_b as *mut libc::c_void); } free(transform as *mut libc::c_void); transform = next_transform @@ -1257,12 +1266,21 @@ unsafe extern "C" fn qcms_modular_transform_create_output( current_block = 15713701561912628542; } else { append_transform(transform, &mut next_transform); - (*transform).output_gamma_lut_r = - Some(build_output_lut((*out).redTRC.as_deref().unwrap())); - (*transform).output_gamma_lut_g = - Some(build_output_lut((*out).greenTRC.as_deref().unwrap())); - (*transform).output_gamma_lut_b = - Some(build_output_lut((*out).blueTRC.as_deref().unwrap())); + build_output_lut( + (*out).redTRC.as_deref().unwrap(), + &mut (*transform).output_gamma_lut_r, + &mut (*transform).output_gamma_lut_r_length, + ); + build_output_lut( + (*out).greenTRC.as_deref().unwrap(), + &mut (*transform).output_gamma_lut_g, + &mut (*transform).output_gamma_lut_g_length, + ); + build_output_lut( + (*out).blueTRC.as_deref().unwrap(), + &mut (*transform).output_gamma_lut_b, + &mut (*transform).output_gamma_lut_b_length, + ); (*transform).transform_module_fn = Some( qcms_transform_module_gamma_lut as unsafe extern "C" fn( @@ -1272,9 +1290,9 @@ unsafe extern "C" fn qcms_modular_transform_create_output( _: usize, ) -> (), ); - if (*transform).output_gamma_lut_r.is_none() - || (*transform).output_gamma_lut_g.is_none() - || (*transform).output_gamma_lut_b.is_none() + if (*transform).output_gamma_lut_r.is_null() + || (*transform).output_gamma_lut_g.is_null() + || (*transform).output_gamma_lut_b.is_null() { current_block = 15713701561912628542; } else { diff --git a/gfx/qcms/src/transform.rs b/gfx/qcms/src/transform.rs index fb06ecd44a96..2b58b9b6d2e4 100644 --- a/gfx/qcms/src/transform.rs +++ b/gfx/qcms/src/transform.rs @@ -109,10 +109,10 @@ pub struct qcms_transform { pub out_gamma_g: f32, pub out_gamma_b: f32, pub out_gamma_gray: f32, - pub output_gamma_lut_r: Option>, - pub output_gamma_lut_g: Option>, - pub output_gamma_lut_b: Option>, - pub output_gamma_lut_gray: Option>, + pub output_gamma_lut_r: *mut u16, + pub output_gamma_lut_g: *mut u16, + pub output_gamma_lut_b: *mut u16, + pub output_gamma_lut_gray: *mut u16, pub output_gamma_lut_r_length: usize, pub output_gamma_lut_g_length: usize, pub output_gamma_lut_b_length: usize, @@ -147,10 +147,10 @@ impl Default for qcms_transform { out_gamma_g: Default::default(), out_gamma_b: Default::default(), out_gamma_gray: Default::default(), - output_gamma_lut_r: Default::default(), - output_gamma_lut_g: Default::default(), - output_gamma_lut_b: Default::default(), - output_gamma_lut_gray: Default::default(), + output_gamma_lut_r: null_mut(), + output_gamma_lut_g: null_mut(), + output_gamma_lut_b: null_mut(), + output_gamma_lut_gray: null_mut(), output_gamma_lut_r_length: Default::default(), output_gamma_lut_g_length: Default::default(), output_gamma_lut_b_length: Default::default(), @@ -534,15 +534,24 @@ unsafe extern "C" fn qcms_transform_data_gray_template_lut( let mut out_device_r: f32 = lut_interp_linear( out_linear_r as f64, - &(*transform).output_gamma_lut_r.as_ref().unwrap(), + std::slice::from_raw_parts( + (*transform).output_gamma_lut_r, + (*transform).output_gamma_lut_r_length, + ), ); let mut out_device_g: f32 = lut_interp_linear( out_linear_g as f64, - (*transform).output_gamma_lut_g.as_ref().unwrap(), + std::slice::from_raw_parts( + (*transform).output_gamma_lut_g, + (*transform).output_gamma_lut_g_length, + ), ); let mut out_device_b: f32 = lut_interp_linear( out_linear_b as f64, - (*transform).output_gamma_lut_b.as_ref().unwrap(), + std::slice::from_raw_parts( + (*transform).output_gamma_lut_b, + (*transform).output_gamma_lut_b_length, + ), ); *dest.offset(F::kRIndex as isize) = clamp_u8(out_device_r * 255f32); *dest.offset(F::kGIndex as isize) = clamp_u8(out_device_g * 255f32); @@ -1126,9 +1144,9 @@ pub unsafe extern "C" fn qcms_transform_release(mut t: *mut qcms_transform) { (*t).input_gamma_table_b = None; (*t).input_gamma_table_gray = None; - (*t).output_gamma_lut_r = None; - (*t).output_gamma_lut_g = None; - (*t).output_gamma_lut_b = None; + free((*t).output_gamma_lut_r as *mut libc::c_void); + free((*t).output_gamma_lut_g as *mut libc::c_void); + free((*t).output_gamma_lut_b as *mut libc::c_void); /* r_clut points to beginning of buffer allocated in qcms_transform_precacheLUT_float */ if !(*t).r_clut.is_null() { free((*t).r_clut as *mut libc::c_void); @@ -1379,15 +1397,24 @@ pub unsafe extern "C" fn qcms_transform_create( qcms_transform_release(transform); return 0 as *mut qcms_transform; } - (*transform).output_gamma_lut_r = Some(build_output_lut((*out).redTRC.as_deref().unwrap())); - (*transform).output_gamma_lut_g = - Some(build_output_lut((*out).greenTRC.as_deref().unwrap())); - (*transform).output_gamma_lut_b = - Some(build_output_lut((*out).blueTRC.as_deref().unwrap())); - - if (*transform).output_gamma_lut_r.is_none() - || (*transform).output_gamma_lut_g.is_none() - || (*transform).output_gamma_lut_b.is_none() + build_output_lut( + (*out).redTRC.as_deref().unwrap(), + &mut (*transform).output_gamma_lut_r, + &mut (*transform).output_gamma_lut_r_length, + ); + build_output_lut( + (*out).greenTRC.as_deref().unwrap(), + &mut (*transform).output_gamma_lut_g, + &mut (*transform).output_gamma_lut_g_length, + ); + build_output_lut( + (*out).blueTRC.as_deref().unwrap(), + &mut (*transform).output_gamma_lut_b, + &mut (*transform).output_gamma_lut_b_length, + ); + if (*transform).output_gamma_lut_r.is_null() + || (*transform).output_gamma_lut_g.is_null() + || (*transform).output_gamma_lut_b.is_null() { qcms_transform_release(transform); return 0 as *mut qcms_transform; diff --git a/gfx/qcms/src/transform_util.rs b/gfx/qcms/src/transform_util.rs index d33cd126291c..9ce0113f3e5e 100644 --- a/gfx/qcms/src/transform_util.rs +++ b/gfx/qcms/src/transform_util.rs @@ -22,6 +22,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. use ::libc; +use libc::{free, malloc}; use crate::matrix::matrix; use crate::{ @@ -378,14 +379,20 @@ invert_lut will produce an inverse of: which has an maximum error of about 9855 (pixel difference of ~38.346) For now, we punt the decision of output size to the caller. */ -fn invert_lut(mut table: &[u16], mut out_length: i32) -> Vec { +unsafe fn invert_lut(mut table: &[u16], mut out_length: i32) -> *mut u16 { /* for now we invert the lut by creating a lut of size out_length * and attempting to lookup a value for each entry using lut_inverse_interp16 */ - let mut output = Vec::with_capacity(out_length as usize); - for i in 0..out_length { + let mut output: *mut u16 = + malloc(::std::mem::size_of::() * out_length as usize) as *mut u16; + if output.is_null() { + return 0 as *mut u16; + } + let mut i: i32 = 0; + while i < out_length { let mut x: f64 = i as f64 * 65535.0f64 / (out_length - 1) as f64; let mut input: uint16_fract_t = (x + 0.5f64).floor() as uint16_fract_t; - output.push(lut_inverse_interp16(input, table)); + *output.offset(i as isize) = lut_inverse_interp16(input, table); + i += 1 } return output; } @@ -440,8 +447,12 @@ pub unsafe extern "C" fn compute_precache(mut trc: &curveType, mut output: *mut if inverted_size < 256 { inverted_size = 256 } - let mut inverted = invert_lut(&gamma_table_uint, inverted_size); - compute_precache_lut(output, inverted.as_mut_ptr(), inverted_size); + let mut inverted: *mut u16 = invert_lut(&gamma_table_uint, inverted_size); + if inverted.is_null() { + return false; + } + compute_precache_lut(output, inverted, inverted_size); + free(inverted as *mut libc::c_void); } curveType::Curve(data) => { if data.len() == 0 { @@ -460,58 +471,87 @@ pub unsafe extern "C" fn compute_precache(mut trc: &curveType, mut output: *mut if inverted_size_0 < 256 { inverted_size_0 = 256 } //XXX turn this conversion into a function - let mut inverted_0 = invert_lut(data, inverted_size_0); - compute_precache_lut(output, inverted_0.as_mut_ptr(), inverted_size_0); + let mut inverted_0: *mut u16 = invert_lut(data, inverted_size_0); + if inverted_0.is_null() { + return false; + } + compute_precache_lut(output, inverted_0, inverted_size_0); + free(inverted_0 as *mut libc::c_void); } } } return true; } -fn build_linear_table(mut length: i32) -> Vec { - let mut output = Vec::with_capacity(length as usize); - for i in 0..length { +unsafe extern "C" fn build_linear_table(mut length: i32) -> *mut u16 { + let mut output: *mut u16 = malloc(::std::mem::size_of::() * length as usize) as *mut u16; + if output.is_null() { + return 0 as *mut u16; + } + let mut i: i32 = 0; + while i < length { let mut x: f64 = i as f64 * 65535.0f64 / (length - 1) as f64; let mut input: uint16_fract_t = (x + 0.5f64).floor() as uint16_fract_t; - output.push(input); + *output.offset(i as isize) = input; + i += 1 } return output; } -fn build_pow_table(mut gamma: f32, mut length: i32) -> Vec { - let mut output = Vec::with_capacity(length as usize); - for i in 0..length { +unsafe extern "C" fn build_pow_table(mut gamma: f32, mut length: i32) -> *mut u16 { + let mut output: *mut u16 = malloc(::std::mem::size_of::() * length as usize) as *mut u16; + if output.is_null() { + return 0 as *mut u16; + } + let mut i: i32 = 0; + while i < length { let mut x: f64 = i as f64 / (length - 1) as f64; x = x.powf(gamma as f64); let mut result: uint16_fract_t = (x * 65535.0f64 + 0.5f64).floor() as uint16_fract_t; - output.push(result); + *output.offset(i as isize) = result; + i += 1 } return output; } -pub fn build_output_lut(mut trc: &curveType) -> Vec { +#[no_mangle] +pub unsafe extern "C" fn build_output_lut( + mut trc: &curveType, + mut output_gamma_lut: *mut *mut u16, + mut output_gamma_lut_length: *mut usize, +) { match trc { curveType::Parametric(params) => { let mut gamma_table = Vec::with_capacity(256); - let mut output = Vec::with_capacity(256); - compute_curve_gamma_table_type_parametric(&mut gamma_table, params); - for i in 0..256 { - output.push((gamma_table[i as usize] * 65535f32) as u16); + + let mut output: *mut u16 = malloc(::std::mem::size_of::() * 256) as *mut u16; + if output.is_null() { + *output_gamma_lut = 0 as *mut u16; + return; } - return output; + compute_curve_gamma_table_type_parametric(&mut gamma_table, params); + *output_gamma_lut_length = 256; + let mut i: u16 = 0u16; + while (i as i32) < 256 { + *output.offset(i as isize) = (gamma_table[i as usize] * 65535f32) as u16; + i = i + 1 + } + *output_gamma_lut = output } curveType::Curve(data) => { if data.len() == 0 { - return build_linear_table(4096); + *output_gamma_lut = build_linear_table(4096); + *output_gamma_lut_length = 4096 } else if data.len() == 1 { let mut gamma: f32 = (1.0f64 / u8Fixed8Number_to_float(data[0]) as f64) as f32; - return build_pow_table(gamma, 4096); + *output_gamma_lut = build_pow_table(gamma, 4096); + *output_gamma_lut_length = 4096 } else { //XXX: the choice of a minimum of 256 here is not backed by any theory, // measurement or data, however it is what lcms uses. - let mut output_gamma_lut_length = data.len(); - if output_gamma_lut_length < 256 { - output_gamma_lut_length = 256 + *output_gamma_lut_length = data.len(); + if *output_gamma_lut_length < 256 { + *output_gamma_lut_length = 256 } - return invert_lut(data, output_gamma_lut_length as i32); + *output_gamma_lut = invert_lut(data, *output_gamma_lut_length as i32) } } }