image2/
pixel.rs

1use crate::*;
2
3/// Normalized image data
4#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5#[derive(Debug, Clone, PartialEq, PartialOrd)]
6pub struct Pixel<C: Color>(Box<[f64]>, std::marker::PhantomData<C>);
7
8impl<C: Color> AsRef<[f64]> for Pixel<C> {
9    fn as_ref(&self) -> &[f64] {
10        self.0.as_ref()
11    }
12}
13
14impl<C: Color> AsMut<[f64]> for Pixel<C> {
15    fn as_mut(&mut self) -> &mut [f64] {
16        self.0.as_mut()
17    }
18}
19
20impl<C: Color> Default for Pixel<C> {
21    fn default() -> Self {
22        Pixel::new()
23    }
24}
25
26impl<C: Color> From<&[f64]> for Pixel<C> {
27    fn from(data: &[f64]) -> Self {
28        let mut px = Pixel::new();
29        px.copy_from_slice(data);
30        px
31    }
32}
33
34impl<C: Color> From<Vec<f64>> for Pixel<C> {
35    fn from(data: Vec<f64>) -> Self {
36        let data = data.into_boxed_slice();
37        Pixel(data, std::marker::PhantomData)
38    }
39}
40
41impl<C: Color> Pixel<C> {
42    /// Create an empty pixel
43    pub fn new() -> Pixel<C> {
44        let data = match C::CHANNELS {
45            1 => Box::new([0.0; 1]) as Box<[f64]>,
46            2 => Box::new([0.0; 2]),
47            3 => Box::new([0.0; 3]),
48            4 => Box::new([0.0; 4]),
49            5 => Box::new([0.0; 5]),
50            _ => vec![0.0; C::CHANNELS].into_boxed_slice(),
51        };
52
53        let mut px = Pixel(data, std::marker::PhantomData);
54        px.with_alpha(1.0);
55        px
56    }
57
58    /// Update the colorspace associated with a pixel without performing any conversion
59    pub fn with_color<D: Color>(self) -> Pixel<D> {
60        assert!(C::CHANNELS == D::CHANNELS);
61        Pixel(self.0, std::marker::PhantomData)
62    }
63
64    /// Data
65    pub fn data(&self) -> Data<f64, C> {
66        Data::new(self.as_ref())
67    }
68
69    /// Mutable Data
70    pub fn data_mut(&mut self) -> DataMut<f64, C> {
71        DataMut::new(self.as_mut())
72    }
73
74    /// Convert into a `Vec`
75    pub fn into_vec(self) -> Vec<f64> {
76        self.0.into_vec()
77    }
78
79    /// Copy and convert to a `Vec`
80    pub fn to_vec(&self) -> Vec<f64> {
81        self.0.to_vec()
82    }
83
84    /// Fill a pixel with a single value
85    pub fn fill<T: Type>(&mut self, x: T) -> &mut Self {
86        self.0.iter_mut().for_each(|a| *a = x.to_norm());
87        self
88    }
89
90    /// Pixel channel count
91    pub fn len(&self) -> Channel {
92        C::CHANNELS
93    }
94
95    /// Pixel has no channels
96    pub fn is_empty(&self) -> bool {
97        self.len() == 0
98    }
99
100    /// Clamp values betwen 0 and 1.0
101    pub fn clamp(&mut self) -> &mut Self {
102        self.map(|x| x.clamp(0., 1.))
103    }
104
105    /// Returns `self` after calling `clamp`
106    pub fn clamped(mut self) -> Self {
107        self.clamp();
108        self
109    }
110
111    /// Returns true when the provided channel index matches the alpha channel index
112    pub fn is_alpha(&self, index: Channel) -> bool {
113        if let Some(alpha) = C::ALPHA {
114            return alpha == index;
115        }
116
117        false
118    }
119
120    /// Get alpha value
121    pub fn alpha(&self) -> Option<f64> {
122        C::ALPHA.map(|x| self[x])
123    }
124
125    /// Set alpha value
126    pub fn with_alpha(&mut self, value: f64) -> &mut Self {
127        if let Some(alpha) = C::ALPHA {
128            (*self)[alpha] = value
129        }
130        self
131    }
132
133    /// Convert pixel color type to an existing pixel
134    pub fn convert_to<D: Color>(&self, dest: &mut Pixel<D>) {
135        let mut tmp = Pixel::new();
136        C::to_rgb(self, &mut tmp);
137        D::from_rgb(&tmp, dest);
138    }
139
140    /// Convert pixel color type
141    pub fn convert<D: Color>(&self) -> Pixel<D> {
142        let mut dest = Pixel::new();
143        self.convert_to(&mut dest);
144        dest
145    }
146
147    /// Copy values from an existing slice
148    #[inline]
149    pub fn copy_from_slice<T: Type>(&mut self, data: impl AsRef<[T]>) -> &mut Self {
150        let data = data.as_ref();
151        self.0.iter_mut().enumerate().for_each(|(i, x)| {
152            *x = data[i].to_norm();
153        });
154        self
155    }
156
157    /// Copy values from an existing slice
158    #[inline]
159    pub fn copy_from_data<T: Type>(&mut self, data: &Data<T, C>) -> &mut Self {
160        let data = data.as_ref();
161        self.0.iter_mut().enumerate().for_each(|(i, x)| {
162            *x = data[i].to_norm();
163        });
164        self
165    }
166
167    /// Convert color and copy to slice
168    pub fn convert_from_data<T: Type, D: Color>(&mut self, data: &Data<T, D>) {
169        Pixel::from_data(data).convert_to(self)
170    }
171
172    /// Convert color and copy to slice
173    pub fn convert_to_data<T: Type, D: Color>(&self, data: &mut DataMut<T, D>) {
174        let d = self.convert::<D>();
175        d.copy_to_slice(data)
176    }
177
178    /// Copy values to an existing slice
179    pub fn copy_to_slice<T: Type>(&self, mut data: impl AsMut<[T]>) {
180        let data = data.as_mut();
181        self.0.iter().enumerate().for_each(|(i, x)| {
182            data[i] = T::from_norm(*x);
183        });
184    }
185
186    /// Create from slice
187    pub fn from_slice<T: Type>(data: impl AsRef<[T]>) -> Pixel<C> {
188        let mut px = Pixel::new();
189        px.copy_from_slice(data);
190        px
191    }
192
193    /// Create from slice
194    pub fn from_data<T: Type>(data: &Data<T, C>) -> Pixel<C> {
195        let mut px = Pixel::new();
196        px.copy_from_slice(data);
197        px
198    }
199
200    /// Create from another pixel
201    pub fn copy_from(&mut self, other: &Pixel<C>) -> &mut Self {
202        self.map2(other, |_, b| b)
203    }
204
205    /// Blend alpha value
206    pub fn blend_alpha(&mut self) -> &mut Self {
207        if let Some(index) = C::ALPHA {
208            let alpha = self[index];
209
210            self.map(|x| x * alpha);
211            (*self)[index] = 1.0;
212        }
213
214        self
215    }
216
217    /// Create a new pixel by applying `f` over an existing pixel
218    pub fn map(&mut self, f: impl Fn(f64) -> f64) -> &mut Self {
219        self.iter_mut().for_each(|x| *x = f(*x));
220        self
221    }
222
223    /// Zip two pixels, apply `f` and return a new pixel with the results
224    pub fn map2(&mut self, other: &Pixel<C>, f: impl Fn(f64, f64) -> f64) -> &mut Self {
225        self.iter_mut()
226            .zip(other.iter())
227            .for_each(|(x, y)| *x = f(*x, *y));
228        self
229    }
230
231    /// Apply `f` for each channel in a pixel
232    pub fn for_each(&self, mut f: impl FnMut(usize, f64)) {
233        for i in 0..self.len() {
234            f(i, self[i])
235        }
236    }
237
238    /// Get iterator over pixel data, ignoring alpha channel
239    pub fn iter(&self) -> impl Iterator<Item = &f64> {
240        let iter = self.0.iter();
241
242        let alpha = C::ALPHA.unwrap_or(std::usize::MAX);
243        iter.enumerate()
244            .filter_map(move |(idx, item)| if idx != alpha { Some(item) } else { None })
245    }
246
247    /// Get a mutable iterator over the pixel data, ignoring alpha channel
248    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut f64> {
249        let iter = self.0.iter_mut();
250        let alpha = C::ALPHA.unwrap_or(std::usize::MAX);
251        iter.enumerate()
252            .filter_map(move |(idx, item)| if idx != alpha { Some(item) } else { None })
253    }
254
255    /// Gamma correction
256    pub fn gamma(&mut self, value: f64) -> &mut Self {
257        self.map(|x| x.powf(value))
258    }
259
260    /// Convert to log RGB
261    pub fn gamma_log(&mut self) -> &mut Self {
262        self.gamma(1. / 2.2)
263    }
264
265    /// Convert to linear RGB
266    pub fn gamma_lin(&mut self) -> &mut Self {
267        self.gamma(2.2)
268    }
269}
270
271impl<T: Type, C: Color> std::iter::FromIterator<T> for Pixel<C> {
272    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
273        Pixel(
274            iter.into_iter().map(|x| x.to_norm()).collect(),
275            std::marker::PhantomData,
276        )
277    }
278}
279
280impl<C: Color> IntoIterator for Pixel<C> {
281    type Item = f64;
282    type IntoIter = std::vec::IntoIter<Self::Item>;
283
284    fn into_iter(self) -> Self::IntoIter {
285        self.0.into_vec().into_iter()
286    }
287}
288
289impl<C: Color> std::ops::Index<Channel> for Pixel<C> {
290    type Output = f64;
291    fn index(&self, index: Channel) -> &f64 {
292        &self.0[index]
293    }
294}
295
296impl<'a, C: Color> std::ops::Index<Channel> for &'a Pixel<C> {
297    type Output = f64;
298    fn index(&self, index: Channel) -> &f64 {
299        &self.0[index]
300    }
301}
302
303impl<'a, C: Color> std::ops::Index<Channel> for &'a mut Pixel<C> {
304    type Output = f64;
305    fn index(&self, index: Channel) -> &f64 {
306        &self.0[index]
307    }
308}
309
310impl<C: Color> std::ops::IndexMut<Channel> for Pixel<C> {
311    fn index_mut(&mut self, index: Channel) -> &mut f64 {
312        &mut self.0[index]
313    }
314}
315
316impl<'a, C: Color> std::ops::IndexMut<Channel> for &'a mut Pixel<C> {
317    fn index_mut(&mut self, index: Channel) -> &mut f64 {
318        &mut self.0[index]
319    }
320}
321
322impl<T: Type, C: Color> std::ops::Add<T> for Pixel<C> {
323    type Output = Pixel<C>;
324
325    fn add(mut self, other: T) -> Pixel<C> {
326        self.map(|x| x + other.to_norm());
327        self
328    }
329}
330
331impl<'a, T: Type, C: Color> std::ops::Add<T> for &'a Pixel<C> {
332    type Output = Pixel<C>;
333
334    fn add(self, other: T) -> Pixel<C> {
335        let mut dest = self.clone();
336        dest.map(|x| x + other.to_norm());
337        dest
338    }
339}
340
341impl<'a, C: Color> std::ops::Add<&'a Pixel<C>> for Pixel<C> {
342    type Output = Pixel<C>;
343
344    fn add(mut self, other: &'a Pixel<C>) -> Pixel<C> {
345        self.map2(other, |x, y| x + y);
346        self
347    }
348}
349
350impl<'a, C: Color> std::ops::Add<&'a Pixel<C>> for &'a Pixel<C> {
351    type Output = Pixel<C>;
352
353    fn add(self, other: &'a Pixel<C>) -> Pixel<C> {
354        let mut dest = self.clone();
355        dest.map2(other, |x, y| x + y);
356        dest
357    }
358}
359
360impl<C: Color> std::ops::Add<Pixel<C>> for Pixel<C> {
361    type Output = Pixel<C>;
362
363    fn add(mut self, other: Pixel<C>) -> Pixel<C> {
364        self.map2(&other, |x, y| x + y);
365        self
366    }
367}
368
369impl<C: Color> std::ops::Add<Pixel<C>> for f64 {
370    type Output = Pixel<C>;
371
372    fn add(self, mut px: Pixel<C>) -> Pixel<C> {
373        px.map(|x| self + x);
374        px
375    }
376}
377
378impl<'a, C: Color> std::ops::Add<&'a Pixel<C>> for f64 {
379    type Output = Pixel<C>;
380
381    fn add(self, px: &'a Pixel<C>) -> Pixel<C> {
382        let mut px = px.clone();
383        px.map(|x| self + x);
384        px
385    }
386}
387
388impl<T: Type, C: Color> std::ops::Sub<T> for Pixel<C> {
389    type Output = Pixel<C>;
390
391    fn sub(mut self, other: T) -> Pixel<C> {
392        self.map(|x| x - other.to_norm());
393        self
394    }
395}
396
397impl<'a, T: Type, C: Color> std::ops::Sub<T> for &'a Pixel<C> {
398    type Output = Pixel<C>;
399
400    fn sub(self, other: T) -> Pixel<C> {
401        let mut dest = self.clone();
402        dest.map(|x| x - other.to_norm());
403        dest
404    }
405}
406
407impl<'a, C: Color> std::ops::Sub<&'a Pixel<C>> for &'a Pixel<C> {
408    type Output = Pixel<C>;
409
410    fn sub(self, other: &'a Pixel<C>) -> Pixel<C> {
411        let mut dest = self.clone();
412        dest.map2(other, |x, y| x - y);
413        dest
414    }
415}
416
417impl<'a, C: Color> std::ops::Sub<&'a Pixel<C>> for Pixel<C> {
418    type Output = Pixel<C>;
419
420    fn sub(mut self, other: &'a Pixel<C>) -> Pixel<C> {
421        self.map2(other, |x, y| x - y);
422        self
423    }
424}
425
426impl<C: Color> std::ops::Sub<Pixel<C>> for Pixel<C> {
427    type Output = Pixel<C>;
428
429    fn sub(mut self, other: Pixel<C>) -> Pixel<C> {
430        self.map2(&other, |x, y| x - y);
431        self
432    }
433}
434
435impl<C: Color> std::ops::Sub<Pixel<C>> for f64 {
436    type Output = Pixel<C>;
437
438    fn sub(self, mut px: Pixel<C>) -> Pixel<C> {
439        px.map(|x| self - x);
440        px
441    }
442}
443
444impl<'a, C: Color> std::ops::Sub<&'a Pixel<C>> for f64 {
445    type Output = Pixel<C>;
446
447    fn sub(self, px: &'a Pixel<C>) -> Pixel<C> {
448        let mut px = px.clone();
449        px.map(|x| self - x);
450        px
451    }
452}
453
454impl<T: Type, C: Color> std::ops::Mul<T> for Pixel<C> {
455    type Output = Pixel<C>;
456
457    fn mul(mut self, other: T) -> Pixel<C> {
458        self.map(|x| x * other.to_norm());
459        self
460    }
461}
462
463impl<'a, T: Type, C: Color> std::ops::Mul<T> for &'a Pixel<C> {
464    type Output = Pixel<C>;
465
466    fn mul(self, other: T) -> Pixel<C> {
467        let mut dest = self.clone();
468        dest.map(|x| x * other.to_norm());
469        dest
470    }
471}
472
473impl<'a, C: Color> std::ops::Mul<&'a Pixel<C>> for &'a Pixel<C> {
474    type Output = Pixel<C>;
475
476    fn mul(self, other: &'a Pixel<C>) -> Pixel<C> {
477        let mut dest = self.clone();
478        dest.map2(other, |x, y| x * y);
479        dest
480    }
481}
482
483impl<'a, C: Color> std::ops::Mul<&'a Pixel<C>> for Pixel<C> {
484    type Output = Pixel<C>;
485
486    fn mul(mut self, other: &'a Pixel<C>) -> Pixel<C> {
487        self.map2(other, |x, y| x * y).clone()
488    }
489}
490
491impl<C: Color> std::ops::Mul<Pixel<C>> for Pixel<C> {
492    type Output = Pixel<C>;
493
494    fn mul(mut self, other: Pixel<C>) -> Pixel<C> {
495        self.map2(&other, |x, y| x * y).clone()
496    }
497}
498
499impl<C: Color> std::ops::Mul<Pixel<C>> for f64 {
500    type Output = Pixel<C>;
501
502    fn mul(self, mut px: Pixel<C>) -> Pixel<C> {
503        px.map(|x| self * x);
504        px
505    }
506}
507
508impl<'a, C: Color> std::ops::Mul<&'a Pixel<C>> for f64 {
509    type Output = Pixel<C>;
510
511    fn mul(self, px: &'a Pixel<C>) -> Pixel<C> {
512        let mut px = px.clone();
513        px.map(|x| self * x);
514        px
515    }
516}
517
518impl<T: Type, C: Color> std::ops::Div<T> for Pixel<C> {
519    type Output = Pixel<C>;
520
521    fn div(mut self, other: T) -> Pixel<C> {
522        self.map(|x| x / other.to_norm());
523        self
524    }
525}
526
527impl<'a, T: Type, C: Color> std::ops::Div<T> for &'a Pixel<C> {
528    type Output = Pixel<C>;
529
530    fn div(self, other: T) -> Pixel<C> {
531        let mut dest = self.clone();
532        dest.map(|x| x / other.to_norm());
533        dest
534    }
535}
536
537impl<'a, C: Color> std::ops::Div<&'a Pixel<C>> for Pixel<C> {
538    type Output = Pixel<C>;
539
540    fn div(mut self, other: &'a Pixel<C>) -> Pixel<C> {
541        self.map2(other, |x, y| x / y);
542        self
543    }
544}
545
546impl<'a, C: Color> std::ops::Div<&'a Pixel<C>> for &'a Pixel<C> {
547    type Output = Pixel<C>;
548
549    fn div(self, other: &'a Pixel<C>) -> Pixel<C> {
550        let mut dest = self.clone();
551        dest.map2(other, |x, y| x / y);
552        dest
553    }
554}
555
556impl<C: Color> std::ops::Div<Pixel<C>> for Pixel<C> {
557    type Output = Pixel<C>;
558
559    fn div(mut self, other: Pixel<C>) -> Pixel<C> {
560        self.map2(&other, |x, y| x / y);
561        self
562    }
563}
564
565impl<C: Color> std::ops::Div<Pixel<C>> for f64 {
566    type Output = Pixel<C>;
567
568    fn div(self, mut px: Pixel<C>) -> Pixel<C> {
569        px.map(|x| self / x);
570        px
571    }
572}
573
574impl<'a, C: Color> std::ops::Div<&'a Pixel<C>> for f64 {
575    type Output = Pixel<C>;
576
577    fn div(self, px: &'a Pixel<C>) -> Pixel<C> {
578        let mut px = px.clone();
579        px.map(|x| self / x);
580        px
581    }
582}
583
584impl<T: Type, C: Color> std::ops::Rem<T> for Pixel<C> {
585    type Output = Pixel<C>;
586
587    fn rem(mut self, other: T) -> Pixel<C> {
588        self.map(|x| x % other.to_norm());
589        self
590    }
591}
592
593impl<'a, T: Type, C: Color> std::ops::Rem<T> for &'a Pixel<C> {
594    type Output = Pixel<C>;
595
596    fn rem(self, other: T) -> Pixel<C> {
597        let mut dest = self.clone();
598        dest.map(|x| x % other.to_norm());
599        dest
600    }
601}
602
603impl<'a, C: Color> std::ops::Rem<&'a Pixel<C>> for &'a Pixel<C> {
604    type Output = Pixel<C>;
605
606    fn rem(self, other: &'a Pixel<C>) -> Pixel<C> {
607        let mut dest = self.clone();
608        dest.map2(other, |x, y| x % y);
609        dest
610    }
611}
612
613impl<'a, C: Color> std::ops::Rem<&'a Pixel<C>> for Pixel<C> {
614    type Output = Pixel<C>;
615
616    fn rem(mut self, other: &'a Pixel<C>) -> Pixel<C> {
617        self.map2(other, |x, y| x % y);
618        self
619    }
620}
621
622impl<C: Color> std::ops::Rem<Pixel<C>> for Pixel<C> {
623    type Output = Pixel<C>;
624
625    fn rem(mut self, other: Pixel<C>) -> Pixel<C> {
626        self.map2(&other, |x, y| x % y);
627        self
628    }
629}
630
631impl<C: Color> std::ops::Rem<Pixel<C>> for f64 {
632    type Output = Pixel<C>;
633
634    fn rem(self, mut px: Pixel<C>) -> Pixel<C> {
635        px.map(|x| self % x);
636        px
637    }
638}
639
640impl<'a, C: Color> std::ops::Rem<&'a Pixel<C>> for f64 {
641    type Output = Pixel<C>;
642
643    fn rem(self, px: &'a Pixel<C>) -> Pixel<C> {
644        let mut px = px.clone();
645        px.map(|x| self % x);
646        px
647    }
648}
649
650impl<T: Type, C: Color> std::ops::AddAssign<T> for Pixel<C> {
651    fn add_assign(&mut self, other: T) {
652        self.map(|x| x + other.to_norm());
653    }
654}
655
656impl<C: Color> std::ops::AddAssign<Pixel<C>> for Pixel<C> {
657    fn add_assign(&mut self, other: Pixel<C>) {
658        self.map2(&other, |x, y| x + y);
659    }
660}
661
662impl<'a, C: Color> std::ops::AddAssign<&'a Pixel<C>> for Pixel<C> {
663    fn add_assign(&mut self, other: &'a Pixel<C>) {
664        self.map2(other, |x, y| x + y);
665    }
666}
667
668impl<T: Type, C: Color> std::ops::SubAssign<T> for Pixel<C> {
669    fn sub_assign(&mut self, other: T) {
670        self.map(|x| x - other.to_norm());
671    }
672}
673
674impl<C: Color> std::ops::SubAssign<Pixel<C>> for Pixel<C> {
675    fn sub_assign(&mut self, other: Pixel<C>) {
676        self.map2(&other, |x, y| x - y);
677    }
678}
679
680impl<'a, C: Color> std::ops::SubAssign<&'a Pixel<C>> for Pixel<C> {
681    fn sub_assign(&mut self, other: &'a Pixel<C>) {
682        self.map2(other, |x, y| x - y);
683    }
684}
685
686impl<T: Type, C: Color> std::ops::MulAssign<T> for Pixel<C> {
687    fn mul_assign(&mut self, other: T) {
688        self.map(|x| x * other.to_norm());
689    }
690}
691
692impl<C: Color> std::ops::MulAssign<Pixel<C>> for Pixel<C> {
693    fn mul_assign(&mut self, other: Pixel<C>) {
694        self.map2(&other, |x, y| x * y);
695    }
696}
697
698impl<'a, C: Color> std::ops::MulAssign<&'a Pixel<C>> for Pixel<C> {
699    fn mul_assign(&mut self, other: &'a Pixel<C>) {
700        self.map2(other, |x, y| x * y);
701    }
702}
703
704impl<T: Type, C: Color> std::ops::DivAssign<T> for Pixel<C> {
705    fn div_assign(&mut self, other: T) {
706        self.map(|x| x / other.to_norm());
707    }
708}
709
710impl<C: Color> std::ops::DivAssign<Pixel<C>> for Pixel<C> {
711    fn div_assign(&mut self, other: Pixel<C>) {
712        self.map2(&other, |x, y| x / y);
713    }
714}
715
716impl<'a, C: Color> std::ops::DivAssign<&'a Pixel<C>> for Pixel<C> {
717    fn div_assign(&mut self, other: &'a Pixel<C>) {
718        self.map2(other, |x, y| x / y);
719    }
720}
721
722impl<T: Type, C: Color> std::ops::RemAssign<T> for Pixel<C> {
723    fn rem_assign(&mut self, other: T) {
724        self.map(|x| x % other.to_norm());
725    }
726}
727
728impl<C: Color> std::ops::RemAssign<Pixel<C>> for Pixel<C> {
729    fn rem_assign(&mut self, other: Pixel<C>) {
730        self.map2(&other, |x, y| x % y);
731    }
732}
733
734impl<'a, C: Color> std::ops::RemAssign<&'a Pixel<C>> for Pixel<C> {
735    fn rem_assign(&mut self, other: &'a Pixel<C>) {
736        self.map2(other, |x, y| x % y);
737    }
738}