mod decoder;
mod encoder;
mod error;
mod ffi;
mod info;
mod sys;
pub use decoder::{DecoderConfig, HeifDecoder};
pub use encoder::{Chroma, EncoderConfig, HeifEncoder, Preset};
pub use error::{HeifError, 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 libheif_version() -> String {
ffi::init();
unsafe {
let ptr = sys::heif_get_version();
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(HeifEncoder::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(HeifEncoder::new(&mut buf))?;
Ok(buf)
}
pub fn decode(data: &[u8]) -> Result<DynamicImage> {
let decoder = HeifDecoder::new(Cursor::new(data))?;
Ok(DynamicImage::from_decoder(decoder)?)
}
pub fn probe(data: &[u8]) -> Result<ImageInfo> {
let decoder = HeifDecoder::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_libheif_version() {
let version = libheif_version();
println!("linked libheif version: {version}");
assert!(!version.is_empty());
}
}