зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1795045 - qcms: Add support for only reading the curves from profiles. r=aosmond
We use this when reading the output profiles to avoid the performance cost of doing the color transformation using LUTs when the output profile has them. This will let us enable ICCv4 everywhere. Differential Revision: https://phabricator.services.mozilla.com/D159273
This commit is contained in:
Родитель
320e015715
Коммит
2091af5f6b
|
@ -159,6 +159,7 @@ qcms_profile* qcms_profile_create_cicp(uint8_t colour_primaries,
|
||||||
uint8_t transfer_characteristics);
|
uint8_t transfer_characteristics);
|
||||||
|
|
||||||
qcms_profile* qcms_profile_from_memory(const void *mem, size_t size);
|
qcms_profile* qcms_profile_from_memory(const void *mem, size_t size);
|
||||||
|
qcms_profile* qcms_profile_from_memory_curves_only(const void *mem, size_t size);
|
||||||
|
|
||||||
qcms_profile* qcms_profile_from_file(FILE *file);
|
qcms_profile* qcms_profile_from_file(FILE *file);
|
||||||
qcms_profile* qcms_profile_from_path(const char *path);
|
qcms_profile* qcms_profile_from_path(const char *path);
|
||||||
|
|
|
@ -79,10 +79,21 @@ pub unsafe extern "C" fn qcms_profile_from_memory(
|
||||||
size: usize,
|
size: usize,
|
||||||
) -> *mut Profile {
|
) -> *mut Profile {
|
||||||
let mem = slice::from_raw_parts(mem as *const libc::c_uchar, size);
|
let mem = slice::from_raw_parts(mem as *const libc::c_uchar, size);
|
||||||
let profile = Profile::new_from_slice(mem);
|
let profile = Profile::new_from_slice(mem, false);
|
||||||
profile.map_or_else(null_mut, Box::into_raw)
|
profile.map_or_else(null_mut, Box::into_raw)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn qcms_profile_from_memory_curves_only(
|
||||||
|
mem: *const libc::c_void,
|
||||||
|
size: usize,
|
||||||
|
) -> *mut Profile {
|
||||||
|
let mem = slice::from_raw_parts(mem as *const libc::c_uchar, size);
|
||||||
|
let profile = Profile::new_from_slice(mem, true);
|
||||||
|
profile.map_or_else(null_mut, Box::into_raw)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn qcms_profile_get_rendering_intent(profile: &Profile) -> Intent {
|
pub extern "C" fn qcms_profile_get_rendering_intent(profile: &Profile) -> Intent {
|
||||||
profile.rendering_intent
|
profile.rendering_intent
|
||||||
|
|
|
@ -917,7 +917,7 @@ mod test {
|
||||||
let mut file = std::fs::File::open(path).unwrap();
|
let mut file = std::fs::File::open(path).unwrap();
|
||||||
let mut data = Vec::new();
|
let mut data = Vec::new();
|
||||||
file.read_to_end(&mut data).unwrap();
|
file.read_to_end(&mut data).unwrap();
|
||||||
Profile::new_from_slice(&data).unwrap()
|
Profile::new_from_slice(&data, false).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
convert::TryInto,
|
convert::TryInto,
|
||||||
sync::atomic::{AtomicBool, Ordering},
|
sync::atomic::AtomicBool,
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1588,10 +1588,10 @@ impl Profile {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_from_path(file: &str) -> Option<Box<Profile>> {
|
pub fn new_from_path(file: &str) -> Option<Box<Profile>> {
|
||||||
Profile::new_from_slice(&std::fs::read(file).ok()?)
|
Profile::new_from_slice(&std::fs::read(file).ok()?, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_from_slice(mem: &[u8]) -> Option<Box<Profile>> {
|
pub fn new_from_slice(mem: &[u8], curves_only: bool) -> Option<Box<Profile>> {
|
||||||
let length: u32;
|
let length: u32;
|
||||||
let mut source: MemSource = MemSource {
|
let mut source: MemSource = MemSource {
|
||||||
buf: mem,
|
buf: mem,
|
||||||
|
@ -1645,23 +1645,25 @@ impl Profile {
|
||||||
|| profile.class_type == COLOR_SPACE_PROFILE
|
|| profile.class_type == COLOR_SPACE_PROFILE
|
||||||
{
|
{
|
||||||
if profile.color_space == RGB_SIGNATURE {
|
if profile.color_space == RGB_SIGNATURE {
|
||||||
if let Some(A2B0) = find_tag(&index, TAG_A2B0) {
|
if !curves_only {
|
||||||
let lut_type = read_u32(src, A2B0.offset as usize);
|
if let Some(A2B0) = find_tag(&index, TAG_A2B0) {
|
||||||
if lut_type == LUT8_TYPE || lut_type == LUT16_TYPE {
|
let lut_type = read_u32(src, A2B0.offset as usize);
|
||||||
profile.A2B0 = read_tag_lutType(src, A2B0)
|
if lut_type == LUT8_TYPE || lut_type == LUT16_TYPE {
|
||||||
} else if lut_type == LUT_MAB_TYPE {
|
profile.A2B0 = read_tag_lutType(src, A2B0)
|
||||||
profile.mAB = read_tag_lutmABType(src, A2B0)
|
} else if lut_type == LUT_MAB_TYPE {
|
||||||
|
profile.mAB = read_tag_lutmABType(src, A2B0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(B2A0) = find_tag(&index, TAG_B2A0) {
|
||||||
|
let lut_type = read_u32(src, B2A0.offset as usize);
|
||||||
|
if lut_type == LUT8_TYPE || lut_type == LUT16_TYPE {
|
||||||
|
profile.B2A0 = read_tag_lutType(src, B2A0)
|
||||||
|
} else if lut_type == LUT_MBA_TYPE {
|
||||||
|
profile.mBA = read_tag_lutmABType(src, B2A0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(B2A0) = find_tag(&index, TAG_B2A0) {
|
if find_tag(&index, TAG_rXYZ).is_some() || curves_only {
|
||||||
let lut_type = read_u32(src, B2A0.offset as usize);
|
|
||||||
if lut_type == LUT8_TYPE || lut_type == LUT16_TYPE {
|
|
||||||
profile.B2A0 = read_tag_lutType(src, B2A0)
|
|
||||||
} else if lut_type == LUT_MBA_TYPE {
|
|
||||||
profile.mBA = read_tag_lutmABType(src, B2A0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if find_tag(&index, TAG_rXYZ).is_some() || !SUPPORTS_ICCV4.load(Ordering::Relaxed) {
|
|
||||||
profile.redColorant = read_tag_XYZType(src, &index, TAG_rXYZ);
|
profile.redColorant = read_tag_XYZType(src, &index, TAG_rXYZ);
|
||||||
profile.greenColorant = read_tag_XYZType(src, &index, TAG_gXYZ);
|
profile.greenColorant = read_tag_XYZType(src, &index, TAG_gXYZ);
|
||||||
profile.blueColorant = read_tag_XYZType(src, &index, TAG_bXYZ)
|
profile.blueColorant = read_tag_XYZType(src, &index, TAG_bXYZ)
|
||||||
|
@ -1670,7 +1672,7 @@ impl Profile {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
if find_tag(&index, TAG_rTRC).is_some() || !SUPPORTS_ICCV4.load(Ordering::Relaxed) {
|
if find_tag(&index, TAG_rTRC).is_some() || curves_only {
|
||||||
profile.redTRC = read_tag_curveType(src, &index, TAG_rTRC);
|
profile.redTRC = read_tag_curveType(src, &index, TAG_rTRC);
|
||||||
profile.greenTRC = read_tag_curveType(src, &index, TAG_gTRC);
|
profile.greenTRC = read_tag_curveType(src, &index, TAG_gTRC);
|
||||||
profile.blueTRC = read_tag_curveType(src, &index, TAG_bTRC);
|
profile.blueTRC = read_tag_curveType(src, &index, TAG_bTRC);
|
||||||
|
|
|
@ -2116,8 +2116,8 @@ void gfxPlatform::InitializeCMS() {
|
||||||
nsTArray<uint8_t> outputProfileData =
|
nsTArray<uint8_t> outputProfileData =
|
||||||
gfxPlatform::GetPlatform()->GetPlatformCMSOutputProfileData();
|
gfxPlatform::GetPlatform()->GetPlatformCMSOutputProfileData();
|
||||||
if (!outputProfileData.IsEmpty()) {
|
if (!outputProfileData.IsEmpty()) {
|
||||||
gCMSOutputProfile = qcms_profile_from_memory(outputProfileData.Elements(),
|
gCMSOutputProfile = qcms_profile_from_memory_curves_only(outputProfileData.Elements(),
|
||||||
outputProfileData.Length());
|
outputProfileData.Length());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче