diff options
author | metamuffin <metamuffin@disroot.org> | 2023-10-28 23:13:15 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2023-10-28 23:13:15 +0200 |
commit | 524230fd8378b699e98012c32e64773b2efba53f (patch) | |
tree | 15d8abdbb5bce93432c60225683818c1078460a2 | |
parent | 421d2843a64ba3f94e773b4ea50238bbf94c742e (diff) | |
download | jellything-524230fd8378b699e98012c32e64773b2efba53f.tar jellything-524230fd8378b699e98012c32e64773b2efba53f.tar.bz2 jellything-524230fd8378b699e98012c32e64773b2efba53f.tar.zst |
"avif decoding"
-rw-r--r-- | Cargo.lock | 49 | ||||
-rw-r--r-- | transcoder/Cargo.toml | 3 | ||||
-rw-r--r-- | transcoder/src/image.rs | 39 |
3 files changed, 82 insertions, 9 deletions
@@ -513,6 +513,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" [[package]] +name = "cmake" +version = "0.1.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130" +dependencies = [ + "cc", +] + +[[package]] name = "color_quant" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1472,6 +1481,7 @@ dependencies = [ "jellybase", "jellycommon", "jellyremuxer", + "libavif-image", "log", "rav1e", "ravif", @@ -1520,12 +1530,51 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" [[package]] +name = "libavif" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c04b57eae4c2aac54e2f1a30c43f1ab8edeac1f232713bb26b5a42d2cec04e78" +dependencies = [ + "libavif-sys", +] + +[[package]] +name = "libavif-image" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ec0b35590b15160bac8f758b23658d632ce79ad59dd11714612b8c06c23f1a1" +dependencies = [ + "image", + "libavif", +] + +[[package]] +name = "libavif-sys" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c7b9293d221c7d4b4290d4479c491a09b877943208593f1563d8521c4b55930" +dependencies = [ + "cmake", + "libc", + "libdav1d-sys", +] + +[[package]] name = "libc" version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" [[package]] +name = "libdav1d-sys" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c21d55fe0bdbb33a65c97ce3351366a1b9edb8e5677bcff64114c4a9ad184b7c" +dependencies = [ + "libc", +] + +[[package]] name = "libfuzzer-sys" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/transcoder/Cargo.toml b/transcoder/Cargo.toml index 1416c10..f77f62c 100644 --- a/transcoder/Cargo.toml +++ b/transcoder/Cargo.toml @@ -13,6 +13,9 @@ image = "0.24.7" # image = { git = "https://github.com/metamuffin/image-rs", features = [ # "avif-decoder", # ] } +libavif-image = { version = "0.10.0", default-features = false, features = [ + "codec-dav1d", +] } anyhow = "1.0.75" rgb = "0.8.36" rav1e = { version = "0.6.6", default-features = false, features = [ diff --git a/transcoder/src/image.rs b/transcoder/src/image.rs index 3cd9986..7f52ff3 100644 --- a/transcoder/src/image.rs +++ b/transcoder/src/image.rs @@ -1,11 +1,14 @@ use crate::LOCAL_TRANSCODING_TASKS; use anyhow::Context; -use image::{imageops::FilterType, ImageFormat}; +use image::imageops::FilterType; use jellybase::{cache::async_cache_file, AssetLocationExt}; use jellycommon::AssetLocation; use log::{debug, info}; use rgb::FromSlice; -use std::{fs::File, io::BufReader}; +use std::{ + fs::File, + io::{BufReader, Read, Seek, SeekFrom}, +}; use tokio::io::AsyncWriteExt; pub async fn transcode( @@ -27,13 +30,31 @@ pub async fn transcode( info!("encoding {asset:?} (speed={speed}, quality={quality}, width={width})"); let encoded = tokio::task::spawn_blocking(move || { let original_path = asset.path(); - // TODO shouldn't be neccessary with guessed format. - let file = BufReader::new(File::open(&original_path).context("opening source")?); - let mut reader = image::io::Reader::new(file); - reader.set_format(ImageFormat::Avif); - let reader = reader.with_guessed_format().context("guessing format")?; - debug!("guessed format (or fallback): {:?}", reader.format()); - let original = reader.decode().context("decoding image")?.to_rgba8(); + let mut file = + BufReader::new(File::open(&original_path).context("opening source")?); + + // TODO: use better image library that supports AVIF + let is_avif = { + let mut magic = [0u8; 12]; + file.read_exact(&mut magic).context("reading magic")?; + file.seek(SeekFrom::Start(0)) + .context("seeking back to start")?; + // TODO: magic experimentally found and probably not working in all cases but fine as long as our avif enc uses that + magic + == [ + 0x00, 0x00, 0x00, 0x18, 0x66, 0x74, 0x79, 0x70, 0x61, 0x76, 0x69, 0x66, + ] + }; + let original = if is_avif { + let mut buf = Vec::new(); + file.read_to_end(&mut buf).context("reading image")?; + libavif_image::read(&buf).unwrap().to_rgba8() + } else { + let reader = image::io::Reader::new(file); + let reader = reader.with_guessed_format().context("guessing format")?; + debug!("guessed format (or fallback): {:?}", reader.format()); + reader.decode().context("decoding image")?.to_rgba8() + }; let image = image::imageops::resize( &original, width as u32, |