While the 0.22 release series received a few bug fixes and feature releases, the next major version was being worked on in the background, and comes with improvements to error handling, and the buffer and loading interfaces. A more detailed view on the changes is in the following paragraphs.

Error handling

We’ve redesigned the error representation from the ground up based on lessons learned from the old error type, which had slowly but steadily grown over time into an unsightly amalgamation of ideas. The new design still present an enum at the top-level, but each variant is similar to std::io::Error which allows attaching decoder specific Error sources and presents more detailed information.

New decoder interface

The ImageDecoder allows reading images into pre-allocated buffers instead of insisting on returning a Vec<u8> . The color type indicated by the decoder informs the consumer how the output bytes have to be interpreted. This has the secondary effect of allowing reading of images directly into buffers of other samples types, such as a [u16] . Note that this required no additional unsafety on image ’s part as the bytemuck crate encapsulates the casts. We chose the crate due to its stability promise and focus on a small, and easily reviewed core of operations.

Updates to the crates behind image have ensure that no more dependencies on outdated versions of the proc-macro syn crate are present and to minimize some dependencies overall. It was not possible to easily do this previously as the crate publicly exposed a few types of the underlying decoder crates. This meant that they couldn’t be upgraded beyond the SemVer compatible versions without a SemVer bump of image . Due to the friction involved in propagating such updates through the ecosystem, the goal was to minimize the number of breaking changes in the future. We’ve now ensured that dependencies which we want to evolve independently are properly hidden.

Towards better color space handling

Let’s be frank, color spaces are far from a solved problem in image and it is often necessary to reach for the lower-level decoder libraries such as png directly. However, this release should bring us a step closer. We’ve greatly reworked the ColorType enum and split parts into one type that represents color layout in ImageBuffer type and one for original layouts from the decoder. Critically, we’ve also made both non-exhaustive so that new variants may be added without a major release.

Call for participation

Do You have an idea for color space handling in decoders? Or can provide educational resources on the topic specifically to Rust programmers? This will be the main project for the next major version and we’d like to hear from You and collaborate on the issue to find an amicable solution.

Also, as alluded to above, there is some remaining work behind-the-scenes for propagating the error improvements across image formats. You can help by claiming and fixing a format in tracking issue #1134.