aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock49
-rw-r--r--transcoder/Cargo.toml3
-rw-r--r--transcoder/src/image.rs39
3 files changed, 82 insertions, 9 deletions
diff --git a/Cargo.lock b/Cargo.lock
index e76170b..c13139d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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,