зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1667374 - Make curveType more Rust like. r=aosmond
Turns curveType into a enum. The change is mostly mechanical fixing of the the code to the new structure except that for Parametrics curves we now store the result of COUNT_TO_LENGTH as the len. This mostly affects compute_curve_gamma_table_type_parametric where we use the post COUNT_TO_LENGTH instead of the pre COUNT_TO_LENGTH. Differential Revision: https://phabricator.services.mozilla.com/D91421
This commit is contained in:
Родитель
5440a231d9
Коммит
b5a1244a00
|
@ -819,7 +819,7 @@ unsafe extern "C" fn qcms_modular_transform_create_mAB(
|
|||
let mut first_transform: *mut qcms_modular_transform = 0 as *mut qcms_modular_transform;
|
||||
let mut next_transform: *mut *mut qcms_modular_transform = &mut first_transform;
|
||||
let mut transform: *mut qcms_modular_transform;
|
||||
if !(*lut).a_curves[0].is_null() {
|
||||
if !(*lut).a_curves[0].is_none() {
|
||||
let mut clut_length: usize;
|
||||
let mut clut: *mut f32;
|
||||
// If the A curve is present this also implies the
|
||||
|
@ -833,9 +833,12 @@ unsafe extern "C" fn qcms_modular_transform_create_mAB(
|
|||
current_block = 7590209878260659629;
|
||||
} else {
|
||||
append_transform(transform, &mut next_transform);
|
||||
(*transform).input_clut_table_r = build_input_gamma_table((*lut).a_curves[0]);
|
||||
(*transform).input_clut_table_g = build_input_gamma_table((*lut).a_curves[1]);
|
||||
(*transform).input_clut_table_b = build_input_gamma_table((*lut).a_curves[2]);
|
||||
(*transform).input_clut_table_r =
|
||||
build_input_gamma_table((*lut).a_curves[0].as_deref());
|
||||
(*transform).input_clut_table_g =
|
||||
build_input_gamma_table((*lut).a_curves[1].as_deref());
|
||||
(*transform).input_clut_table_b =
|
||||
build_input_gamma_table((*lut).a_curves[2].as_deref());
|
||||
(*transform).transform_module_fn = Some(
|
||||
qcms_transform_module_gamma_table
|
||||
as unsafe extern "C" fn(
|
||||
|
@ -894,7 +897,7 @@ unsafe extern "C" fn qcms_modular_transform_create_mAB(
|
|||
}
|
||||
match current_block {
|
||||
10652014663920648156 => {
|
||||
if !(*lut).m_curves[0].is_null() {
|
||||
if !(*lut).m_curves[0].is_none() {
|
||||
// M curve imples the presence of a Matrix
|
||||
// Prepare M curve
|
||||
transform = qcms_modular_transform_alloc();
|
||||
|
@ -902,9 +905,12 @@ unsafe extern "C" fn qcms_modular_transform_create_mAB(
|
|||
current_block = 7590209878260659629;
|
||||
} else {
|
||||
append_transform(transform, &mut next_transform);
|
||||
(*transform).input_clut_table_r = build_input_gamma_table((*lut).m_curves[0]);
|
||||
(*transform).input_clut_table_g = build_input_gamma_table((*lut).m_curves[1]);
|
||||
(*transform).input_clut_table_b = build_input_gamma_table((*lut).m_curves[2]);
|
||||
(*transform).input_clut_table_r =
|
||||
build_input_gamma_table((*lut).m_curves[0].as_deref());
|
||||
(*transform).input_clut_table_g =
|
||||
build_input_gamma_table((*lut).m_curves[1].as_deref());
|
||||
(*transform).input_clut_table_b =
|
||||
build_input_gamma_table((*lut).m_curves[2].as_deref());
|
||||
(*transform).transform_module_fn = Some(
|
||||
qcms_transform_module_gamma_table
|
||||
as unsafe extern "C" fn(
|
||||
|
@ -947,17 +953,17 @@ unsafe extern "C" fn qcms_modular_transform_create_mAB(
|
|||
match current_block {
|
||||
7590209878260659629 => {}
|
||||
_ => {
|
||||
if !(*lut).b_curves[0].is_null() {
|
||||
if !(*lut).b_curves[0].is_none() {
|
||||
// Prepare B curve
|
||||
transform = qcms_modular_transform_alloc();
|
||||
if !transform.is_null() {
|
||||
append_transform(transform, &mut next_transform);
|
||||
(*transform).input_clut_table_r =
|
||||
build_input_gamma_table((*lut).b_curves[0]);
|
||||
build_input_gamma_table((*lut).b_curves[0].as_deref());
|
||||
(*transform).input_clut_table_g =
|
||||
build_input_gamma_table((*lut).b_curves[1]);
|
||||
build_input_gamma_table((*lut).b_curves[1].as_deref());
|
||||
(*transform).input_clut_table_b =
|
||||
build_input_gamma_table((*lut).b_curves[2]);
|
||||
build_input_gamma_table((*lut).b_curves[2].as_deref());
|
||||
(*transform).transform_module_fn = Some(
|
||||
qcms_transform_module_gamma_table
|
||||
as unsafe extern "C" fn(
|
||||
|
@ -1118,9 +1124,9 @@ pub unsafe extern "C" fn qcms_modular_transform_create_input(
|
|||
current_block = 8903102000210989603;
|
||||
} else {
|
||||
append_transform(transform, &mut next_transform);
|
||||
(*transform).input_clut_table_r = build_input_gamma_table((*in_0).redTRC);
|
||||
(*transform).input_clut_table_g = build_input_gamma_table((*in_0).greenTRC);
|
||||
(*transform).input_clut_table_b = build_input_gamma_table((*in_0).blueTRC);
|
||||
(*transform).input_clut_table_r = build_input_gamma_table((*in_0).redTRC.as_deref());
|
||||
(*transform).input_clut_table_g = build_input_gamma_table((*in_0).greenTRC.as_deref());
|
||||
(*transform).input_clut_table_b = build_input_gamma_table((*in_0).blueTRC.as_deref());
|
||||
(*transform).transform_module_fn = Some(
|
||||
qcms_transform_module_gamma_table
|
||||
as unsafe extern "C" fn(
|
||||
|
@ -1216,7 +1222,7 @@ unsafe extern "C" fn qcms_modular_transform_create_output(
|
|||
append_transform(lut_transform_0, &mut next_transform);
|
||||
current_block = 13131896068329595644;
|
||||
}
|
||||
} else if !(*out).redTRC.is_null() && !(*out).greenTRC.is_null() && !(*out).blueTRC.is_null() {
|
||||
} else if !(*out).redTRC.is_none() && !(*out).greenTRC.is_none() && !(*out).blueTRC.is_none() {
|
||||
let mut transform: *mut qcms_modular_transform = qcms_modular_transform_alloc();
|
||||
if transform.is_null() {
|
||||
current_block = 15713701561912628542;
|
||||
|
@ -1262,17 +1268,17 @@ unsafe extern "C" fn qcms_modular_transform_create_output(
|
|||
} else {
|
||||
append_transform(transform, &mut next_transform);
|
||||
build_output_lut(
|
||||
(*out).redTRC,
|
||||
(*out).redTRC.as_deref().unwrap(),
|
||||
&mut (*transform).output_gamma_lut_r,
|
||||
&mut (*transform).output_gamma_lut_r_length,
|
||||
);
|
||||
build_output_lut(
|
||||
(*out).greenTRC,
|
||||
(*out).greenTRC.as_deref().unwrap(),
|
||||
&mut (*transform).output_gamma_lut_g,
|
||||
&mut (*transform).output_gamma_lut_g_length,
|
||||
);
|
||||
build_output_lut(
|
||||
(*out).blueTRC,
|
||||
(*out).blueTRC.as_deref().unwrap(),
|
||||
&mut (*transform).output_gamma_lut_b,
|
||||
&mut (*transform).output_gamma_lut_b_length,
|
||||
);
|
||||
|
|
|
@ -2,9 +2,7 @@
|
|||
mod test {
|
||||
|
||||
use crate::{
|
||||
iccread::*,
|
||||
transform::*,
|
||||
transform_util::lut_inverse_interp16, QCMS_INTENT_PERCEPTUAL,
|
||||
iccread::*, transform::*, transform_util::lut_inverse_interp16, QCMS_INTENT_PERCEPTUAL,
|
||||
};
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -84,10 +84,10 @@ pub struct qcms_profile {
|
|||
pub redColorant: XYZNumber,
|
||||
pub blueColorant: XYZNumber,
|
||||
pub greenColorant: XYZNumber,
|
||||
pub redTRC: *mut curveType,
|
||||
pub blueTRC: *mut curveType,
|
||||
pub greenTRC: *mut curveType,
|
||||
pub grayTRC: *mut curveType,
|
||||
pub redTRC: Option<Box<curveType>>,
|
||||
pub blueTRC: Option<Box<curveType>>,
|
||||
pub greenTRC: Option<Box<curveType>>,
|
||||
pub grayTRC: Option<Box<curveType>>,
|
||||
pub A2B0: *mut lutType,
|
||||
pub B2A0: *mut lutType,
|
||||
pub mAB: *mut lutmABType,
|
||||
|
@ -122,16 +122,12 @@ impl Drop for qcms_profile {
|
|||
if !self.mBA.is_null() {
|
||||
mAB_release(self.mBA);
|
||||
}
|
||||
free(self.redTRC as *mut libc::c_void);
|
||||
free(self.blueTRC as *mut libc::c_void);
|
||||
free(self.greenTRC as *mut libc::c_void);
|
||||
free(self.grayTRC as *mut libc::c_void);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct lutmABType {
|
||||
pub num_in_channels: u8,
|
||||
pub num_out_channels: u8,
|
||||
|
@ -150,19 +146,17 @@ pub struct lutmABType {
|
|||
pub e23: s15Fixed16Number,
|
||||
pub reversed: bool,
|
||||
pub clut_table: *mut f32,
|
||||
pub a_curves: [*mut curveType; 10],
|
||||
pub b_curves: [*mut curveType; 10],
|
||||
pub m_curves: [*mut curveType; 10],
|
||||
pub a_curves: [Option<Box<curveType>>; 10],
|
||||
pub b_curves: [Option<Box<curveType>>; 10],
|
||||
pub m_curves: [Option<Box<curveType>>; 10],
|
||||
pub clut_table_data: [f32; 0],
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct curveType {
|
||||
pub type_0: u32,
|
||||
pub count: u32,
|
||||
pub parameter: [f32; 7],
|
||||
pub data: [uInt16Number; 0],
|
||||
#[derive(Clone)]
|
||||
pub enum curveType {
|
||||
Curve(Vec<uInt16Number>),
|
||||
Parametric(Vec<f32>),
|
||||
}
|
||||
pub type uInt16Number = u16;
|
||||
|
||||
|
@ -647,93 +641,75 @@ fn read_tag_XYZType(mut src: &mut mem_source, mut index: &tag_index, mut tag_id:
|
|||
// Read the tag at a given offset rather then the tag_index.
|
||||
// This method is used when reading mAB tags where nested curveType are
|
||||
// present that are not part of the tag_index.
|
||||
unsafe extern "C" fn read_curveType(
|
||||
fn read_curveType(
|
||||
mut src: &mut mem_source,
|
||||
mut offset: u32,
|
||||
mut len: *mut u32,
|
||||
) -> *mut curveType {
|
||||
static mut COUNT_TO_LENGTH: [u32; 5] = [1, 3, 4, 5, 7]; //PARAMETRIC_CURVE_TYPE
|
||||
mut len: &mut u32,
|
||||
) -> Option<Box<curveType>> {
|
||||
const COUNT_TO_LENGTH: [u32; 5] = [1, 3, 4, 5, 7]; //PARAMETRIC_CURVE_TYPE
|
||||
let mut curve: *mut curveType;
|
||||
let mut type_0: u32 = read_u32(src, offset as usize);
|
||||
let mut count: u32;
|
||||
let mut i: u32;
|
||||
if type_0 != CURVE_TYPE && type_0 != PARAMETRIC_CURVE_TYPE {
|
||||
invalid_source(src, "unexpected type, expected CURV or PARA");
|
||||
return 0 as *mut curveType;
|
||||
return None;
|
||||
}
|
||||
if type_0 == CURVE_TYPE {
|
||||
count = read_u32(src, (offset + 8) as usize);
|
||||
//arbitrary
|
||||
if count > 40000 {
|
||||
invalid_source(src, "curve size too large");
|
||||
return 0 as *mut curveType;
|
||||
return None;
|
||||
}
|
||||
curve = malloc(
|
||||
::std::mem::size_of::<curveType>()
|
||||
+ ::std::mem::size_of::<uInt16Number>() * count as usize,
|
||||
) as *mut curveType;
|
||||
if curve.is_null() {
|
||||
return 0 as *mut curveType;
|
||||
let mut table = Vec::with_capacity(count as usize);
|
||||
for i in 0..count {
|
||||
table.push(read_u16(src, (offset + 12 + i * 2) as usize));
|
||||
}
|
||||
(*curve).count = count;
|
||||
(*curve).type_0 = CURVE_TYPE;
|
||||
i = 0;
|
||||
while i < count {
|
||||
*(*curve).data.as_mut_ptr().offset(i as isize) =
|
||||
read_u16(src, (offset + 12 + i * 2) as usize);
|
||||
i = i + 1
|
||||
}
|
||||
*len = 12 + count * 2
|
||||
*len = 12 + count * 2;
|
||||
return Some(Box::new(curveType::Curve(table)));
|
||||
} else {
|
||||
count = read_u16(src, (offset + 8) as usize) as u32;
|
||||
if count > 4 {
|
||||
invalid_source(src, "parametric function type not supported.");
|
||||
return 0 as *mut curveType;
|
||||
return None;
|
||||
}
|
||||
curve = malloc(::std::mem::size_of::<curveType>()) as *mut curveType;
|
||||
if curve.is_null() {
|
||||
return 0 as *mut curveType;
|
||||
}
|
||||
(*curve).count = count;
|
||||
(*curve).type_0 = PARAMETRIC_CURVE_TYPE;
|
||||
i = 0;
|
||||
while i < COUNT_TO_LENGTH[count as usize] {
|
||||
(*curve).parameter[i as usize] = s15Fixed16Number_to_float(read_s15Fixed16Number(
|
||||
let mut params = Vec::with_capacity(count as usize);
|
||||
for i in 0..COUNT_TO_LENGTH[count as usize] {
|
||||
params.push(s15Fixed16Number_to_float(read_s15Fixed16Number(
|
||||
src,
|
||||
(offset + 12 + i * 4) as usize,
|
||||
));
|
||||
i = i + 1
|
||||
)));
|
||||
}
|
||||
*len = 12 + COUNT_TO_LENGTH[count as usize] * 4;
|
||||
if count == 1 || count == 2 {
|
||||
/* we have a type 1 or type 2 function that has a division by 'a' */
|
||||
let mut a: f32 = (*curve).parameter[1];
|
||||
let mut a: f32 = params[1];
|
||||
if a == 0.0 {
|
||||
invalid_source(src, "parametricCurve definition causes division by zero");
|
||||
}
|
||||
}
|
||||
return Some(Box::new(curveType::Parametric(params)));
|
||||
}
|
||||
return curve;
|
||||
}
|
||||
unsafe fn read_tag_curveType(
|
||||
fn read_tag_curveType(
|
||||
mut src: &mut mem_source,
|
||||
mut index: &tag_index,
|
||||
mut tag_id: u32,
|
||||
) -> *mut curveType {
|
||||
) -> Option<Box<curveType>> {
|
||||
let mut tag = find_tag(index, tag_id);
|
||||
let mut curve: *mut curveType = 0 as *mut curveType;
|
||||
if let Some(tag) = tag {
|
||||
let mut len: u32 = 0;
|
||||
return read_curveType(src, (*tag).offset, &mut len);
|
||||
} else {
|
||||
invalid_source(src, "missing curvetag");
|
||||
}
|
||||
return curve;
|
||||
return None;
|
||||
}
|
||||
// arbitrary
|
||||
unsafe extern "C" fn read_nested_curveType(
|
||||
mut src: &mut mem_source,
|
||||
mut curveArray: *mut [*mut curveType; 10],
|
||||
mut curveArray: *mut [Option<Box<curveType>>; 10],
|
||||
mut num_channels: u8,
|
||||
mut curve_offset: u32,
|
||||
) {
|
||||
|
@ -744,7 +720,7 @@ unsafe extern "C" fn read_nested_curveType(
|
|||
let mut tag_len: u32 = 0;
|
||||
(*curveArray)[i as usize] =
|
||||
read_curveType(src, curve_offset + channel_offset, &mut tag_len);
|
||||
if (*curveArray)[i as usize].is_null() {
|
||||
if (*curveArray)[i as usize].is_none() {
|
||||
invalid_source(src, "invalid nested curveType curve");
|
||||
break;
|
||||
} else {
|
||||
|
@ -761,13 +737,13 @@ unsafe extern "C" fn mAB_release(mut lut: *mut lutmABType) {
|
|||
let mut i: u8;
|
||||
i = 0u8;
|
||||
while (i as i32) < (*lut).num_in_channels as i32 {
|
||||
free((*lut).a_curves[i as usize] as *mut libc::c_void);
|
||||
(*lut).a_curves[i as usize] = None;
|
||||
i = i + 1
|
||||
}
|
||||
i = 0u8;
|
||||
while (i as i32) < (*lut).num_out_channels as i32 {
|
||||
free((*lut).b_curves[i as usize] as *mut libc::c_void);
|
||||
free((*lut).m_curves[i as usize] as *mut libc::c_void);
|
||||
(*lut).b_curves[i as usize] = None;
|
||||
(*lut).m_curves[i as usize] = None;
|
||||
i = i + 1
|
||||
}
|
||||
free(lut as *mut libc::c_void);
|
||||
|
@ -1139,26 +1115,15 @@ unsafe extern "C" fn build_sRGB_gamma_table(mut num_entries: i32) -> *mut u16 {
|
|||
}
|
||||
return table;
|
||||
}
|
||||
unsafe extern "C" fn curve_from_table(mut table: *mut u16, mut num_entries: i32) -> *mut curveType {
|
||||
unsafe extern "C" fn curve_from_table(mut table: *mut u16, mut num_entries: i32) -> Box<curveType> {
|
||||
let mut curve: *mut curveType;
|
||||
let mut i: i32;
|
||||
curve = malloc(
|
||||
::std::mem::size_of::<curveType>()
|
||||
+ ::std::mem::size_of::<uInt16Number>() * num_entries as usize,
|
||||
) as *mut curveType;
|
||||
if curve.is_null() {
|
||||
return 0 as *mut curveType;
|
||||
let mut data = Vec::with_capacity(num_entries as usize);
|
||||
for i in 0..num_entries {
|
||||
data.push(*table.offset(i as isize));
|
||||
}
|
||||
(*curve).type_0 = CURVE_TYPE;
|
||||
(*curve).count = num_entries as u32;
|
||||
i = 0;
|
||||
while i < num_entries {
|
||||
*(*curve).data.as_mut_ptr().offset(i as isize) = *table.offset(i as isize);
|
||||
i += 1
|
||||
return Box::new(curveType::Curve(data));
|
||||
}
|
||||
return curve;
|
||||
}
|
||||
unsafe extern "C" fn float_to_u8Fixed8Number(mut a: f32) -> u16 {
|
||||
fn float_to_u8Fixed8Number(mut a: f32) -> u16 {
|
||||
if a > 255.0 + 255.0 / 256f32 {
|
||||
return 0xffffu16;
|
||||
} else if a < 0.0 {
|
||||
|
@ -1167,20 +1132,9 @@ unsafe extern "C" fn float_to_u8Fixed8Number(mut a: f32) -> u16 {
|
|||
return (a * 256.0 + 0.5).floor() as u16;
|
||||
};
|
||||
}
|
||||
unsafe extern "C" fn curve_from_gamma(mut gamma: f32) -> *mut curveType {
|
||||
let mut curve: *mut curveType;
|
||||
let mut num_entries: i32 = 1;
|
||||
curve = malloc(
|
||||
::std::mem::size_of::<curveType>()
|
||||
+ ::std::mem::size_of::<uInt16Number>() * num_entries as usize,
|
||||
) as *mut curveType;
|
||||
if curve.is_null() {
|
||||
return 0 as *mut curveType;
|
||||
}
|
||||
(*curve).count = num_entries as u32;
|
||||
*(*curve).data.as_mut_ptr().offset(0isize) = float_to_u8Fixed8Number(gamma);
|
||||
(*curve).type_0 = CURVE_TYPE;
|
||||
return curve;
|
||||
|
||||
fn curve_from_gamma(mut gamma: f32) -> Box<curveType> {
|
||||
Box::new(curveType::Curve(vec![float_to_u8Fixed8Number(gamma)]))
|
||||
}
|
||||
//XXX: it would be nice if we had a way of ensuring
|
||||
// everything in a profile was initialized regardless of how it was created
|
||||
|
@ -1200,10 +1154,10 @@ pub unsafe extern "C" fn qcms_profile_create_rgb_with_gamma_set(
|
|||
if !set_rgb_colorants(&mut profile, white_point, primaries) {
|
||||
return 0 as *mut qcms_profile;
|
||||
}
|
||||
(*profile).redTRC = curve_from_gamma(redGamma);
|
||||
(*profile).blueTRC = curve_from_gamma(blueGamma);
|
||||
(*profile).greenTRC = curve_from_gamma(greenGamma);
|
||||
if (*profile).redTRC.is_null() || (*profile).blueTRC.is_null() || (*profile).greenTRC.is_null()
|
||||
(*profile).redTRC = Some(curve_from_gamma(redGamma));
|
||||
(*profile).blueTRC = Some(curve_from_gamma(blueGamma));
|
||||
(*profile).greenTRC = Some(curve_from_gamma(greenGamma));
|
||||
if (*profile).redTRC.is_none() || (*profile).blueTRC.is_none() || (*profile).greenTRC.is_none()
|
||||
{
|
||||
return 0 as *mut qcms_profile;
|
||||
}
|
||||
|
@ -1218,8 +1172,8 @@ pub unsafe extern "C" fn qcms_profile_create_rgb_with_gamma_set(
|
|||
pub unsafe extern "C" fn qcms_profile_create_gray_with_gamma(mut gamma: f32) -> *mut qcms_profile {
|
||||
let mut profile = qcms_profile_create();
|
||||
|
||||
(*profile).grayTRC = curve_from_gamma(gamma);
|
||||
if (*profile).grayTRC.is_null() {
|
||||
(*profile).grayTRC = Some(curve_from_gamma(gamma));
|
||||
if (*profile).grayTRC.is_none() {
|
||||
return 0 as *mut qcms_profile;
|
||||
}
|
||||
(*profile).class_type = DISPLAY_DEVICE_PROFILE;
|
||||
|
@ -1249,10 +1203,10 @@ pub unsafe extern "C" fn qcms_profile_create_rgb_with_table(
|
|||
if !set_rgb_colorants(&mut profile, white_point, primaries) {
|
||||
return 0 as *mut qcms_profile;
|
||||
}
|
||||
(*profile).redTRC = curve_from_table(table, num_entries);
|
||||
(*profile).blueTRC = curve_from_table(table, num_entries);
|
||||
(*profile).greenTRC = curve_from_table(table, num_entries);
|
||||
if (*profile).redTRC.is_null() || (*profile).blueTRC.is_null() || (*profile).greenTRC.is_null()
|
||||
(*profile).redTRC = Some(curve_from_table(table, num_entries));
|
||||
(*profile).blueTRC = Some(curve_from_table(table, num_entries));
|
||||
(*profile).greenTRC = Some(curve_from_table(table, num_entries));
|
||||
if (*profile).redTRC.is_none() || (*profile).blueTRC.is_none() || (*profile).greenTRC.is_none()
|
||||
{
|
||||
return 0 as *mut qcms_profile;
|
||||
}
|
||||
|
@ -1451,16 +1405,16 @@ pub unsafe extern "C" fn qcms_profile_from_memory(
|
|||
(*profile).redTRC = read_tag_curveType(src, &index, TAG_rTRC);
|
||||
(*profile).greenTRC = read_tag_curveType(src, &index, TAG_gTRC);
|
||||
(*profile).blueTRC = read_tag_curveType(src, &index, TAG_bTRC);
|
||||
if (*profile).redTRC.is_null()
|
||||
|| (*profile).blueTRC.is_null()
|
||||
|| (*profile).greenTRC.is_null()
|
||||
if (*profile).redTRC.is_none()
|
||||
|| (*profile).blueTRC.is_none()
|
||||
|| (*profile).greenTRC.is_none()
|
||||
{
|
||||
return null_mut();
|
||||
}
|
||||
}
|
||||
} else if (*profile).color_space == GRAY_SIGNATURE {
|
||||
(*profile).grayTRC = read_tag_curveType(src, &index, TAG_kTRC);
|
||||
if (*profile).grayTRC.is_null() {
|
||||
if (*profile).grayTRC.is_none() {
|
||||
return null_mut();
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -1186,7 +1186,7 @@ pub unsafe extern "C" fn qcms_profile_precache_output_transform(mut profile: *mu
|
|||
}
|
||||
}
|
||||
/* don't precache if we do not have the TRC curves */
|
||||
if (*profile).redTRC.is_null() || (*profile).greenTRC.is_null() || (*profile).blueTRC.is_null()
|
||||
if (*profile).redTRC.is_none() || (*profile).greenTRC.is_none() || (*profile).blueTRC.is_none()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -1194,7 +1194,7 @@ pub unsafe extern "C" fn qcms_profile_precache_output_transform(mut profile: *mu
|
|||
(*profile).output_table_r = precache_create();
|
||||
if !(*profile).output_table_r.is_null()
|
||||
&& !compute_precache(
|
||||
(*profile).redTRC,
|
||||
(*profile).redTRC.as_deref().unwrap(),
|
||||
(*(*profile).output_table_r).data.as_mut_ptr(),
|
||||
)
|
||||
{
|
||||
|
@ -1206,7 +1206,7 @@ pub unsafe extern "C" fn qcms_profile_precache_output_transform(mut profile: *mu
|
|||
(*profile).output_table_g = precache_create();
|
||||
if !(*profile).output_table_g.is_null()
|
||||
&& !compute_precache(
|
||||
(*profile).greenTRC,
|
||||
(*profile).greenTRC.as_deref().unwrap(),
|
||||
(*(*profile).output_table_g).data.as_mut_ptr(),
|
||||
)
|
||||
{
|
||||
|
@ -1218,7 +1218,7 @@ pub unsafe extern "C" fn qcms_profile_precache_output_transform(mut profile: *mu
|
|||
(*profile).output_table_b = precache_create();
|
||||
if !(*profile).output_table_b.is_null()
|
||||
&& !compute_precache(
|
||||
(*profile).blueTRC,
|
||||
(*profile).blueTRC.as_deref().unwrap(),
|
||||
(*(*profile).output_table_b).data.as_mut_ptr(),
|
||||
)
|
||||
{
|
||||
|
@ -1367,22 +1367,22 @@ pub unsafe extern "C" fn qcms_transform_create(
|
|||
(*transform).output_table_g = precache_reference((*out).output_table_g);
|
||||
(*transform).output_table_b = precache_reference((*out).output_table_b)
|
||||
} else {
|
||||
if (*out).redTRC.is_null() || (*out).greenTRC.is_null() || (*out).blueTRC.is_null() {
|
||||
if (*out).redTRC.is_none() || (*out).greenTRC.is_none() || (*out).blueTRC.is_none() {
|
||||
qcms_transform_release(transform);
|
||||
return 0 as *mut qcms_transform;
|
||||
}
|
||||
build_output_lut(
|
||||
(*out).redTRC,
|
||||
(*out).redTRC.as_deref().unwrap(),
|
||||
&mut (*transform).output_gamma_lut_r,
|
||||
&mut (*transform).output_gamma_lut_r_length,
|
||||
);
|
||||
build_output_lut(
|
||||
(*out).greenTRC,
|
||||
(*out).greenTRC.as_deref().unwrap(),
|
||||
&mut (*transform).output_gamma_lut_g,
|
||||
&mut (*transform).output_gamma_lut_g_length,
|
||||
);
|
||||
build_output_lut(
|
||||
(*out).blueTRC,
|
||||
(*out).blueTRC.as_deref().unwrap(),
|
||||
&mut (*transform).output_gamma_lut_b,
|
||||
&mut (*transform).output_gamma_lut_b_length,
|
||||
);
|
||||
|
@ -1449,9 +1449,9 @@ pub unsafe extern "C" fn qcms_transform_create(
|
|||
(*transform).transform_fn = Some(qcms_transform_data_bgra_out_lut)
|
||||
}
|
||||
//XXX: avoid duplicating tables if we can
|
||||
(*transform).input_gamma_table_r = build_input_gamma_table((*in_0).redTRC);
|
||||
(*transform).input_gamma_table_g = build_input_gamma_table((*in_0).greenTRC);
|
||||
(*transform).input_gamma_table_b = build_input_gamma_table((*in_0).blueTRC);
|
||||
(*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()
|
||||
|
@ -1494,7 +1494,7 @@ pub unsafe extern "C" fn qcms_transform_create(
|
|||
(*transform).matrix[1][2] = result_0.m[2][1];
|
||||
(*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);
|
||||
(*transform).input_gamma_table_gray = build_input_gamma_table((*in_0).grayTRC.as_deref());
|
||||
if (*transform).input_gamma_table_gray.is_null() {
|
||||
qcms_transform_release(transform);
|
||||
return 0 as *mut qcms_transform;
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
use ::libc;
|
||||
use libc::{free, malloc};
|
||||
|
||||
use crate::{iccread::PARAMETRIC_CURVE_TYPE, matrix::matrix};
|
||||
use crate::matrix::matrix;
|
||||
use crate::{
|
||||
iccread::{curveType, qcms_profile},
|
||||
s15Fixed16Number_to_float,
|
||||
|
@ -73,7 +73,7 @@ pub fn clamp_float(mut a: f32) -> f32 {
|
|||
#[no_mangle]
|
||||
pub unsafe extern "C" fn lut_interp_linear(
|
||||
mut input_value: f64,
|
||||
mut table: *mut u16,
|
||||
mut table: *const u16,
|
||||
mut length: i32,
|
||||
) -> f32 {
|
||||
input_value = input_value * (length - 1) as f64;
|
||||
|
@ -91,7 +91,7 @@ pub unsafe extern "C" fn lut_interp_linear(
|
|||
#[no_mangle]
|
||||
pub unsafe extern "C" fn lut_interp_linear16(
|
||||
mut input_value: u16,
|
||||
mut table: *mut u16,
|
||||
mut table: *const u16,
|
||||
mut length: i32,
|
||||
) -> u16 {
|
||||
/* Start scaling input_value to the length of the array: 65535*(length-1).
|
||||
|
@ -162,22 +162,18 @@ pub unsafe extern "C" fn compute_curve_gamma_table_type1(
|
|||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn compute_curve_gamma_table_type2(
|
||||
mut gamma_table: *mut f32,
|
||||
mut table: *mut u16,
|
||||
mut length: i32,
|
||||
) {
|
||||
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, length);
|
||||
*gamma_table.offset(i as isize) =
|
||||
lut_interp_linear(i as f64 / 255.0f64, table.as_ptr(), table.len() as i32);
|
||||
i = i + 1
|
||||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn compute_curve_gamma_table_type_parametric(
|
||||
pub unsafe fn compute_curve_gamma_table_type_parametric(
|
||||
mut gamma_table: *mut f32,
|
||||
mut parameter: *mut f32,
|
||||
mut count: i32,
|
||||
mut params: &[f32],
|
||||
) {
|
||||
let mut interval: f32;
|
||||
let mut a: f32;
|
||||
|
@ -185,42 +181,43 @@ pub unsafe extern "C" fn compute_curve_gamma_table_type_parametric(
|
|||
let mut c: f32;
|
||||
let mut e: f32;
|
||||
let mut f: f32;
|
||||
let mut y: f32 = *parameter.offset(0isize);
|
||||
if count == 0 {
|
||||
let mut y: f32 = params[0];
|
||||
// XXX: this could probably be cleaner with slice patterns
|
||||
if params.len() == 1 {
|
||||
a = 1.;
|
||||
b = 0.;
|
||||
c = 0.;
|
||||
e = 0.;
|
||||
f = 0.;
|
||||
interval = -1.
|
||||
} else if count == 1 {
|
||||
a = *parameter.offset(1isize);
|
||||
b = *parameter.offset(2isize);
|
||||
} else if params.len() == 3 {
|
||||
a = params[1];
|
||||
b = params[2];
|
||||
c = 0.;
|
||||
e = 0.;
|
||||
f = 0.;
|
||||
interval = -1. * *parameter.offset(2isize) / *parameter.offset(1isize)
|
||||
} else if count == 2 {
|
||||
a = *parameter.offset(1isize);
|
||||
b = *parameter.offset(2isize);
|
||||
interval = -1. * params[2] / params[1]
|
||||
} else if params.len() == 4 {
|
||||
a = params[1];
|
||||
b = params[2];
|
||||
c = 0.;
|
||||
e = *parameter.offset(3isize);
|
||||
f = *parameter.offset(3isize);
|
||||
interval = -1. * *parameter.offset(2isize) / *parameter.offset(1isize)
|
||||
} else if count == 3 {
|
||||
a = *parameter.offset(1isize);
|
||||
b = *parameter.offset(2isize);
|
||||
c = *parameter.offset(3isize);
|
||||
e = params[3];
|
||||
f = params[3];
|
||||
interval = -1. * params[2] / params[1]
|
||||
} else if params.len() == 5 {
|
||||
a = params[1];
|
||||
b = params[2];
|
||||
c = params[3];
|
||||
e = -c;
|
||||
f = 0.;
|
||||
interval = *parameter.offset(4isize)
|
||||
} else if count == 4 {
|
||||
a = *parameter.offset(1isize);
|
||||
b = *parameter.offset(2isize);
|
||||
c = *parameter.offset(3isize);
|
||||
e = *parameter.offset(5isize) - c;
|
||||
f = *parameter.offset(6isize);
|
||||
interval = *parameter.offset(4isize)
|
||||
interval = params[4]
|
||||
} else if params.len() == 7 {
|
||||
a = params[1];
|
||||
b = params[2];
|
||||
c = params[3];
|
||||
e = params[5] - c;
|
||||
f = params[6];
|
||||
interval = params[4]
|
||||
} else {
|
||||
debug_assert!(false, "invalid parametric function type.");
|
||||
a = 1.;
|
||||
|
@ -256,28 +253,26 @@ pub unsafe extern "C" fn compute_curve_gamma_table_type0(mut gamma_table: *mut f
|
|||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn build_input_gamma_table(mut TRC: *mut curveType) -> *mut f32 {
|
||||
if TRC.is_null() {
|
||||
return 0 as *mut f32;
|
||||
}
|
||||
pub unsafe extern "C" fn build_input_gamma_table(mut TRC: Option<&curveType>) -> *mut f32 {
|
||||
let TRC = match TRC {
|
||||
Some(TRC) => TRC,
|
||||
None => return 0 as *mut f32,
|
||||
};
|
||||
let mut gamma_table: *mut f32 = malloc(::std::mem::size_of::<f32>() * 256) as *mut f32;
|
||||
if !gamma_table.is_null() {
|
||||
if (*TRC).type_0 == PARAMETRIC_CURVE_TYPE {
|
||||
compute_curve_gamma_table_type_parametric(
|
||||
gamma_table,
|
||||
(*TRC).parameter.as_mut_ptr(),
|
||||
(*TRC).count as i32,
|
||||
);
|
||||
} else if (*TRC).count == 0 {
|
||||
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 (*TRC).count == 1 {
|
||||
compute_curve_gamma_table_type1(gamma_table, *(*TRC).data.as_mut_ptr().offset(0isize));
|
||||
} else if data.len() == 1 {
|
||||
compute_curve_gamma_table_type1(gamma_table, data[0]);
|
||||
} else {
|
||||
compute_curve_gamma_table_type2(
|
||||
gamma_table,
|
||||
(*TRC).data.as_mut_ptr(),
|
||||
(*TRC).count as i32,
|
||||
);
|
||||
compute_curve_gamma_table_type2(gamma_table, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return gamma_table;
|
||||
|
@ -307,7 +302,7 @@ pub unsafe extern "C" fn build_colorant_matrix(mut p: *mut qcms_profile) -> matr
|
|||
#[no_mangle]
|
||||
pub unsafe extern "C" fn lut_inverse_interp16(
|
||||
mut Value: u16,
|
||||
mut LutTable: *mut u16,
|
||||
mut LutTable: *const u16,
|
||||
mut length: i32,
|
||||
) -> uint16_fract_t {
|
||||
let mut l: i32 = 1; // 'int' Give spacing for negative values
|
||||
|
@ -413,7 +408,7 @@ 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. */
|
||||
unsafe extern "C" fn invert_lut(
|
||||
mut table: *mut u16,
|
||||
mut table: *const u16,
|
||||
mut length: i32,
|
||||
mut out_length: i32,
|
||||
) -> *mut u16 {
|
||||
|
@ -464,17 +459,14 @@ pub unsafe extern "C" fn compute_precache_linear(mut output: *mut u8) {
|
|||
}
|
||||
}
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn compute_precache(mut trc: *mut curveType, mut output: *mut u8) -> bool {
|
||||
if (*trc).type_0 == PARAMETRIC_CURVE_TYPE {
|
||||
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_uint: [u16; 256] = [0; 256];
|
||||
|
||||
let mut inverted_size: i32 = 256;
|
||||
compute_curve_gamma_table_type_parametric(
|
||||
gamma_table.as_mut_ptr(),
|
||||
(*trc).parameter.as_mut_ptr(),
|
||||
(*trc).count as i32,
|
||||
);
|
||||
compute_curve_gamma_table_type_parametric(gamma_table.as_mut_ptr(), 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;
|
||||
|
@ -487,22 +479,24 @@ pub unsafe extern "C" fn compute_precache(mut trc: *mut curveType, mut output: *
|
|||
if inverted_size < 256 {
|
||||
inverted_size = 256
|
||||
}
|
||||
let mut inverted: *mut u16 = invert_lut(gamma_table_uint.as_mut_ptr(), 256, inverted_size);
|
||||
let mut inverted: *mut u16 =
|
||||
invert_lut(gamma_table_uint.as_mut_ptr(), 256, inverted_size);
|
||||
if inverted.is_null() {
|
||||
return false;
|
||||
}
|
||||
compute_precache_lut(output, inverted, inverted_size);
|
||||
free(inverted as *mut libc::c_void);
|
||||
} else if (*trc).count == 0 {
|
||||
}
|
||||
curveType::Curve(data) => {
|
||||
if data.len() == 0 {
|
||||
compute_precache_linear(output);
|
||||
} else if (*trc).count == 1 {
|
||||
} else if data.len() == 1 {
|
||||
compute_precache_pow(
|
||||
output,
|
||||
(1.0f64 / u8Fixed8Number_to_float(*(*trc).data.as_mut_ptr().offset(0isize)) as f64)
|
||||
as f32,
|
||||
(1.0f64 / u8Fixed8Number_to_float(data[0]) as f64) as f32,
|
||||
);
|
||||
} else {
|
||||
let mut inverted_size_0: i32 = (*trc).count as i32;
|
||||
let mut inverted_size_0: i32 = data.len() as i32;
|
||||
//XXX: the choice of a minimum of 256 here is not backed by any theory,
|
||||
// measurement or data, howeve r it is what lcms uses.
|
||||
// the maximum number we would need is 65535 because that's the
|
||||
|
@ -510,17 +504,16 @@ pub unsafe extern "C" fn compute_precache(mut trc: *mut curveType, mut output: *
|
|||
if inverted_size_0 < 256 {
|
||||
inverted_size_0 = 256
|
||||
} //XXX turn this conversion into a function
|
||||
let mut inverted_0: *mut u16 = invert_lut(
|
||||
(*trc).data.as_mut_ptr(),
|
||||
(*trc).count as i32,
|
||||
inverted_size_0,
|
||||
);
|
||||
let mut inverted_0: *mut u16 =
|
||||
invert_lut(data.as_ptr(), data.len() as i32, 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;
|
||||
}
|
||||
unsafe extern "C" fn build_linear_table(mut length: i32) -> *mut u16 {
|
||||
|
@ -555,11 +548,12 @@ unsafe extern "C" fn build_pow_table(mut gamma: f32, mut length: i32) -> *mut u1
|
|||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn build_output_lut(
|
||||
mut trc: *mut curveType,
|
||||
mut trc: &curveType,
|
||||
mut output_gamma_lut: *mut *mut u16,
|
||||
mut output_gamma_lut_length: *mut usize,
|
||||
) {
|
||||
if (*trc).type_0 == PARAMETRIC_CURVE_TYPE {
|
||||
match trc {
|
||||
curveType::Parametric(params) => {
|
||||
let mut gamma_table: [f32; 256] = [0.; 256];
|
||||
|
||||
let mut output: *mut u16 = malloc(::std::mem::size_of::<u16>() * 256) as *mut u16;
|
||||
|
@ -567,11 +561,7 @@ pub unsafe extern "C" fn build_output_lut(
|
|||
*output_gamma_lut = 0 as *mut u16;
|
||||
return;
|
||||
}
|
||||
compute_curve_gamma_table_type_parametric(
|
||||
gamma_table.as_mut_ptr(),
|
||||
(*trc).parameter.as_mut_ptr(),
|
||||
(*trc).count as i32,
|
||||
);
|
||||
compute_curve_gamma_table_type_parametric(gamma_table.as_mut_ptr(), params);
|
||||
*output_gamma_lut_length = 256;
|
||||
let mut i: u16 = 0u16;
|
||||
while (i as i32) < 256 {
|
||||
|
@ -579,26 +569,28 @@ pub unsafe extern "C" fn build_output_lut(
|
|||
i = i + 1
|
||||
}
|
||||
*output_gamma_lut = output
|
||||
} else if (*trc).count == 0 {
|
||||
}
|
||||
curveType::Curve(data) => {
|
||||
if data.len() == 0 {
|
||||
*output_gamma_lut = build_linear_table(4096);
|
||||
*output_gamma_lut_length = 4096
|
||||
} else if (*trc).count == 1 {
|
||||
let mut gamma: f32 = (1.0f64
|
||||
/ u8Fixed8Number_to_float(*(*trc).data.as_mut_ptr().offset(0isize)) as f64)
|
||||
as f32;
|
||||
} else if data.len() == 1 {
|
||||
let mut gamma: f32 = (1.0f64 / u8Fixed8Number_to_float(data[0]) as f64) as f32;
|
||||
*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.
|
||||
*output_gamma_lut_length = (*trc).count as usize;
|
||||
*output_gamma_lut_length = data.len();
|
||||
if *output_gamma_lut_length < 256 {
|
||||
*output_gamma_lut_length = 256
|
||||
}
|
||||
*output_gamma_lut = invert_lut(
|
||||
(*trc).data.as_mut_ptr(),
|
||||
(*trc).count as i32,
|
||||
data.as_ptr(),
|
||||
data.len() as i32,
|
||||
*output_gamma_lut_length as i32,
|
||||
)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче