diff --git a/Cargo.toml b/Cargo.toml index 0c6f1fff3f..dcbf9206b1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,6 +47,7 @@ quickcheck = "0.9" criterion = "0.3" [features] +# TODO: Add "avif" to this list while preparing for 0.24.0 default = ["gif", "jpeg", "ico", "png", "pnm", "tga", "tiff", "webp", "bmp", "hdr", "dxt", "dds", "farbfeld", "jpeg_rayon"] ico = ["bmp", "png"] diff --git a/README.md b/README.md index 25d5bf2b3f..c253695629 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ All image processing functions provided operate on types that implement the `Gen | ICO | Yes | Yes | | TIFF | Baseline(no fax support) + LZW + PackBits | RGB(8), RGBA(8), Gray(8) | | WebP | Lossy(Luma channel only) | No | -| AVIF | No | Lossy | +| AVIF | Only 8-bit | Lossy | | PNM | PBM, PGM, PPM, standard PAM | Yes | | DDS | DXT1, DXT3, DXT5 | No | | TGA | Yes | RGB(8), RGBA(8), BGR(8), BGRA(8), Gray(8), GrayA(8) | diff --git a/src/image.rs b/src/image.rs index cc3b3414c5..6a61ee8be8 100644 --- a/src/image.rs +++ b/src/image.rs @@ -83,6 +83,7 @@ impl ImageFormat { let ext = ext.to_str()?.to_ascii_lowercase(); Some(match ext.as_str() { + "avif" => ImageFormat::Avif, "jpg" | "jpeg" => ImageFormat::Jpeg, "png" => ImageFormat::Png, "gif" => ImageFormat::Gif, @@ -150,7 +151,7 @@ impl ImageFormat { ImageFormat::Hdr => true, ImageFormat::Pnm => true, ImageFormat::Farbfeld => true, - ImageFormat::Avif => false, + ImageFormat::Avif => true, ImageFormat::__NonExhaustive(marker) => match marker._private {}, } } @@ -201,7 +202,7 @@ impl ImageFormat { ImageFormat::Hdr => &["hdr"], ImageFormat::Farbfeld => &["ff"], // According to: https://aomediacodec.github.io/av1-avif/#mime-registration - ImageFormat::Avif => &["avif", "heif", "heifs", "hif"], + ImageFormat::Avif => &["avif"], ImageFormat::__NonExhaustive(marker) => match marker._private {}, } } @@ -1203,6 +1204,7 @@ mod tests { assert_eq!(from_path("./a.pAM").unwrap(), ImageFormat::Pnm); assert_eq!(from_path("./a.Ppm").unwrap(), ImageFormat::Pnm); assert_eq!(from_path("./a.pgm").unwrap(), ImageFormat::Pnm); + assert_eq!(from_path("./a.AViF").unwrap(), ImageFormat::Avif); assert!(from_path("./a.txt").is_err()); assert!(from_path("./a").is_err()); } @@ -1298,7 +1300,7 @@ mod tests { #[test] fn image_formats_are_recognized() { use ImageFormat::*; - const ALL_FORMATS: &'static [ImageFormat] = &[Png, Jpeg, Gif, WebP, Pnm, Tiff, Tga, Dds, Bmp, Ico, Hdr, Farbfeld]; + const ALL_FORMATS: &'static [ImageFormat] = &[Avif, Png, Jpeg, Gif, WebP, Pnm, Tiff, Tga, Dds, Bmp, Ico, Hdr, Farbfeld]; for &format in ALL_FORMATS { let mut file = Path::new("file.nothing").to_owned(); for ext in format.extensions_str() { diff --git a/src/io/free_functions.rs b/src/io/free_functions.rs index d58d7c5ef9..aa82b41882 100644 --- a/src/io/free_functions.rs +++ b/src/io/free_functions.rs @@ -28,7 +28,7 @@ use crate::codecs::webp; #[cfg(feature = "farbfeld")] use crate::codecs::farbfeld; #[cfg(feature = "avif")] -use crate::avif; +use crate::codecs::avif; use crate::color; use crate::image; @@ -59,6 +59,8 @@ pub fn load(r: R, format: ImageFormat) -> ImageResult DynamicImage::from_decoder(avif::AvifDecoder::new(r)?), #[cfg(feature = "png")] image::ImageFormat::Png => DynamicImage::from_decoder(png::PngDecoder::new(r)?), #[cfg(feature = "gif")] @@ -105,6 +107,8 @@ pub(crate) fn image_dimensions_with_format_impl(fin: R, forma // Default is unreachable if all features are supported. // Code after the match is unreachable if none are. Ok(match format { + #[cfg(feature = "avif")] + image::ImageFormat::Avif => avif::AvifDecoder::new(fin)?.dimensions(), #[cfg(feature = "jpeg")] image::ImageFormat::Jpeg => jpeg::JpegDecoder::new(fin)?.dimensions(), #[cfg(feature = "png")] @@ -204,7 +208,7 @@ pub(crate) fn save_buffer_with_format_impl( } } -static MAGIC_BYTES: [(&[u8], ImageFormat); 19] = [ +static MAGIC_BYTES: [(&[u8], ImageFormat); 20] = [ (b"\x89PNG\r\n\x1a\n", ImageFormat::Png), (&[0xff, 0xd8, 0xff], ImageFormat::Jpeg), (b"GIF89a", ImageFormat::Gif), @@ -224,6 +228,7 @@ static MAGIC_BYTES: [(&[u8], ImageFormat); 19] = [ (b"P6", ImageFormat::Pnm), (b"P7", ImageFormat::Pnm), (b"farbfeld", ImageFormat::Farbfeld), + (b"\0\0\0 ftypavif", ImageFormat::Avif), ]; /// Guess image format from memory block