image_buffer/
traits.rs

1use std::ops::{Index, IndexMut};
2use num_traits::{Bounded, Num, NumCast};
3
4/// A generalized pixel.
5///
6/// A pixel object is usually not used standalone but as a view into an image buffer.
7pub trait Color
8    : Copy + Clone + AsRef<<Self as Color>::Storage> + AsMut<<Self as Color>::Storage> + 'static
9    {
10    /// The underlying subpixel type.
11
12    type Subpixel: Primitive;
13    // TODO: Workaround until associated consts work.
14    type Storage: AsRef<[Self::Subpixel]> + AsMut<[Self::Subpixel]> + 'static;
15    // TODO: The preferred solution would be:
16    // type Subpixel: Primitive;
17    // const NUM_CHANNELS: usize;
18
19    /// Returns the number of channels of this pixel type.
20    // TODO: Remove is NUM_CHANNELS is available
21    fn channel_count() -> usize;
22
23    /// Returns the components as a slice.
24    fn channels(&self) -> &Self::Storage;
25    // TODO: The preferred solution would be:
26    // fn channels(&self) -> &[Self::Subpixel; Self::NUM_CHANNELS];
27
28    /// Returns the components as a mutable slice
29    fn channels_mut(&mut self) -> &mut Self::Storage;
30    // TODO: The preferred solution would be:
31    // fn channels_mut(&mut self) -> &mut [Self::Subpixel; Self::NUM_CHANNELS];
32
33    /// Construct a pixel from the 4 channels a, b, c and d.
34    /// If the pixel does not contain 4 channels the extra are ignored.
35    fn from_channels(Self::Storage) -> Self;
36    // TODO: The preferred solution would be:
37    // fn from_channels([Self::Subpixel; Self::NUM_CHANNELS]) -> Self;
38
39    /// Returns a string that can help to interprete the meaning each channel
40    /// See [gimp babl](http://gegl.org/babl/).
41    fn color_model() -> &'static str;
42
43    /// Returns a view into a slice.
44    ///
45    /// # Panics
46    ///
47    /// If the slice it not long enough this method will panic.
48    fn from_slice<'a>(slice: &'a [Self::Subpixel]) -> &'a Self;
49
50    /// Returns mutable view into a mutable slice.
51    ///
52    /// # Panics
53    ///
54    /// If the slice it not long enough this method will panic.
55    fn from_slice_mut<'a>(slice: &'a mut [Self::Subpixel]) -> &'a mut Self;
56
57    /// Apply the function ```f``` to each channel of this pixel.
58    fn map<F>(&self, f: F) -> Self
59        where F: Fn(Self::Subpixel) -> Self::Subpixel
60    {
61        let mut this = (*self).clone();
62        this.apply(f);
63        this
64    }
65
66    /// Apply the function ```f``` to each channel of this pixel.
67    fn apply<F>(&mut self, f: F)
68        where F: Fn(Self::Subpixel) -> Self::Subpixel
69    {
70        for v in self.as_mut().as_mut().iter_mut() {
71            *v = f(*v)
72        }
73    }
74
75    /// Apply the function ```f``` to each channel except the alpha channel.
76    /// Apply the function ```g``` to the alpha channel.
77    fn map_with_alpha<F, G>(&self, f: F, g: G) -> Self
78        where F: Fn(Self::Subpixel) -> Self::Subpixel,
79              G: Fn(Self::Subpixel) -> Self::Subpixel
80    {
81        let mut this = (*self).clone();
82        this.apply_with_alpha(f, g);
83        this
84    }
85
86    /// Apply the function ```f``` to each channel except the alpha channel.
87    /// Apply the function ```g``` to the alpha channel. Works in-place.
88    fn apply_with_alpha<F, G>(&mut self, f: F, g: G)
89        where F: Fn(Self::Subpixel) -> Self::Subpixel,
90              G: Fn(Self::Subpixel) -> Self::Subpixel;
91
92    /// Apply the function ```f``` to each channel of this pixel and
93    /// ```other``` pairwise.
94    fn map2<F>(&self, other: &Self, f: F) -> Self
95        where F: Fn(Self::Subpixel, Self::Subpixel) -> Self::Subpixel
96    {
97        let mut this = (*self).clone();
98        this.apply2(other, f);
99        this
100    }
101    /// Apply the function ```f``` to each channel of this pixel and
102    /// ```other``` pairwise. Works in-place.
103    fn apply2<F>(&mut self, other: &Self, f: F)
104        where F: Fn(Self::Subpixel, Self::Subpixel) -> Self::Subpixel
105    {
106        for (a, &b) in self.as_mut().as_mut().iter_mut().zip(other.as_ref().as_ref().iter()) {
107            *a = f(*a, b)
108        }
109
110    }
111}
112
113/// Color math operations.
114///
115/// Math operations on a color. Uses double dispatch to avoid type problems due to conflicting
116/// implementations of `Add` and friends.
117pub trait ColorMathOps<C: Color>: Sized {
118    #[inline(always)]
119    fn add(self, rhs: C) -> C;
120    #[inline(always)]
121    fn sub(self, rhs: C) -> C;
122    #[inline(always)]
123    fn div(self, rhs: C) -> C;
124    #[inline(always)]
125    fn mul(self, rhs: C) -> C;
126}
127
128/// A view into an image
129pub trait ImageView<P: Color>
130    : Index<(u32, u32), Output = P> + IndexMut<(u32, u32)> {
131}
132
133/// Returns value which is used to scale a value of a channel.
134///
135/// Returns `T::max_value()` for unsigned integers and `1.0` for floats.
136pub trait ChannelMax {
137    fn channel_max() -> Self;
138}
139
140impl ChannelMax for usize {
141    fn channel_max() -> Self {
142        usize::max_value()
143    }
144}
145impl ChannelMax for u8 {
146    fn channel_max() -> Self {
147        u8::max_value()
148    }
149}
150impl ChannelMax for u16 {
151    fn channel_max() -> Self {
152        u16::max_value()
153    }
154}
155impl ChannelMax for u32 {
156    fn channel_max() -> Self {
157        u32::max_value()
158    }
159}
160impl ChannelMax for u64 {
161    fn channel_max() -> Self {
162        u64::max_value()
163    }
164}
165impl ChannelMax for f32 {
166    fn channel_max() -> Self {
167        1.0
168    }
169}
170impl ChannelMax for f64 {
171    fn channel_max() -> Self {
172        1.0
173    }
174}
175
176/// `Primitive` trait from old stdlib.
177pub trait Primitive
178    : Copy + Clone + NumCast + Num + PartialOrd<Self> + Bounded + 'static {
179}
180
181macro_rules! primitive_impls {
182    {$(
183        $ident: ident,
184    )*} => {
185$( // START Implementations
186
187impl Primitive for $ident {}
188
189impl<C: Color<Subpixel=$ident>> ColorMathOps<C> for $ident
190    where C::Storage: AsRef<[$ident]> + AsMut<[$ident]>
191{
192    #[inline(always)]
193    fn add(self, mut rhs: C) -> C {
194        for val in rhs.as_mut().as_mut() {
195            *val = *val + self
196        }
197        rhs
198    }
199    #[inline(always)]
200    fn sub(self, mut rhs: C) -> C {
201        for val in rhs.as_mut().as_mut() {
202            *val = *val - self
203        }
204        rhs
205    }
206    #[inline(always)]
207    fn div(self, mut rhs: C) -> C {
208        for val in rhs.as_mut().as_mut() {
209            *val = *val / self
210        }
211        rhs
212    }
213    #[inline(always)]
214    fn mul(self, mut rhs: C) -> C {
215        for val in rhs.as_mut().as_mut() {
216            *val = *val * self
217        }
218        rhs
219    }
220}
221
222)* // END Implementations
223
224    }
225}
226
227primitive_impls!(
228    usize,
229    u8,
230    u16,
231    u32,
232    u64,
233    isize,
234    i8,
235    i16,
236    i32,
237    i64,
238    f32,
239    f64,
240);