use crate::frame::{WidthAlignment, WidthAlignmentRequirement};
use super::{
super::{
Y2xxFrame, Y2xxFrameError, Y210BeFrame, Y210Frame, Y210LeFrame, Y212BeFrame, Y212Frame,
Y216BeFrame, Y216Frame,
},
util::le_encoded_u16_buf,
};
use std::vec;
#[test]
fn y210_frame_try_new_accepts_valid_tight() {
let buf = vec![0u16; 8 * 2];
let frame = Y210Frame::try_new(&buf, 4, 2, 8).unwrap();
assert_eq!(frame.width(), 4);
assert_eq!(frame.height(), 2);
assert_eq!(frame.stride(), 8);
}
#[test]
fn y210_frame_try_new_accepts_oversized_stride() {
let buf = vec![0u16; 16 * 4];
Y210Frame::try_new(&buf, 4, 4, 16).unwrap();
}
#[test]
fn y210_frame_try_new_rejects_zero_dimension() {
let buf: [u16; 0] = [];
let err = Y210Frame::try_new(&buf, 0, 1, 0).unwrap_err();
assert!(matches!(err, Y2xxFrameError::ZeroDimension(_)));
let err = Y210Frame::try_new(&buf, 4, 0, 8).unwrap_err();
assert!(matches!(err, Y2xxFrameError::ZeroDimension(_)));
}
#[test]
fn y210_frame_try_new_rejects_odd_width() {
let buf = vec![0u16; 64];
for w in [1u32, 3, 5, 7, 9, 11, 13] {
let stride = (w as usize) * 2;
let err = Y210Frame::try_new(&buf, w, 1, stride as u32).unwrap_err();
assert!(matches!(
err,
Y2xxFrameError::WidthAlignment(WidthAlignment {
required: WidthAlignmentRequirement::Even,
..
})
));
}
for w in [2u32, 4, 6, 8] {
let stride = w * 2;
let buf = vec![0u16; stride as usize];
Y210Frame::try_new(&buf, w, 1, stride).unwrap();
}
}
#[test]
fn y210_frame_try_new_rejects_stride_too_small() {
let buf = vec![0u16; 16];
let err = Y210Frame::try_new(&buf, 4, 1, 7).unwrap_err();
assert!(matches!(err, Y2xxFrameError::InsufficientStride(_)));
}
#[test]
fn y210_frame_try_new_rejects_short_plane() {
let buf = vec![0u16; 7]; let err = Y210Frame::try_new(&buf, 4, 1, 8).unwrap_err();
assert!(matches!(err, Y2xxFrameError::InsufficientPlane(_)));
}
#[test]
fn y210_frame_accessors_round_trip() {
let buf = vec![0u16; 16 * 4];
let frame = Y210Frame::try_new(&buf, 8, 4, 16).unwrap();
assert_eq!(frame.packed().len(), 16 * 4);
assert_eq!(frame.width(), 8);
assert_eq!(frame.height(), 4);
assert_eq!(frame.stride(), 16);
}
#[test]
fn y2xx_frame_try_new_rejects_unsupported_bits() {
let buf = vec![0u16; 16];
let err = Y2xxFrame::<11>::try_new(&buf, 4, 1, 8).unwrap_err();
assert!(matches!(err, Y2xxFrameError::UnsupportedBits(_)));
let err = Y2xxFrame::<8>::try_new(&buf, 4, 1, 8).unwrap_err();
assert!(matches!(err, Y2xxFrameError::UnsupportedBits(_)));
let err = Y2xxFrame::<14>::try_new(&buf, 4, 1, 8).unwrap_err();
assert!(matches!(err, Y2xxFrameError::UnsupportedBits(_)));
}
#[test]
fn y210_frame_try_new_checked_rejects_low_bit_violations() {
let mut intended = vec![0u16; 8]; intended[0] = 0xFFC0; intended[1] = 0xFFC1; let buf = le_encoded_u16_buf(&intended);
let err = Y210Frame::try_new_checked(&buf, 4, 1, 8).unwrap_err();
assert_eq!(err, Y2xxFrameError::SampleLowBitsSet);
}
#[test]
fn y210_frame_try_new_checked_accepts_valid_msb_aligned_data() {
let intended: std::vec::Vec<u16> = (0..8).map(|i| ((i as u16) << 6) & 0xFFC0).collect();
let buf: std::vec::Vec<u16> = intended
.iter()
.map(|v| u16::from_ne_bytes(v.to_le_bytes()))
.collect();
Y210Frame::try_new_checked(&buf, 4, 1, 8).unwrap();
}
#[test]
fn y210_frame_try_new_checked_accepts_le_encoded_buffer() {
let intended: std::vec::Vec<u16> = (0..8u16).map(|i| (i << 6) & 0xFFC0).collect();
let le_bytes: std::vec::Vec<u8> = intended.iter().flat_map(|v| v.to_le_bytes()).collect();
let buf: std::vec::Vec<u16> = le_bytes
.chunks_exact(2)
.map(|b| u16::from_ne_bytes([b[0], b[1]]))
.collect();
Y210Frame::try_new_checked(&buf, 4, 1, 8).unwrap();
}
#[test]
fn y210_frame_try_new_checked_rejects_be_encoded_buffer_with_low_bits() {
let intended: std::vec::Vec<u16> = vec![0xFFC0u16; 8];
let be_bytes: std::vec::Vec<u8> = intended.iter().flat_map(|v| v.to_be_bytes()).collect();
let buf: std::vec::Vec<u16> = be_bytes
.chunks_exact(2)
.map(|b| u16::from_ne_bytes([b[0], b[1]]))
.collect();
let err = Y210Frame::try_new_checked(&buf, 4, 1, 8).unwrap_err();
assert_eq!(err, Y2xxFrameError::SampleLowBitsSet);
}
#[test]
#[should_panic(expected = "invalid Y2xxFrame:")]
fn y210_frame_new_panics_on_invalid() {
let buf: [u16; 0] = [];
let _ = Y210Frame::new(&buf, 0, 0, 0);
}
#[test]
fn y210_frame_try_new_checked_ignores_stride_padding_bytes() {
let mut intended = [0u16; 12 * 2]; for row in 0..2 {
for i in 0..8 {
intended[row * 12 + i] = ((i as u16) << 6) & 0xFFC0;
}
for i in 8..12 {
intended[row * 12 + i] = 0xFFFF; }
}
let buf: std::vec::Vec<u16> = intended
.iter()
.map(|v| u16::from_ne_bytes(v.to_le_bytes()))
.collect();
Y210Frame::try_new_checked(&buf, 4, 2, 12).unwrap();
}
#[test]
fn y212_frame_try_new_accepts_valid_tight() {
let buf = vec![0u16; 8 * 2];
let frame = Y212Frame::try_new(&buf, 4, 2, 8).unwrap();
assert_eq!(frame.width(), 4);
assert_eq!(frame.height(), 2);
}
#[test]
fn y212_frame_try_new_checked_rejects_low_bit_violations() {
let mut intended = vec![0u16; 8]; intended[0] = 0xFFF0; intended[1] = 0xFFF1; let buf = le_encoded_u16_buf(&intended);
let err = Y212Frame::try_new_checked(&buf, 4, 1, 8).unwrap_err();
assert_eq!(err, Y2xxFrameError::SampleLowBitsSet);
}
#[test]
fn y216_frame_try_new_accepts_valid_tight() {
let buf = vec![0xFFFFu16; 8 * 2];
let frame = Y216Frame::try_new(&buf, 4, 2, 8).unwrap();
assert_eq!(frame.width(), 4);
assert_eq!(frame.height(), 2);
assert_eq!(frame.stride(), 8);
}
#[test]
fn y216_frame_try_new_accepts_oversized_stride() {
let buf = vec![0u16; 16 * 4];
Y216Frame::try_new(&buf, 4, 4, 16).unwrap();
}
#[test]
fn y216_frame_try_new_rejects_zero_dimension() {
let buf: [u16; 0] = [];
let err = Y216Frame::try_new(&buf, 0, 1, 0).unwrap_err();
assert!(matches!(err, Y2xxFrameError::ZeroDimension(_)));
let err = Y216Frame::try_new(&buf, 4, 0, 8).unwrap_err();
assert!(matches!(err, Y2xxFrameError::ZeroDimension(_)));
}
#[test]
fn y216_frame_try_new_rejects_odd_width() {
let buf = vec![0u16; 64];
for w in [1u32, 3, 5, 7, 9, 11, 13] {
let stride = (w as usize) * 2;
let err = Y216Frame::try_new(&buf, w, 1, stride as u32).unwrap_err();
assert!(matches!(
err,
Y2xxFrameError::WidthAlignment(WidthAlignment {
required: WidthAlignmentRequirement::Even,
..
})
));
}
for w in [2u32, 4, 6, 8] {
let stride = w * 2;
let buf = vec![0u16; stride as usize];
Y216Frame::try_new(&buf, w, 1, stride).unwrap();
}
}
#[test]
fn y216_frame_try_new_rejects_stride_too_small() {
let buf = vec![0u16; 16];
let err = Y216Frame::try_new(&buf, 4, 1, 7).unwrap_err();
assert!(matches!(err, Y2xxFrameError::InsufficientStride(_)));
}
#[test]
fn y216_frame_try_new_rejects_short_plane() {
let buf = vec![0u16; 7]; let err = Y216Frame::try_new(&buf, 4, 1, 8).unwrap_err();
assert!(matches!(err, Y2xxFrameError::InsufficientPlane(_)));
}
#[test]
fn y216_frame_accessors_round_trip() {
let buf = vec![0xFFFFu16; 16 * 4];
let frame = Y216Frame::try_new(&buf, 8, 4, 16).unwrap();
assert_eq!(frame.packed().len(), 16 * 4);
assert_eq!(frame.width(), 8);
assert_eq!(frame.height(), 4);
assert_eq!(frame.stride(), 16);
}
#[test]
fn y216_frame_try_new_checked_accepts_arbitrary_low_bits() {
let buf = vec![0xFFFFu16; 8]; Y216Frame::try_new_checked(&buf, 4, 1, 8).unwrap();
let buf: std::vec::Vec<u16> = (0..8u16).map(|i| 0x0001 + i).collect();
Y216Frame::try_new_checked(&buf, 4, 1, 8).unwrap();
}
#[test]
fn y216_frame_try_new_checked_accepts_valid_tight() {
let buf = vec![0u16; 8 * 2];
let frame = Y216Frame::try_new_checked(&buf, 4, 2, 8).unwrap();
assert_eq!(frame.width(), 4);
assert_eq!(frame.height(), 2);
}
#[test]
#[should_panic(expected = "invalid Y2xxFrame:")]
fn y216_frame_new_panics_on_invalid() {
let buf: [u16; 0] = [];
let _ = Y216Frame::new(&buf, 0, 0, 0);
}
#[test]
fn y210_be_frame_alias_constructs() {
let buf = vec![0u16; 8 * 2];
let f = Y210BeFrame::try_new(&buf, 4, 2, 8).unwrap();
assert!(f.is_be());
assert_eq!(f.width(), 4);
assert_eq!(f.height(), 2);
}
#[test]
fn y212_be_frame_alias_constructs() {
let buf = vec![0u16; 8 * 2];
let f = Y212BeFrame::try_new(&buf, 4, 2, 8).unwrap();
assert!(f.is_be());
}
#[test]
fn y216_be_frame_alias_constructs() {
let buf = vec![0u16; 8 * 2];
let f = Y216BeFrame::try_new(&buf, 4, 2, 8).unwrap();
assert!(f.is_be());
}
#[test]
fn y210_le_frame_alias_is_default() {
let buf = vec![0u16; 8 * 2];
let f_default = Y210Frame::try_new(&buf, 4, 2, 8).unwrap();
let f_explicit = Y210LeFrame::try_new(&buf, 4, 2, 8).unwrap();
assert!(!f_default.is_be());
assert!(!f_explicit.is_be());
}
#[test]
fn y210_be_frame_try_new_checked_validates_be_encoded_low_bits() {
let intended: std::vec::Vec<u16> = (0..8).map(|i| (i << 6) as u16).collect(); let pix_be: std::vec::Vec<u16> = intended
.iter()
.map(|v| u16::from_ne_bytes(v.to_be_bytes()))
.collect();
Y210BeFrame::try_new_checked(&pix_be, 4, 1, 8)
.expect("valid BE-encoded 10-bit MSB-aligned plane should pass");
}
#[test]
fn y210_be_frame_try_new_checked_rejects_be_encoded_low_bits() {
let intended: std::vec::Vec<u16> = vec![0x0001u16; 8];
let pix_be: std::vec::Vec<u16> = intended
.iter()
.map(|v| u16::from_ne_bytes(v.to_be_bytes()))
.collect();
let err = Y210BeFrame::try_new_checked(&pix_be, 4, 1, 8).unwrap_err();
assert_eq!(err, Y2xxFrameError::SampleLowBitsSet);
}