зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1667691 - qcms: Make lutType safe. r=aosmond
Instead of using a common buffer for all lookup tables we just use individual Vecs for each. Differential Revision: https://phabricator.services.mozilla.com/D91534
This commit is contained in:
Родитель
ac8e8a021c
Коммит
8d848ca717
|
@ -72,12 +72,12 @@ fn lerp(mut a: f32, mut b: f32, mut t: f32) -> f32 {
|
|||
return a * (1.0 - t) + b * t;
|
||||
}
|
||||
|
||||
unsafe extern "C" fn build_lut_matrix(mut lut: *mut lutType) -> matrix {
|
||||
unsafe extern "C" fn build_lut_matrix(mut lut: Option<&lutType>) -> matrix {
|
||||
let mut result: matrix = matrix {
|
||||
m: [[0.; 3]; 3],
|
||||
invalid: false,
|
||||
};
|
||||
if !lut.is_null() {
|
||||
if let Some(lut) = lut {
|
||||
result.m[0][0] = s15Fixed16Number_to_float((*lut).e00);
|
||||
result.m[0][1] = s15Fixed16Number_to_float((*lut).e01);
|
||||
result.m[0][2] = s15Fixed16Number_to_float((*lut).e02);
|
||||
|
@ -992,7 +992,7 @@ unsafe extern "C" fn qcms_modular_transform_create_mAB(
|
|||
return 0 as *mut qcms_modular_transform;
|
||||
}
|
||||
unsafe extern "C" fn qcms_modular_transform_create_lut(
|
||||
mut lut: *mut lutType,
|
||||
mut lut: &lutType,
|
||||
) -> *mut qcms_modular_transform {
|
||||
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;
|
||||
|
@ -1006,7 +1006,7 @@ unsafe extern "C" fn qcms_modular_transform_create_lut(
|
|||
let mut transform: *mut qcms_modular_transform = qcms_modular_transform_alloc();
|
||||
if !transform.is_null() {
|
||||
append_transform(transform, &mut next_transform);
|
||||
(*transform).matrix = build_lut_matrix(lut);
|
||||
(*transform).matrix = build_lut_matrix(Some(lut));
|
||||
if !(*transform).matrix.invalid {
|
||||
(*transform).transform_module_fn = Some(
|
||||
qcms_transform_module_matrix
|
||||
|
@ -1027,7 +1027,7 @@ unsafe extern "C" fn qcms_modular_transform_create_lut(
|
|||
if !in_curves.is_null() {
|
||||
memcpy(
|
||||
in_curves as *mut libc::c_void,
|
||||
(*lut).input_table as *const libc::c_void,
|
||||
(*lut).input_table.as_ptr() as *mut libc::c_void,
|
||||
in_curve_len,
|
||||
);
|
||||
(*transform).input_clut_table_r =
|
||||
|
@ -1045,7 +1045,7 @@ unsafe extern "C" fn qcms_modular_transform_create_lut(
|
|||
if !clut.is_null() {
|
||||
memcpy(
|
||||
clut as *mut libc::c_void,
|
||||
(*lut).clut_table as *const libc::c_void,
|
||||
(*lut).clut_table.as_ptr() as *const libc::c_void,
|
||||
clut_length,
|
||||
);
|
||||
(*transform).r_clut = clut.offset(0isize);
|
||||
|
@ -1060,7 +1060,7 @@ unsafe extern "C" fn qcms_modular_transform_create_lut(
|
|||
if !out_curves.is_null() {
|
||||
memcpy(
|
||||
out_curves as *mut libc::c_void,
|
||||
(*lut).output_table as *const libc::c_void,
|
||||
(*lut).output_table.as_ptr() as *const libc::c_void,
|
||||
out_curve_len,
|
||||
);
|
||||
(*transform).output_clut_table_r = out_curves
|
||||
|
@ -1097,9 +1097,9 @@ pub unsafe extern "C" fn qcms_modular_transform_create_input(
|
|||
let mut current_block: u64;
|
||||
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;
|
||||
if !(*in_0).A2B0.is_null() {
|
||||
if !(*in_0).A2B0.is_none() {
|
||||
let mut lut_transform: *mut qcms_modular_transform =
|
||||
qcms_modular_transform_create_lut((*in_0).A2B0);
|
||||
qcms_modular_transform_create_lut((*in_0).A2B0.as_deref().unwrap());
|
||||
if lut_transform.is_null() {
|
||||
current_block = 8903102000210989603;
|
||||
} else {
|
||||
|
@ -1201,9 +1201,9 @@ unsafe extern "C" fn qcms_modular_transform_create_output(
|
|||
let mut current_block: u64;
|
||||
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;
|
||||
if !(*out).B2A0.is_null() {
|
||||
if !(*out).B2A0.is_none() {
|
||||
let mut lut_transform: *mut qcms_modular_transform =
|
||||
qcms_modular_transform_create_lut((*out).B2A0);
|
||||
qcms_modular_transform_create_lut((*out).B2A0.as_deref().unwrap());
|
||||
if lut_transform.is_null() {
|
||||
current_block = 15713701561912628542;
|
||||
} else {
|
||||
|
|
|
@ -88,8 +88,8 @@ pub struct qcms_profile {
|
|||
pub blueTRC: Option<Box<curveType>>,
|
||||
pub greenTRC: Option<Box<curveType>>,
|
||||
pub grayTRC: Option<Box<curveType>>,
|
||||
pub A2B0: *mut lutType,
|
||||
pub B2A0: *mut lutType,
|
||||
pub A2B0: Option<Box<lutType>>,
|
||||
pub B2A0: Option<Box<lutType>>,
|
||||
pub mAB: *mut lutmABType,
|
||||
pub mBA: *mut lutmABType,
|
||||
pub chromaticAdaption: matrix,
|
||||
|
@ -110,12 +110,6 @@ impl Drop for qcms_profile {
|
|||
if !self.output_table_b.is_null() {
|
||||
precache_release(self.output_table_b);
|
||||
}
|
||||
if !self.A2B0.is_null() {
|
||||
lut_release(self.A2B0);
|
||||
}
|
||||
if !self.B2A0.is_null() {
|
||||
lut_release(self.B2A0);
|
||||
}
|
||||
if !self.mAB.is_null() {
|
||||
mAB_release(self.mAB);
|
||||
}
|
||||
|
@ -161,7 +155,7 @@ pub enum curveType {
|
|||
pub type uInt16Number = u16;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
#[derive(Clone)]
|
||||
pub struct lutType {
|
||||
pub num_input_channels: u8,
|
||||
pub num_output_channels: u8,
|
||||
|
@ -177,10 +171,9 @@ pub struct lutType {
|
|||
pub e22: s15Fixed16Number,
|
||||
pub num_input_table_entries: u16,
|
||||
pub num_output_table_entries: u16,
|
||||
pub input_table: *mut f32,
|
||||
pub clut_table: *mut f32,
|
||||
pub output_table: *mut f32,
|
||||
pub table_data: [f32; 0],
|
||||
pub input_table: Vec<f32>,
|
||||
pub clut_table: Vec<f32>,
|
||||
pub output_table: Vec<f32>,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
|
@ -489,8 +482,8 @@ pub extern "C" fn qcms_profile_is_bogus(mut profile: &mut qcms_profile) -> bool
|
|||
if (*profile).color_space != RGB_SIGNATURE {
|
||||
return false;
|
||||
}
|
||||
if !(*profile).A2B0.is_null()
|
||||
|| !(*profile).B2A0.is_null()
|
||||
if !(*profile).A2B0.is_none()
|
||||
|| !(*profile).B2A0.is_none()
|
||||
|| !(*profile).mAB.is_null()
|
||||
|| !(*profile).mBA.is_null()
|
||||
{
|
||||
|
@ -901,7 +894,7 @@ unsafe fn read_tag_lutmABType(mut src: &mut mem_source, mut tag: &tag) -> *mut l
|
|||
}
|
||||
return lut;
|
||||
}
|
||||
unsafe fn read_tag_lutType(mut src: &mut mem_source, mut tag: &tag) -> *mut lutType {
|
||||
fn read_tag_lutType(mut src: &mut mem_source, mut tag: &tag) -> Option<Box<lutType>> {
|
||||
let mut offset: u32 = (*tag).offset;
|
||||
let mut type_0: u32 = read_u32(src, offset as usize);
|
||||
let mut num_input_table_entries: u16;
|
||||
|
@ -914,7 +907,6 @@ unsafe fn read_tag_lutType(mut src: &mut mem_source, mut tag: &tag) -> *mut lutT
|
|||
let mut output_offset: u32;
|
||||
let mut clut_size: u32;
|
||||
let mut entry_size: usize;
|
||||
let mut lut: *mut lutType;
|
||||
let mut i: u32;
|
||||
if type_0 == LUT8_TYPE {
|
||||
num_input_table_entries = 256u16;
|
||||
|
@ -926,14 +918,14 @@ unsafe fn read_tag_lutType(mut src: &mut mem_source, mut tag: &tag) -> *mut lutT
|
|||
num_output_table_entries = read_u16(src, (offset + 50) as usize);
|
||||
if num_input_table_entries as i32 == 0 || num_output_table_entries as i32 == 0 {
|
||||
invalid_source(src, "Bad channel count");
|
||||
return 0 as *mut lutType;
|
||||
return None;
|
||||
}
|
||||
entry_size = 2;
|
||||
input_offset = 52
|
||||
} else {
|
||||
debug_assert!(false);
|
||||
invalid_source(src, "Unexpected lut type");
|
||||
return 0 as *mut lutType;
|
||||
return None;
|
||||
}
|
||||
in_chan = read_u8(src, (offset + 8) as usize);
|
||||
out_chan = read_u8(src, (offset + 9) as usize);
|
||||
|
@ -941,120 +933,112 @@ unsafe fn read_tag_lutType(mut src: &mut mem_source, mut tag: &tag) -> *mut lutT
|
|||
clut_size = (grid_points as f64).powf(in_chan as f64) as u32;
|
||||
if clut_size > 500000 {
|
||||
invalid_source(src, "CLUT too large");
|
||||
return 0 as *mut lutType;
|
||||
return None;
|
||||
}
|
||||
if clut_size <= 0 {
|
||||
invalid_source(src, "CLUT must not be empty.");
|
||||
return 0 as *mut lutType;
|
||||
return None;
|
||||
}
|
||||
if in_chan as i32 != 3 || out_chan as i32 != 3 {
|
||||
invalid_source(src, "CLUT only supports RGB");
|
||||
return 0 as *mut lutType;
|
||||
return None;
|
||||
}
|
||||
lut = malloc(
|
||||
::std::mem::size_of::<lutType>()
|
||||
+ ((num_input_table_entries as i32 * in_chan as i32) as libc::c_uint
|
||||
+ clut_size * out_chan as libc::c_uint
|
||||
+ (num_output_table_entries as i32 * out_chan as i32) as libc::c_uint)
|
||||
as usize
|
||||
* ::std::mem::size_of::<f32>(),
|
||||
) as *mut lutType;
|
||||
if lut.is_null() {
|
||||
invalid_source(src, "CLUT too large");
|
||||
return 0 as *mut lutType;
|
||||
}
|
||||
/* compute the offsets of tables */
|
||||
(*lut).input_table = &mut *(*lut).table_data.as_mut_ptr().offset(0isize) as *mut f32;
|
||||
(*lut).clut_table = &mut *(*lut)
|
||||
.table_data
|
||||
.as_mut_ptr()
|
||||
.offset((in_chan as i32 * num_input_table_entries as i32) as isize)
|
||||
as *mut f32;
|
||||
(*lut).output_table = &mut *(*lut).table_data.as_mut_ptr().offset(
|
||||
((in_chan as i32 * num_input_table_entries as i32) as libc::c_uint
|
||||
+ clut_size * out_chan as libc::c_uint) as isize,
|
||||
) as *mut f32;
|
||||
(*lut).num_input_table_entries = num_input_table_entries;
|
||||
(*lut).num_output_table_entries = num_output_table_entries;
|
||||
(*lut).num_input_channels = in_chan;
|
||||
(*lut).num_output_channels = out_chan;
|
||||
(*lut).num_clut_grid_points = grid_points;
|
||||
(*lut).e00 = read_s15Fixed16Number(src, (offset + 12) as usize);
|
||||
(*lut).e01 = read_s15Fixed16Number(src, (offset + 16) as usize);
|
||||
(*lut).e02 = read_s15Fixed16Number(src, (offset + 20) as usize);
|
||||
(*lut).e10 = read_s15Fixed16Number(src, (offset + 24) as usize);
|
||||
(*lut).e11 = read_s15Fixed16Number(src, (offset + 28) as usize);
|
||||
(*lut).e12 = read_s15Fixed16Number(src, (offset + 32) as usize);
|
||||
(*lut).e20 = read_s15Fixed16Number(src, (offset + 36) as usize);
|
||||
(*lut).e21 = read_s15Fixed16Number(src, (offset + 40) as usize);
|
||||
(*lut).e22 = read_s15Fixed16Number(src, (offset + 44) as usize);
|
||||
i = 0;
|
||||
while i < ((*lut).num_input_table_entries as i32 * in_chan as i32) as u32 {
|
||||
|
||||
let e00 = read_s15Fixed16Number(src, (offset + 12) as usize);
|
||||
let e01 = read_s15Fixed16Number(src, (offset + 16) as usize);
|
||||
let e02 = read_s15Fixed16Number(src, (offset + 20) as usize);
|
||||
let e10 = read_s15Fixed16Number(src, (offset + 24) as usize);
|
||||
let e11 = read_s15Fixed16Number(src, (offset + 28) as usize);
|
||||
let e12 = read_s15Fixed16Number(src, (offset + 32) as usize);
|
||||
let e20 = read_s15Fixed16Number(src, (offset + 36) as usize);
|
||||
let e21 = read_s15Fixed16Number(src, (offset + 40) as usize);
|
||||
let e22 = read_s15Fixed16Number(src, (offset + 44) as usize);
|
||||
|
||||
let mut input_table = Vec::with_capacity((num_input_table_entries * in_chan as u16) as usize);
|
||||
for i in 0..(num_input_table_entries * in_chan as u16) {
|
||||
if type_0 == LUT8_TYPE {
|
||||
*(*lut).input_table.offset(i as isize) = uInt8Number_to_float(read_uInt8Number(
|
||||
input_table.push(uInt8Number_to_float(read_uInt8Number(
|
||||
src,
|
||||
(offset + input_offset) as usize + i as usize * entry_size,
|
||||
))
|
||||
)))
|
||||
} else {
|
||||
*(*lut).input_table.offset(i as isize) = uInt16Number_to_float(read_uInt16Number(
|
||||
input_table.push(uInt16Number_to_float(read_uInt16Number(
|
||||
src,
|
||||
(offset + input_offset) as usize + i as usize * entry_size,
|
||||
))
|
||||
)))
|
||||
}
|
||||
i = i + 1
|
||||
}
|
||||
clut_offset = ((offset + input_offset) as usize
|
||||
+ ((*lut).num_input_table_entries as i32 * in_chan as i32) as usize * entry_size)
|
||||
+ (num_input_table_entries as i32 * in_chan as i32) as usize * entry_size)
|
||||
as u32;
|
||||
i = 0;
|
||||
while i < clut_size * out_chan as libc::c_uint {
|
||||
|
||||
let mut clut_table = Vec::with_capacity((clut_size * out_chan as u32) as usize);
|
||||
for i in (0..clut_size * out_chan as u32).step_by(3) {
|
||||
if type_0 == LUT8_TYPE {
|
||||
*(*lut).clut_table.offset((i + 0) as isize) = uInt8Number_to_float(read_uInt8Number(
|
||||
clut_table.push(uInt8Number_to_float(read_uInt8Number(
|
||||
src,
|
||||
clut_offset as usize + i as usize * entry_size + 0,
|
||||
));
|
||||
*(*lut).clut_table.offset((i + 1) as isize) = uInt8Number_to_float(read_uInt8Number(
|
||||
)));
|
||||
clut_table.push(uInt8Number_to_float(read_uInt8Number(
|
||||
src,
|
||||
clut_offset as usize + i as usize * entry_size + 1,
|
||||
));
|
||||
*(*lut).clut_table.offset((i + 2) as isize) = uInt8Number_to_float(read_uInt8Number(
|
||||
)));
|
||||
clut_table.push(uInt8Number_to_float(read_uInt8Number(
|
||||
src,
|
||||
clut_offset as usize + i as usize * entry_size + 2,
|
||||
))
|
||||
)))
|
||||
} else {
|
||||
*(*lut).clut_table.offset((i + 0) as isize) = uInt16Number_to_float(read_uInt16Number(
|
||||
clut_table.push(uInt16Number_to_float(read_uInt16Number(
|
||||
src,
|
||||
clut_offset as usize + i as usize * entry_size + 0,
|
||||
));
|
||||
*(*lut).clut_table.offset((i + 1) as isize) = uInt16Number_to_float(read_uInt16Number(
|
||||
)));
|
||||
clut_table.push(uInt16Number_to_float(read_uInt16Number(
|
||||
src,
|
||||
clut_offset as usize + i as usize * entry_size + 2,
|
||||
));
|
||||
*(*lut).clut_table.offset((i + 2) as isize) = uInt16Number_to_float(read_uInt16Number(
|
||||
)));
|
||||
clut_table.push(uInt16Number_to_float(read_uInt16Number(
|
||||
src,
|
||||
clut_offset as usize + i as usize * entry_size + 4,
|
||||
))
|
||||
)))
|
||||
}
|
||||
i = i + 3
|
||||
}
|
||||
output_offset =
|
||||
(clut_offset as usize + (clut_size * out_chan as u32) as usize * entry_size) as u32;
|
||||
i = 0;
|
||||
while i < ((*lut).num_output_table_entries as i32 * out_chan as i32) as u32 {
|
||||
|
||||
let mut output_table =
|
||||
Vec::with_capacity((num_output_table_entries * out_chan as u16) as usize);
|
||||
for i in 0..num_output_table_entries * out_chan as u16 {
|
||||
if type_0 == LUT8_TYPE {
|
||||
*(*lut).output_table.offset(i as isize) = uInt8Number_to_float(read_uInt8Number(
|
||||
output_table.push(uInt8Number_to_float(read_uInt8Number(
|
||||
src,
|
||||
output_offset as usize + i as usize * entry_size,
|
||||
))
|
||||
)))
|
||||
} else {
|
||||
*(*lut).output_table.offset(i as isize) = uInt16Number_to_float(read_uInt16Number(
|
||||
output_table.push(uInt16Number_to_float(read_uInt16Number(
|
||||
src,
|
||||
output_offset as usize + i as usize * entry_size,
|
||||
))
|
||||
)))
|
||||
}
|
||||
i = i + 1
|
||||
}
|
||||
return lut;
|
||||
Some(Box::new(lutType {
|
||||
num_input_table_entries: num_input_table_entries,
|
||||
num_output_table_entries: num_output_table_entries,
|
||||
num_input_channels: in_chan,
|
||||
num_output_channels: out_chan,
|
||||
num_clut_grid_points: grid_points,
|
||||
e00,
|
||||
e01,
|
||||
e02,
|
||||
e10,
|
||||
e11,
|
||||
e12,
|
||||
e20,
|
||||
e21,
|
||||
e22,
|
||||
input_table,
|
||||
clut_table,
|
||||
output_table,
|
||||
}))
|
||||
}
|
||||
fn read_rendering_intent(mut profile: &mut qcms_profile, mut src: &mut mem_source) {
|
||||
(*profile).rendering_intent = read_u32(src, 64);
|
||||
|
@ -1439,9 +1423,7 @@ pub unsafe extern "C" fn qcms_profile_get_color_space(
|
|||
) -> icColorSpaceSignature {
|
||||
return (*profile).color_space;
|
||||
}
|
||||
unsafe extern "C" fn lut_release(mut lut: *mut lutType) {
|
||||
free(lut as *mut libc::c_void);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn qcms_profile_release(mut profile: *mut qcms_profile) {
|
||||
drop(Box::from_raw(profile));
|
||||
|
|
|
@ -1167,7 +1167,7 @@ pub unsafe extern "C" fn qcms_profile_precache_output_transform(mut profile: *mu
|
|||
}
|
||||
if qcms_supports_iccv4.load(Ordering::Relaxed) {
|
||||
/* don't precache since we will use the B2A LUT */
|
||||
if !(*profile).B2A0.is_null() {
|
||||
if !(*profile).B2A0.is_none() {
|
||||
return;
|
||||
}
|
||||
/* don't precache since we will use the mBA LUT */
|
||||
|
@ -1333,8 +1333,8 @@ pub unsafe extern "C" fn qcms_transform_create(
|
|||
&& (in_type == QCMS_DATA_RGB_8
|
||||
|| in_type == QCMS_DATA_RGBA_8
|
||||
|| in_type == QCMS_DATA_BGRA_8)
|
||||
&& (!(*in_0).A2B0.is_null()
|
||||
|| !(*out).B2A0.is_null()
|
||||
&& (!(*in_0).A2B0.is_none()
|
||||
|| !(*out).B2A0.is_none()
|
||||
|| !(*in_0).mAB.is_null()
|
||||
|| !(*out).mAB.is_null())
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче