| 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::image_reader::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" ))] |
| 131 | extern crate test; |
| 132 | |
| 133 | #[cfg (test)] |
| 134 | #[macro_use ] |
| 135 | extern crate quickcheck; |
| 136 | |
| 137 | pub use crate::color::{ColorType, ExtendedColorType}; |
| 138 | |
| 139 | pub use crate::color::{Luma, LumaA, Rgb, Rgba}; |
| 140 | |
| 141 | pub use crate::error::{ImageError, ImageResult}; |
| 142 | |
| 143 | pub use crate::image::{ |
| 144 | AnimationDecoder, |
| 145 | GenericImage, |
| 146 | GenericImageView, |
| 147 | ImageDecoder, |
| 148 | ImageDecoderRect, |
| 149 | ImageEncoder, |
| 150 | ImageFormat, |
| 151 | // Iterators |
| 152 | Pixels, |
| 153 | SubImage, |
| 154 | }; |
| 155 | |
| 156 | pub use crate::buffer_::{ |
| 157 | GrayAlphaImage, |
| 158 | GrayImage, |
| 159 | // Image types |
| 160 | ImageBuffer, |
| 161 | Rgb32FImage, |
| 162 | RgbImage, |
| 163 | Rgba32FImage, |
| 164 | RgbaImage, |
| 165 | }; |
| 166 | |
| 167 | pub use crate::flat::FlatSamples; |
| 168 | |
| 169 | // Traits |
| 170 | pub use crate::traits::{EncodableLayout, Pixel, PixelWithColorType, Primitive}; |
| 171 | |
| 172 | // Opening and loading images |
| 173 | pub use crate::dynimage::{ |
| 174 | image_dimensions, load_from_memory, load_from_memory_with_format, open, save_buffer, |
| 175 | save_buffer_with_format, write_buffer_with_format, |
| 176 | }; |
| 177 | pub use crate::image_reader::free_functions::{guess_format, load}; |
| 178 | pub use crate::image_reader::{ImageReader, LimitSupport, Limits}; |
| 179 | |
| 180 | pub use crate::dynimage::DynamicImage; |
| 181 | |
| 182 | pub use crate::animation::{Delay, Frame, Frames}; |
| 183 | |
| 184 | // More detailed error type |
| 185 | pub mod error; |
| 186 | |
| 187 | /// Iterators and other auxiliary structure for the `ImageBuffer` type. |
| 188 | pub mod buffer { |
| 189 | // Only those not exported at the top-level |
| 190 | pub use crate::buffer_::{ |
| 191 | ConvertBuffer, EnumeratePixels, EnumeratePixelsMut, EnumerateRows, EnumerateRowsMut, |
| 192 | Pixels, PixelsMut, Rows, RowsMut, |
| 193 | }; |
| 194 | |
| 195 | #[cfg (feature = "rayon" )] |
| 196 | pub use crate::buffer_par::*; |
| 197 | } |
| 198 | |
| 199 | // Math utils |
| 200 | pub mod math; |
| 201 | |
| 202 | // Image processing functions |
| 203 | pub mod imageops; |
| 204 | |
| 205 | // Buffer representations for ffi. |
| 206 | pub mod flat; |
| 207 | |
| 208 | /// Encoding and decoding for various image file formats. |
| 209 | /// |
| 210 | /// # Supported formats |
| 211 | /// |
| 212 | /// <!--- NOTE: Make sure to keep this table in sync with the README --> |
| 213 | /// |
| 214 | /// | Format | Decoding | Encoding | |
| 215 | /// | -------- | ----------------------------------------- | --------------------------------------- | |
| 216 | /// | AVIF | Yes \* | Yes (lossy only) | |
| 217 | /// | BMP | Yes | Yes | |
| 218 | /// | DDS | Yes | --- | |
| 219 | /// | Farbfeld | Yes | Yes | |
| 220 | /// | GIF | Yes | Yes | |
| 221 | /// | HDR | Yes | Yes | |
| 222 | /// | ICO | Yes | Yes | |
| 223 | /// | JPEG | Yes | Yes | |
| 224 | /// | EXR | Yes | Yes | |
| 225 | /// | PNG | Yes | Yes | |
| 226 | /// | PNM | Yes | Yes | |
| 227 | /// | QOI | Yes | Yes | |
| 228 | /// | TGA | Yes | Yes | |
| 229 | /// | TIFF | Yes | Yes | |
| 230 | /// | WebP | Yes | Yes (lossless only) | |
| 231 | /// |
| 232 | /// - \* Requires the `avif-native` feature, uses the libdav1d C library. |
| 233 | /// |
| 234 | /// ## A note on format specific features |
| 235 | /// |
| 236 | /// One of the main goals of `image` is stability, in runtime but also for programmers. This |
| 237 | /// ensures that performance as well as safety fixes reach a majority of its user base with little |
| 238 | /// effort. Re-exporting all details of its dependencies would run counter to this goal as it |
| 239 | /// linked _all_ major version bumps between them and `image`. As such, we are wary of exposing too |
| 240 | /// many details, or configuration options, that are not shared between different image formats. |
| 241 | /// |
| 242 | /// Nevertheless, the advantage of precise control is hard to ignore. We will thus consider |
| 243 | /// _wrappers_, not direct re-exports, in either of the following cases: |
| 244 | /// |
| 245 | /// 1. A standard specifies that configuration _x_ is required for decoders/encoders and there |
| 246 | /// exists an essentially canonical way to control it. |
| 247 | /// 2. At least two different implementations agree on some (sub-)set of features in practice. |
| 248 | /// 3. A technical argument including measurements of the performance, space benefits, or otherwise |
| 249 | /// objectively quantified benefits can be made, and the added interface is unlikely to require |
| 250 | /// breaking changes. |
| 251 | /// |
| 252 | /// Features that fulfill two or more criteria are preferred. |
| 253 | /// |
| 254 | /// Re-exports of dependencies that reach version `1` will be discussed when it happens. |
| 255 | pub mod codecs { |
| 256 | #[cfg (any(feature = "avif" , feature = "avif-native" ))] |
| 257 | pub mod avif; |
| 258 | #[cfg (feature = "bmp" )] |
| 259 | pub mod bmp; |
| 260 | #[cfg (feature = "dds" )] |
| 261 | pub mod dds; |
| 262 | #[cfg (feature = "ff" )] |
| 263 | pub mod farbfeld; |
| 264 | #[cfg (feature = "gif" )] |
| 265 | pub mod gif; |
| 266 | #[cfg (feature = "hdr" )] |
| 267 | pub mod hdr; |
| 268 | #[cfg (feature = "ico" )] |
| 269 | pub mod ico; |
| 270 | #[cfg (feature = "jpeg" )] |
| 271 | pub mod jpeg; |
| 272 | #[cfg (feature = "exr" )] |
| 273 | pub mod openexr; |
| 274 | #[cfg (feature = "pcx" )] |
| 275 | pub mod pcx; |
| 276 | #[cfg (feature = "png" )] |
| 277 | pub mod png; |
| 278 | #[cfg (feature = "pnm" )] |
| 279 | pub mod pnm; |
| 280 | #[cfg (feature = "qoi" )] |
| 281 | pub mod qoi; |
| 282 | #[cfg (feature = "tga" )] |
| 283 | pub mod tga; |
| 284 | #[cfg (feature = "tiff" )] |
| 285 | pub mod tiff; |
| 286 | #[cfg (feature = "webp" )] |
| 287 | pub mod webp; |
| 288 | |
| 289 | #[cfg (feature = "dds" )] |
| 290 | mod dxt; |
| 291 | } |
| 292 | |
| 293 | mod animation; |
| 294 | #[path = "buffer.rs" ] |
| 295 | mod buffer_; |
| 296 | #[cfg (feature = "rayon" )] |
| 297 | mod buffer_par; |
| 298 | mod color; |
| 299 | mod dynimage; |
| 300 | mod image; |
| 301 | mod image_reader; |
| 302 | pub mod metadata; |
| 303 | //TODO delete this module after a few releases |
| 304 | /// deprecated io module the original io module has been renamed to `image_reader` |
| 305 | pub mod io { |
| 306 | #[deprecated (note = "this type has been moved and renamed to image::ImageReader" )] |
| 307 | /// Deprecated re-export of `ImageReader` as `Reader` |
| 308 | pub type Reader<R> = super::ImageReader<R>; |
| 309 | #[deprecated (note = "this type has been moved to image::Limits" )] |
| 310 | /// Deprecated re-export of `Limits` |
| 311 | pub type Limits = super::Limits; |
| 312 | #[deprecated (note = "this type has been moved to image::LimitSupport" )] |
| 313 | /// Deprecated re-export of `LimitSupport` |
| 314 | pub type LimitSupport = super::LimitSupport; |
| 315 | } |
| 316 | mod traits; |
| 317 | mod utils; |
| 318 | |
| 319 | // Can't use the macro-call itself within the `doc` attribute. So force it to eval it as part of |
| 320 | // the macro invocation. |
| 321 | // |
| 322 | // The inspiration for the macro and implementation is from |
| 323 | // <https://github.com/GuillaumeGomez/doc-comment> |
| 324 | // |
| 325 | // MIT License |
| 326 | // |
| 327 | // Copyright (c) 2018 Guillaume Gomez |
| 328 | macro_rules! insert_as_doc { |
| 329 | { $content:expr } => { |
| 330 | #[allow(unused_doc_comments)] |
| 331 | #[doc = $content] extern "Rust" { } |
| 332 | } |
| 333 | } |
| 334 | |
| 335 | // Provides the README.md as doc, to ensure the example works! |
| 336 | insert_as_doc!(include_str!("../README.md" )); |
| 337 | |