image-rs / image-webp

Apache License 2.0
42 stars 9 forks source link

Fails to decode animated webp images produced by ImageMagick using default settings. #75

Closed awused closed 5 months ago

awused commented 5 months ago

This seems to reproduce reliably on any animated gif converted by imagemagick. The animated webps open in other programs or when using the webp-animation crate which wraps libwebp. This is at git head for image-webp where I added a test that just tries to decode every frame of dog.webp.

convert dog.gif dog.webp

cargo test

---- test_broken stdout ----
Read frame 1
thread 'test_broken' panicked at tests/decode.rs:170:43:
called `Result::unwrap()` on an `Err` value: IoError(Error { kind: UnexpectedEof, message: "failed to fill whole buffer" })
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Version: ImageMagick 7.1.1-26 Q16-HDRI x86_64 21914 https://imagemagick.org
Copyright: (C) 1999 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Cipher DPC HDRI Modules OpenMP(4.5)
Delegates (built-in): bzlib cairo djvu fftw fontconfig freetype gslib gvc heic jbig jng jp2 jpeg jxl lcms lqr ltdl lzma openexr pangocairo png ps raqm raw rsvg tiff webp wmf x xml zip zlib zstd
Compiler: gcc (14.0)

dog

dog webp

fintelia commented 5 months ago

Could you share the code you are using to decode?

awused commented 5 months ago

In my application I just used image's into_frames() method, but for the test run I put this at the end of tests/decode.rs based copying and pasting on the existing tests.

#[test]
fn test_broken() {
    let contents = std::fs::read("dog.webp").unwrap();
    let mut decoder = image_webp::WebPDecoder::new(Cursor::new(contents)).unwrap();
    let (width, height) = decoder.dimensions();
    if decoder.is_animated() {
        for i in 1..=decoder.num_frames() {
            // Decode WebP
            let bytes_per_pixel = if decoder.has_alpha() { 4 } else { 3 };
            let mut data = vec![0; width as usize * height as usize * bytes_per_pixel];
            decoder.read_frame(&mut data).unwrap();
            println!("Read frame {i}");
        }
    }
}
fintelia commented 5 months ago

Thanks for reporting this!