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
//! Load and Save AVIF from [image](https://crates.io/crates/image)
//! types.
//!
//! Converts to and from YUV (`image` only does RGB).

use image::{DynamicImage, ImageBuffer};

use libavif::AvifData;
pub use libavif::{is_avif, Error};

/// Read data that is in an AVIF file and load it into an image
pub fn read(buf: &[u8]) -> Result<DynamicImage, Error> {
    let pixels = libavif::decode_rgb(buf)?;
    let buffer = ImageBuffer::from_vec(pixels.width(), pixels.height(), pixels.to_vec())
        .expect("pixels doesn't fit image::ImageBuffer");

    Ok(DynamicImage::ImageRgba8(buffer))
}

/// Save an image into an AVIF file
pub fn save(img: &DynamicImage) -> Result<AvifData, Error> {
    let data = match img {
        DynamicImage::ImageRgb8(img) => {
            let rgb = img.as_flat_samples();
            libavif::encode_rgb8(img.width(), img.height(), rgb.as_slice())?
        }
        DynamicImage::ImageRgba8(img) => {
            let rgb = img.as_flat_samples();
            libavif::encode_rgb8(img.width(), img.height(), rgb.as_slice())?
        }
        DynamicImage::ImageLuma8(img) => {
            let rgb = img.as_flat_samples();
            libavif::encode_rgb8(img.width(), img.height(), rgb.as_slice())?
        }
        _ => return Err(Error::UnsupportedImageType),
    };

    Ok(data)
}