image/
lib.rs

1//! # Overview
2//!
3//! This crate provides native rust implementations of image encoding and decoding as well as some
4//! basic image manipulation functions. Additional documentation can currently also be found in the
5//! [README.md file which is most easily viewed on
6//! github](https://github.com/image-rs/image/blob/main/README.md).
7//!
8//! There are two core problems for which this library provides solutions: a unified interface for image
9//! encodings and simple generic buffers for their content. It's possible to use either feature
10//! without the other. The focus is on a small and stable set of common operations that can be
11//! supplemented by other specialized crates. The library also prefers safe solutions with few
12//! dependencies.
13//!
14//! # High level API
15//!
16//! Load images using [`ImageReader`](crate::ImageReader):
17//!
18//! ```rust,no_run
19//! use std::io::Cursor;
20//! use image::ImageReader;
21//! # fn main() -> Result<(), image::ImageError> {
22//! # let bytes = vec![0u8];
23//!
24//! let img = ImageReader::open("myimage.png")?.decode()?;
25//! let img2 = ImageReader::new(Cursor::new(bytes)).with_guessed_format()?.decode()?;
26//! # Ok(())
27//! # }
28//! ```
29//!
30//! And save them using [`save`] or [`write_to`] methods:
31//!
32//! ```rust,no_run
33//! # use std::io::{Write, Cursor};
34//! # use image::{DynamicImage, ImageFormat};
35//! # #[cfg(feature = "png")]
36//! # fn main() -> Result<(), image::ImageError> {
37//! # let img: DynamicImage = unimplemented!();
38//! # let img2: DynamicImage = unimplemented!();
39//! img.save("empty.jpg")?;
40//!
41//! let mut bytes: Vec<u8> = Vec::new();
42//! img2.write_to(&mut Cursor::new(&mut bytes), image::ImageFormat::Png)?;
43//! # Ok(())
44//! # }
45//! # #[cfg(not(feature = "png"))] fn main() {}
46//! ```
47//!
48//! With default features, the crate includes support for [many common image formats](codecs/index.html#supported-formats).
49//!
50//! [`save`]: enum.DynamicImage.html#method.save
51//! [`write_to`]: enum.DynamicImage.html#method.write_to
52//! [`ImageReader`]: struct.Reader.html
53//!
54//! # Image buffers
55//!
56//! The two main types for storing images:
57//! * [`ImageBuffer`] which holds statically typed image contents.
58//! * [`DynamicImage`] which is an enum over the supported `ImageBuffer` formats
59//!   and supports conversions between them.
60//!
61//! As well as a few more specialized options:
62//! * [`GenericImage`] trait for a mutable image buffer.
63//! * [`GenericImageView`] trait for read only references to a `GenericImage`.
64//! * [`flat`] module containing types for interoperability with generic channel
65//!   matrices and foreign interfaces.
66//!
67//! [`GenericImageView`]: trait.GenericImageView.html
68//! [`GenericImage`]: trait.GenericImage.html
69//! [`ImageBuffer`]: struct.ImageBuffer.html
70//! [`DynamicImage`]: enum.DynamicImage.html
71//! [`flat`]: flat/index.html
72//!
73//! # Low level encoding/decoding API
74//!
75//! Implementations of [`ImageEncoder`] provides low level control over encoding:
76//! ```rust,no_run
77//! # use std::io::Write;
78//! # use image::DynamicImage;
79//! # use image::ImageEncoder;
80//! # #[cfg(feature = "jpeg")]
81//! # fn main() -> Result<(), image::ImageError> {
82//! # use image::codecs::jpeg::JpegEncoder;
83//! # let img: DynamicImage = unimplemented!();
84//! # let writer: Box<dyn Write> = unimplemented!();
85//! let encoder = JpegEncoder::new_with_quality(&mut writer, 95);
86//! img.write_with_encoder(encoder)?;
87//! # Ok(())
88//! # }
89//! # #[cfg(not(feature = "jpeg"))] fn main() {}
90//! ```
91//! While [`ImageDecoder`] and [`ImageDecoderRect`] give access to more advanced decoding options:
92//!
93//! ```rust,no_run
94//! # use std::io::{BufReader, Cursor};
95//! # use image::DynamicImage;
96//! # use image::ImageDecoder;
97//! # #[cfg(feature = "png")]
98//! # fn main() -> Result<(), image::ImageError> {
99//! # use image::codecs::png::PngDecoder;
100//! # let img: DynamicImage = unimplemented!();
101//! # let reader: BufReader<Cursor<&[u8]>> = unimplemented!();
102//! let decoder = PngDecoder::new(&mut reader)?;
103//! let icc = decoder.icc_profile();
104//! let img = DynamicImage::from_decoder(decoder)?;
105//! # Ok(())
106//! # }
107//! # #[cfg(not(feature = "png"))] fn main() {}
108//! ```
109//!
110//! [`DynamicImage::from_decoder`]: enum.DynamicImage.html#method.from_decoder
111//! [`ImageDecoderRect`]: trait.ImageDecoderRect.html
112//! [`ImageDecoder`]: trait.ImageDecoder.html
113//! [`ImageEncoder`]: trait.ImageEncoder.html
114#![warn(missing_docs)]
115#![warn(unused_qualifications)]
116#![deny(unreachable_pub)]
117#![deny(deprecated)]
118#![deny(missing_copy_implementations)]
119#![cfg_attr(all(test, feature = "benchmarks"), feature(test))]
120#![cfg_attr(docsrs, feature(doc_auto_cfg))]
121// We've temporarily disabled PCX support for 0.25.5 release
122// by removing the corresponding feature.
123// We want to ship bug fixes without committing to PCX support.
124//
125// Cargo shows warnings about code depending on a nonexistent feature
126// even to people using the crate as a dependency,
127// so we have to suppress those warnings.
128#![allow(unexpected_cfgs)]
129
130#[cfg(all(test, feature = "benchmarks"))]
131extern crate test;
132
133#[cfg(test)]
134#[macro_use]
135extern crate quickcheck;
136
137pub use crate::color::{ColorType, ExtendedColorType};
138
139pub use crate::color::{Luma, LumaA, Rgb, Rgba};
140
141pub use crate::error::{ImageError, ImageResult};
142
143pub use crate::images::generic_image::{GenericImage, GenericImageView, Pixels};
144
145pub use crate::images::sub_image::SubImage;
146
147pub use crate::images::buffer::{
148    ConvertColorOptions,
149    GrayAlphaImage,
150    GrayImage,
151    // Image types
152    ImageBuffer,
153    Rgb32FImage,
154    RgbImage,
155    Rgba32FImage,
156    RgbaImage,
157};
158
159pub use crate::flat::FlatSamples;
160
161// Traits
162pub use crate::traits::{EncodableLayout, Pixel, PixelWithColorType, Primitive};
163
164// Opening and loading images
165pub use crate::images::dynimage::{
166    image_dimensions, load_from_memory, load_from_memory_with_format, open,
167    write_buffer_with_format,
168};
169pub use crate::io::free_functions::{guess_format, load, save_buffer, save_buffer_with_format};
170
171pub use crate::io::{
172    decoder::{AnimationDecoder, ImageDecoder, ImageDecoderRect},
173    encoder::ImageEncoder,
174    format::ImageFormat,
175    image_reader_type::ImageReader,
176    limits::{LimitSupport, Limits},
177};
178
179pub use crate::images::dynimage::DynamicImage;
180
181pub use crate::animation::{Delay, Frame, Frames};
182
183// More detailed error type
184pub mod error;
185
186/// Iterators and other auxiliary structure for the `ImageBuffer` type.
187pub mod buffer {
188    // Only those not exported at the top-level
189    pub use crate::images::buffer::{
190        ConvertBuffer, EnumeratePixels, EnumeratePixelsMut, EnumerateRows, EnumerateRowsMut,
191        Pixels, PixelsMut, Rows, RowsMut,
192    };
193
194    #[cfg(feature = "rayon")]
195    pub use crate::images::buffer_par::*;
196}
197
198// Math utils
199pub mod math;
200
201// Image processing functions
202pub mod imageops;
203
204// Buffer representations for ffi.
205pub use crate::images::flat;
206
207/// Encoding and decoding for various image file formats.
208///
209/// # Supported formats
210///
211/// | Feature | Format   | Notes
212/// | ------- | -------- | -----
213/// | `avif`  | AVIF     | Decoding requires the `avif-native` feature, uses the libdav1d C library.
214/// | `bmp`   | BMP      |
215/// | `dds`   | DDS      | Only decoding is supported.
216/// | `exr`   | OpenEXR  |
217/// | `ff`    | Farbfeld |
218/// | `gif`   | GIF      |
219/// | `hdr`   | HDR      |
220/// | `ico`   | ICO      |
221/// | `jpeg`  | JPEG     |
222/// | `png`   | PNG      |
223/// | `pnm`   | PNM      |
224/// | `qoi`   | QOI      |
225/// | `tga`   | TGA      |
226/// | `tiff`  | TIFF     |
227/// | `webp`  | WebP     | Only lossless encoding is currently supported.
228///
229/// ## A note on format specific features
230///
231/// One of the main goals of `image` is stability, in runtime but also for programmers. This
232/// ensures that performance as well as safety fixes reach a majority of its user base with little
233/// effort. Re-exporting all details of its dependencies would run counter to this goal as it
234/// linked _all_ major version bumps between them and `image`. As such, we are wary of exposing too
235/// many details, or configuration options, that are not shared between different image formats.
236///
237/// Nevertheless, the advantage of precise control is hard to ignore. We will thus consider
238/// _wrappers_, not direct re-exports, in either of the following cases:
239///
240/// 1. A standard specifies that configuration _x_ is required for decoders/encoders and there
241///    exists an essentially canonical way to control it.
242/// 2. At least two different implementations agree on some (sub-)set of features in practice.
243/// 3. A technical argument including measurements of the performance, space benefits, or otherwise
244///    objectively quantified benefits can be made, and the added interface is unlikely to require
245///    breaking changes.
246///
247/// Features that fulfill two or more criteria are preferred.
248///
249/// Re-exports of dependencies that reach version `1` will be discussed when it happens.
250pub mod codecs {
251    #[cfg(any(feature = "avif", feature = "avif-native"))]
252    pub mod avif;
253    #[cfg(feature = "bmp")]
254    pub mod bmp;
255    #[cfg(feature = "dds")]
256    pub mod dds;
257    #[cfg(feature = "ff")]
258    pub mod farbfeld;
259    #[cfg(feature = "gif")]
260    pub mod gif;
261    #[cfg(feature = "hdr")]
262    pub mod hdr;
263    #[cfg(feature = "ico")]
264    pub mod ico;
265    #[cfg(feature = "jpeg")]
266    pub mod jpeg;
267    #[cfg(feature = "exr")]
268    pub mod openexr;
269    #[cfg(feature = "pcx")]
270    pub mod pcx;
271    #[cfg(feature = "png")]
272    pub mod png;
273    #[cfg(feature = "pnm")]
274    pub mod pnm;
275    #[cfg(feature = "qoi")]
276    pub mod qoi;
277    #[cfg(feature = "tga")]
278    pub mod tga;
279    #[cfg(feature = "tiff")]
280    pub mod tiff;
281    #[cfg(feature = "webp")]
282    pub mod webp;
283
284    #[cfg(feature = "dds")]
285    mod dxt;
286}
287
288mod animation;
289mod color;
290pub mod hooks;
291mod images;
292/// Deprecated io module the original io module has been renamed to `image_reader`.
293/// This is going to be internal.
294pub mod io;
295pub mod metadata;
296//TODO delete this module after a few releases
297mod traits;
298mod utils;
299
300// Can't use the macro-call itself within the `doc` attribute. So force it to eval it as part of
301// the macro invocation.
302//
303// The inspiration for the macro and implementation is from
304// <https://github.com/GuillaumeGomez/doc-comment>
305//
306// MIT License
307//
308// Copyright (c) 2018 Guillaume Gomez
309macro_rules! insert_as_doc {
310    { $content:expr } => {
311        #[allow(unused_doc_comments)]
312        #[doc = $content] extern "Rust" { }
313    }
314}
315
316// Provides the README.md as doc, to ensure the example works!
317insert_as_doc!(include_str!("../README.md"));