1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274
//! This crate provides native rust implementations of //! image encoders and decoders and basic image manipulation //! functions. //! //! Additional documentation can currently also be found in the //! [README.md file which is most easily viewed on github](https://github.com/image-rs/image/blob/master/README.md). //! //! [Jump forward to crate content](#reexports) //! //! # Overview //! //! There are two core problems for this library provides solutions: a unified interface for images //! encodings and simple generic buffers for their content. It's possible to use either feature //! without the other. The focus is on small and stable set of common operations that can be //! supplemented by other specialized crates. The library also prefers safe solutions with few //! dependencies. //! //! | Format | Decoding | Encoding | //! | ------ | -------- | -------- | //! | PNG | All supported color types | Same as decoding | //! | JPEG | Baseline and progressive | Baseline JPEG | //! | GIF | Yes | Yes | //! | BMP | Yes | RGB(8), RGBA(8), Gray(8), GrayA(8) | //! | ICO | Yes | Yes | //! | TIFF | Baseline(no fax support) + LZW + PackBits | RGB(8), RGBA(8), Gray(8) | //! | WebP | Lossy(Luma channel only) | No | //! | PNM | PBM, PGM, PPM, standard PAM | Yes | //! | DDS | DXT1, DXT3, DXT5 | No | //! | TGA | Yes | No | //! | farbfeld | Yes | Yes | //! //! ## Using images decoders //! //! There exists a huge variety of image formats that are concerned with efficiently encoding image //! pixel data and auxiliary meta data for many different purposes. The `image` library provides //! decoders for many common formats, depending on the active features. The best way to use them //! depends on your use case. //! //! * [`open`] is a very simple way to load images from the file system, automatically deducing the //! format but offering little customization. //! * [`load_from_memory`], [`load_from_memory_with_format`] present a similar interface for images //! whose encoded data is already present in memory. //! * [`io::Reader`] is a builder providing a superset of the functions. It offers both //! customization and auto-deduction but is slightly more involved. The main benefit is that the //! interface is easier to evolve. //! * [`ImageDecoder`] is a trait for querying meta data and reading image pixels into a generic //! byte buffer. It also contains a `Read` adaptor for stream reading the pixels. //! * [`DynamicImage::from_decoder`] can be used for creating a buffer from a single specific or //! any custom decoder implementing the [`ImageDecoder`] trait. //! //! [`open`]: fn.open.html //! [`load_from_memory`]: fn.load_from_memory.html //! [`load_from_memory_with_format`]: fn.load_from_memory_with_format.html //! [`io::Reader`]: io/struct.Reader.html //! [`DynamicImage::from_decoder`]: enum.DynamicImage.html#method.from_decoder //! [`ImageDecoder`]: trait.ImageDecoder.html //! //! ## Using image encoders //! //! Encoding pixel data is supported for the majority of formats but not quite as broadly. //! //! * [`DynamicImage::save`] is converse of `open` and stores a `DynamicImage`. //! * [`DynamicImage::write_to`] can be used to encode an image into any writer, for example into a //! vector of bytes in memory. //! * [`save_buffer`], [`save_buffer_with_format`] are a low-level interface for saving an image //! in the file system where the library initializes the chosen encoder. //! * [`ImageEncoder`] is a trait for encoding a byte buffer of image data and the inverse of the //! `ImageDecoder` interface. //! //! [`save_buffer`]: #fn.save_buffer.html //! [`save_buffer_with_format`]: #fn.save_buffer_with_format.html //! [`DynamicImage::save`]: enum.DynamicImage.html#method.save //! [`DynamicImage::write_to`]: enum.DynamicImage.html#method.write_to //! [`ImageEncoder`]: trait.ImageEncoder.html //! //! ## Image buffers //! //! The library adds containers for channel data which together form some representation of a 2D //! matrix of pixels. These are all statically typed to avoid misinterpretation of byte data (and //! since Rust has no standard safe encapsulation for reinterpreting byte slices as another type). //! The main traits [`GenericImageView`] and [`GenericImage`] model a view on a 2D-matrix of //! addressable pixels and a buffer of independently accessible pixels respectively. //! //! The two main types for owning pixel data are [`ImageBuffer`] and [`DynamicImage`]. Note that //! the latter is an enum over well-supported pixel types that also offers conversion //! functionality. //! //! Additionally, the [`flat`] module contains items for interoperability with generic channel //! matrices and foreign interface. While still strict typed these dynamically validate length and //! other layout assumptions required to provide the trait interface. While quite generic You //! should be prepared for a bit of boilerplate when using these types. //! //! [`GenericImageView`]: trait.GenericImageView.html //! [`GenericImage`]: trait.GenericImage.html //! [`ImageBuffer`]: struct.ImageBuffer.html //! [`DynamicImage`]: enum.DynamicImage.html //! [`flat`]: flat/index.html //! //! ## A note on format specific features //! //! One of the main goals of `image` is stability, in runtime but also for programmers. This //! ensures that performance as well as safety fixes reach a majority of its user base with little //! effort. Re-exporting all details of its dependencies would run counter to this goal as it //! linked _all_ major version bumps between them and `image`. As such, we are wary of exposing too //! many details, or configuration options, that are not shared between different image formats. //! //! Nevertheless, the advantage of precise control is hard to ignore. We will thus consider //! _wrappers_, not direct re-exports, in either of the following cases: //! //! 1. A standard specifies that configuration _x_ is required for decoders/encoders and there //! exists an essentially canonical way to control it. //! 2. At least two different implementations agree on some (sub-)set of features in practice. //! 3. A technical argument including measurements of the performance, space benefits, or otherwise //! objectively quantified benefits can be made, and the added interface is unlikely to require //! breaking changes. //! //! Features that fulfill two or more criteria are preferred. //! //! Re-exports of dependencies that reach version `1` will be discussed when it happens. #![warn(missing_docs)] #![warn(unused_qualifications)] #![deny(unreachable_pub)] #![deny(deprecated)] #![deny(missing_copy_implementations)] #![cfg_attr(all(test, feature = "benchmarks"), feature(test))] // it's a bit of a pain otherwise #![allow(clippy::many_single_char_names)] #[cfg(all(test, feature = "benchmarks"))] extern crate test; #[cfg(test)] #[macro_use] extern crate quickcheck; use std::io::Write; pub use crate::color::{ColorType, ExtendedColorType}; pub use crate::color::{Luma, LumaA, Rgb, Rgba, Bgr, Bgra}; pub use crate::error::{ImageError, ImageResult}; pub use crate::image::{AnimationDecoder, GenericImage, GenericImageView, ImageDecoder, ImageDecoderExt, ImageEncoder, ImageFormat, ImageOutputFormat, Progress, // Iterators Pixels, SubImage}; pub use crate::buffer_::{ GrayAlphaImage, GrayImage, // Image types ImageBuffer, RgbImage, RgbaImage}; pub use crate::flat::FlatSamples; // Traits pub use crate::traits::{Primitive, Pixel}; // Opening and loading images pub use crate::io::free_functions::{guess_format, load}; pub use crate::dynimage::{load_from_memory, load_from_memory_with_format, open, save_buffer, save_buffer_with_format, image_dimensions}; pub use crate::dynimage::DynamicImage; pub use crate::animation::{Delay, Frame, Frames}; // More detailed error type pub mod error; /// Iterators and other auxiliary structure for the `ImageBuffer` type. pub mod buffer { // Only those not exported at the top-level pub use crate::buffer_::{ ConvertBuffer, EnumeratePixels, EnumeratePixelsMut, EnumerateRows, EnumerateRowsMut, Pixels, PixelsMut, Rows, RowsMut, }; } // Math utils pub mod math; // Image processing functions pub mod imageops; // Io bindings pub mod io; // Buffer representations for ffi. pub mod flat; // Image codecs #[cfg(feature = "bmp")] pub mod bmp; #[cfg(feature = "dds")] pub mod dds; #[cfg(feature = "dxt")] pub mod dxt; #[cfg(feature = "gif")] pub mod gif; #[cfg(feature = "hdr")] pub mod hdr; #[cfg(feature = "ico")] pub mod ico; #[cfg(feature = "jpeg")] pub mod jpeg; #[cfg(feature = "png")] pub mod png; #[cfg(feature = "pnm")] pub mod pnm; #[cfg(feature = "tga")] pub mod tga; #[cfg(feature = "tiff")] pub mod tiff; #[cfg(feature = "webp")] pub mod webp; #[cfg(feature = "farbfeld")] pub mod farbfeld; mod animation; #[path = "buffer.rs"] mod buffer_; mod color; mod dynimage; mod image; mod traits; mod utils; // Can't use the macro-call itself within the `doc` attribute. So force it to eval it as part of // the macro invocation. // // The inspiration for the macro and implementation is from // <https://github.com/GuillaumeGomez/doc-comment> // // MIT License // // Copyright (c) 2018 Guillaume Gomez macro_rules! insert_as_doc { { $content:expr } => { #[doc = $content] extern { } } } // Provides the README.md as doc, to ensure the example works! insert_as_doc!(include_str!("../README.md")); // Copies data from `src` to `dst` // // Panics if the length of `dst` is less than the length of `src`. #[inline] fn copy_memory(src: &[u8], mut dst: &mut [u8]) { let len_src = src.len(); assert!(dst.len() >= len_src); dst.write_all(src).unwrap(); }