use rusty_jpeg::decode::Decoder;
use std::io::Cursor;
const LIBJPEG_PROGRESSIVE: &[u8] = include_bytes!("fixtures/progressive_libjpeg.jpg");
#[test]
fn progressive_dc_scan_before_any_ac_table_does_not_panic() {
let img = Decoder::new(Cursor::new(LIBJPEG_PROGRESSIVE))
.decode()
.expect("libjpeg progressive file must decode");
assert_eq!(img.len(), 32 * 32 * 3, "unexpected decoded size");
let first = img[0];
assert!(
img.iter().any(|&p| p != first),
"decoded progressive image is a flat constant"
);
}
#[test]
fn progressive_decodes_through_the_planar_path_too() {
let mut d = Decoder::new(Cursor::new(LIBJPEG_PROGRESSIVE));
d.set_single_threaded(true);
let img = d.decode_planar().expect("planar progressive decode");
assert_eq!(img.components.len(), 3);
for c in &img.components {
let need = c.stride * c.height.saturating_sub(1) + c.width;
assert!(c.data.len() >= need, "plane smaller than its geometry");
}
}
#[test]
fn missing_ac_table_on_an_ac_scan_is_an_error_not_a_panic() {
for cut in (24..LIBJPEG_PROGRESSIVE.len()).step_by(7) {
let data = &LIBJPEG_PROGRESSIVE[..cut];
let res = std::panic::catch_unwind(|| {
let mut d = Decoder::new(Cursor::new(data));
d.set_single_threaded(true);
d.decode().is_ok()
});
assert!(
res.is_ok(),
"panicked on a progressive file truncated to {cut} bytes"
);
}
}