use super::*;
fn solid_x2rgb10_frame(width: u32, height: u32, r10: u32, g10: u32, b10: u32) -> Vec<u8> {
let w = width as usize;
let h = height as usize;
let pix: u32 = ((r10 & 0x3FF) << 20) | ((g10 & 0x3FF) << 10) | (b10 & 0x3FF);
let mut buf = std::vec![0u8; w * h * 4];
for px in buf.chunks_mut(4) {
px.copy_from_slice(&pix.to_le_bytes());
}
buf
}
fn solid_x2bgr10_frame(width: u32, height: u32, r10: u32, g10: u32, b10: u32) -> Vec<u8> {
let w = width as usize;
let h = height as usize;
let pix: u32 = ((b10 & 0x3FF) << 20) | ((g10 & 0x3FF) << 10) | (r10 & 0x3FF);
let mut buf = std::vec![0u8; w * h * 4];
for px in buf.chunks_mut(4) {
px.copy_from_slice(&pix.to_le_bytes());
}
buf
}
#[test]
#[cfg_attr(
miri,
ignore = "SIMD-dispatched row kernels use intrinsics unsupported by Miri"
)]
fn x2rgb10_with_rgb_downshifts_to_8bit() {
let pix = solid_x2rgb10_frame(16, 4, 0x3FC, 0x200, 0x080);
let src = X2Rgb10Frame::try_new(&pix, 16, 4, 64).unwrap();
let mut rgb_out = std::vec![0u8; 16 * 4 * 3];
let mut sink = MixedSinker::<X2Rgb10>::new(16, 4)
.with_rgb(&mut rgb_out)
.unwrap();
x2rgb10_to(&src, true, ColorMatrix::Bt709, &mut sink).unwrap();
for px in rgb_out.chunks(3) {
assert_eq!(px, [0xFF, 0x80, 0x20]);
}
}
#[test]
#[cfg_attr(
miri,
ignore = "SIMD-dispatched row kernels use intrinsics unsupported by Miri"
)]
fn x2rgb10_with_rgba_forces_alpha_to_ff() {
let pix = solid_x2rgb10_frame(16, 4, 0x3FC, 0x200, 0x080);
let src = X2Rgb10Frame::try_new(&pix, 16, 4, 64).unwrap();
let mut rgba_out = std::vec![0u8; 16 * 4 * 4];
let mut sink = MixedSinker::<X2Rgb10>::new(16, 4)
.with_rgba(&mut rgba_out)
.unwrap();
x2rgb10_to(&src, true, ColorMatrix::Bt709, &mut sink).unwrap();
for px in rgba_out.chunks(4) {
assert_eq!(px, [0xFF, 0x80, 0x20, 0xFF]);
}
}
#[test]
#[cfg_attr(
miri,
ignore = "SIMD-dispatched row kernels use intrinsics unsupported by Miri"
)]
fn x2rgb10_with_rgb_u16_preserves_native_precision() {
let pix = solid_x2rgb10_frame(16, 4, 0x3FC, 0x200, 0x080);
let src = X2Rgb10Frame::try_new(&pix, 16, 4, 64).unwrap();
let mut rgb_out = std::vec![0u16; 16 * 4 * 3];
let mut sink = MixedSinker::<X2Rgb10>::new(16, 4)
.with_rgb_u16(&mut rgb_out)
.unwrap();
x2rgb10_to(&src, true, ColorMatrix::Bt709, &mut sink).unwrap();
for px in rgb_out.chunks(3) {
assert_eq!(px, [0x3FC, 0x200, 0x080]);
}
}
#[test]
#[cfg_attr(
miri,
ignore = "SIMD-dispatched row kernels use intrinsics unsupported by Miri"
)]
fn x2bgr10_with_rgb_swaps_channels() {
let pix = solid_x2bgr10_frame(16, 4, 0x3FC, 0x200, 0x080);
let src = X2Bgr10Frame::try_new(&pix, 16, 4, 64).unwrap();
let mut rgb_out = std::vec![0u8; 16 * 4 * 3];
let mut sink = MixedSinker::<X2Bgr10>::new(16, 4)
.with_rgb(&mut rgb_out)
.unwrap();
x2bgr10_to(&src, true, ColorMatrix::Bt709, &mut sink).unwrap();
for px in rgb_out.chunks(3) {
assert_eq!(px, [0xFF, 0x80, 0x20]);
}
}
#[test]
#[cfg_attr(
miri,
ignore = "SIMD-dispatched row kernels use intrinsics unsupported by Miri"
)]
fn x2bgr10_with_rgba_swaps_and_forces_alpha() {
let pix = solid_x2bgr10_frame(16, 4, 0x3FC, 0x200, 0x080);
let src = X2Bgr10Frame::try_new(&pix, 16, 4, 64).unwrap();
let mut rgba_out = std::vec![0u8; 16 * 4 * 4];
let mut sink = MixedSinker::<X2Bgr10>::new(16, 4)
.with_rgba(&mut rgba_out)
.unwrap();
x2bgr10_to(&src, true, ColorMatrix::Bt709, &mut sink).unwrap();
for px in rgba_out.chunks(4) {
assert_eq!(px, [0xFF, 0x80, 0x20, 0xFF]);
}
}
#[test]
#[cfg_attr(
miri,
ignore = "SIMD-dispatched row kernels use intrinsics unsupported by Miri"
)]
fn x2rgb10_simd_matches_scalar_with_random_input() {
let w = 1921usize;
let h = 4usize;
let mut pix = std::vec![0u8; w * h * 4];
pseudo_random_u8(&mut pix, 0x1234_5678);
let src = X2Rgb10Frame::try_new(&pix, w as u32, h as u32, (w * 4) as u32).unwrap();
let mut rgb_simd = std::vec![0u8; w * h * 3];
let mut rgb_scalar = std::vec![0u8; w * h * 3];
let mut rgba_simd = std::vec![0u8; w * h * 4];
let mut rgba_scalar = std::vec![0u8; w * h * 4];
let mut rgb_u16_simd = std::vec![0u16; w * h * 3];
let mut rgb_u16_scalar = std::vec![0u16; w * h * 3];
let mut luma_simd = std::vec![0u8; w * h];
let mut luma_scalar = std::vec![0u8; w * h];
let mut s_simd = MixedSinker::<X2Rgb10>::new(w, h)
.with_rgb(&mut rgb_simd)
.unwrap()
.with_rgba(&mut rgba_simd)
.unwrap()
.with_rgb_u16(&mut rgb_u16_simd)
.unwrap()
.with_luma(&mut luma_simd)
.unwrap();
x2rgb10_to(&src, true, ColorMatrix::Bt709, &mut s_simd).unwrap();
let mut s_scalar = MixedSinker::<X2Rgb10>::new(w, h)
.with_rgb(&mut rgb_scalar)
.unwrap()
.with_rgba(&mut rgba_scalar)
.unwrap()
.with_rgb_u16(&mut rgb_u16_scalar)
.unwrap()
.with_luma(&mut luma_scalar)
.unwrap();
s_scalar.set_simd(false);
x2rgb10_to(&src, true, ColorMatrix::Bt709, &mut s_scalar).unwrap();
assert_eq!(rgb_simd, rgb_scalar, "RGB output diverges");
assert_eq!(rgba_simd, rgba_scalar, "RGBA output diverges");
assert_eq!(rgb_u16_simd, rgb_u16_scalar, "RGB u16 output diverges");
assert_eq!(luma_simd, luma_scalar, "Luma output diverges");
}
#[test]
#[cfg_attr(
miri,
ignore = "SIMD-dispatched row kernels use intrinsics unsupported by Miri"
)]
fn x2bgr10_simd_matches_scalar_with_random_input() {
let w = 1921usize;
let h = 4usize;
let mut pix = std::vec![0u8; w * h * 4];
pseudo_random_u8(&mut pix, 0xABCD_EF01);
let src = X2Bgr10Frame::try_new(&pix, w as u32, h as u32, (w * 4) as u32).unwrap();
let mut rgb_simd = std::vec![0u8; w * h * 3];
let mut rgb_scalar = std::vec![0u8; w * h * 3];
let mut rgba_simd = std::vec![0u8; w * h * 4];
let mut rgba_scalar = std::vec![0u8; w * h * 4];
let mut rgb_u16_simd = std::vec![0u16; w * h * 3];
let mut rgb_u16_scalar = std::vec![0u16; w * h * 3];
let mut luma_simd = std::vec![0u8; w * h];
let mut luma_scalar = std::vec![0u8; w * h];
let mut s_simd = MixedSinker::<X2Bgr10>::new(w, h)
.with_rgb(&mut rgb_simd)
.unwrap()
.with_rgba(&mut rgba_simd)
.unwrap()
.with_rgb_u16(&mut rgb_u16_simd)
.unwrap()
.with_luma(&mut luma_simd)
.unwrap();
x2bgr10_to(&src, true, ColorMatrix::Bt709, &mut s_simd).unwrap();
let mut s_scalar = MixedSinker::<X2Bgr10>::new(w, h)
.with_rgb(&mut rgb_scalar)
.unwrap()
.with_rgba(&mut rgba_scalar)
.unwrap()
.with_rgb_u16(&mut rgb_u16_scalar)
.unwrap()
.with_luma(&mut luma_scalar)
.unwrap();
s_scalar.set_simd(false);
x2bgr10_to(&src, true, ColorMatrix::Bt709, &mut s_scalar).unwrap();
assert_eq!(rgb_simd, rgb_scalar, "RGB output diverges");
assert_eq!(rgba_simd, rgba_scalar, "RGBA output diverges");
assert_eq!(rgb_u16_simd, rgb_u16_scalar, "RGB u16 output diverges");
assert_eq!(luma_simd, luma_scalar, "Luma output diverges");
}
fn pack_x2rgb10_word(r10: u32, g10: u32, b10: u32) -> u32 {
((r10 & 0x3FF) << 20) | ((g10 & 0x3FF) << 10) | (b10 & 0x3FF)
}
fn pack_x2bgr10_word(r10: u32, g10: u32, b10: u32) -> u32 {
((b10 & 0x3FF) << 20) | ((g10 & 0x3FF) << 10) | (r10 & 0x3FF)
}
fn x2_plane_bytes<F: Fn(usize) -> u32>(width: u32, height: u32, word_at: F, be: bool) -> Vec<u8> {
let n = (width as usize) * (height as usize);
let mut buf = std::vec![0u8; n * 4];
for (i, chunk) in buf.chunks_mut(4).enumerate() {
let w = word_at(i);
let bytes = if be { w.to_be_bytes() } else { w.to_le_bytes() };
chunk.copy_from_slice(&bytes);
}
buf
}
#[test]
fn x2rgb10_le_be_roundtrip_byte_identical() {
let words: Vec<u32> = (0..16 * 4)
.map(|i| pack_x2rgb10_word(0x100 + i as u32, 0x200, 0x080 + (i as u32 & 0xF)))
.collect();
let pix_le = x2_plane_bytes(16, 4, |i| words[i], false);
let pix_be = x2_plane_bytes(16, 4, |i| words[i], true);
let frame_le = X2Rgb10Frame::try_new(&pix_le, 16, 4, 64).unwrap();
let mut out_le = vec![0u8; 16 * 4 * 4];
let mut sink_le = MixedSinker::<X2Rgb10>::new(16, 4)
.with_simd(false)
.with_rgba(&mut out_le)
.unwrap();
x2rgb10_to(&frame_le, true, ColorMatrix::Bt709, &mut sink_le).unwrap();
let frame_be = X2Rgb10BeFrame::try_new(&pix_be, 16, 4, 64).unwrap();
let mut out_be = vec![0u8; 16 * 4 * 4];
let mut sink_be = MixedSinker::<X2Rgb10<true>>::new(16, 4)
.with_simd(false)
.with_rgba(&mut out_be)
.unwrap();
x2rgb10_to_endian(&frame_be, true, ColorMatrix::Bt709, &mut sink_be).unwrap();
assert_eq!(
out_le, out_be,
"X2Rgb10 LE/BE outputs diverge — `<const BE>` propagation broken"
);
}
#[test]
fn x2bgr10_le_be_roundtrip_byte_identical() {
let words: Vec<u32> = (0..16 * 4)
.map(|i| pack_x2bgr10_word(0x100 + i as u32, 0x200, 0x080 + (i as u32 & 0xF)))
.collect();
let pix_le = x2_plane_bytes(16, 4, |i| words[i], false);
let pix_be = x2_plane_bytes(16, 4, |i| words[i], true);
let frame_le = X2Bgr10Frame::try_new(&pix_le, 16, 4, 64).unwrap();
let mut out_le = vec![0u8; 16 * 4 * 4];
let mut sink_le = MixedSinker::<X2Bgr10>::new(16, 4)
.with_simd(false)
.with_rgba(&mut out_le)
.unwrap();
x2bgr10_to(&frame_le, true, ColorMatrix::Bt709, &mut sink_le).unwrap();
let frame_be = X2Bgr10BeFrame::try_new(&pix_be, 16, 4, 64).unwrap();
let mut out_be = vec![0u8; 16 * 4 * 4];
let mut sink_be = MixedSinker::<X2Bgr10<true>>::new(16, 4)
.with_simd(false)
.with_rgba(&mut out_be)
.unwrap();
x2bgr10_to_endian(&frame_be, true, ColorMatrix::Bt709, &mut sink_be).unwrap();
assert_eq!(
out_le, out_be,
"X2Bgr10 LE/BE outputs diverge — `<const BE>` propagation broken"
);
}