Skip to content

Commit

Permalink
gpui: Support animated WebP image (#20778)
Browse files Browse the repository at this point in the history
Add support for decoding animated WebP images into their individual
frames.

Release Notes:

- N/A
  • Loading branch information
MatinAniss authored Dec 6, 2024
1 parent e019d14 commit 21a6664
Showing 1 changed file with 30 additions and 1 deletion.
31 changes: 30 additions & 1 deletion crates/gpui/src/elements/img.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -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();
Expand Down

0 comments on commit 21a6664

Please sign in to comment.