gpui: Support animated WebP image (#20778)

Add support for decoding animated WebP images into their individual
frames.

Release Notes:

- N/A
This commit is contained in:
Matin Aniss 2024-12-07 09:53:27 +11:00 committed by GitHub
parent e019d1405a
commit 21a6664cf8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -8,7 +8,8 @@ use anyhow::{anyhow, Result};
use futures::{AsyncReadExt, Future};
use image::{
codecs::gif::GifDecoder, AnimationDecoder, Frame, ImageBuffer, ImageError, ImageFormat,
codecs::{gif::GifDecoder, webp::WebPDecoder},
AnimationDecoder, DynamicImage, Frame, ImageBuffer, ImageError, ImageFormat, Rgba,
};
use smallvec::SmallVec;
use std::{
@ -542,6 +543,34 @@ impl Asset for ImageAssetLoader {
frames
}
ImageFormat::WebP => {
let mut decoder = WebPDecoder::new(Cursor::new(&bytes))?;
if decoder.has_animation() {
let _ = decoder.set_background_color(Rgba([0, 0, 0, 0]));
let mut frames = SmallVec::new();
for frame in decoder.into_frames() {
let mut frame = frame?;
// Convert from RGBA to BGRA.
for pixel in frame.buffer_mut().chunks_exact_mut(4) {
pixel.swap(0, 2);
}
frames.push(frame);
}
frames
} else {
let mut data = DynamicImage::from_decoder(decoder)?.into_rgba8();
// Convert from RGBA to BGRA.
for pixel in data.chunks_exact_mut(4) {
pixel.swap(0, 2);
}
SmallVec::from_elem(Frame::new(data), 1)
}
}
_ => {
let mut data =
image::load_from_memory_with_format(&bytes, format)?.into_rgba8();