From 524230fd8378b699e98012c32e64773b2efba53f Mon Sep 17 00:00:00 2001 From: metamuffin Date: Sat, 28 Oct 2023 23:13:15 +0200 Subject: "avif decoding" --- transcoder/src/image.rs | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) (limited to 'transcoder/src') 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, -- cgit v1.2.3-70-g09d2