/* This file is part of jellything (https://codeberg.org/metamuffin/jellything) which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2026 metamuffin */ use super::error::MyResult; use crate::{request_info::RequestInfo, responders::cache::CacheControlImage}; use anyhow::Context; use rocket::{get, http::ContentType}; use std::path::PathBuf; pub const AVIF_QUALITY: u32 = 70; pub const AVIF_SPEED: u8 = 5; #[get("/image/?")] pub async fn r_image( ri: RequestInfo<'_>, path: PathBuf, size: Option, ) -> MyResult<(ContentType, CacheControlImage)> { let size = size.unwrap_or(2048); let path = path.to_string_lossy().to_string(); // fit the resolution into a finite set so the maximum cache is finite too. let width = 2usize.pow(size.clamp(128, 2048).ilog2()); let encoded = jellytranscoder::image::transcode(&ri.state.cache, &path, AVIF_QUALITY, AVIF_SPEED, width) .context("transcoding asset")?; Ok((ContentType::AVIF, CacheControlImage(encoded))) } // #[get("/n//image/?")] // pub async fn r_item_poster( // session: A, // id: A, // slot: &str, // size: Option, // ) -> MyResult { // let slot = PictureSlot::from_str(slot).map_err(|_| anyhow!("slot invalid"))?; // let node = get_node(&session.0, id.0, false, false, NodeFilterSort::default())?; // let picture = node // .node // .pictures // .get(&slot) // .cloned() // .ok_or(anyhow!("no pic todo"))?; // Ok(Redirect::permanent(rocket::uri!(r_image(picture, size)))) // } // #[get("/n//thumbnail?&")] // pub async fn r_node_thumbnail( // session: A, // id: A, // t: f64, // size: Option, // ) -> MyResult { // let picture = get_node_thumbnail(&session.0, id.0, t).await?; // Ok(Redirect::permanent(rocket::uri!(r_image(picture, size)))) // }