Fast-PNG: PNG image decoder and encoder
17 comments
·March 11, 2025astrange
I think it's bad luck to name a project "fast". Relative names like "faster" may be okay, but what if it's not fast? Then it's an attractive nuisance.
superfamicom
Nice! Remarkably similar to my own PNG implementation. I don't think I have pushed up the encoding work I did but should. I would highly recommend anyone / everyone to write a parser for a file format, you learn a lot. I also didn't implement the interlacing support.
My goal was not to be fast however, but to just document a good reference and be able to come back to it and understand what it was doing and what I wrote.
davimdo
"fast" in Typescript...
pixelpoet
Not a single benchmark on the page...
Just sloppy TBH.
tracker1
Seems to largely rely on the pako package in npm fpr inflate/deflate. The deflate method seems faster than the zlib implementation it compares to for compression, decompression(inflate) seems slower.
Would be interested to see a comparison to a thin WASM implementation in a low level language.
-- edit:
Looks like wasm-flate is much faster... not sure on overhead though.
kevingadd
When shipping an image decoder make sure you're not using it on untrusted inputs unless it's been very vigorously fuzzed and security audited. Common mistake to be made and other fast/simple decoder libraries for PNG have had vulnerabilities before.
EDIT: Thankfully I don't see any native code in this repo, it looked like a wrapper around a native binary at first. So the attack surface is smaller, but it's still worth being careful! You might want to check whether Inflator etc are robust.
Retr0id
So, how fast is it?
Retr0id
Looks like it depends on https://github.com/nodeca/pako for the zlib compression.
> Almost as fast in modern JS engines as C implementation (see benchmarks).
Impressive, although "almost" is doing some heavy lifting there.
> deflate-pako x 10.22 ops/sec ±0.33% (29 runs sampled)
> deflate-zlib x 18.48 ops/sec ±0.24% (48 runs sampled)
> inflate-pako x 134 ops/sec ±0.66% (83 runs sampled)
> inflate-zlib x 402 ops/sec ±0.74% (87 runs sampled)
stragies
Yes, calling something that is 2-3 slower than the reference "almost as fast" is a very creative use of the English language.
a_t48
I had to look this week for a faster/lighter png encoder in cpp, couldn’t find any alternatives to libpng.
mmozeiko
https://github.com/veluca93/fpnge is a very fast png encoder. A bit lower compression ratio, but runs significantly faster than alternatives. Here is a presentation with benchmarks:
a_t48
This looks right up my alley, thanks! Will give it a shot.
toastie_toastie
stb_image is a single header image encoder/decoder that is used pretty widely across game development codebases. and it supports a ton of different formats.
a_t48
The main page implies it only does decoding, am I reading it wrong?
Edit: stb_image_write exists, I was reading it wrong
masklinn
libsnpng is pure C.
And it doesn't look like the png crate provides a C API but if your usage is not overly complex it might be easy enough to byo?
null
Last time I benchmarked png-tools, it was about 2-6x faster than fast-png for encoding.
https://github.com/mattdesl/png-tools
I’ve also added some other features like multi-threaded encoding, cancellation, encoding physical dimensions, color profiles, all of which is useful for encoding large print-ready PNGs on the client.
(No shade against fast-png, it’s a good library, but maybe not the fastest!)