The image crate offers a powerful and versatile core of operations for encoding, decoding and manipulating images. It is used in game libraries, graphics API bindings and, as the pool of Rust programs expands, even in editors. It very recently reached 1.000.000 total downloads 🎉. Given the scope of the project, it isn’t perfect and may never be, but it works for many real world use cases and we are grateful for all the positive feedback we get.

Many use cases for decoding pixel matrices involve an inherently untrustworthy environment. For instance a web browser may have to handle media sent by potentially shady servers, or an open image processing service on the web might receive malicious inputs. Rust’s safety guarantees help in this area, but don’t go far enough. Services can still be vulnerable to denial of service attacks caused by panics or resource exhaustion.

The versatility pushed down the priority of other engineering considerations, but we’ve started to harden the library against malicious inputs via fuzzing. For those who aren’t familiar, fuzzing refers to automated methods of finding misbehaving inputs to programs. You can find out more in the documentation of two prominent tools for Rust: afl.rs and cargo-fuzz. These tools together have already been used to find and patch a significant number of bugs in the png, gif and pnm decoders.

It shouldn’t come as a surprise in today’s internet infrastructure that this is available as a service as well, very similar to hosting and CI. We’re also glad to announce that fuzzit.dev allows us to their platform as an open source organization. Thank you,

They have also been welcoming and helped out where possible with the setup. The png decoder in particular has been happily running and did not turn up anything, while having generated a corpus of new test cases for CI – very unique valid and invalid files.

It is worth adding that the work on fuzzing has applications beyond just having stability for trustless computation. Edges cases resulting from malformed inputs, misconfiguration, or just general mistakes can still cause program crashes if not properly addressed. This work helps prevent those sorts of bugs as well, resulting in a better, more robust library for all use cases.

A new configurable reader interface

So, how else can the newly released version 0.22.3 help?

This also brings us to the newly available interface for reading images: image::io::Reader. It unifies all previous functions into a single builder and utility struct. This simplifies many operations such as reading an image from memory with an automatically deduced type, or opening a file and inspecting the path deduced format before processing, or overriding the guess from the image library.

The improved structure also opens up more possibilities for future versions. We plan on bringing a unified interface for configuring memory limits or maximum sizes so that there is no need to manually inspect potentially misleading metadata beforehand. We are also considering helpers for reading only parts of an image, potentially saving CPU time and I/O capacity. This was hard before due to concerns about the explosion of function combinations it would spawn.

The current version is intentionally somewhat minimal to avoid risks of breaking changes, so feel free to suggest new functionality you’d like to see. We’re open to feedback!