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
//! Image-producing operations: conversion, resize, geometry, filters, morphology, and template matching.
//!
//! Start with [`convert_image`](crate::transform::convert_image) when the pixel type changes, [`resize`](crate::transform::resize) when
//! dimensions change, [`combine_images`](crate::transform::combine_images) when two same-sized images become one,
//! and the filter/convolution APIs when each output pixel depends on a
//! neighborhood.
//!
//! ## Common choices
//!
//! | Task | Start with | Important constraint |
//! |---|---|---|
//! | Convert sRGB to linear light | [`convert_image`](crate::transform::convert_image) + [`SrgbGamma`](crate::transform::SrgbGamma) | The strategy names the transfer function. |
//! | Resize by copying samples | [`resize`](crate::transform::resize) + [`NearestNeighbor`](crate::transform::NearestNeighbor) | Works for gamma-encoded pixels because no blending occurs. |
//! | Resize smoothly | [`resize`](crate::transform::resize) + [`Bilinear`](crate::transform::Bilinear) | Requires [`crate::pixel::LinearSpace`]. Linearize sRGB first. |
//! | Combine two images pixel-wise | [`combine_images`](crate::transform::combine_images) | Inputs must have the same size. |
//! | Apply a convolution/filter | [`convolve`](crate::transform::convolve) or named filters | Choose an explicit border policy. |
//! | Erode/dilate/median | [`map_neighborhood`](crate::transform::map_neighborhood) or morphology helpers | Use masks for active neighborhood positions. |
//!
//! ## Geometry and flips
//!
//! Pixel **positions** are rearranged without modifying pixel **values**.
//! [`flip_h`](crate::transform::flip_h), [`flip_v`](crate::transform::flip_v),
//! [`rotate_90`](crate::transform::rotate_90),
//! [`rotate_180`](crate::transform::rotate_180),
//! [`rotate_270`](crate::transform::rotate_270),
//! and [`transpose`](crate::transform::transpose) each return a fresh,
//! fully-fledged [`Image`](crate::image::Image) (or write into a caller-supplied
//! [`RasterImageMut`](crate::image::RasterImageMut)).
//! Because the operation is purely a coordinate permutation, the pixel
//! bound is only [`Copy`] — every pixel type the library defines is
//! supported (including [`crate::pixel::Srgb8`] and
//! [`crate::pixel::Indexed8`]). These are physical operations rather
//! than view wrappers, so the result is a normal image.
//!
//! ## Pixel conversion
//!
//! Apply a function to every pixel independently, potentially changing the
//! pixel type. The workhorse here is [`convert_image`](crate::transform::convert_image)
//! (and the in-place [`convert_image_into`](crate::transform::convert_image_into)).
//! Named strategies such as [`Luminance`](crate::transform::Luminance),
//! [`SrgbGamma`](crate::transform::SrgbGamma), and
//! [`Clamp`](crate::transform::Clamp) cover the most common conversions; the
//! [`PixelMap`](crate::transform::PixelMap) wrapper lets you pass an arbitrary closure.
//!
//! ## Image arithmetic
//!
//! Combine two images of the same size pixel-wise, producing a third image.
//! [`combine_images`](crate::transform::combine_images) is the generic engine;
//! named strategies ([`PixelAdd`](crate::transform::PixelAdd),
//! [`PixelSubtract`](crate::transform::PixelSubtract),
//! [`PixelMultiply`](crate::transform::PixelMultiply),
//! [`AbsDiff`](crate::transform::AbsDiff),
//! [`Min`](crate::transform::Min),
//! [`Max`](crate::transform::Max),
//! [`LinearCombine`](crate::transform::LinearCombine),
//! [`Blend`](crate::transform::Blend),
//! [`Magnitude`](crate::transform::Magnitude)) cover everyday arithmetic.
//! Thin free-function wrappers ([`add`](crate::transform::add),
//! [`subtract`](crate::transform::subtract),
//! [`abs_diff`](crate::transform::abs_diff),
//! [`image_min`](crate::transform::image_min),
//! [`image_max`](crate::transform::image_max)) are provided as
//! discoverability shortcuts.
//!
//! ## Neighbourhood transforms
//!
//! Each output pixel is computed from a window of input pixels centred at
//! that position. Two complementary primitives are provided:
//!
//! * **[`fold_neighborhood`](crate::transform::fold_neighborhood)** — fixed,
//! weighted aggregation (convolution, separable filters, …).
//! The [`FoldOp`](crate::transform::FoldOp) trait +
//! [`ClosureFold`](crate::transform::ClosureFold) wrapper
//! give a zero-overhead, monomorphised hot path.
//!
//! * **[`map_neighborhood`](crate::transform::map_neighborhood)** — non-linear,
//! data-dependent transforms (erosion/dilation, median, bilateral, …).
//! The [`MapOp`](crate::transform::MapOp) trait +
//! [`ClosureMap`](crate::transform::ClosureMap) wrapper follow the same
//! design; a boolean [`Mask`](crate::image::Mask) selects which neighbours
//! are active.
//!
//! Both engines use an interior/boundary split: the interior pixels are
//! processed with fast direct indexing; only the thin boundary strip goes
//! through the [`crate::border::BorderPolicy`] accessor.
pub use crateblend;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;