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

Faster decompression of non-fdeflate encoded PNGs #384

Closed fintelia closed 1 year ago

fintelia commented 1 year ago

This PR brings image-png decoding performance to around 90-95% of what zune-png can do. It uses a work-in-progress branch of fdeflate which adds support for arbitrary zlib streams and incorporates some of the optimizations from zune-inflate.

$ cargo run --release --example corpus-bench -- qoi_benchmark_suite/

Directory                                     Ratio             zune-png                  image-png
---------                                    -------     --------------------      --------------------
qoi_benchmark_suite/images/pngimg              0.00%     191 mps   0.71 GiB/s      176 mps   0.65 GiB/s
qoi_benchmark_suite/images/icon_512            0.00%     447 mps   1.67 GiB/s      336 mps   1.25 GiB/s
qoi_benchmark_suite/images/textures_photo      0.00%     116 mps   0.32 GiB/s      101 mps   0.28 GiB/s
qoi_benchmark_suite/images/photo_kodak         0.00%     128 mps   0.36 GiB/s      112 mps   0.31 GiB/s
qoi_benchmark_suite/images/screenshot_game     0.00%     214 mps   0.69 GiB/s      172 mps   0.55 GiB/s
qoi_benchmark_suite/images/icon_64             0.00%     154 mps   0.58 GiB/s       87 mps   0.33 GiB/s
qoi_benchmark_suite/images/photo_tecnick       0.00%     117 mps   0.33 GiB/s      164 mps   0.46 GiB/s
qoi_benchmark_suite/images/textures_pk         0.00%      86 mps   0.32 GiB/s       82 mps   0.31 GiB/s
qoi_benchmark_suite/images/photo_wikipedia     0.00%     112 mps   0.32 GiB/s      123 mps   0.34 GiB/s
qoi_benchmark_suite/images/textures_pk01       0.00%     145 mps   0.54 GiB/s      122 mps   0.45 GiB/s
qoi_benchmark_suite/images/textures_plants     0.00%     201 mps   0.75 GiB/s      168 mps   0.63 GiB/s
qoi_benchmark_suite/images/textures_pk02       0.00%     131 mps   0.49 GiB/s      113 mps   0.42 GiB/s
qoi_benchmark_suite/images/screenshot_web      0.00%     313 mps   1.17 GiB/s      312 mps   1.16 GiB/s

Total                                         0.000%     181 mps  0.616 GiB/s      170 mps  0.579 GiB/s
fintelia commented 1 year ago

Interestingly the results are reversed if I first re-encode each image with fdeflate (making the zlib stream incredibly literal heavy):

Directory                                     Ratio             zune-png                  image-png
---------                                    -------     --------------------      --------------------
Total                                         0.000%     150 mps  0.509 GiB/s      183 mps  0.622 GiB/s
fintelia commented 1 year ago

I did some more optimization of how fdeflate builds decoding tables, and performance is now even closer:

Directory                                     Ratio             zune-png                  Decode
---------                                    -------     --------------------      --------------------
Total                                         0.000%     181 mps  0.614 GiB/s      179 mps  0.608 GiB/s