use super::*;
use std::vec;
fn planes() -> (std::vec::Vec<u8>, std::vec::Vec<u8>, std::vec::Vec<u8>) {
(vec![0u8; 16 * 8], vec![128u8; 8 * 4], vec![128u8; 8 * 4])
}
#[test]
fn try_new_accepts_valid_tight() {
let (y, u, v) = planes();
let f = Yuv420pFrame::try_new(&y, &u, &v, 16, 8, 16, 8, 8).expect("valid");
assert_eq!(f.width(), 16);
assert_eq!(f.height(), 8);
}
#[test]
fn try_new_accepts_valid_padded_strides() {
let y = vec![0u8; 32 * 8];
let u = vec![128u8; 16 * 4];
let v = vec![128u8; 16 * 4];
let f = Yuv420pFrame::try_new(&y, &u, &v, 16, 8, 32, 16, 16).expect("valid");
assert_eq!(f.y_stride(), 32);
}
#[test]
fn try_new_rejects_zero_dim() {
let (y, u, v) = planes();
let e = Yuv420pFrame::try_new(&y, &u, &v, 0, 8, 16, 8, 8).unwrap_err();
assert!(matches!(e, Yuv420pFrameError::ZeroDimension(_)));
}
#[test]
fn try_new_rejects_odd_width() {
let (y, u, v) = planes();
let e = Yuv420pFrame::try_new(&y, &u, &v, 15, 8, 16, 8, 8).unwrap_err();
assert!(matches!(
e,
Yuv420pFrameError::WidthAlignment(WidthAlignment {
required: WidthAlignmentRequirement::Even,
..
})
));
}
#[test]
fn try_new_accepts_odd_height() {
let y = vec![0u8; 16 * 9];
let u = vec![128u8; 8 * 5];
let v = vec![128u8; 8 * 5];
let f = Yuv420pFrame::try_new(&y, &u, &v, 16, 9, 16, 8, 8).expect("odd height valid");
assert_eq!(f.height(), 9);
}
#[test]
fn try_new_rejects_y_stride_under_width() {
let y = vec![0u8; 16 * 8];
let u = vec![128u8; 8 * 4];
let v = vec![128u8; 8 * 4];
let e = Yuv420pFrame::try_new(&y, &u, &v, 16, 8, 8, 8, 8).unwrap_err();
assert!(matches!(e, Yuv420pFrameError::InsufficientYStride(_)));
}
#[test]
fn try_new_rejects_short_y_plane() {
let y = vec![0u8; 10];
let u = vec![128u8; 8 * 4];
let v = vec![128u8; 8 * 4];
let e = Yuv420pFrame::try_new(&y, &u, &v, 16, 8, 16, 8, 8).unwrap_err();
assert!(matches!(e, Yuv420pFrameError::InsufficientYPlane(_)));
}
#[test]
fn try_new_rejects_short_u_plane() {
let y = vec![0u8; 16 * 8];
let u = vec![128u8; 4];
let v = vec![128u8; 8 * 4];
let e = Yuv420pFrame::try_new(&y, &u, &v, 16, 8, 16, 8, 8).unwrap_err();
assert!(matches!(e, Yuv420pFrameError::InsufficientUPlane(_)));
}
#[test]
#[should_panic(expected = "invalid Yuv420pFrame")]
fn new_panics_on_invalid() {
let y = vec![0u8; 10];
let u = vec![128u8; 8 * 4];
let v = vec![128u8; 8 * 4];
let _ = Yuv420pFrame::new(&y, &u, &v, 16, 8, 16, 8, 8);
}
fn yuv410p_planes() -> (std::vec::Vec<u8>, std::vec::Vec<u8>, std::vec::Vec<u8>) {
(vec![0u8; 16 * 8], vec![128u8; 4 * 2], vec![128u8; 4 * 2])
}
fn planes_411(w: u32, h: u32) -> (std::vec::Vec<u8>, std::vec::Vec<u8>, std::vec::Vec<u8>) {
let ws = w as usize;
let hs = h as usize;
let cw = ws.div_ceil(4);
(
vec![0u8; ws * hs],
vec![128u8; cw * hs],
vec![128u8; cw * hs],
)
}
#[test]
fn yuv410p_try_new_accepts_valid_tight() {
let (y, u, v) = yuv410p_planes();
let f = Yuv410pFrame::try_new(&y, &u, &v, 16, 8, 16, 4, 4).expect("valid");
assert_eq!(f.width(), 16);
assert_eq!(f.height(), 8);
assert_eq!(f.u_stride(), 4);
}
#[test]
fn yuv411p_try_new_accepts_valid_tight() {
let (y, u, v) = planes_411(16, 8);
let f = Yuv411pFrame::try_new(&y, &u, &v, 16, 8, 16, 4, 4).expect("valid");
assert_eq!(f.width(), 16);
assert_eq!(f.height(), 8);
assert_eq!(f.u_stride(), 4);
}
#[test]
fn yuv410p_try_new_accepts_valid_padded_strides() {
let y = vec![0u8; 32 * 8];
let u = vec![128u8; 8 * 2];
let v = vec![128u8; 8 * 2];
let f = Yuv410pFrame::try_new(&y, &u, &v, 16, 8, 32, 8, 8).expect("valid");
assert_eq!(f.y_stride(), 32);
}
#[test]
fn yuv410p_try_new_rejects_zero_dim() {
let (y, u, v) = yuv410p_planes();
let e = Yuv410pFrame::try_new(&y, &u, &v, 0, 8, 16, 4, 4).unwrap_err();
assert!(matches!(e, Yuv410pFrameError::ZeroDimension(_)));
}
#[test]
fn yuv410p_try_new_rejects_width_not_multiple_of_4() {
let y = vec![0u8; 14 * 8];
let u = vec![128u8; 4 * 2];
let v = vec![128u8; 4 * 2];
let e = Yuv410pFrame::try_new(&y, &u, &v, 14, 8, 14, 4, 4).unwrap_err();
assert!(matches!(
e,
Yuv410pFrameError::WidthAlignment(WidthAlignment {
required: WidthAlignmentRequirement::MultipleOfFour,
..
})
));
}
#[test]
fn yuv410p_try_new_accepts_height_not_multiple_of_4() {
let y = vec![0u8; 16 * 6];
let u = vec![128u8; 4 * 2];
let v = vec![128u8; 4 * 2];
let f = Yuv410pFrame::try_new(&y, &u, &v, 16, 6, 16, 4, 4).expect("valid");
assert_eq!(f.height(), 6);
}
#[test]
fn yuv410p_try_new_accepts_height_10_with_three_chroma_rows() {
let y = vec![0u8; 16 * 10];
let u = vec![128u8; 4 * 3];
let v = vec![128u8; 4 * 3];
let f = Yuv410pFrame::try_new(&y, &u, &v, 16, 10, 16, 4, 4).expect("valid");
assert_eq!(f.height(), 10);
}
#[test]
fn yuv410p_try_new_rejects_short_chroma_for_partial_group() {
let y = vec![0u8; 16 * 6];
let u = vec![128u8; 4]; let v = vec![128u8; 4 * 2];
let e = Yuv410pFrame::try_new(&y, &u, &v, 16, 6, 16, 4, 4).unwrap_err();
assert!(matches!(e, Yuv410pFrameError::InsufficientUPlane(_)));
}
#[test]
fn yuv410p_try_new_rejects_y_stride_under_width() {
let (y, u, v) = yuv410p_planes();
let e = Yuv410pFrame::try_new(&y, &u, &v, 16, 8, 8, 4, 4).unwrap_err();
assert!(matches!(e, Yuv410pFrameError::InsufficientYStride(_)));
}
#[test]
fn yuv410p_try_new_rejects_u_stride_under_chroma_width() {
let (y, u, v) = yuv410p_planes();
let e = Yuv410pFrame::try_new(&y, &u, &v, 16, 8, 16, 2, 4).unwrap_err();
assert!(matches!(e, Yuv410pFrameError::InsufficientUStride(_)));
}
#[test]
fn yuv410p_try_new_rejects_short_y_plane() {
let y = vec![0u8; 10];
let u = vec![128u8; 4 * 2];
let v = vec![128u8; 4 * 2];
let e = Yuv410pFrame::try_new(&y, &u, &v, 16, 8, 16, 4, 4).unwrap_err();
assert!(matches!(e, Yuv410pFrameError::InsufficientYPlane(_)));
}
#[test]
fn yuv410p_try_new_rejects_short_u_plane() {
let y = vec![0u8; 16 * 8];
let u = vec![128u8; 2];
let v = vec![128u8; 4 * 2];
let e = Yuv410pFrame::try_new(&y, &u, &v, 16, 8, 16, 4, 4).unwrap_err();
assert!(matches!(e, Yuv410pFrameError::InsufficientUPlane(_)));
}
#[test]
fn yuv410p_try_new_rejects_short_v_plane() {
let y = vec![0u8; 16 * 8];
let u = vec![128u8; 4 * 2];
let v = vec![128u8; 2];
let e = Yuv410pFrame::try_new(&y, &u, &v, 16, 8, 16, 4, 4).unwrap_err();
assert!(matches!(e, Yuv410pFrameError::InsufficientVPlane(_)));
}
#[test]
#[should_panic(expected = "invalid Yuv410pFrame")]
fn yuv410p_new_panics_on_invalid() {
let y = vec![0u8; 10];
let u = vec![128u8; 4 * 2];
let v = vec![128u8; 4 * 2];
let _ = Yuv410pFrame::new(&y, &u, &v, 16, 8, 16, 4, 4);
}
#[cfg(target_pointer_width = "32")]
#[test]
fn yuv410p_try_new_rejects_y_geometry_overflow() {
let big: u32 = 0x1_0000;
let y: [u8; 0] = [];
let u: [u8; 0] = [];
let v: [u8; 0] = [];
let e = Yuv410pFrame::try_new(&y, &u, &v, big, big, big, big / 4, big / 4).unwrap_err();
assert!(matches!(e, Yuv410pFrameError::GeometryOverflow(_)));
}
#[test]
fn yuv411p_try_new_rejects_zero_dim() {
let (y, u, v) = planes_411(16, 8);
let e = Yuv411pFrame::try_new(&y, &u, &v, 0, 8, 16, 4, 4).unwrap_err();
assert!(matches!(e, Yuv411pFrameError::ZeroDimension(_)));
}
#[test]
fn yuv411p_try_new_accepts_non_4_aligned_widths() {
for (w, expected_cw) in [
(1u32, 1u32),
(2, 1),
(3, 1),
(5, 2),
(6, 2),
(7, 2),
(9, 3),
(17, 5),
(641, 161),
] {
let ws = w as usize;
let cws = expected_cw as usize;
let h: u32 = 4;
let hs = h as usize;
let y = vec![0u8; ws * hs];
let u = vec![128u8; cws * hs];
let v = vec![128u8; cws * hs];
let f = Yuv411pFrame::try_new(&y, &u, &v, w, h, w, expected_cw, expected_cw)
.unwrap_or_else(|e| panic!("width={w} (chroma={expected_cw}) should be valid: {e:?}"));
assert_eq!(f.width(), w, "width={w}");
assert_eq!(f.u_stride(), expected_cw, "width={w}");
assert_eq!(f.v_stride(), expected_cw, "width={w}");
}
}
#[test]
fn yuv411p_try_new_rejects_chroma_stride_below_div_ceil_4() {
let y = vec![0u8; 5 * 4];
let u = vec![128u8; 2 * 4];
let v = vec![128u8; 2 * 4];
let e = Yuv411pFrame::try_new(&y, &u, &v, 5, 4, 5, 1, 2).unwrap_err();
assert!(
matches!(e, Yuv411pFrameError::InsufficientUStride(_)),
"{e:?}"
);
}
#[test]
fn yuv411p_try_new_accepts_odd_height() {
let y = vec![0u8; 16 * 9];
let u = vec![128u8; 4 * 9];
let v = vec![128u8; 4 * 9];
let f = Yuv411pFrame::try_new(&y, &u, &v, 16, 9, 16, 4, 4).expect("odd height valid");
assert_eq!(f.height(), 9);
}
#[test]
fn yuv411p_try_new_rejects_y_stride_under_width() {
let (y, u, v) = planes_411(16, 8);
let e = Yuv411pFrame::try_new(&y, &u, &v, 16, 8, 8, 4, 4).unwrap_err();
assert!(matches!(e, Yuv411pFrameError::InsufficientYStride(_)));
}
#[test]
fn yuv411p_try_new_rejects_u_stride_under_chroma_width() {
let (y, u, v) = planes_411(16, 8);
let e = Yuv411pFrame::try_new(&y, &u, &v, 16, 8, 16, 3, 4).unwrap_err();
assert!(matches!(e, Yuv411pFrameError::InsufficientUStride(_)));
}
#[test]
fn yuv411p_try_new_rejects_short_y_plane() {
let y = vec![0u8; 10];
let u = vec![128u8; 4 * 8];
let v = vec![128u8; 4 * 8];
let e = Yuv411pFrame::try_new(&y, &u, &v, 16, 8, 16, 4, 4).unwrap_err();
assert!(matches!(e, Yuv411pFrameError::InsufficientYPlane(_)));
}
#[test]
fn yuv411p_try_new_rejects_short_u_plane() {
let y = vec![0u8; 16 * 8];
let u = vec![128u8; 4];
let v = vec![128u8; 4 * 8];
let e = Yuv411pFrame::try_new(&y, &u, &v, 16, 8, 16, 4, 4).unwrap_err();
assert!(matches!(e, Yuv411pFrameError::InsufficientUPlane(_)));
}
#[test]
#[should_panic(expected = "invalid Yuv411pFrame")]
fn yuv411p_new_panics_on_invalid() {
let y = vec![0u8; 10];
let u = vec![128u8; 4 * 8];
let v = vec![128u8; 4 * 8];
let _ = Yuv411pFrame::new(&y, &u, &v, 16, 8, 16, 4, 4);
}