Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebP Extended animation format needs to be rendered into frames… #1925

Conversation

bu5hm4nn
Copy link

@bu5hm4nn bu5hm4nn commented May 7, 2023

before it can be copied.
Previous code was copying raw webp frames which can be smaller than the canvas.
Fixes #1856.

I license past and future contributions under the dual MIT/Apache-2.0 license,
allowing licensees to choose either at their option.

…e it can be copied. Previous code was copying raw webp frames which can be smaller than the canvas. Fixes image-rs#1856.
@fintelia
Copy link
Contributor

fintelia commented May 9, 2023

The CI seems to detect one failure with cargo test -v --release. Should just be a matter of changing the "expected" hashes for any images that are now decoded differently

@@ -321,16 +321,35 @@ impl<'a, R: 'a + Read> ImageDecoder<'a> for WebPDecoder<R> {
}

fn read_image(self, buf: &mut [u8]) -> ImageResult<()> {
assert_eq!(u64::try_from(buf.len()), Ok(self.total_bytes()));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not get rid of this assert. The spec for read_image guarantees a panic if this condition doesn't hold.

Theoretically the values of {vp8_frame, lossless_frame, extended}.get_buf_size() should match, but there could be bugs

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why doesn't the spec make use of ImageResult instead? Much cleaner.

Also the bug I'm trying to fix happily passed this check and then panicked at copy_from_slice() in the fill_buf() function. So didn't do much good there.

@sophie-h
Copy link
Contributor

I still think that the whole concept of the WebP animation decoder, decoding all frames before being able to show them, is fundamentally broken for image viewers. See #1924 and https://gitlab.gnome.org/GNOME/Incubator/loupe/-/issues/160

Not sure if it's in the scope of this MR to fix it, but a bunch of things happening in this MR would have to be changed again when adding frame-by-frame decoding.

@@ -147,6 +147,54 @@ impl ExtendedImage {
Frames::new(Box::new(frame_iter))
}

pub(crate) fn as_frames<'a>(&'a self) -> Frames<'a> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding the as_frames API. That's very useful. However, does the code have to be duplicated with into_frames, or could into_frames cust call as_frames?

Copy link
Contributor

@sophie-h sophie-h May 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fintelia I think having as_frames for #1869 would be good. Should it maybe take a &mut self just to be safe?

EDIT: It's not public API here, so irrelevant.

@bu5hm4nn
Copy link
Author

I don't have the time to do the perfect fix, happy to drop this PR as long as the bug gets fixed.
It's also an interesting dynamic how much passion there is about how not to fix this bug but it did not bother anyone that it existed for months without a suggested fix.

@sophie-h It does not decode all frames, into_frames() and as_frames() return an iterator and each frame is rendered when next() is called. So it will only decode as many images as you iterate over.

I was just trying to fix the bug while changing as little as possible on the existing code.

@fintelia
Copy link
Contributor

Superseded by #1959

@fintelia fintelia closed this Jul 19, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Lossy WEBP with alpha: source slice length (761600) does not match destination slice length (997920)
3 participants