webp icon indicating copy to clipboard operation
webp copied to clipboard

Encoder panic

Open optozorax opened this issue 3 years ago • 10 comments

I'm trying to convert this png to webp, but it panics here:

https://github.com/jaredforth/webp/blob/81e42aa54d2f87e87811eacce2706c6cccd85283/src/encoder.rs#L26

optozorax avatar Aug 23 '21 05:08 optozorax

Thanks for letting me know! I'll work on tackling this today

jaredforth avatar Aug 23 '21 13:08 jaredforth

Also, this line always panics when I trying convert webp to webp.

optozorax avatar Aug 27 '21 16:08 optozorax

@optozorax, your png link 404s for me. Could you try attaching it again so I can test locally against that specific image?

jaredforth avatar Aug 30 '21 14:08 jaredforth

apollon_1

optozorax avatar Aug 30 '21 15:08 optozorax

Thanks! Also, can you share a minumum reproducible example of how you are trying to use the library with this image?

jaredforth avatar Aug 30 '21 19:08 jaredforth

I'm trying to convert this image to webp with quality 75 and fit option with width=1280, height=1280 using zola's function resize_image. I can try to create MRE on weekdays.

optozorax avatar Aug 31 '21 16:08 optozorax

The Encoder will now return a Result instead of calling unreachable!() so you can handle errors in 0.2.0 per the commit https://github.com/jaredforth/webp/commit/25eb15518cf1aab90be6ade47ff9aa482a099c6a

Once you have an MRE I will continue to work on implementation so that you can use this crate for your desired functionality.

jaredforth avatar Sep 08 '21 15:09 jaredforth

@jaredforth I've run into this through Zola as well, I've extracted it into the following MRE in case it's useful:

use image::{imageops::FilterType, EncodableLayout};

use std::fs::File;
use std::io::Write;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    const INPUT_PATH: &str = "/path/to/image/on/disk.webp";

    let img = image::open(&INPUT_PATH)?;

    let img = img.resize_exact(384, 384, FilterType::Lanczos3);

    let encoder = webp::Encoder::from_image(&img).unwrap();
    let memory = encoder.encode_lossless();

    let mut f = File::create("target.webp")?;
    f.write_all(memory.as_bytes())?;

    Ok(())
}

In my case, I'm attempting to convert my profile image (which is already a WebP, exported from Gimp) to smaller sizes so I can add it to my website.

Edit: for what it's worth, this is also triggering the ImageLuma8 case. I'd recommend mentioning that somewhere in the Err that's returned from Encoder::from_image; right now it's impossible to figure out what isn't implemented without using a modified webp fork.

antonok-edm avatar Dec 07 '21 08:12 antonok-edm

I dug into this a little bit further. Prior to image-rs/image#1624 (merged recently but still unreleased), the Supported Image Formats section on the image README was as follows:

Format Decoding Encoding
... ... ...
WebP Lossy(Rgb only) No
... ... ...

As it turns out, patching out the image dependency to use the latest master branch allows my example to work. The issue is purely with how image is decoding the input file.

As for the original example provided by @optozorax, it looks like the original source PNG is encoded as grayscale, so it makes sense that it's being passed in as a Luma8 image.

It looks like the WebP format has no special encoding for grayscale images, so I think the best approach here is to just use image's built-in support for converting it to a corresponding RGB image.

antonok-edm avatar Dec 07 '21 08:12 antonok-edm

@antonok-edm I am just reading through this thread again now. I have improved the error messages so that it is obvious what case is triggering the error. https://github.com/jaredforth/webp/commit/6e0ca1ad715a0f32ee80fe0af3b27264bdd85d8b

jaredforth avatar Jan 31 '22 16:01 jaredforth