image v0.24.0 Release Notes

  • ๐Ÿ’ฅ Breaking changes

    Structural changes:

    • Minimum Rust version is now 1.56 and may change in minor versions until further notice. It is now tracked in the library's Cargo.toml, instead, by the standard [package.rust-version] field. Note: this applies to the library itself. You may need different version resolutions for dependencies when using a non-stable version of Rust.
    • ๐Ÿšš The math::utils::{nq, utils} modules have been removed. These are better served through the color_quant crate and the standard library respectively.
    • All codecs are now available through image::codecs, no longer top-level.
    • ExtendedColorType and DynamicImage have been made #[non_exhaustive], providing more methods instead of exhaustive matching.
    • Reading images through the generic io::Reader, as well as generic convenience interfaces, now requires the underlying reader to be BufRead + Seek. This allows more efficient support more formats. Similarly, writing now requires writers to be Write + Seek.
    • ๐Ÿ‘ The Bgra* variants of buffers, which were only half-supported, have been removed. The owning buffer types ImageBuffer and DynamicImage fundamentally already make a choice in supported pixel representations. This allows for more consistent internal behavior. Callers are expected to convert formats when using those buffers, which they are required to do in any case already, and which is routinely performed by decoders.

    Trait reworks:

    • The Pixel trait is no longer implemented quite as liberally for structs defined in the crate. Instead, it is now restricted to a set of known channel which ensures accuracy in computations involving those channels.
    • The ImageDecoderExt trait has been renamed to ImageDecoderRect, according to its actual functionality.
    • The Pixel trait and its Subpixel field no longer require (or provide) a 'static lifetime bound.
    • The Pixel trait no longer requires specifying an associated, constant ColorType. This was of little relevance to computation but made it much harder to implement and extend correctly. Instead, the private PixelWithColorType extension is added for interfaces that require a properly known variant.
    • Reworked how SubImage interacts with the GenericImage trait. It is now a default implementation. Note that SubImage now has inherent methods that avoid double-indirection, the trait's method will no longer avoid this.
    • The Primitive trait now requires implementations to provide a minimum and maximum logical bound for the purpose of converting to other primitive representations.

    โž• Additions

    Image formats:

    • ๐Ÿ‘ Reading lossless WebP is now supported.
    • ๐Ÿ‘ The OpenEXR format is now supported.
    • โฌ†๏ธ The jpeg decoder has been upgraded to Lossless JPEG.
    • The AvifEncoder now correctly handles alpha-less images. Some additional color formats are converted to RGBA as well.
    • The Bmp codec now decodes more valid images. It can decode a raw image without performing the palette mapping. It provides a method to access the palette. The encoder provides the inverse capabilities.
    • Tiff is now an output format.

    Buffers and Operations:

    • ๐Ÿ‘ The channel / primitive type f32 is now supported. Currently only the OpenEXR codec makes full use of it but this is expected to change.
    • ImageBuffer::{get_pixel_checked, get_pixel_mut_checked} provide panic-free access to pixels and channels by returning Option<&P> and Option<&mut P>.
    • ImageBuffer::write_to has been added, encoding the buffer to a writer. This method already existed on DynamicImage.
    • ๐Ÿ‘ DynamicImage now implements From<_> for all supported buffer types.
    • 0๏ธโƒฃ DynamicImage now implements Default, an empty Rgba8 image.
    • imageops::overlay now takes coordinates as i64.

    Limits:

    • โž• Added Limits and LimitSupport, utilized in io::Reader. These can be configured for rudimentary protection against resource exhaustion (images pretending to require a very large buffer). These types are not yet exhaustive by design, and more and stricter limits may be added in the future.
    • ๐Ÿ‘ Encoders that do provide inherent support for limits, or reserve a significant amount of internal memory, are urged to implement the set_limits extension to ImageDecoder. Some strict limit are opt-in, which may cause decoding to fail if not supported.

    Miscellaneous:

    • PNMSubtype has been renamed to PnmSubtype, by Rust's naming scheme.
    • ๐Ÿšš Several incorrectly capitalized PNM* aliases have been removed.
    • Several enum types that had previously used a hidden variant now use the official #[non_exhaustive] attribute instead.