Skip to content
Snippets Groups Projects
Commit 03c2fad3 authored by Dorel Luca's avatar Dorel Luca
Browse files

Backed out changeset 02f6caf121bb (bug 1672309) for Backout conflicts with Bug 1654103. CLOSED TREE

parent 08166f3a
No related branches found
No related tags found
No related merge requests found
#[cfg(test)]
mod test {
use crate::{
iccread::*, transform::*, transform_util::lut_inverse_interp16, QCMS_INTENT_DEFAULT,
QCMS_INTENT_PERCEPTUAL,
};
use libc::c_void;
use std::ptr::null_mut;
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
use crate::transform_neon::{
qcms_transform_data_bgra_out_lut_neon, qcms_transform_data_rgb_out_lut_neon,
qcms_transform_data_rgba_out_lut_neon,
};
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
use crate::{
transform_avx::{
qcms_transform_data_bgra_out_lut_avx, qcms_transform_data_rgb_out_lut_avx,
qcms_transform_data_rgba_out_lut_avx,
},
transform_sse2::{
qcms_transform_data_bgra_out_lut_sse2, qcms_transform_data_rgb_out_lut_sse2,
qcms_transform_data_rgba_out_lut_sse2,
},
iccread::*, transform::*, transform_util::lut_inverse_interp16, QCMS_INTENT_PERCEPTUAL,
};
#[test]
......@@ -353,503 +332,4 @@ mod test {
unsafe { qcms_profile_release(profile) }
unsafe { qcms_profile_release(srgb_profile) }
}
fn CmpRgbChannel(reference: &[u8], test: &[u8], index: usize) -> bool {
(reference[index] as i32 - test[index] as i32).abs() <= 1
}
fn CmpRgbBufferImpl(
refBuffer: &[u8],
testBuffer: &[u8],
pixels: usize,
kSwapRB: bool,
hasAlpha: bool,
) -> bool {
let pixelSize = if hasAlpha { 4 } else { 3 };
if refBuffer[..pixels * pixelSize] == testBuffer[..pixels * pixelSize] {
return true;
}
let kRIndex = if kSwapRB { 2 } else { 0 };
let kGIndex = 1;
let kBIndex = if kSwapRB { 0 } else { 2 };
let kAIndex = 3;
let mut remaining = pixels;
let mut reference = &refBuffer[..];
let mut test = &testBuffer[..];
while remaining > 0 {
if !CmpRgbChannel(reference, test, kRIndex)
|| !CmpRgbChannel(reference, test, kGIndex)
|| !CmpRgbChannel(reference, test, kBIndex)
|| (hasAlpha && reference[kAIndex] != test[kAIndex])
{
assert_eq!(test[kRIndex], reference[kRIndex]);
assert_eq!(test[kGIndex], reference[kGIndex]);
assert_eq!(test[kBIndex], reference[kBIndex]);
if hasAlpha {
assert_eq!(test[kAIndex], reference[kAIndex]);
}
return false;
}
remaining -= 1;
reference = &reference[pixelSize..];
test = &test[pixelSize..];
}
true
}
fn GetRgbInputBufferImpl(kSwapRB: bool, kHasAlpha: bool) -> (usize, Vec<u8>) {
let colorSamples = [0, 5, 16, 43, 101, 127, 182, 255];
let colorSampleMax = colorSamples.len();
let pixelSize = if kHasAlpha { 4 } else { 3 };
let pixelCount = colorSampleMax * colorSampleMax * 256 * 3;
let mut outBuffer = vec![0; pixelCount * pixelSize];
let kRIndex = if kSwapRB { 2 } else { 0 };
let kGIndex = 1;
let kBIndex = if kSwapRB { 0 } else { 2 };
let kAIndex = 3;
// Sample every red pixel value with a subset of green and blue.
let mut color = &mut outBuffer[..];
for r in 0..=255 {
for &g in colorSamples.iter() {
for &b in colorSamples.iter() {
color[kRIndex] = r;
color[kGIndex] = g;
color[kBIndex] = b;
if kHasAlpha {
color[kAIndex] = 0x80;
}
color = &mut color[pixelSize..];
}
}
}
// Sample every green pixel value with a subset of red and blue.
let mut color = &mut outBuffer[..];
for &r in colorSamples.iter() {
for g in 0..=255 {
for &b in colorSamples.iter() {
color[kRIndex] = r;
color[kGIndex] = g;
color[kBIndex] = b;
if kHasAlpha {
color[kAIndex] = 0x80;
}
color = &mut color[pixelSize..];
}
}
}
// Sample every blue pixel value with a subset of red and green.
let mut color = &mut outBuffer[..];
for &r in colorSamples.iter() {
for &g in colorSamples.iter() {
for b in 0..=255 {
color[kRIndex] = r;
color[kGIndex] = g;
color[kBIndex] = b;
if kHasAlpha {
color[kAIndex] = 0x80;
}
color = &mut color[pixelSize..];
}
}
}
(pixelCount, outBuffer)
}
fn GetRgbInputBuffer() -> (usize, Vec<u8>) {
GetRgbInputBufferImpl(false, false)
}
fn GetRgbaInputBuffer() -> (usize, Vec<u8>) {
GetRgbInputBufferImpl(false, true)
}
fn GetBgraInputBuffer() -> (usize, Vec<u8>) {
GetRgbInputBufferImpl(true, true)
}
fn CmpRgbBuffer(refBuffer: &[u8], testBuffer: &[u8], pixels: usize) -> bool {
CmpRgbBufferImpl(refBuffer, testBuffer, pixels, false, false)
}
fn CmpRgbaBuffer(refBuffer: &[u8], testBuffer: &[u8], pixels: usize) -> bool {
CmpRgbBufferImpl(refBuffer, testBuffer, pixels, false, true)
}
fn CmpBgraBuffer(refBuffer: &[u8], testBuffer: &[u8], pixels: usize) -> bool {
CmpRgbBufferImpl(refBuffer, testBuffer, pixels, true, true)
}
fn ClearRgbBuffer(buffer: &mut [u8], pixels: usize) {
for i in 0..pixels * 3 {
buffer[i] = 0;
}
}
fn ClearRgbaBuffer(buffer: &mut [u8], pixels: usize) {
for i in 0..pixels * 4 {
buffer[i] = 0;
}
}
fn GetRgbOutputBuffer(pixels: usize) -> Vec<u8> {
vec![0; pixels * 3]
}
fn GetRgbaOutputBuffer(pixels: usize) -> Vec<u8> {
vec![0; pixels * 4]
}
struct QcmsProfileTest {
in_profile: *mut qcms_profile,
out_profile: *mut qcms_profile,
transform: *mut qcms_transform,
input: Vec<u8>,
output: Vec<u8>,
reference: Vec<u8>,
pixels: usize,
storage_type: qcms_data_type,
precache: bool,
}
impl QcmsProfileTest {
fn new() -> QcmsProfileTest {
QcmsProfileTest {
in_profile: null_mut(),
out_profile: null_mut(),
transform: null_mut(),
input: Vec::new(),
output: Vec::new(),
reference: Vec::new(),
pixels: 0,
storage_type: QCMS_DATA_RGB_8,
precache: false,
}
}
fn SetUp(&mut self) {
unsafe {
qcms_enable_iccv4();
}
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
unsafe {
if is_x86_feature_detected!("avx") {
qcms_enable_avx()
}
};
#[cfg(target_arch = "arm")]
unsafe {
use crate::transform::qcms_enable_neon;
if is_arm_feature_detected!("neon") {
qcms_enable_neon()
}
};
#[cfg(target_arch = "aarch64")]
unsafe {
use crate::transform::qcms_enable_neon;
if is_aarch64_feature_detected!("neon") {
qcms_enable_neon()
}
};
}
unsafe fn TearDown(&mut self) {
if self.in_profile != null_mut() {
qcms_profile_release(self.in_profile)
}
if self.out_profile != null_mut() {
qcms_profile_release(self.out_profile)
}
if self.transform != null_mut() {
qcms_transform_release(self.transform)
}
}
unsafe fn SetTransform(&mut self, transform: *mut qcms_transform) -> bool {
if self.transform != null_mut() {
qcms_transform_release(self.transform)
}
self.transform = transform;
!(self.transform == null_mut())
}
unsafe fn SetTransformForType(&mut self, ty: qcms_data_type) -> bool {
self.SetTransform(qcms_transform_create(
self.in_profile,
ty,
self.out_profile,
ty,
QCMS_INTENT_DEFAULT,
))
}
unsafe fn SetBuffers(&mut self, ty: qcms_data_type) -> bool {
match ty {
QCMS_DATA_RGB_8 => {
let (pixels, input) = GetRgbInputBuffer();
self.input = input;
self.pixels = pixels;
self.reference = GetRgbOutputBuffer(self.pixels);
self.output = GetRgbOutputBuffer(self.pixels)
}
QCMS_DATA_RGBA_8 => {
let (pixels, input) = GetBgraInputBuffer();
self.input = input;
self.pixels = pixels;
self.reference = GetRgbaOutputBuffer(self.pixels);
self.output = GetRgbaOutputBuffer(self.pixels);
}
QCMS_DATA_BGRA_8 => {
let (pixels, input) = GetRgbaInputBuffer();
self.input = input;
self.pixels = pixels;
self.reference = GetRgbaOutputBuffer(self.pixels);
self.output = GetRgbaOutputBuffer(self.pixels);
}
_ => unreachable!("Unknown type!"),
}
self.storage_type = ty;
self.pixels > 0
}
unsafe fn ClearOutputBuffer(&mut self) {
match self.storage_type {
QCMS_DATA_RGB_8 => ClearRgbBuffer(&mut self.output, self.pixels),
QCMS_DATA_RGBA_8 | QCMS_DATA_BGRA_8 => {
ClearRgbaBuffer(&mut self.output, self.pixels)
}
_ => unreachable!("Unknown type!"),
}
}
unsafe fn ProduceRef(&mut self, trans_fn: transform_fn_t) {
trans_fn.unwrap()(
self.transform,
self.input.as_mut_ptr(),
self.reference.as_mut_ptr(),
self.pixels,
)
}
fn CopyInputToRef(&mut self) {
let pixelSize = match self.storage_type {
QCMS_DATA_RGB_8 => 3,
QCMS_DATA_RGBA_8 | QCMS_DATA_BGRA_8 => 4,
_ => unreachable!("Unknown type!"),
};
self.reference
.copy_from_slice(&self.input[..self.pixels * pixelSize])
}
unsafe fn ProduceOutput(&mut self, trans_fn: transform_fn_t) {
self.ClearOutputBuffer();
trans_fn.unwrap()(
self.transform,
self.input.as_mut_ptr(),
self.output.as_mut_ptr(),
self.pixels,
)
}
unsafe fn VerifyOutput(&self, buf: &[u8]) -> bool {
match self.storage_type {
QCMS_DATA_RGB_8 => return CmpRgbBuffer(buf, &self.output, self.pixels),
QCMS_DATA_RGBA_8 => return CmpRgbaBuffer(buf, &self.output, self.pixels),
QCMS_DATA_BGRA_8 => return CmpBgraBuffer(buf, &self.output, self.pixels),
_ => unreachable!("Unknown type!"),
}
}
unsafe fn ProduceVerifyOutput(&mut self, trans_fn: transform_fn_t) -> bool {
self.ProduceOutput(trans_fn);
return self.VerifyOutput(&self.reference);
}
unsafe fn PrecacheOutput(&mut self) {
qcms_profile_precache_output_transform(self.out_profile);
self.precache = true;
}
unsafe fn TransformPrecache(&mut self) {
assert_eq!(self.precache, false);
assert!(self.SetBuffers(QCMS_DATA_RGB_8));
assert!(self.SetTransformForType(QCMS_DATA_RGB_8));
self.ProduceRef(Some(qcms_transform_data_rgb_out_lut));
self.PrecacheOutput();
assert!(self.SetTransformForType(QCMS_DATA_RGB_8));
assert!(self.ProduceVerifyOutput(Some(qcms_transform_data_rgb_out_lut_precache)))
}
unsafe fn TransformPrecachePlatformExt(&mut self) {
self.PrecacheOutput();
// Verify RGB transforms.
assert!(self.SetBuffers(QCMS_DATA_RGB_8));
assert!(self.SetTransformForType(QCMS_DATA_RGB_8));
self.ProduceRef(Some(qcms_transform_data_rgb_out_lut_precache));
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
{
assert!(self.ProduceVerifyOutput(Some(qcms_transform_data_rgb_out_lut_sse2)));
if is_x86_feature_detected!("avx") {
assert!(self.ProduceVerifyOutput(Some(qcms_transform_data_rgb_out_lut_avx)))
}
}
#[cfg(target_arch = "arm")]
{
if is_arm_feature_detected!("neon") {
assert!(self.ProduceVerifyOutput(qcms_transform_data_rgb_out_lut_neon))
}
}
#[cfg(target_arch = "aarch64")]
{
if is_aarch64_feature_detected!("neon") {
assert!(self.ProduceVerifyOutput(qcms_transform_data_rgb_out_lut_neon))
}
}
// Verify RGBA transform.
assert!(self.SetBuffers(QCMS_DATA_RGBA_8));
assert!(self.SetTransformForType(QCMS_DATA_RGBA_8));
self.ProduceRef(Some(qcms_transform_data_rgba_out_lut_precache));
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
{
assert!(self.ProduceVerifyOutput(Some(qcms_transform_data_rgba_out_lut_sse2)));
if is_x86_feature_detected!("avx") {
assert!(self.ProduceVerifyOutput(Some(qcms_transform_data_rgba_out_lut_avx)))
}
}
#[cfg(target_arch = "arm")]
{
if is_arm_feature_detected!("neon") {
assert!(self.ProduceVerifyOutput(Some(qcms_transform_data_rgba_out_lut_neon)))
}
}
#[cfg(target_arch = "aarch64")]
{
if is_aarch64_feature_detected!("neon") {
assert!(self.ProduceVerifyOutput(Some(qcms_transform_data_rgba_out_lut_neon)))
}
}
// Verify BGRA transform.
assert!(self.SetBuffers(QCMS_DATA_BGRA_8));
assert!(self.SetTransformForType(QCMS_DATA_BGRA_8));
self.ProduceRef(Some(qcms_transform_data_bgra_out_lut_precache));
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
{
assert!(self.ProduceVerifyOutput(Some(qcms_transform_data_bgra_out_lut_sse2)));
if is_x86_feature_detected!("avx") {
assert!(self.ProduceVerifyOutput(Some(qcms_transform_data_bgra_out_lut_avx)))
}
}
#[cfg(target_arch = "arm")]
{
if is_arm_feature_detected!("neon") {
assert!(self.ProduceVerifyOutput(Some(qcms_transform_data_bgra_out_lut_neon)))
}
}
#[cfg(target_arch = "aarch64")]
{
if is_aarch64_feature_detected!("neon") {
assert!(self.ProduceVerifyOutput(Some(qcms_transform_data_bgra_out_lut_neon)))
}
}
}
}
#[test]
fn sRGB_to_sRGB_precache() {
unsafe {
let mut pt = QcmsProfileTest::new();
pt.SetUp();
pt.in_profile = qcms_profile_sRGB();
pt.out_profile = qcms_profile_sRGB();
pt.TransformPrecache();
pt.TearDown();
}
}
#[test]
fn sRGB_to_sRGB_transform_identity() {
unsafe {
let mut pt = QcmsProfileTest::new();
pt.SetUp();
pt.in_profile = qcms_profile_sRGB();
pt.out_profile = qcms_profile_sRGB();
pt.PrecacheOutput();
pt.SetBuffers(QCMS_DATA_RGB_8);
pt.SetTransformForType(QCMS_DATA_RGB_8);
qcms_transform_data(
pt.transform,
pt.input.as_mut_ptr() as *mut c_void,
pt.output.as_mut_ptr() as *mut c_void,
pt.pixels,
);
assert!(pt.VerifyOutput(&pt.input));
pt.TearDown();
}
}
fn profile_from_path(file: &str) -> *mut qcms_profile {
use std::io::Read;
let mut path = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
path.push("profiles");
path.push(file);
let mut file = std::fs::File::open(path).unwrap();
let mut data = Vec::new();
file.read_to_end(&mut data).unwrap();
let profile =
unsafe { qcms_profile_from_memory(data.as_ptr() as *const c_void, data.len()) };
assert_ne!(profile, std::ptr::null_mut());
profile
}
#[test]
fn sRGB_to_ThinkpadW540() {
unsafe {
let mut pt = QcmsProfileTest::new();
pt.SetUp();
pt.in_profile = qcms_profile_sRGB();
pt.out_profile = profile_from_path("lcms_thinkpad_w540.icc");
pt.TransformPrecachePlatformExt();
pt.TearDown();
}
}
#[test]
fn sRGB_to_SamsungSyncmaster() {
unsafe {
let mut pt = QcmsProfileTest::new();
pt.SetUp();
pt.in_profile = qcms_profile_sRGB();
pt.out_profile = profile_from_path("lcms_samsung_syncmaster.icc");
pt.TransformPrecachePlatformExt();
pt.TearDown();
}
}
}
......@@ -68,8 +68,8 @@ SOURCES += [
# notice embedded in the profiles should be reviewed to ensure there are
# no known restrictions on distribution.
TEST_HARNESS_FILES.gtest += [
"../../qcms/profiles/lcms_samsung_syncmaster.icc",
"../../qcms/profiles/lcms_thinkpad_w540.icc",
"icc_profiles/lcms_samsung_syncmaster.icc",
"icc_profiles/lcms_thinkpad_w540.icc",
]
include("/ipc/chromium/chromium-config.mozbuild")
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment