use heifer_hevc_enc::encoder::{EncodedPicture, EncoderConfig, Planes, encode_picture};
use heifer_isobmff::boxes::HevcConfig;
use heifer_isobmff::writer::{ALPHA_URN, HeifWriter, ImageSpec};
fn grey(w: u32, h: u32) -> EncodedPicture {
let y = vec![128u8; (w * h) as usize];
let c = vec![128u8; (w / 2 * h / 2) as usize];
encode_picture(
w,
h,
Planes {
y: &y,
chroma: Some((&c, &c)),
},
&EncoderConfig::default(),
)
.unwrap()
}
fn spec<'a>(
width: u32,
height: u32,
picture: &'a EncodedPicture,
auxiliary_type: Option<&'a str>,
) -> ImageSpec<'a> {
ImageSpec {
width,
height,
config: HevcConfig {
profile_idc: picture.profile_idc,
level_idc: picture.level_idc,
chroma_format: picture.chroma_format,
bit_depth_luma: 8,
bit_depth_chroma: 8,
nal_length_size: 4,
nal_units: picture.parameter_sets.clone(),
},
slices: &picture.slices,
color: None,
auxiliary_type,
hidden: auxiliary_type.is_some(),
crop: None,
}
}
#[test]
fn grid_tile_with_zero_size_is_rejected() {
let picture = grey(64, 32);
let mut writer = HeifWriter::new();
let tile = writer.add_image(&spec(0, 0, &picture, None));
let grid = writer.add_grid(1, 1, 64, 32, &[tile], None, None);
writer.set_primary(grid);
let error = heifer::decode(&writer.finish()).expect_err("a 0×0 tile must be rejected");
assert!(
matches!(error, heifer::Error::Invalid(_)),
"unexpected error: {error}"
);
}
#[test]
fn alpha_plane_shorter_than_the_image_is_rejected() {
let image = grey(64, 32);
let alpha = grey(64, 16);
let mut writer = HeifWriter::new();
let id = writer.add_image(&spec(64, 32, &image, None));
writer.add_alpha(id, &spec(64, 16, &alpha, Some(ALPHA_URN)));
writer.set_primary(id);
let error =
heifer::decode(&writer.finish()).expect_err("a smaller alpha plane must be rejected");
assert!(
matches!(error, heifer::Error::Unsupported(_)),
"unexpected error: {error}"
);
}
#[test]
fn exact_size_alpha_plane_is_accepted() {
let image = grey(64, 32);
let alpha = grey(64, 32);
let mut writer = HeifWriter::new();
let id = writer.add_image(&spec(64, 32, &image, None));
writer.add_alpha(id, &spec(64, 32, &alpha, Some(ALPHA_URN)));
writer.set_primary(id);
let decoded = heifer::decode(&writer.finish()).expect("valid file");
assert!(decoded.has_alpha);
}
#[test]
fn absurd_tile_size_is_rejected() {
let picture = grey(64, 32);
let mut writer = HeifWriter::new();
let tile = writer.add_image(&spec(1, 300_000_000, &picture, None));
let grid = writer.add_grid(1, 1, 1, 1, &[tile], None, None);
writer.set_primary(grid);
let error = heifer::decode(&writer.finish()).expect_err("an absurd tile size must be rejected");
assert!(
matches!(error, heifer::Error::Invalid(_)),
"unexpected error: {error}"
);
}