Rust PNG crate gets even faster, used by GNOME and Chromium

nicoburns1 pts0 comments

Rust PNG crate gets even faster, used by GNOME and Chromium | blog.image-rs.org

Rust PNG crate gets even faster, used by GNOME and Chromium

June 18, 2026

by

Shnatsel

Rust png crate, also known as image-png, implements PNG encoding and decoding in safe Rust. It is compliant with the third edition of the PNG specification, including APNG support.

A year ago it was already the fastest PNG decoder in the world. Since then it has gotten even faster.

The adoption milestones over the past year are just as impressive as the technical ones.

Adoption in Chromium

image-png is used as the default PNG implementation in Chromium since M139 (August 2025) across all platforms, both on desktop and on mobile.

This required meeting a remarkably high bar in terms of features, performance, correctness, compatibility and security. It would only ship if there were no regressions in any of those categories!

Outperforming every other off-the-shelf PNG implementation was not enough: Chromium has its own fork of zlib optimized specifically for Chromium’s use cases. More work was needed to match its performance, both due to differences in workloads (e.g. lots of very small images instead of a single large one) and in the hardware (e.g. low-end ARM chips in older Android phones).

Compatibility and correctness required surprisingly little work. The library is extensively tested, and we’ve already been regularly testing the code on tens of thousands of real-world images to make sure we can handle even non-compliant images that other implementations just so happen to decode. We only had to adjust the error reporting in case of corrupt chunk and/or invalid chunk orders to match libpng, and fix a bug in streaming decoding mode with unusual buffer sizes. OSS-fuzz continuously validates that the input is always the same regardless of buffer sizes to prevent such bugs from reoccurring.

In terms of features, we had to implement displaying intermediate decoding states for partially downloaded PNGs and add support for mDCV and cLLI chunks that were being standardized while we were working on this, but with that we’re at feature parity with Chromium’s memory-unsafe PNG code.

The switch to image-png for billions of users across all of Chromium’s supported platforms is the ultimate vote of confidence in the code, and we hope this will encourage further adoption of image-png and other memory-safe image processing across the industry.

Adoption in GNOME

In 2023, GNOME 45 was released with a new default Image Viewer. This app used GNOME’s new image loading library glycin, which uses image-rs for loading most of the supported image formats, including image-png.

GNOME 49 was released in September 2025. In this release GNOME’s legacy image-loading library, gdk-pixbuf, was converted to build as a thin wrapper around glycin on Linux. Multiple distributions (Fedora, Arch, OpenSuse Tumbleweed, Ubuntu, Debian testing) have already adopted the change of gdk-pixbuf to a simple shim. This switches most GNOME apps to using glycin and with that image-rs by default.

Improved performance of PNG handling was not a major selling point for GNOME. With large PNG images being relatively rare, libpng was already fast enough for most uses. The primary reasons for this migration were memory safety and new features.

All modern web browsers support animated PNG, but it isn’t implemented in upstream libpng, so web browsers have to carry patches on top of the original code. Since most Linux distributions do not ship a patched libpng, GNOME apps could not support APNG either.

image-png has supported APNG since 2020, so migrating to it enabled APNG support first in the image viewer, and now in nearly all other GNOME apps.

Benchmarks

Due to the differences between implementations, one can always find a single image for which a given implementation performs especially well or especially poorly.

To avoid bias, we compare performance across all 2848 images from the independent, third-party QOI benchmark corpus that contains many different kinds of images. We also calculate and report the geometric mean to avoid skewing the results due to outliers. You can find the benchmarking harness used for the measurements here.

Ryzen 9 7950X

image-png: 410.8 MP/s (average) 339.9 MP/s (geomean)<br>zune-png: 394.6 MP/s (average) 313.2 MP/s (geomean)<br>wuffs-png: 381.4 MP/s (average) 290.9 MP/s (geomean)<br>libpng: 218.5 MP/s (average) 180.4 MP/s (geomean)<br>stb_image: 240.8 MP/s (average) 174.9 MP/s (geomean)<br>spng: 298.7 MP/s (average) 233.1 MP/s (geomean)

Apple M4

image-png: 387.7 MP/s (average) 310.5 MP/s (geomean)<br>zune-png: 327.6 MP/s (average) 253.7 MP/s (geomean)<br>wuffs-png: 317.5 MP/s (average) 246.7 MP/s (geomean)<br>libpng: 207.8 MP/s (average) 177.6 MP/s (geomean)<br>stb_image: 228.3 MP/s (average) 163.4 MP/s (geomean)<br>spng: 209.4 MP/s (average) 159.1 MP/s (geomean)

all numbers are in megapixels per second, higher is better

As you can see, all three memory-safe PNG...

image gnome average geomean chromium images

Related Articles