diff --git a/pages/wallpapers/src/lib.rs b/pages/wallpapers/src/lib.rs index 27b4e60..aed1423 100644 --- a/pages/wallpapers/src/lib.rs +++ b/pages/wallpapers/src/lib.rs @@ -4,7 +4,7 @@ use fast_image_resize::SrcCropping; use futures_lite::Stream; use futures_util::StreamExt; use image::imageops::FilterType; -use image::{DynamicImage, ImageBuffer, Rgba, RgbaImage}; +use image::{DynamicImage, ImageBuffer, ImageDecoder, ImageResult, Limits, Rgba, RgbaImage}; use jxl_oxide::integration::JxlDecoder; use std::borrow::Cow; use std::collections::HashMap; @@ -304,7 +304,7 @@ fn open_image(input_buffer: &mut Vec, path: &Path) -> Option { return None; }; - match image_decoder.decode() { + match decode(image_decoder) { Ok(image) => Some(image), Err(why) => { tracing::error!(?path, ?why, "image decode failed"); @@ -313,6 +313,24 @@ fn open_image(input_buffer: &mut Vec, path: &Path) -> Option { } } +fn decode( + mut reader: image::ImageReader>>, +) -> ImageResult { + let mut limits = Limits::default(); + reader.limits(limits.clone()); + + let mut decoder = reader.into_decoder()?; + let orientation = decoder.orientation()?; + + limits.reserve(decoder.total_bytes())?; + decoder.set_limits(limits)?; + + let mut image = DynamicImage::from_decoder(decoder)?; + image.apply_orientation(orientation); + + Ok(image) +} + // https://users.rust-lang.org/t/how-to-trim-image-to-circle-image-without-jaggy/70374/2 fn round(img: &mut image::ImageBuffer, Vec>, radius: [u32; 4]) { let (width, height) = img.dimensions(); @@ -434,11 +452,19 @@ fn border_radius( pub fn decode_jpegxl(path: &std::path::Path) -> eyre::Result { let file = File::open(path).map_err(|why| eyre!("failed to open jxl image file: {why}"))?; - let decoder = + let mut decoder = JxlDecoder::new(file).map_err(|why| eyre!("failed to read jxl image header: {why}"))?; - image::DynamicImage::from_decoder(decoder) - .map_err(|why| eyre!("failed to decode jxl image: {why}")) + let orientation = decoder + .orientation() + .map_err(|why| eyre!("failed to read jxl image orientation: {why}"))?; + + let mut image = image::DynamicImage::from_decoder(decoder) + .map_err(|why| eyre!("failed to decode jxl image: {why}"))?; + + image.apply_orientation(orientation); + + Ok(image) } /// Use `fast-image-resize` crate for faster thumbnail generation.