aboutsummaryrefslogtreecommitdiff
path: root/transcoder/src
diff options
context:
space:
mode:
Diffstat (limited to 'transcoder/src')
-rw-r--r--transcoder/src/image.rs46
-rw-r--r--transcoder/src/lib.rs1
2 files changed, 47 insertions, 0 deletions
diff --git a/transcoder/src/image.rs b/transcoder/src/image.rs
new file mode 100644
index 0000000..d721e7b
--- /dev/null
+++ b/transcoder/src/image.rs
@@ -0,0 +1,46 @@
+use jellybase::{cache_file, AssetLocationExt};
+use jellycommon::AssetLocation;
+use log::info;
+use rgb::FromSlice;
+use std::{
+ fs::File,
+ io::{BufReader, Write},
+ path::PathBuf,
+};
+
+pub fn transcode(
+ asset: AssetLocation,
+ quality: f32,
+ speed: u8,
+ width: usize,
+) -> anyhow::Result<PathBuf> {
+ let original_path = asset.path();
+ let path = cache_file(&[
+ original_path.as_os_str().to_str().unwrap(),
+ &format!("{width} {quality} {speed}"),
+ ]);
+ if !path.exists() {
+ info!("encoding {path:?} (speed={speed}, quality={quality}, width={width})");
+ let reader = image::io::Reader::new(BufReader::new(File::open(original_path)?))
+ .with_guessed_format()?;
+ let original = reader.decode()?.to_rgba8();
+ let image = image::imageops::resize(
+ &original,
+ width as u32,
+ width as u32 * original.height() / original.width(),
+ image::imageops::FilterType::Lanczos3,
+ );
+ let pixels = image.to_vec();
+ let encoded = ravif::Encoder::new()
+ .with_speed(speed.clamp(1, 10))
+ .with_quality(quality.clamp(1., 100.))
+ .encode_rgba(ravif::Img::new(
+ pixels.as_rgba(),
+ image.width() as usize,
+ image.height() as usize,
+ ))?;
+ info!("writing to cache: {path:?}");
+ File::create(&path)?.write_all(&encoded.avif_file)?;
+ }
+ Ok(path)
+}
diff --git a/transcoder/src/lib.rs b/transcoder/src/lib.rs
index 6ddc2a4..e74a7f5 100644
--- a/transcoder/src/lib.rs
+++ b/transcoder/src/lib.rs
@@ -3,3 +3,4 @@
which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
Copyright (C) 2023 metamuffin <metamuffin.org>
*/
+pub mod image;