use oxideav_webp::{decode_webp, encode_webp_lossless, WebpError, WebpFrame};
fn make_rgba(width: u32, height: u32) -> Vec<u8> {
let mut buf = Vec::with_capacity((width * height * 4) as usize);
for y in 0..height {
for x in 0..width {
buf.push((x.wrapping_mul(37).wrapping_add(y) & 0xff) as u8); buf.push((y.wrapping_mul(53).wrapping_add(x) & 0xff) as u8); buf.push(((x ^ y).wrapping_mul(101) & 0xff) as u8); buf.push((255 - ((x.wrapping_add(y)) & 0xff)) as u8); }
}
buf
}
fn roundtrip(width: u32, height: u32, rgba: &[u8]) -> WebpFrame {
let file = encode_webp_lossless(rgba, width, height).expect("VP8L lossless encode");
let image = decode_webp(&file).expect("decode_webp on our own encoded file");
assert_eq!(
image.frames.len(),
1,
"still image yields exactly one frame"
);
assert_eq!(image.anim_background_rgba, None);
assert_eq!(image.anim_loop_count, None);
image.frames.into_iter().next().unwrap()
}
#[test]
fn decode_webp_roundtrip_is_flat_rgba_buffer() {
let (w, h) = (7u32, 5u32);
let src = make_rgba(w, h);
let frame = roundtrip(w, h, &src);
assert_eq!(frame.width, w);
assert_eq!(frame.height, h);
assert_eq!(frame.duration_ms, 0, "still image has zero frame delay");
assert_eq!(frame.rgba.len(), (w * h * 4) as usize);
assert_eq!(frame.rgba.len(), src.len());
assert_eq!(frame.rgba, src, "round-tripped RGBA must equal the input");
}
#[test]
fn decode_webp_roundtrip_1x1() {
let src = vec![0x12, 0x34, 0x56, 0x78];
let frame = roundtrip(1, 1, &src);
assert_eq!(frame.width, 1);
assert_eq!(frame.height, 1);
assert_eq!(frame.rgba.len(), 4);
assert_eq!(frame.rgba, src);
}
#[test]
fn decode_webp_roundtrip_larger_buffer_shape() {
let (w, h) = (16u32, 16u32);
let src = make_rgba(w, h);
let frame = roundtrip(w, h, &src);
assert_eq!(frame.rgba.len(), (w * h * 4) as usize);
assert_eq!(frame.rgba, src);
}
#[test]
fn decode_webp_rejects_garbage_as_invalid_data() {
let err = decode_webp(b"not a webp file at all").expect_err("garbage is rejected");
assert_eq!(err, WebpError::InvalidData);
}