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/master/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 [`io::Reader`]:
17 //!
18 //! ```rust,no_run
19 //! # use std::io::Cursor;
20 //! use image::io::Reader as 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)).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;
34 //! # use image::ImageOutputFormat;
35 //! # use image::DynamicImage;
36 //! # #[cfg(feature = "png")]
37 //! # fn main() -> Result<(), image::ImageError> {
38 //! # let img: DynamicImage = unimplemented!();
39 //! # let img2: DynamicImage = unimplemented!();
40 //! img.save("empty.jpg")?;
41 //!
42 //! let mut bytes: Vec<u8> = Vec::new();
43 //! img2.write_to(&mut bytes, image::ImageOutputFormat::Png)?;
44 //! # Ok(())
45 //! # }
46 //! # #[cfg(not(feature = "png"))] fn main() {}
47 //! ```
48 //!
49 //! With default features, the crate includes support for [many common image formats](codecs/index.html#supported-formats).
50 //!
51 //! [`save`]: enum.DynamicImage.html#method.save
52 //! [`write_to`]: enum.DynamicImage.html#method.write_to
53 //! [`io::Reader`]: io/struct.Reader.html
54 //!
55 //! # Image buffers
56 //!
57 //! The two main types for storing images:
58 //! * [`ImageBuffer`] which holds statically typed image contents.
59 //! * [`DynamicImage`] which is an enum over the supported ImageBuffer formats
60 //! and supports conversions between them.
61 //!
62 //! As well as a few more specialized options:
63 //! * [`GenericImage`] trait for a mutable image buffer.
64 //! * [`GenericImageView`] trait for read only references to a GenericImage.
65 //! * [`flat`] module containing types for interoperability with generic channel
66 //! matrices and foreign interfaces.
67 //!
68 //! [`GenericImageView`]: trait.GenericImageView.html
69 //! [`GenericImage`]: trait.GenericImage.html
70 //! [`ImageBuffer`]: struct.ImageBuffer.html
71 //! [`DynamicImage`]: enum.DynamicImage.html
72 //! [`flat`]: flat/index.html
73 //!
74 //! # Low level encoding/decoding API
75 //!
76 //! The [`ImageDecoder`] and [`ImageDecoderExt`] traits are implemented for many image file
77 //! formats. They decode image data by directly on raw byte slices. Given an ImageDecoder, you can
78 //! produce a DynamicImage via [`DynamicImage::from_decoder`].
79 //!
80 //! [`ImageEncoder`] provides the analogous functionality for encoding image data.
81 //!
82 //! [`DynamicImage::from_decoder`]: enum.DynamicImage.html#method.from_decoder
83 //! [`ImageDecoderExt`]: trait.ImageDecoderExt.html
84 //! [`ImageDecoder`]: trait.ImageDecoder.html
85 //! [`ImageEncoder`]: trait.ImageEncoder.html
86 #![warn(missing_docs)]
87 #![warn(unused_qualifications)]
88 #![deny(unreachable_pub)]
89 #![deny(deprecated)]
90 #![deny(missing_copy_implementations)]
91 #![cfg_attr(all(test, feature = "benchmarks"), feature(test))]
92 // it's a bit of a pain otherwise
93 #![allow(clippy::many_single_char_names)]
94 // it's a backwards compatibility break
95 #![allow(clippy::wrong_self_convention, clippy::enum_variant_names)]
96
97 #[cfg(all(test, feature = "benchmarks"))]
98 extern crate test;
99
100 #[cfg(test)]
101 #[macro_use]
102 extern crate quickcheck;
103
104 use std::io::Write;
105
106 pub use crate::color::{ColorType, ExtendedColorType};
107
108 pub use crate::color::{Luma, LumaA, Rgb, Rgba, Bgr, Bgra};
109
110 pub use crate::error::{ImageError, ImageResult};
111
112 pub use crate::image::{AnimationDecoder,
113 GenericImage,
114 GenericImageView,
115 ImageDecoder,
116 ImageDecoderExt,
117 ImageEncoder,
118 ImageFormat,
119 ImageOutputFormat,
120 Progress,
121 // Iterators
122 Pixels,
123 SubImage};
124
125 pub use crate::buffer_::{
126 GrayAlphaImage,
127 GrayImage,
128 // Image types
129 ImageBuffer,
130 RgbImage,
131 RgbaImage};
132
133 pub use crate::flat::FlatSamples;
134
135 // Traits
136 pub use crate::traits::{EncodableLayout, Primitive, Pixel};
137
138 // Opening and loading images
139 pub use crate::io::free_functions::{guess_format, load};
140 pub use crate::dynimage::{load_from_memory, load_from_memory_with_format, open,
141 save_buffer, save_buffer_with_format, image_dimensions};
142
143 pub use crate::dynimage::DynamicImage;
144
145 pub use crate::animation::{Delay, Frame, Frames};
146
147 // More detailed error type
148 pub mod error;
149
150 /// Iterators and other auxiliary structure for the `ImageBuffer` type.
151 pub mod buffer {
152 // Only those not exported at the top-level
153 pub use crate::buffer_::{
154 ConvertBuffer,
155 EnumeratePixels,
156 EnumeratePixelsMut,
157 EnumerateRows,
158 EnumerateRowsMut,
159 Pixels,
160 PixelsMut,
161 Rows,
162 RowsMut,
163 };
164 }
165
166 // Math utils
167 pub mod math;
168
169 // Image processing functions
170 pub mod imageops;
171
172 // Io bindings
173 pub mod io;
174
175 // Buffer representations for ffi.
176 pub mod flat;
177
178 /// Encoding and decoding for various image file formats.
179 ///
180 /// # Supported formats
181 ///
182 /// | Format | Decoding | Encoding |
183 /// | ------ | -------- | -------- |
184 /// | PNG | All supported color types | Same as decoding |
185 /// | JPEG | Baseline and progressive | Baseline JPEG |
186 /// | GIF | Yes | Yes |
187 /// | BMP | Yes | RGB8, RGBA8, Gray8, GrayA8 |
188 /// | ICO | Yes | Yes |
189 /// | TIFF | Baseline(no fax support) + LZW + PackBits | RGB8, RGBA8, Gray8 |
190 /// | WebP | Lossy(Luma channel only) | No |
191 /// | AVIF | Only 8-bit | Lossy |
192 /// | PNM | PBM, PGM, PPM, standard PAM | Yes |
193 /// | DDS | DXT1, DXT3, DXT5 | No |
194 /// | TGA | Yes | RGB8, RGBA8, BGR8, BGRA8, Gray8, GrayA8 |
195 /// | farbfeld | Yes | Yes |
196 ///
197 /// ## A note on format specific features
198 ///
199 /// One of the main goals of `image` is stability, in runtime but also for programmers. This
200 /// ensures that performance as well as safety fixes reach a majority of its user base with little
201 /// effort. Re-exporting all details of its dependencies would run counter to this goal as it
202 /// linked _all_ major version bumps between them and `image`. As such, we are wary of exposing too
203 /// many details, or configuration options, that are not shared between different image formats.
204 ///
205 /// Nevertheless, the advantage of precise control is hard to ignore. We will thus consider
206 /// _wrappers_, not direct re-exports, in either of the following cases:
207 ///
208 /// 1. A standard specifies that configuration _x_ is required for decoders/encoders and there
209 /// exists an essentially canonical way to control it.
210 /// 2. At least two different implementations agree on some (sub-)set of features in practice.
211 /// 3. A technical argument including measurements of the performance, space benefits, or otherwise
212 /// objectively quantified benefits can be made, and the added interface is unlikely to require
213 /// breaking changes.
214 ///
215 /// Features that fulfill two or more criteria are preferred.
216 ///
217 /// Re-exports of dependencies that reach version `1` will be discussed when it happens.
218 pub mod codecs {
219 #[cfg(any(feature = "avif-encoder", feature = "avif-decoder"))]
220 pub mod avif;
221 #[cfg(feature = "bmp")]
222 pub mod bmp;
223 #[cfg(feature = "dds")]
224 pub mod dds;
225 #[cfg(feature = "dxt")]
226 pub mod dxt;
227 #[cfg(feature = "farbfeld")]
228 pub mod farbfeld;
229 #[cfg(feature = "gif")]
230 pub mod gif;
231 #[cfg(feature = "hdr")]
232 pub mod hdr;
233 #[cfg(feature = "ico")]
234 pub mod ico;
235 #[cfg(feature = "jpeg")]
236 pub mod jpeg;
237 #[cfg(feature = "png")]
238 pub mod png;
239 #[cfg(feature = "pnm")]
240 pub mod pnm;
241 #[cfg(feature = "tga")]
242 pub mod tga;
243 #[cfg(feature = "tiff")]
244 pub mod tiff;
245 #[cfg(feature = "webp")]
246 pub mod webp;
247 }
248
249 #[cfg(feature = "avif-encoder")]
250 #[deprecated = "Use codecs::avif instead"]
251 pub mod avif {
252 //! Encoding of AVIF images.
253 pub use crate::codecs::avif::AvifEncoder;
254 }
255 #[cfg(feature = "bmp")]
256 #[deprecated = "Use codecs::bmp instead"]
257 pub mod bmp {
258 //! Decoding and Encoding of BMP Images
259 #[allow(deprecated)]
260 pub use crate::codecs::bmp::{BMPEncoder, BmpDecoder, BmpEncoder};
261 }
262 #[cfg(feature = "dds")]
263 #[deprecated = "Use codecs::dds instead"]
264 pub mod dds {
265 //! Decoding of DDS images
266 pub use crate::codecs::dds::DdsDecoder;
267 }
268 #[cfg(feature = "dxt")]
269 #[deprecated = "Use codecs:: instead"]
270 pub mod dxt {
271 //! Decoding of DXT (S3TC) compression
272 #[allow(deprecated)]
273 pub use crate::codecs::dxt::{
274 DXTEncoder, DXTReader, DXTVariant, DxtDecoder, DxtEncoder, DxtReader, DxtVariant,
275 };
276 }
277 #[cfg(feature = "farbfeld")]
278 #[deprecated = "Use codecs::farbfeld instead"]
279 pub mod farbfeld {
280 //! Decoding of farbfeld images
281 pub use crate::codecs::farbfeld::{FarbfeldDecoder, FarbfeldEncoder, FarbfeldReader};
282 }
283 #[cfg(feature = "gif")]
284 #[deprecated = "Use codecs::gif instead"]
285 pub mod gif {
286 //! Decoding of GIF Images
287 #[allow(deprecated)]
288 pub use crate::codecs::gif::{Encoder, GifDecoder, GifEncoder, GifReader, Repeat};
289 }
290 #[cfg(feature = "hdr")]
291 #[deprecated = "Use codecs::hdr instead"]
292 pub mod hdr {
293 //! Decoding of Radiance HDR Images
294 #[allow(deprecated)]
295 pub use crate::codecs::hdr::{
296 read_raw_file, rgbe8, to_rgbe8, HDRAdapter, HDREncoder, HDRImageDecoderIterator,
297 HDRMetadata, HdrAdapter, HdrDecoder, HdrEncoder, HdrImageDecoderIterator, HdrMetadata,
298 HdrReader, RGBE8Pixel, Rgbe8Pixel, SIGNATURE,
299 };
300 }
301 #[cfg(feature = "ico")]
302 #[deprecated = "Use codecs::ico instead"]
303 pub mod ico {
304 //! Decoding and Encoding of ICO files
305 #[allow(deprecated)]
306 pub use crate::codecs::ico::{ICOEncoder, IcoDecoder, IcoEncoder};
307 }
308 #[cfg(feature = "jpeg")]
309 #[deprecated = "Use codecs::jpeg instead"]
310 pub mod jpeg {
311 //! Decoding and Encoding of JPEG Images
312 #[allow(deprecated)]
313 pub use crate::codecs::jpeg::{
314 JPEGEncoder, JpegDecoder, JpegEncoder, PixelDensity, PixelDensityUnit,
315 };
316 }
317 #[cfg(feature = "png")]
318 #[deprecated = "Use codecs::png instead"]
319 pub mod png {
320 //! Decoding and Encoding of PNG Images
321 #[allow(deprecated)]
322 pub use crate::codecs::png::{
323 ApngDecoder, CompressionType, FilterType, PNGEncoder, PNGReader, PngDecoder, PngEncoder,
324 PngReader,
325 };
326 }
327 #[cfg(feature = "pnm")]
328 #[deprecated = "Use codecs::pnm instead"]
329 pub mod pnm {
330 //! Decoding and Encoding of netpbm image formats (pbm, pgm, ppm and pam)
331 #[allow(deprecated)]
332 pub use crate::codecs::pnm::{
333 ArbitraryHeader, ArbitraryTuplType, BitmapHeader, GraymapHeader, PNMEncoder, PNMHeader,
334 PNMSubtype, PixmapHeader, PnmDecoder, PnmEncoder, PnmHeader, PnmSubtype, SampleEncoding,
335 };
336 }
337 #[cfg(feature = "tga")]
338 #[deprecated = "Use codecs::tga instead"]
339 pub mod tga {
340 //! Decoding and Encoding of TGA Images
341 #[allow(deprecated)]
342 pub use crate::codecs::tga::{TgaDecoder, TgaEncoder};
343 }
344 #[cfg(feature = "tiff")]
345 #[deprecated = "Use codecs::tiff instead"]
346 pub mod tiff {
347 //! Decoding and Encoding of TIFF Images
348 #[allow(deprecated)]
349 pub use crate::codecs::tiff::{TiffDecoder, TiffEncoder, TiffReader};
350 }
351 #[cfg(feature = "webp")]
352 #[deprecated = "Use codecs::webp instead"]
353 pub mod webp {
354 //! Decoding of WebP Images
355 #[allow(deprecated)]
356 pub use crate::codecs::webp::{vp8, WebPDecoder};
357 }
358
359
360 mod animation;
361 #[path = "buffer.rs"]
362 mod buffer_;
363 mod color;
364 mod dynimage;
365 mod image;
366 mod traits;
367 mod utils;
368
369 // Can't use the macro-call itself within the `doc` attribute. So force it to eval it as part of
370 // the macro invocation.
371 //
372 // The inspiration for the macro and implementation is from
373 // <https://github.com/GuillaumeGomez/doc-comment>
374 //
375 // MIT License
376 //
377 // Copyright (c) 2018 Guillaume Gomez
378 macro_rules! insert_as_doc {
379 { $content:expr } => {
380 #[doc = $content] extern { }
381 }
382 }
383
384 // Provides the README.md as doc, to ensure the example works!
385 insert_as_doc!(include_str!("../README.md"));
386
387 // Copies data from `src` to `dst`
388 //
389 // Panics if the length of `dst` is less than the length of `src`.
390 #[inline]
copy_memory(src: &[u8], mut dst: &mut [u8])391 fn copy_memory(src: &[u8], mut dst: &mut [u8]) {
392 let len_src = src.len();
393 assert!(dst.len() >= len_src);
394 dst.write_all(src).unwrap();
395 }
396