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