1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#![allow(clippy::many_single_char_names)]
pub use self::data::AvifData;
pub use self::encoder::Encoder;
pub use self::error::Error;
pub use self::format::YuvFormat;
pub use self::image::AvifImage;
pub use self::rgb::RgbPixels;
use libavif_sys as sys;
mod data;
mod encoder;
mod error;
mod format;
mod image;
mod rgb;
pub fn is_avif(avif_bytes: &[u8]) -> bool {
let raw = sys::avifROData {
data: avif_bytes.as_ptr(),
size: avif_bytes.len(),
};
unsafe { sys::avifPeekCompatibleFileType(&raw) == 1 }
}
pub fn decode(avif_bytes: &[u8]) -> Result<AvifImage, Error> {
let mut image = AvifImage::empty();
unsafe {
let decoder = sys::avifDecoderCreate();
let result = sys::avifDecoderReadMemory(
decoder,
image.inner_mut(),
avif_bytes.as_ptr(),
avif_bytes.len(),
);
sys::avifDecoderDestroy(decoder);
Error::code(result)?;
Ok(image)
}
}
pub fn decode_rgb(avif_bytes: &[u8]) -> Result<RgbPixels, Error> {
decode(avif_bytes).map(Into::into)
}
pub fn encode_rgb8(width: u32, height: u32, rgb: &[u8]) -> Result<AvifData<'static>, Error> {
let rgb = RgbPixels::new(width, height, rgb)?;
let image = rgb.to_image(YuvFormat::Yuv444);
let mut encoder = Encoder::new();
encoder.set_max_threads(1);
encoder.set_quantizer(20);
encoder.encode(&image)
}