use crate::{AddImageFlags, AvifData, AvifImage, Error};
use libavif_sys as sys;
pub struct Encoder {
encoder: *mut sys::avifEncoder,
}
impl Encoder {
pub fn new() -> Self {
let encoder = unsafe { sys::avifEncoderCreate() };
Self { encoder }
}
pub fn max_threads(&self) -> usize {
unsafe { (*self.encoder).maxThreads as usize }
}
pub fn set_max_threads(&mut self, max_threads: usize) -> &mut Self {
unsafe { (*self.encoder).maxThreads = max_threads.max(1) as i32 }
self
}
pub fn quality(&self) -> u8 {
unsafe { (*self.encoder).quality as u8 }
}
pub fn set_quality(&mut self, quality: u8) -> &mut Self {
let quality = quality.min(100);
unsafe {
(*self.encoder).quality = quality.into();
}
self
}
pub fn alpha_quality(&self) -> u8 {
unsafe { (*self.encoder).qualityAlpha as u8 }
}
pub fn set_alpha_quality(&mut self, alpha_quality: u8) -> &mut Self {
let alpha_quality = alpha_quality.min(100);
unsafe {
(*self.encoder).qualityAlpha = alpha_quality.into();
}
self
}
pub fn speed(&self) -> u8 {
unsafe { (*self.encoder).speed as u8 }
}
pub fn set_speed(&mut self, speed: u8) -> &mut Self {
unsafe { (*self.encoder).speed = speed.min(10) as i32 }
self
}
pub fn timescale(&self) -> u64 {
unsafe { (*self.encoder).timescale }
}
pub fn set_timescale(&mut self, timescale: u64) -> &mut Self {
unsafe { (*self.encoder).timescale = timescale }
self
}
pub fn encode(&self, image: &AvifImage) -> Result<AvifData<'static>, Error> {
let mut data = Default::default();
unsafe {
Error::code(sys::avifEncoderWrite(
self.encoder,
image.inner(),
&mut data,
))?;
Ok(AvifData::from_raw(data))
}
}
pub fn add_image(
&self,
image: &AvifImage,
duration_in_timescales: u64,
flags: AddImageFlags,
) -> Result<(), super::Error> {
unsafe {
Error::code(sys::avifEncoderAddImage(
self.encoder,
image.inner(),
duration_in_timescales,
flags.into(),
))
}
}
pub fn finish(&self) -> Result<AvifData<'static>, super::Error> {
unsafe {
let mut data = Default::default();
Error::code(sys::avifEncoderFinish(self.encoder, &mut data))?;
Ok(AvifData::from_raw(data))
}
}
}
impl Drop for Encoder {
fn drop(&mut self) {
unsafe {
sys::avifEncoderDestroy(self.encoder);
}
}
}
impl Default for Encoder {
fn default() -> Self {
Self::new()
}
}