forked from image-rs/image-png
-
Notifications
You must be signed in to change notification settings - Fork 0
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
[pull] master from image-rs:master #7
Open
pull
wants to merge
618
commits into
mesalock-linux:master
Choose a base branch
from
image-rs:master
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Fix a bunch of warnings
Consolidate Avg remainder loop to main loop
Use iterators in Up and Avg filtering
Drastically improve encoding performance
Co-authored-by: okaneco <[email protected]>
Optimize adaptive filtering
Add an initial roundtrip fuzz target
Optimize Paeth decoding
Also roundtrip-fuzz with various bit depths
Use observations from the optimized Paeth encoding filter to do less work.
Simplify Paeth decode filter, fix remaining lib clippy lints
Use bitwise manipulation to find the average of two integers without casting to a wider integer type
The idea for SWAR is to treat regular integer types like `u32|u64` as a SIMD register for arbitrary smaller-width bit lanes. We can calculate 3 bytes per pixel and 4bpp pixels within a `u32`, 6bpp and 8bpp pixels within a `u64`. It's not an n-times speedup based on the number of lanes because SWAR may require some overhead of maintaining the lanes depending on the operation (shifts, for instance). This is evidenced by masking operations during calculation to correct or prevent lanes from overlapping. For the wrapping addition operation here, 7-bit arithmetic is calculated to prevent a carry digit affecting neighboring lanes. After the addition, a correcting XOR addition is done to repair the most significant bit and arrive at the correct answer for 8-bit wrapping unsigned arithmetic.
Before this commit, `next_frame` would take care to read till the end of an `IDAT`/`fdAT` chunks sequence, by calling `self.decoder.finish_decoding` when `!self.subframe.consumed_and_flushed`. `next_row` wouldn't do this and therefore the next call to `next_frame` would be temporarily stuck on the previous frame (i.e. finishing decoding after the previous frame rather than advancing to the next frame). After this commit, the `finish_decoding` code is extracted to a separate helper function that is called by *both* `next_frame` and `next_interlaced_row` (once they detect that all rows of a frame have been already decoded). This commit fixes the `test_row_by_row_then_next_frame` unit test.
In an earlier commit 278b1d4 we stopped using `Reader.next_frame` for deciding whether to call `read_until_image_data` from `next_frame`. This commit goes one step further and removes the `next_frame` field entirely. There are no known cases where the previous code would result in incorrect behavior, but this commit still seems desirable: * It simplifies the code * It ensures that a single "end-of-IDAT/fdAT-sequence" event kind controls both 1) `consumed_and_flushed` state, and 2) counting remaining frames. (Before this commit `next_frame` would also be mutated after a separate "fcTL-encountered" event. And also after "end-of-IDAT/fdAT-sequence" but only from `next_frame` and not from `next_row`.)
When `StreamingDecoder` reports an error, it leaves `state` set to `None`. Before this commit, calling `next_frame` in this state would have led to an infinite loop: * `ReadDecoder::decode_next` would loop forever (`!self.at_eof` is true after an error) and would fail to make progress, because * When `StreamingDecoder::update` sees `state` saw set to `None` then before this commit it wouldn't enter the `next_state` loop and would immediately return no progress (`Ok((/* consumer bytes = */ 0, Decoded::Nothing))`). After this commit, `StreamingDecoder::update` checks if the `state` is `None` and treats this as an error.
Before this commit calling `Reader.finish` a 2nd time would return a random, accidental error (`UnexpectedEof`), because of how `StreamingDecoder`'s `state` is set after processing the `IEND` chunk. After this commit, `Reader.finish` will handle this condition explicitly, in a similar same way to how `next_frame` handles being called when we have already consumed all the frames.
After a recent commit, all public APIs of a `Reader` take care of not going beyond the `IEND` chunk and returning `PolledAfterEndOfImage` instead. This means that tracking `at_eof` at the level of `ReadDecoder` is obsolete and leads to unnecessary complexity. This commit refactors away this complexity.
`ReadDecoder::finish_decoding` now reuses `decode_next` instead of duplicating some of its code. Some duplication (e.g. handling of `Decoded::Nothing` remains - this will be taken care of in a subsequent commit).
This commit means that `decode_next` can be a private method of `ReadDecoder` (this is not enforced yet, before a subsequent commit moves `ReadDecoder` into a separate `mod`ule).
Before this commit `fn decode_next` would `loop` to skip `Decoded::Nothing` events. This is unnecessary, because all the callers of `decode_next` already account for `Decoded::Nothing` (explicitly or implicitly via a wildcard).
This commit helps to keep some aspects of `ReadDecoder` private (e.g. its fields, `decode_next` methods, etc.). This commit also means that `mod.rs` no longer directly depends on `Decoded` nor `StreamingDecoder`.
Simplify and encapsulate `ReadDecoder` implementation
Extract a separate `unfiltered_rows_buffer` module.
Add support for parsing the sBIT chunk in the decoder
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
See Commits and Changes for more details.
Created by pull[bot]
Can you help keep this open source service alive? 💖 Please sponsor : )