diff --git a/gfx/qcms/src/chain.rs b/gfx/qcms/src/chain.rs index 12292330bd2b..fec5d8c55278 100644 --- a/gfx/qcms/src/chain.rs +++ b/gfx/qcms/src/chain.rs @@ -36,15 +36,15 @@ use crate::{ use ::libc::{self, calloc, free, malloc, memcpy}; #[repr(C)] -#[derive(Copy, Clone)] +#[derive(Clone)] pub struct qcms_modular_transform { pub matrix: matrix, pub tx: f32, pub ty: f32, pub tz: f32, - pub input_clut_table_r: *mut f32, - pub input_clut_table_g: *mut f32, - pub input_clut_table_b: *mut f32, + pub input_clut_table_r: Option>, + pub input_clut_table_g: Option>, + pub input_clut_table_b: Option>, pub input_clut_table_length: u16, pub r_clut: *mut f32, pub g_clut: *mut f32, @@ -309,6 +309,9 @@ unsafe extern "C" fn qcms_transform_module_clut( |table: *mut f32, x, y, z| *table.offset(((x * len + y * x_len + z * xy_len) * 3) as isize); let mut i: usize = 0; + let input_clut_table_r = (*transform).input_clut_table_r.as_ref().unwrap(); + let input_clut_table_g = (*transform).input_clut_table_g.as_ref().unwrap(); + let input_clut_table_b = (*transform).input_clut_table_b.as_ref().unwrap(); while i < length { debug_assert!((*transform).grid_size as i32 >= 1); let fresh18 = src; @@ -322,17 +325,17 @@ unsafe extern "C" fn qcms_transform_module_clut( let mut device_b: f32 = *fresh20; let mut linear_r: f32 = lut_interp_linear_float( device_r, - (*transform).input_clut_table_r, + input_clut_table_r.as_ptr(), (*transform).input_clut_table_length as i32, ); let mut linear_g: f32 = lut_interp_linear_float( device_g, - (*transform).input_clut_table_g, + input_clut_table_g.as_ptr(), (*transform).input_clut_table_length as i32, ); let mut linear_b: f32 = lut_interp_linear_float( device_b, - (*transform).input_clut_table_b, + input_clut_table_b.as_ptr(), (*transform).input_clut_table_length as i32, ); let mut x: i32 = (linear_r * ((*transform).grid_size as i32 - 1) as f32).floor() as i32; @@ -530,6 +533,10 @@ unsafe extern "C" fn qcms_transform_module_gamma_table( let mut out_g: f32; let mut out_b: f32; let mut i: usize = 0; + let input_clut_table_r = (*transform).input_clut_table_r.as_ref().unwrap(); + let input_clut_table_g = (*transform).input_clut_table_g.as_ref().unwrap(); + let input_clut_table_b = (*transform).input_clut_table_b.as_ref().unwrap(); + while i < length { let fresh24 = src; src = src.offset(1); @@ -540,9 +547,9 @@ unsafe extern "C" fn qcms_transform_module_gamma_table( let fresh26 = src; src = src.offset(1); let mut in_b: f32 = *fresh26; - out_r = lut_interp_linear_float(in_r, (*transform).input_clut_table_r, 256); - out_g = lut_interp_linear_float(in_g, (*transform).input_clut_table_g, 256); - out_b = lut_interp_linear_float(in_b, (*transform).input_clut_table_b, 256); + out_r = lut_interp_linear_float(in_r, input_clut_table_r.as_ptr(), 256); + out_g = lut_interp_linear_float(in_g, input_clut_table_g.as_ptr(), 256); + out_b = lut_interp_linear_float(in_b, input_clut_table_b.as_ptr(), 256); let fresh27 = dest; dest = dest.offset(1); *fresh27 = clamp_float(out_r); @@ -707,31 +714,11 @@ unsafe extern "C" fn qcms_modular_transform_release(mut transform: *mut qcms_mod let mut next_transform: *mut qcms_modular_transform; while !transform.is_null() { next_transform = (*transform).next_transform; - // clut may use a single block of memory. - // Perhaps we should remove this to simply the code. - if (*transform) - .input_clut_table_r - .offset((*transform).input_clut_table_length as i32 as isize) - == (*transform).input_clut_table_g - && (*transform) - .input_clut_table_g - .offset((*transform).input_clut_table_length as i32 as isize) - == (*transform).input_clut_table_b - { - if !(*transform).input_clut_table_r.is_null() { - free((*transform).input_clut_table_r as *mut libc::c_void); - } - } else { - if !(*transform).input_clut_table_r.is_null() { - free((*transform).input_clut_table_r as *mut libc::c_void); - } - if !(*transform).input_clut_table_g.is_null() { - free((*transform).input_clut_table_g as *mut libc::c_void); - } - if !(*transform).input_clut_table_b.is_null() { - free((*transform).input_clut_table_b as *mut libc::c_void); - } - } + + (*transform).input_clut_table_r = None; + (*transform).input_clut_table_g = None; + (*transform).input_clut_table_b = None; + if (*transform).r_clut.offset(1isize) == (*transform).g_clut && (*transform).g_clut.offset(1isize) == (*transform).b_clut { @@ -1027,12 +1014,21 @@ unsafe extern "C" fn qcms_modular_transform_create_lut( (*lut).input_table.as_ptr() as *mut libc::c_void, in_curve_len, ); - (*transform).input_clut_table_r = - in_curves.offset(((*lut).num_input_table_entries as i32 * 0) as isize); - (*transform).input_clut_table_g = - in_curves.offset(((*lut).num_input_table_entries as i32 * 1) as isize); - (*transform).input_clut_table_b = - in_curves.offset(((*lut).num_input_table_entries as i32 * 2) as isize); + // XXX: in_curves is unused + free(in_curves as *mut libc::c_void); + (*transform).input_clut_table_r = Some( + (*lut).input_table[0..(*lut).num_input_table_entries as usize].to_vec(), + ); + (*transform).input_clut_table_g = Some( + (*lut).input_table[(*lut).num_input_table_entries as usize + ..(*lut).num_input_table_entries as usize * 2] + .to_vec(), + ); + (*transform).input_clut_table_b = Some( + (*lut).input_table[(*lut).num_input_table_entries as usize * 2 + ..(*lut).num_input_table_entries as usize * 3] + .to_vec(), + ); (*transform).input_clut_table_length = (*lut).num_input_table_entries; // Prepare table clut_length = (::std::mem::size_of::() as f64 @@ -1133,9 +1129,9 @@ pub unsafe extern "C" fn qcms_modular_transform_create_input( _: usize, ) -> (), ); - if (*transform).input_clut_table_r.is_null() - || (*transform).input_clut_table_g.is_null() - || (*transform).input_clut_table_b.is_null() + if (*transform).input_clut_table_r.is_none() + || (*transform).input_clut_table_g.is_none() + || (*transform).input_clut_table_b.is_none() { current_block = 8903102000210989603; } else { diff --git a/gfx/qcms/src/transform.rs b/gfx/qcms/src/transform.rs index c3c16d00dc52..678e6639ca95 100644 --- a/gfx/qcms/src/transform.rs +++ b/gfx/qcms/src/transform.rs @@ -89,9 +89,9 @@ impl Default for precache_output { #[derive(Clone)] pub struct qcms_transform { pub matrix: [[f32; 4]; 3], - pub input_gamma_table_r: *mut f32, - pub input_gamma_table_g: *mut f32, - pub input_gamma_table_b: *mut f32, + pub input_gamma_table_r: Option>, + pub input_gamma_table_g: Option>, + pub input_gamma_table_b: Option>, pub input_clut_table_r: *mut f32, pub input_clut_table_g: *mut f32, pub input_clut_table_b: *mut f32, @@ -104,7 +104,7 @@ pub struct qcms_transform { pub output_clut_table_g: *mut f32, pub output_clut_table_b: *mut f32, pub output_clut_table_length: u16, - pub input_gamma_table_gray: *mut f32, + pub input_gamma_table_gray: Option>, pub out_gamma_r: f32, pub out_gamma_g: f32, pub out_gamma_b: f32, @@ -127,9 +127,9 @@ impl Default for qcms_transform { fn default() -> qcms_transform { qcms_transform { matrix: Default::default(), - input_gamma_table_r: null_mut(), - input_gamma_table_b: null_mut(), - input_gamma_table_g: null_mut(), + input_gamma_table_r: Default::default(), + input_gamma_table_b: Default::default(), + input_gamma_table_g: Default::default(), input_clut_table_r: null_mut(), input_clut_table_g: null_mut(), input_clut_table_b: null_mut(), @@ -142,7 +142,7 @@ impl Default for qcms_transform { output_clut_table_g: null_mut(), output_clut_table_b: null_mut(), output_clut_table_length: Default::default(), - input_gamma_table_gray: null_mut(), + input_gamma_table_gray: Default::default(), out_gamma_r: Default::default(), out_gamma_g: Default::default(), out_gamma_b: Default::default(), @@ -513,6 +513,11 @@ unsafe extern "C" fn qcms_transform_data_gray_template_lut( let output_table_r = ((*transform).output_table_r).as_deref().unwrap(); let output_table_g = ((*transform).output_table_g).as_deref().unwrap(); let output_table_b = ((*transform).output_table_b).as_deref().unwrap(); + let input_gamma_table_r = (*transform).input_gamma_table_r.as_ref().unwrap().as_ptr(); + let input_gamma_table_g = (*transform).input_gamma_table_g.as_ref().unwrap().as_ptr(); + let input_gamma_table_b = (*transform).input_gamma_table_b.as_ref().unwrap().as_ptr(); let mut mat: *const [f32; 4] = (*transform).matrix.as_ptr(); let mut i: libc::c_uint = 0; @@ -691,9 +705,9 @@ unsafe extern "C" fn qcms_transform_data_template_lut_precache( } src = src.offset(components as isize); - let mut linear_r: f32 = *(*transform).input_gamma_table_r.offset(device_r as isize); - let mut linear_g: f32 = *(*transform).input_gamma_table_g.offset(device_g as isize); - let mut linear_b: f32 = *(*transform).input_gamma_table_b.offset(device_b as isize); + let mut linear_r: f32 = *input_gamma_table_r.offset(device_r as isize); + let mut linear_g: f32 = *input_gamma_table_g.offset(device_g as isize); + let mut linear_b: f32 = *input_gamma_table_b.offset(device_b as isize); let mut out_linear_r: f32 = (*mat.offset(0isize))[0] * linear_r + (*mat.offset(1isize))[0] * linear_g + (*mat.offset(2isize))[0] * linear_b; @@ -1013,6 +1027,9 @@ unsafe extern "C" fn qcms_transform_data_template_lut( let mut mat: *const [f32; 4] = (*transform).matrix.as_ptr(); let mut i: libc::c_uint = 0; + let input_gamma_table_r = (*transform).input_gamma_table_r.as_ref().unwrap().as_ptr(); + let input_gamma_table_g = (*transform).input_gamma_table_g.as_ref().unwrap().as_ptr(); + let input_gamma_table_b = (*transform).input_gamma_table_b.as_ref().unwrap().as_ptr(); while (i as usize) < length { let mut device_r: libc::c_uchar = *src.offset(F::kRIndex as isize); let mut device_g: libc::c_uchar = *src.offset(F::kGIndex as isize); @@ -1023,9 +1040,9 @@ unsafe extern "C" fn qcms_transform_data_template_lut( } src = src.offset(components as isize); - let mut linear_r: f32 = *(*transform).input_gamma_table_r.offset(device_r as isize); - let mut linear_g: f32 = *(*transform).input_gamma_table_g.offset(device_g as isize); - let mut linear_b: f32 = *(*transform).input_gamma_table_b.offset(device_b as isize); + let mut linear_r: f32 = *input_gamma_table_r.offset(device_r as isize); + let mut linear_g: f32 = *input_gamma_table_g.offset(device_g as isize); + let mut linear_b: f32 = *input_gamma_table_b.offset(device_b as isize); let mut out_linear_r: f32 = (*mat.offset(0isize))[0] * linear_r + (*mat.offset(1isize))[0] * linear_g + (*mat.offset(2isize))[0] * linear_b; @@ -1110,16 +1127,11 @@ pub unsafe extern "C" fn qcms_transform_release(mut t: *mut qcms_transform) { (*t).output_table_g = None; (*t).output_table_b = None; - free((*t).input_gamma_table_r as *mut libc::c_void); - if (*t).input_gamma_table_g != (*t).input_gamma_table_r { - free((*t).input_gamma_table_g as *mut libc::c_void); - } - if (*t).input_gamma_table_g != (*t).input_gamma_table_r - && (*t).input_gamma_table_g != (*t).input_gamma_table_b - { - free((*t).input_gamma_table_b as *mut libc::c_void); - } - free((*t).input_gamma_table_gray as *mut libc::c_void); + (*t).input_gamma_table_r = None; + (*t).input_gamma_table_g = None; + (*t).input_gamma_table_b = None; + + (*t).input_gamma_table_gray = 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); @@ -1454,9 +1466,9 @@ pub unsafe extern "C" fn qcms_transform_create( (*transform).input_gamma_table_r = build_input_gamma_table((*in_0).redTRC.as_deref()); (*transform).input_gamma_table_g = build_input_gamma_table((*in_0).greenTRC.as_deref()); (*transform).input_gamma_table_b = build_input_gamma_table((*in_0).blueTRC.as_deref()); - if (*transform).input_gamma_table_r.is_null() - || (*transform).input_gamma_table_g.is_null() - || (*transform).input_gamma_table_b.is_null() + if (*transform).input_gamma_table_r.is_none() + || (*transform).input_gamma_table_g.is_none() + || (*transform).input_gamma_table_b.is_none() { qcms_transform_release(transform); return 0 as *mut qcms_transform; @@ -1497,7 +1509,7 @@ pub unsafe extern "C" fn qcms_transform_create( (*transform).matrix[2][2] = result_0.m[2][2] } else if (*in_0).color_space == 0x47524159 { (*transform).input_gamma_table_gray = build_input_gamma_table((*in_0).grayTRC.as_deref()); - if (*transform).input_gamma_table_gray.is_null() { + if (*transform).input_gamma_table_gray.is_none() { qcms_transform_release(transform); return 0 as *mut qcms_transform; } diff --git a/gfx/qcms/src/transform_avx.rs b/gfx/qcms/src/transform_avx.rs index e530d89292e9..ba710d9465df 100644 --- a/gfx/qcms/src/transform_avx.rs +++ b/gfx/qcms/src/transform_avx.rs @@ -33,9 +33,9 @@ unsafe extern "C" fn qcms_transform_data_template_lut_avx( * locations in separate registers */ let mut output: *const u32 = &mut input as *mut Output as *mut u32; /* deref *transform now to avoid it in loop */ - let mut igtbl_r: *const f32 = (*transform).input_gamma_table_r; - let mut igtbl_g: *const f32 = (*transform).input_gamma_table_g; - let mut igtbl_b: *const f32 = (*transform).input_gamma_table_b; + let mut igtbl_r: *const f32 = (*transform).input_gamma_table_r.as_ref().unwrap().as_ptr(); + let mut igtbl_g: *const f32 = (*transform).input_gamma_table_g.as_ref().unwrap().as_ptr(); + let mut igtbl_b: *const f32 = (*transform).input_gamma_table_b.as_ref().unwrap().as_ptr(); /* deref *transform now to avoid it in loop */ let mut otdata_r: *const u8 = (*transform) .output_table_r diff --git a/gfx/qcms/src/transform_neon.rs b/gfx/qcms/src/transform_neon.rs index 147c0d27f51e..39d4a6a77ed4 100644 --- a/gfx/qcms/src/transform_neon.rs +++ b/gfx/qcms/src/transform_neon.rs @@ -30,9 +30,9 @@ unsafe extern "C" fn qcms_transform_data_template_lut_neon( * locations in separate registers */ let mut output: *const u32 = input as *mut u32; /* deref *transform now to avoid it in loop */ - let mut igtbl_r: *const f32 = (*transform).input_gamma_table_r; - let mut igtbl_g: *const f32 = (*transform).input_gamma_table_g; - let mut igtbl_b: *const f32 = (*transform).input_gamma_table_b; + let mut igtbl_r: *const f32 = (*transform).input_gamma_table_r.as_ref().unwrap().as_ptr(); + let mut igtbl_g: *const f32 = (*transform).input_gamma_table_g.as_ref().unwrap().as_ptr(); + let mut igtbl_b: *const f32 = (*transform).input_gamma_table_b.as_ref().unwrap().as_ptr(); /* deref *transform now to avoid it in loop */ let mut otdata_r: *const u8 = (*transform) .output_table_r diff --git a/gfx/qcms/src/transform_sse2.rs b/gfx/qcms/src/transform_sse2.rs index 381ef6a57a02..c077f5f428df 100644 --- a/gfx/qcms/src/transform_sse2.rs +++ b/gfx/qcms/src/transform_sse2.rs @@ -26,9 +26,9 @@ unsafe extern "C" fn qcms_transform_data_template_lut_sse2( * locations in separate registers */ let mut output: *const u32 = &mut input as *mut Output as *mut u32; /* deref *transform now to avoid it in loop */ - let mut igtbl_r: *const f32 = (*transform).input_gamma_table_r; - let mut igtbl_g: *const f32 = (*transform).input_gamma_table_g; - let mut igtbl_b: *const f32 = (*transform).input_gamma_table_b; + let mut igtbl_r: *const f32 = (*transform).input_gamma_table_r.as_ref().unwrap().as_ptr(); + let mut igtbl_g: *const f32 = (*transform).input_gamma_table_g.as_ref().unwrap().as_ptr(); + let mut igtbl_b: *const f32 = (*transform).input_gamma_table_b.as_ref().unwrap().as_ptr(); /* deref *transform now to avoid it in loop */ let mut otdata_r: *const u8 = (*transform) .output_table_r diff --git a/gfx/qcms/src/transform_util.rs b/gfx/qcms/src/transform_util.rs index 66d9e8b84be6..cb2d8208458d 100644 --- a/gfx/qcms/src/transform_util.rs +++ b/gfx/qcms/src/transform_util.rs @@ -144,31 +144,26 @@ pub unsafe extern "C" fn lut_interp_linear_float( /* scale the value */ return value; } -#[no_mangle] -pub unsafe extern "C" fn compute_curve_gamma_table_type1( - mut gamma_table: *mut f32, - mut gamma: u16, -) { +fn compute_curve_gamma_table_type1(mut gamma_table: &mut Vec, mut gamma: u16) { let mut gamma_float: f32 = u8Fixed8Number_to_float(gamma); - let mut i: libc::c_uint = 0; - while i < 256 { + for i in 0..256 { // 0..1^(0..255 + 255/256) will always be between 0 and 1 - *gamma_table.offset(i as isize) = (i as f64 / 255.0f64).powf(gamma_float as f64) as f32; - i = i + 1 + gamma_table.push((i as f64 / 255.0f64).powf(gamma_float as f64) as f32); } } #[no_mangle] -pub unsafe fn compute_curve_gamma_table_type2(mut gamma_table: *mut f32, mut table: &[u16]) { - let mut i: libc::c_uint = 0; - while i < 256 { - *gamma_table.offset(i as isize) = - lut_interp_linear(i as f64 / 255.0f64, table.as_ptr(), table.len() as i32); - i = i + 1 +pub unsafe fn compute_curve_gamma_table_type2(mut gamma_table: &mut Vec, mut table: &[u16]) { + for i in 0..256 { + gamma_table.push(lut_interp_linear( + i as f64 / 255.0f64, + table.as_ptr(), + table.len() as i32, + )); } } #[no_mangle] pub unsafe fn compute_curve_gamma_table_type_parametric( - mut gamma_table: *mut f32, + mut gamma_table: &mut Vec, mut params: &[f32], ) { let mut interval: f32; @@ -223,55 +218,51 @@ pub unsafe fn compute_curve_gamma_table_type_parametric( f = 0.; interval = -1. } - let mut X: usize = 0; - while X < 256 { + for X in 0..256 { if X as f32 >= interval { // XXX The equations are not exactly as defined in the spec but are // algebraically equivalent. // TODO Should division by 255 be for the whole expression. - *gamma_table.offset(X as isize) = clamp_float( + gamma_table.push(clamp_float( (((a * X as f32) as f64 / 255.0f64 + b as f64).powf(y as f64) + c as f64 + e as f64) as f32, - ) + )); } else { - *gamma_table.offset(X as isize) = - clamp_float(((c * X as f32) as f64 / 255.0f64 + f as f64) as f32) + gamma_table.push(clamp_float( + ((c * X as f32) as f64 / 255.0f64 + f as f64) as f32, + )); } - X = X + 1 + } +} + +fn compute_curve_gamma_table_type0(mut gamma_table: &mut Vec) { + for i in 0..256 { + gamma_table.push((i as f64 / 255.0f64) as f32); } } #[no_mangle] -pub unsafe extern "C" fn compute_curve_gamma_table_type0(mut gamma_table: *mut f32) { - let mut i: libc::c_uint = 0; - while i < 256 { - *gamma_table.offset(i as isize) = (i as f64 / 255.0f64) as f32; - i = i + 1 - } -} -#[no_mangle] -pub unsafe extern "C" fn build_input_gamma_table(mut TRC: Option<&curveType>) -> *mut f32 { +pub unsafe fn build_input_gamma_table(mut TRC: Option<&curveType>) -> Option> { let TRC = match TRC { Some(TRC) => TRC, - None => return 0 as *mut f32, + None => return None, }; - let mut gamma_table: *mut f32 = malloc(::std::mem::size_of::() * 256) as *mut f32; - if !gamma_table.is_null() { - match TRC { - curveType::Parametric(params) => { - compute_curve_gamma_table_type_parametric(gamma_table, params) - } - curveType::Curve(data) => { - if data.len() == 0 { - compute_curve_gamma_table_type0(gamma_table); - } else if data.len() == 1 { - compute_curve_gamma_table_type1(gamma_table, data[0]); - } else { - compute_curve_gamma_table_type2(gamma_table, data); - } + let mut gamma_table = Vec::with_capacity(256); + match TRC { + curveType::Parametric(params) => { + compute_curve_gamma_table_type_parametric(&mut gamma_table, params) + } + curveType::Curve(data) => { + if data.len() == 0 { + compute_curve_gamma_table_type0(&mut gamma_table); + } else if data.len() == 1 { + compute_curve_gamma_table_type1(&mut gamma_table, data[0]); + } else { + compute_curve_gamma_table_type2(&mut gamma_table, data); } } } - return gamma_table; + + return Some(gamma_table); } #[no_mangle] pub unsafe extern "C" fn build_colorant_matrix(mut p: &qcms_profile) -> matrix { @@ -449,11 +440,11 @@ pub unsafe extern "C" fn compute_precache_linear(mut output: *mut u8) { pub unsafe extern "C" fn compute_precache(mut trc: &curveType, mut output: *mut u8) -> bool { match trc { curveType::Parametric(params) => { - let mut gamma_table: [f32; 256] = [0.; 256]; + let mut gamma_table = Vec::with_capacity(256); let mut gamma_table_uint: [u16; 256] = [0; 256]; let mut inverted_size: i32 = 256; - compute_curve_gamma_table_type_parametric(gamma_table.as_mut_ptr(), params); + compute_curve_gamma_table_type_parametric(&mut gamma_table, params); let mut i: u16 = 0u16; while (i as i32) < 256 { gamma_table_uint[i as usize] = (gamma_table[i as usize] * 65535f32) as u16; @@ -539,14 +530,14 @@ pub unsafe extern "C" fn build_output_lut( ) { match trc { curveType::Parametric(params) => { - let mut gamma_table: [f32; 256] = [0.; 256]; + let mut gamma_table = Vec::with_capacity(256); 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; } - compute_curve_gamma_table_type_parametric(gamma_table.as_mut_ptr(), params); + 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 {