From 7cb8187ac8daa84b7aa08e27a85c4463cdc259e0 Mon Sep 17 00:00:00 2001 From: Aely <29923178+Aely0@users.noreply.github.com> Date: Tue, 7 Jan 2025 09:35:58 +0200 Subject: [PATCH] Support RGB WebP images (#5586) Current WebP loader assumes all WebP images to be RGBA, which is the case if the image is animated (that's what `image` crate assumes at least). Static images can instead choose to exclude its alpha channel, though it seems to be more of a default choice to include it, even if it's not being utilized. Currently, loading a static RGB WebP image will cause a panic when `ColorImage::from_rgba_unmultiplied` gets called in the loader ``` thread 'main' panicked at /home/aely/.cargo/git/checkouts/egui-226fc7cdd51201c1/f87219d/crates/epaint/src/image.rs:97:9: assertion `left == right` failed left: 29184 right: 21888 ``` --- crates/egui_extras/src/loaders/webp_loader.rs | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/crates/egui_extras/src/loaders/webp_loader.rs b/crates/egui_extras/src/loaders/webp_loader.rs index bb042093..528c449a 100644 --- a/crates/egui_extras/src/loaders/webp_loader.rs +++ b/crates/egui_extras/src/loaders/webp_loader.rs @@ -5,7 +5,7 @@ use egui::{ mutex::Mutex, ColorImage, FrameDurations, Id, }; -use image::{codecs::webp::WebPDecoder, AnimationDecoder as _, ImageDecoder, Rgba}; +use image::{codecs::webp::WebPDecoder, AnimationDecoder as _, ColorType, ImageDecoder, Rgba}; use std::{io::Cursor, mem::size_of, sync::Arc, time::Duration}; #[derive(Clone)] @@ -48,6 +48,17 @@ impl WebP { frame_durations: FrameDurations::new(durations), })) } else { + // color_type() of WebPDecoder only returns Rgb8/Rgba8 variants of ColorType + let create_image = match decoder.color_type() { + ColorType::Rgb8 => ColorImage::from_rgb, + ColorType::Rgba8 => ColorImage::from_rgba_unmultiplied, + unreachable => { + return Err(format!( + "Unreachable WebP color type, expected Rgb8/Rgba8, got {unreachable:?}" + )) + } + }; + let (width, height) = decoder.dimensions(); let size = decoder.total_bytes() as usize; @@ -56,10 +67,10 @@ impl WebP { .read_image(&mut data) .map_err(|error| format!("WebP image read failure ({error})"))?; - let image = - ColorImage::from_rgba_unmultiplied([width as usize, height as usize], &data); - - Ok(Self::Static(Arc::new(image))) + Ok(Self::Static(Arc::new(create_image( + [width as usize, height as usize], + &data, + )))) } }