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 encode #1978

Merged
merged 18 commits into from
Aug 25, 2023
Merged

Webp encode #1978

merged 18 commits into from
Aug 25, 2023

Conversation

fintelia
Copy link
Contributor

@fintelia fintelia commented Aug 9, 2023

The goal of this PR is to have "good enough" pure-Rust webp encoding to enable it by default and remove our dependency on libwebp.

My plan is to completely ignore lossy webp encoding (we already have pure-Rust lossy jpeg and avif encoders) and only focus on lossless mode. Right now, the code is able to produce valid lossless webp's, but they're completely uncompressed. Actually compressing the input will require building huffman trees based on symbol frequency.

I have however implemented hard-coded "subtract green" and "predictor" transforms which should make the data at least somewhat compressible. That's in contrast to libwebp which tries a whole bunch of different transform configurations to see what produces the best compression. Nonetheless, it might be enough to get compression ratios on par with PNG

Update: Huffman compression is implemented.

@fintelia fintelia marked this pull request as ready for review August 13, 2023 19:53
@fintelia
Copy link
Contributor Author

Compression ratio on the QOI benchmark suite is currently 29%, compared to about 17% when using libwebp. On the plus side, this encoder is something like 60x faster.

src/codecs/webp/encoder.rs Outdated Show resolved Hide resolved
src/codecs/webp/encoder.rs Outdated Show resolved Hide resolved
@fintelia
Copy link
Contributor Author

fintelia commented Aug 14, 2023

At this point, the compression speed is about 230M pixels/s, which is right on par with QOI and our fast PNG encoding. And the run length compression got the compression ratio to just under 23%, which is way better than the 27-28% ratios those other encoders get on this corpus. This encoder is coming together better than I was expecting!

@sophie-h
Copy link
Contributor

Would it maybe make sense to move all the webp code to a web-rs crate at some point?

@fintelia
Copy link
Contributor Author

I started splitting off the webp decoder into its own crate here, but it is proving to be rather involved. I do want to continue with that process, but in the meantime I think it makes sense to go ahead and merge this PR

@fintelia fintelia merged commit 23c347e into image-rs:master Aug 25, 2023
35 checks passed
@fintelia fintelia deleted the webp-encode branch August 25, 2023 05:00
@hahouari
Copy link

hahouari commented Mar 8, 2024

I'm not sure if this feature is available or not, the README still mentions Webp encoding requires webp-encoder but this PR is merged 7 months ago. Can someone clearify if the pure-Rust webp encoder is available even if unstable? and if possible the AVIF decoder state as well.

Thank you.

@fintelia
Copy link
Contributor Author

fintelia commented Mar 8, 2024

In the 0.24.9 release, both the pure-Rust webp encoder and the C based encoder are used. The pure-Rust one is used by the high level methods that don't take options, or if you call WebPEncoder::new_lossless. The C-based one is used if you call WebPEncoder::{new, new_with_quality}.

In 0.25.0-preview.0, only pure-Rust encoding is used. Though it actually relies on a copy of this code that has been moved into the image-webp crate.

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.

4 participants