-
Notifications
You must be signed in to change notification settings - Fork 144
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Unfilter in place instead of copying data out of
ZlibStream
's buffers.
Before this commit the decompressed image data would flow as follows: 1. `fdeflate` writes the raw data into `ZlibStream::out_buffer` 2. Each byte of (raw) image data is copied (i.e. `append`-ed) into `Reader::current`. See [`append` here](https://github.com/image-rs/image-png/blob/f10238a1e886b228e7da5301e5c0f5011316f2d6/src/decoder/zlib.rs#L168) and [`extend` here](https://github.com/image-rs/image-png/blob/f10238a1e886b228e7da5301e5c0f5011316f2d6/src/decoder/zlib.rs#L208). A. Before this happens, `Reader::current` is compacted, which would requires some additional copying of data. See [`drain` here](https://github.com/image-rs/image-png/blob/f10238a1e886b228e7da5301e5c0f5011316f2d6/src/decoder/mod.rs#L733-L737) B. After this happens, the `ZlibStream::out_buffer` is **always** compacted - the consumed data is removed and the remaining data is copied within the buffer (i.e. shifted left, to position 0). See [`drain` here](https://github.com/image-rs/image-png/blob/f10238a1e886b228e7da5301e5c0f5011316f2d6/src/decoder/zlib.rs#L208) 3. The data is `unfilter`-ed in place, inside `Reader::current` 4. Each byte of (unfiltered) image data is copied into `Reader::prev`. See [`copy_from_slice` here](https://github.com/image-rs/image-png/blob/f10238a1e886b228e7da5301e5c0f5011316f2d6/src/decoder/mod.rs#L769) 5. The unfiltered data is used as input for `expand_...` calls. After this commit we avoid copies in steps 2 and 4 and instead keep the data in `ZlibStream::out_buffer` a bit longer. In particular, Unfiltering is done by keeping the previous and current row within `ZlibStream::out_buffer` and mutating a portion of `ZlibStream::out_buffer` in place. Additionally, after this commit compaction of `ZlibStream::out_buffer` (in step 2B above) is rate-limited, so that at most 1 byte goes through `memcpy` (or `memset`) per 1 byte of decompressed output. And after this commit the compaction of `Reader::current` (in step 2A above) doesn't happen at all (since this buffer has been removed entirely). The changes in this commit should have miminal or no impact on the cache/memory pressure. On one hand, this commit *removes* some memory pressure by removing the `Reader::current` and `Reader::prev` buffers. OTOH, this commit *increases* the amount of data stored in the `ZlibStream::out_buffer` (by more or less the same amount). Therefore the overall amount of memory used during decoding should stay the same (if we ignore change stemming from the tweaks to the frequency of compaction of `ZlibStream::out_buffer`). This commit includes a breaking API change and therefore increases the crate version in `Cargo.toml`. In particular, after this commit the `png::StreamingDecoder::update` API no longer takes `&mut Vec<u8>` and the stream of decompressed data has to be instead accessed and/or manipilated via the following new methids: `decompressed_image_data`, `decompressed_image_data_mut`, `discard_image_data`.
- Loading branch information
1 parent
f10238a
commit 87b44a8
Showing
5 changed files
with
227 additions
and
102 deletions.
There are no files selected for viewing
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
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
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
Oops, something went wrong.