Release 0.24.0
-- A long awaited rework with floating point images, modern Rust,
simplified traits, and more image formats.
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.
- `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.