use oxideav_tiff::decode_tiff;
fn entry_short(tag: u16, value: u16) -> [u8; 12] {
let mut e = [0u8; 12];
e[0..2].copy_from_slice(&tag.to_le_bytes());
e[2..4].copy_from_slice(&3u16.to_le_bytes()); e[4..8].copy_from_slice(&1u32.to_le_bytes()); e[8..10].copy_from_slice(&value.to_le_bytes());
e
}
fn build_1x1_gray8(sample_format: Option<u16>) -> Vec<u8> {
let mut out = Vec::new();
out.extend_from_slice(b"II");
out.extend_from_slice(&42u16.to_le_bytes());
out.extend_from_slice(&16u32.to_le_bytes());
out.push(0xAB);
out.extend_from_slice(&[0u8; 7]);
let n: u16 = 9 + if sample_format.is_some() { 1 } else { 0 };
out.extend_from_slice(&n.to_le_bytes());
out.extend_from_slice(&entry_short(256, 1)); out.extend_from_slice(&entry_short(257, 1)); out.extend_from_slice(&entry_short(258, 8)); out.extend_from_slice(&entry_short(259, 1)); out.extend_from_slice(&entry_short(262, 1)); out.extend_from_slice(&entry_short(273, 8)); out.extend_from_slice(&entry_short(277, 1)); out.extend_from_slice(&entry_short(278, 1)); out.extend_from_slice(&entry_short(279, 1)); if let Some(fmt) = sample_format {
out.extend_from_slice(&entry_short(339, fmt));
}
out.extend_from_slice(&0u32.to_le_bytes());
out
}
#[test]
fn sample_format_absent_decodes_as_unsigned() {
let bytes = build_1x1_gray8(None);
let d = decode_tiff(&bytes).expect("baseline 1x1 Gray8 must decode");
assert_eq!((d.width, d.height), (1, 1));
assert_eq!(d.frame.planes[0].data, vec![0xAB]);
}
#[test]
fn sample_format_uint_decodes_as_unsigned() {
let bytes = build_1x1_gray8(Some(1));
let d = decode_tiff(&bytes).expect("SampleFormat=1 must decode");
assert_eq!(d.frame.planes[0].data, vec![0xAB]);
}
#[test]
fn sample_format_undefined_falls_back_to_unsigned() {
let bytes = build_1x1_gray8(Some(4));
let d = decode_tiff(&bytes).expect("SampleFormat=4 must fall back to unsigned");
assert_eq!(d.frame.planes[0].data, vec![0xAB]);
}
fn expect_err_containing(bytes: &[u8], needle: &str) {
match decode_tiff(bytes) {
Ok(_) => panic!("expected an error containing {needle:?}, got Ok(..)"),
Err(e) => {
let msg = format!("{e}");
assert!(
msg.contains(needle),
"expected error to contain {needle:?}, got: {msg}"
);
}
}
}
#[test]
fn sample_format_signed_int_8bit_gray_offset_binary() {
let bytes = build_1x1_gray8(Some(2));
let d = decode_tiff(&bytes).expect("8-bit signed grayscale must decode");
assert_eq!((d.width, d.height), (1, 1));
assert_eq!(d.frame.planes[0].data, vec![0x2Bu8]); }
#[test]
fn sample_format_ieee_fp_terminates_gracefully() {
let bytes = build_1x1_gray8(Some(3));
expect_err_containing(&bytes, "SampleFormat=3");
}
#[test]
fn sample_format_unknown_value_is_rejected() {
let bytes = build_1x1_gray8(Some(99));
expect_err_containing(&bytes, "SampleFormat=99");
}