image-rs / image-png

PNG decoding and encoding library in pure Rust
https://docs.rs/png
Apache License 2.0
357 stars 140 forks source link

Avoiding `scratch_buffer` (a field of `struct Reader<R>`) #417

Open anforowicz opened 1 year ago

anforowicz commented 1 year ago

There is a TODO in next_interlaced_row asking to "change the interface of next_interlaced_row to take an output buffer instead of making us return a reference to a buffer that we own". I very much agree with this TODO - it seems that it would be best to output directly to the final buffer (as the next_frame API does) rather than forcing the caller to copy the bytes. I assume that outputting directly to the final buffer would be good for:

FWIW, the performance considerations above mostly do not affect the next_frame API (which calls into lower-level functions like next_interlaced_row_impl for non-interlaced images) and therefore mostly do not affect png crate's benchmarks. OTOH, users of the png crate who wish to post-process the output (e.g. to transform RGB into RGBA, or alpha-multiply) may wish to do such post-processing row-by-row (while the freshly decoded row is still hot in the L1 cache). More specifically, the performance considerations to apply to:

So (given the presence of TODO + performance benefits), should I just go ahead and make a breaking change to the png::Reader::next_row and png::Reader::next_interlaced_row APIs?

WDYT? Are there some alternative API designs that we should consider first?

fintelia commented 1 year ago

That sounds good to me. If we're doing a breaking change, it might make sense to drop next_row entirely given that it is just a very thin wrapper over next_interlaced_row:

https://github.com/image-rs/image-png/blob/f10238a1e886b228e7da5301e5c0f5011316f2d6/src/decoder/mod.rs#L560-L563