#![allow(clippy::unwrap_used, reason = "allow in test files")]
#![allow(clippy::undocumented_unsafe_blocks, reason = "allow in test files")]
#![allow(clippy::indexing_slicing, reason = "allow in test files")]
#![allow(unused_unsafe)]
use std::num::NonZeroUsize;
use pastey::paste;
const DEGRAIN_SIZES: &[(usize, usize)] = &[
(2, 2),
(2, 4),
(4, 2),
(4, 4),
(4, 8),
(8, 1),
(8, 2),
(8, 4),
(8, 8),
(8, 16),
(16, 1),
(16, 2),
(16, 4),
(16, 8),
(16, 16),
(16, 32),
(32, 8),
(32, 16),
(32, 32),
(32, 64),
(64, 16),
(64, 32),
(64, 64),
(64, 128),
(128, 32),
(128, 64),
(128, 128),
];
macro_rules! degrain_tests {
($module:ident) => {
paste! {
#[test]
fn [<degrain_uniform_u8_ $module>]() {
for radius in 1..=6 {
for &(w, h) in DEGRAIN_SIZES {
let pitch = w + 8;
let mut dest = vec![0_u8; pitch * h];
let mut src = vec![0_u8; pitch * h];
for y in 0..h {
for x in 0..w {
src[y * pitch + x] = 37;
}
}
let refs_data = vec![vec![0_u8; pitch * h]; radius * 2];
let refs = refs_data.iter().map(std::vec::Vec::as_slice).collect::<Vec<_>>();
let refs_pitch = vec![NonZeroUsize::new(pitch).unwrap(); radius * 2];
let w_refs = vec![0_i32; radius * 2];
verify_asm!($module, degrain_test(
&mut dest,
NonZeroUsize::new(w).unwrap(),
NonZeroUsize::new(h).unwrap(),
&src,
NonZeroUsize::new(pitch).unwrap(),
&refs,
&refs_pitch,
256,
&w_refs,
));
for y in 0..h {
for x in 0..w {
assert_eq!(dest[y * pitch + x], 37, "radius={radius} {w}x{h}");
}
}
}
}
}
#[test]
fn [<degrain_uniform_u16_ $module>]() {
for radius in 1..=6 {
for &(w, h) in DEGRAIN_SIZES {
let pitch = w + 8;
let mut dest = vec![0_u16; pitch * h];
let mut src = vec![0_u16; pitch * h];
for y in 0..h {
for x in 0..w {
src[y * pitch + x] = 503;
}
}
let refs_data = vec![vec![0_u16; pitch * h]; radius * 2];
let refs = refs_data.iter().map(std::vec::Vec::as_slice).collect::<Vec<_>>();
let refs_pitch = vec![NonZeroUsize::new(pitch).unwrap(); radius * 2];
let w_refs = vec![0_i32; radius * 2];
verify_asm!($module, degrain_test(
&mut dest,
NonZeroUsize::new(w).unwrap(),
NonZeroUsize::new(h).unwrap(),
&src,
NonZeroUsize::new(pitch).unwrap(),
&refs,
&refs_pitch,
256,
&w_refs,
));
for y in 0..h {
for x in 0..w {
assert_eq!(dest[y * pitch + x], 503, "radius={radius} {w}x{h}");
}
}
}
}
}
#[test]
fn [<degrain_weighted_u8_ $module>]() {
let radius = 2;
for &(w, h) in DEGRAIN_SIZES {
let pitch = w + 5;
let mut dest = vec![0_u8; pitch * h];
let mut src = vec![0_u8; pitch * h];
let mut refs_data = vec![vec![0_u8; pitch * h]; radius * 2];
for y in 0..h {
for x in 0..w {
src[y * pitch + x] = ((x * 3 + y * 5 + 11) & 0xff) as u8;
refs_data[0][y * pitch + x] = ((x * 7 + y * 2 + 13) & 0xff) as u8;
refs_data[1][y * pitch + x] = ((x * 9 + y * 3 + 17) & 0xff) as u8;
refs_data[2][y * pitch + x] = ((x * 5 + y * 11 + 19) & 0xff) as u8;
refs_data[3][y * pitch + x] = ((x * 13 + y * 7 + 23) & 0xff) as u8;
}
}
let refs = refs_data.iter().map(std::vec::Vec::as_slice).collect::<Vec<_>>();
let refs_pitch = vec![NonZeroUsize::new(pitch).unwrap(); radius * 2];
let w_refs = vec![16, 24, 32, 40];
verify_asm!($module, degrain_test(
&mut dest,
NonZeroUsize::new(w).unwrap(),
NonZeroUsize::new(h).unwrap(),
&src,
NonZeroUsize::new(pitch).unwrap(),
&refs,
&refs_pitch,
144,
&w_refs,
));
}
}
#[test]
fn [<degrain_weighted_u16_ $module>]() {
let radius = 3;
for &(w, h) in DEGRAIN_SIZES {
let pitch = w + 7;
let mut dest = vec![0_u16; pitch * h];
let mut src = vec![0_u16; pitch * h];
let mut refs_data = vec![vec![0_u16; pitch * h]; radius * 2];
for y in 0..h {
for x in 0..w {
src[y * pitch + x] = ((x * 113 + y * 71 + 97) & 0xffff) as u16;
refs_data[0][y * pitch + x] = ((x * 31 + y * 17 + 101) & 0xffff) as u16;
refs_data[1][y * pitch + x] = ((x * 43 + y * 29 + 103) & 0xffff) as u16;
refs_data[2][y * pitch + x] = ((x * 59 + y * 37 + 107) & 0xffff) as u16;
refs_data[3][y * pitch + x] = ((x * 67 + y * 41 + 109) & 0xffff) as u16;
refs_data[4][y * pitch + x] = ((x * 73 + y * 47 + 113) & 0xffff) as u16;
refs_data[5][y * pitch + x] = ((x * 79 + y * 53 + 127) & 0xffff) as u16;
}
}
let refs = refs_data.iter().map(std::vec::Vec::as_slice).collect::<Vec<_>>();
let refs_pitch = vec![NonZeroUsize::new(pitch).unwrap(); radius * 2];
let w_refs = vec![8, 12, 16, 20, 24, 28];
verify_asm!($module, degrain_test(
&mut dest,
NonZeroUsize::new(w).unwrap(),
NonZeroUsize::new(h).unwrap(),
&src,
NonZeroUsize::new(pitch).unwrap(),
&refs,
&refs_pitch,
148,
&w_refs,
));
}
}
}
};
}
degrain_tests!(rust);
#[cfg(all(target_arch = "x86_64", feature = "avx2"))]
degrain_tests!(avx2);