1use std::ops::{Index, IndexMut};
2use num_traits::{Bounded, Num, NumCast};
3
4pub trait Color
8 : Copy + Clone + AsRef<<Self as Color>::Storage> + AsMut<<Self as Color>::Storage> + 'static
9 {
10 type Subpixel: Primitive;
13 type Storage: AsRef<[Self::Subpixel]> + AsMut<[Self::Subpixel]> + 'static;
15 fn channel_count() -> usize;
22
23 fn channels(&self) -> &Self::Storage;
25 fn channels_mut(&mut self) -> &mut Self::Storage;
30 fn from_channels(Self::Storage) -> Self;
36 fn color_model() -> &'static str;
42
43 fn from_slice<'a>(slice: &'a [Self::Subpixel]) -> &'a Self;
49
50 fn from_slice_mut<'a>(slice: &'a mut [Self::Subpixel]) -> &'a mut Self;
56
57 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 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 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 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 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 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
113pub 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
128pub trait ImageView<P: Color>
130 : Index<(u32, u32), Output = P> + IndexMut<(u32, u32)> {
131}
132
133pub 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
176pub trait Primitive
178 : Copy + Clone + NumCast + Num + PartialOrd<Self> + Bounded + 'static {
179}
180
181macro_rules! primitive_impls {
182 {$(
183 $ident: ident,
184 )*} => {
185$( impl 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)* }
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);