mod decoder;
mod encoder;
mod error;
mod ffi;
mod info;
mod sys;
pub use decoder::{AvifDecoder, DecoderConfig};
pub use encoder::{AvifEncoder, EncoderConfig};
pub use error::{AvifError, Result};
pub use info::{BitDepth, ImageInfo};
use std::ffi::CStr;
use std::io::Cursor;
use std::ops::Deref;
use image::{DynamicImage, EncodableLayout, ImageBuffer, ImageDecoder, PixelWithColorType};
pub fn libavif_version() -> String {
unsafe {
let ptr = sys::avifVersion();
CStr::from_ptr(ptr).to_string_lossy().into_owned()
}
}
pub fn encode(image: &DynamicImage) -> Result<Vec<u8>> {
let mut buf = Vec::new();
image.write_with_encoder(AvifEncoder::new(&mut buf))?;
Ok(buf)
}
pub fn encode_buffer<P, C>(buffer: &ImageBuffer<P, C>) -> Result<Vec<u8>>
where
P: PixelWithColorType,
[P::Subpixel]: EncodableLayout,
C: Deref<Target = [P::Subpixel]>,
{
let mut buf = Vec::new();
buffer.write_with_encoder(AvifEncoder::new(&mut buf))?;
Ok(buf)
}
pub fn decode(data: &[u8]) -> Result<DynamicImage> {
let decoder = AvifDecoder::new(Cursor::new(data))?;
Ok(DynamicImage::from_decoder(decoder)?)
}
pub fn probe(data: &[u8]) -> Result<ImageInfo> {
let decoder = AvifDecoder::new(Cursor::new(data))?;
let (width, height) = decoder.dimensions();
Ok(ImageInfo {
width,
height,
color_type: decoder.color_type(),
bit_depth: decoder.bit_depth(),
})
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn reports_libavif_version() {
let version = libavif_version();
println!("linked libavif version: {version}");
assert!(!version.is_empty());
}
}