14 releases (8 breaking)
0.8.2 | May 18, 2021 |
---|---|
0.8.0 | Feb 15, 2021 |
0.7.0 | Sep 19, 2020 |
0.6.0 | Jul 26, 2020 |
0.0.1 | Jul 25, 2019 |
#206 in Images
3,583 downloads per month
Used in 12 crates
(8 directly)
150KB
3K
SLoC
A pure Rust PNG/APNG encoder & decoder
This is a pure Rust PNG image decoder and encoder taking inspiration from lodepng. This crate allows easy reading and writing of PNG files without any system dependencies.
Why another PNG crate?
These are the 4 Rust PNG encoder/decoder crates I know of:
- png - The one everyone uses (used to be able to load less pngs than png_pong and slower, but has caught up).
- lodepng - Loads all the PNGs, code is ported from C, therefore code is hard read & maintain, also uses slow implementation of deflate/inflate algorithm.
- imagefmt - Abandoned, and limited in what files it can open, but with a lot less lines of code.
- imagine - PNG decoding only.
Originally I made the aci_png based
on imagefmt, and intended to add more features. At the time, I didn't want to
write a PNG encoder/decoder from scratch so I decided to take lodepng
which
has more features (and more low level features) and clean up the code, upgrade
to 2018 edition of Rust, depend on the miniz_oxide crate (because it can
decompress faster than lodepng's INFLATE implementation) and get rid of the libc
dependency so it actually becomes pure Rust (lodepng claims to be, but calls
C's malloc and free). Then, I rewrote the entire library, based on
gift and pix.
Goals
- Forbid unsafe.
- APNG support as iterator.
- Fast.
- Compatible with pix / gift-style API.
- Load all PNG files crushed with pngcrush.
- Save crushed PNG files.
- Clean, well-documented, concise code.
- Implement all completed, non-deprecated chunks in the PNG 1.2 Specification, including the PNG 1.2 Extensions and the APNG Specification
TODO
- Implement APNG reading.
- Implement Chunk reading (with all the different chunk structs).
- StepDecoder should wrap StepDecoder, RasterEncoder should wrap ChunkEncoder
- More test cases to test against.
Benchmarks And Comparisons
Using Rust 1.52.1, criterion and 4 different PNG sizes with PNGs from "./tests/png/" (units are: us / microseconds). I stopped anything that was predicted to take longer than a half hour with criterion with the message "TIMEOUT".
- sRGB 1x1: Uses
tests/png/profile.png
- sRGBA 1x1: Uses
tests/png/test.png
- sRGB 64x64: Uses
test/png/4.png
- sRGBA 64x64: Uses
tests/png/res.png
- sRGB 256x256:
tests/png/PngSuite.png
- sRGBA 256x256: Uses
tests/png/icon.png
- sRGB 4096x4096:
tests/png/plopgrizzly.png
- sRGBA 4096x4096: Uses
tests/png/noise.png
Encoder
Library | sRGB 1x1 | sRGBA 1x1 | sRGB 64x64 | sRGBA 64x64 | sRGB 256x256 | sRGBA 256x256 | sRGB 4096x4096 | sRGBA 4096x4096 |
---|---|---|---|---|---|---|---|---|
png_pong | 41.956 | 8.2661 | 1_025.7 | 700.80 | 2_646.1 | 5_061.5 | 587_320 | 3_587_100 |
png | 29.538 | 9.4122 | 213.49 | 203.02 | 944.99 | 1_534.3 | 201_680 | 1_535_300 |
lodepng | 59.989 | 10.700 | 1_399.3 | 982.63 | 3_391.3 | 6_664.7 | 831_190 | 3_394_900 |
imagefmt | 8.7942 | 8.7399 | 211.01 | 177.82 | 901.22 | 1_569.4 | 218_550 | 1_285_700 |
imagine | --- | --- | --- | --- | --- | --- | --- | --- |
aci_png | FAILS | 30.987 | FAILS | 289.24 | FAILS | 2_298.1 | FAILS | 2_135_400 |
libpng-sys | 6.8443 | 2.9461 | 1_613.5 | 769.70 | 2_261.1 | 4_745.2 | 520_770 | 2_926_900 |
Decoder
Library | sRGB 1x1 | sRGBA 1x1 | sRGB 64x64 | sRGBA 64x64 | sRGB 256x256 | sRGBA 256x256 | sRGB 4096x4096 | sRGBA 4096x4096 |
---|---|---|---|---|---|---|---|---|
png_pong | 7.7520 | 3.9459 | 77.981 | 99.384 | 752.95 | 901.98 | 178_880 | 570_200 |
png | 8.1195 | 6.6107 | 54.834 | 71.873 | 643.09 | 686.29 | 128_000 | 355_080 |
lodepng | 5.8958 | 5.4527 | 77.050 | 97.762 | 882.83 | 982.76 | 230_570 | 563_210 |
imagefmt | 4.2864 | 4.8706 | 74.715 | 82.026 | 566.86 | 758.27 | 69_465 | 545_060 |
imagine | 2.8809 | 0.44822 | 3_202.3 | 2_266.4 | 2_056.1 | 10_753 | 442_750 | 27_944_000 |
aci_png | 5.0243 | 4.3516 | 201.29 | 174.30 | 1_500.6 | 1_689.8 | 398_340 | 1_323_600 |
libpng-sys | 3.6011 | 0.48747 | 1.8175 | 0.67344 | 25.809 | 4.4175 | 19_400 | 18_262 |
Table of Contents
API
API documentation can be found on docs.rs.
Features
There are no optional features.
Upgrade
You can use the changelog to facilitate upgrading this crate as a dependency.
License
Licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0)
- Zlib License, (LICENSE-ZLIB or https://opensource.org/licenses/Zlib)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
Before contributing, check out the contribution guidelines, and, as always, make sure to always follow the code of conduct.
Dependencies
~420KB