-
Notifications
You must be signed in to change notification settings - Fork 4
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
Possible regression and possible fix #38
Comments
Thinking about this further, I realise this should probably be on the caller to wrap it if appropriate and not zopfli's responsibility at all. Also, I found the BufReader incurs a performance penalty. Using Box instead gives the same output without the speed loss. |
I suspect it's a bug that buffering affects the output at all. I don't recall anything in the underlying C API that requires feeding the library larger chunks of data – block boundaries and flushing are handled independently of the input buffer size. |
I don't think it's actually about buffering. I just happened to try the BufReader initially but wrapping the &[u8] in any Read implementer seems to resolve the issue, such as Box, Cursor, or a custom Read struct that does nothing but wrap the &[u8] (the HashingAndCountingRead served this purpose prior to v0.8). It doesn't seem to affect the zopfli cli tool where the Readable is File. [edit] I've been doing some benchmarks and found a clear trend of smaller files with the change, despite some that increased in size by a tiny amount. So I don't think it's just noise. |
Coincidentally, From what I've seen, Zopfli can be sensitive to how the input data is chunked, so that would explain the size differences. I don't expect such a behavior change to be a deal-breaker for using Zopfli, as any regressions or improvements should be minor, at least for the most part. I'd like to trace calls to the C equivalent of the |
Ah, the copy change sounds like a likely suspect. For reference, the greatest difference I've observed so far was 0.8% on a ~350k (compressed size) png. |
This is in reference to shssoichiro/oxipng#579 where a regression was reported with zopfli v0.8.0 (in conjunction with Rust 1.74) when compressing some images.
I've found this can be resolved by adding a single line in
lib.rs
:Format::Zlib => { let mut zlib_encoder = ZlibEncoder::new_buffered(options, BlockType::Dynamic, out)?; + let mut in_data = std::io::BufReader::new(in_data); std::io::copy(&mut in_data, &mut zlib_encoder)?; zlib_encoder.into_inner()?.finish().map(|_| ()) }
Why this changes anything I have no idea. It's possible it's not so much a regression as just noise but I haven't tested on many files to get an idea of the average case. So I'm not sure whether the above is actually an appropriate change to make.
For a faster test case than the one originally reported, try using
issue-29.png
in the oxipng test files.The "bad" output from oxipng 9:
The "good" output from oxipng 8 or with the above change applied:
The text was updated successfully, but these errors were encountered: