mattdesl 3 days ago

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!)

  • tubs 2 days ago

    Interesting you default to paeth.

    Only working on grayscale 16bit images with only the lower 10bits populated I never found it reduced image size. But I was doing per scan adaptive filtering so maybe if I was only allowed one filter for the entire image that would be it?

    Just wondering if you did any experiments with different filter strategies?

    • mattdesl a day ago

      I think in the inputs I tested, I found Paeth to be the best for lower file sizes. I haven’t tested it extensively and to be honest, I should probably include some easier API for per-scanline filter selection rather than just a global choice. It should be possible right now with the lower level functions the library exposes, but not as easy.

kevingadd 3 days ago

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.

astrange 3 days ago

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.

davimdo 3 days ago

"fast" in Typescript...

  • pixelpoet 3 days ago

    Not a single benchmark on the page...

    Just sloppy TBH.

  • tracker1 3 days ago

    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.

    https://drbh.github.io/wasm-flate/

superfamicom 3 days ago

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.

https://github.com/uttori/uttori-image-png

Retr0id 3 days ago

So, how fast is it?

  • Retr0id 3 days ago

    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 3 days ago

      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 3 days ago

I had to look this week for a faster/lighter png encoder in cpp, couldn’t find any alternatives to libpng.

  • mmozeiko 3 days ago

    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:

    https://www.lucaversari.it/FJXL_and_FPNGE.pdf

    • a_t48 3 days ago

      This worked out for me. What I was actually interested in was reducing CPU utilization, which generally speed is a fine substitute for (the same work being done in a smaller time slice means lower overall utilization). It reduced utilization enough that I'll likely push to use it for production in the future (not immediately, there's bigger low hanging fruit).

    • a_t48 3 days ago

      This looks right up my alley, thanks! Will give it a shot.

  • toastie_toastie 3 days ago

    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.

    https://github.com/nothings/stb

    • a_t48 3 days ago

      The main page implies it only does decoding, am I reading it wrong?

      Edit: stb_image_write exists, I was reading it wrong

  • masklinn 3 days ago

    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?