1use crate::chan::{Alpha, Channel, Gamma, Linear, Premultiplied};
8use crate::matte::Matte;
9use crate::ops::Blend;
10use crate::private::Sealed;
11use crate::rgb::Rgb;
12use crate::ColorModel;
13use std::any::TypeId;
14use std::fmt::Debug;
15use std::marker::PhantomData;
16
17pub trait Pixel: Clone + Copy + Debug + Default + PartialEq + Sealed {
54 type Chan: Channel;
56
57 type Model: ColorModel;
59
60 type Alpha: Alpha;
62
63 type Gamma: Gamma;
65
66 fn from_channels(ch: &[Self::Chan]) -> Self;
68
69 fn from_bit_depth<P>(p: P) -> Self
71 where
72 P: Pixel,
73 Self::Chan: From<P::Chan>;
74
75 fn channels(&self) -> &[Self::Chan];
77
78 fn channels_mut(&mut self) -> &mut [Self::Chan];
80
81 fn one(self) -> Self::Chan {
83 *self.channels().first().unwrap_or(&Self::Chan::MAX)
84 }
85
86 fn one_mut(&mut self) -> &mut Self::Chan {
88 &mut self.channels_mut()[0]
89 }
90
91 fn two(self) -> Self::Chan {
93 *self.channels().get(1).unwrap_or(&Self::Chan::MAX)
94 }
95
96 fn two_mut(&mut self) -> &mut Self::Chan {
98 &mut self.channels_mut()[1]
99 }
100
101 fn three(self) -> Self::Chan {
103 *self.channels().get(2).unwrap_or(&Self::Chan::MAX)
104 }
105
106 fn three_mut(&mut self) -> &mut Self::Chan {
108 &mut self.channels_mut()[2]
109 }
110
111 fn four(self) -> Self::Chan {
113 *self.channels().get(3).unwrap_or(&Self::Chan::MAX)
114 }
115
116 fn four_mut(&mut self) -> &mut Self::Chan {
118 &mut self.channels_mut()[3]
119 }
120
121 fn alpha(self) -> Self::Chan {
133 let chan = self.channels();
134 *chan.get(Self::Model::ALPHA).unwrap_or(&Self::Chan::MAX)
135 }
136
137 fn alpha_mut(&mut self) -> &mut Self::Chan {
154 let chan = self.channels_mut();
155 chan.get_mut(Self::Model::ALPHA).unwrap()
156 }
157
158 fn convert<D>(self) -> D
162 where
163 D: Pixel,
164 D::Chan: From<Self::Chan>,
165 {
166 if TypeId::of::<Self::Model>() == TypeId::of::<D::Model>() {
167 convert_same_model::<D, Self>(self)
168 } else {
169 convert_thru_rgba::<D, Self>(self)
170 }
171 }
172
173 fn copy_color(dst: &mut [Self], clr: &Self) {
175 for d in dst.iter_mut() {
176 *d = *clr;
177 }
178 }
179
180 fn copy_slice(dst: &mut [Self], src: &[Self]) {
182 for (d, s) in dst.iter_mut().zip(src) {
183 *d = *s;
184 }
185 }
186
187 fn composite_color<O>(dst: &mut [Self], clr: &Self, op: O)
189 where
190 Self: Pixel<Alpha = Premultiplied, Gamma = Linear>,
191 O: Blend,
192 {
193 for d in dst.iter_mut() {
194 d.composite_channels(clr, op);
195 }
196 }
197
198 fn composite_matte<M, O>(dst: &mut [Self], src: &[M], clr: &Self, op: O)
200 where
201 Self: Pixel<Alpha = Premultiplied, Gamma = Linear>,
202 M: Pixel<Chan = Self::Chan, Model = Matte, Gamma = Linear>,
203 O: Blend,
204 {
205 for (d, s) in dst.iter_mut().zip(src) {
206 d.composite_channels_alpha(clr, op, &s.alpha());
207 }
208 }
209
210 fn composite_slice<O>(dst: &mut [Self], src: &[Self], op: O)
212 where
213 Self: Pixel<Alpha = Premultiplied, Gamma = Linear>,
214 O: Blend,
215 {
216 for (d, s) in dst.iter_mut().zip(src) {
217 d.composite_channels(s, op);
218 }
219 }
220
221 fn composite_channels<O>(&mut self, src: &Self, op: O)
223 where
224 Self: Pixel<Alpha = Premultiplied, Gamma = Linear>,
225 O: Blend,
226 {
227 let da1 = Self::Chan::MAX - self.alpha();
228 let sa1 = Self::Chan::MAX - src.alpha();
229 let d_chan = &mut self.channels_mut()[Self::Model::CIRCULAR];
231 let s_chan = &src.channels()[Self::Model::CIRCULAR];
232 d_chan
233 .iter_mut()
234 .zip(s_chan)
235 .for_each(|(d, s)| circ_composite(d, da1, *s, sa1, op));
236 let d_chan = &mut self.channels_mut()[Self::Model::LINEAR];
238 let s_chan = &src.channels()[Self::Model::LINEAR];
239 d_chan
240 .iter_mut()
241 .zip(s_chan)
242 .for_each(|(d, s)| O::composite(d, da1, s, sa1));
243 O::composite(self.alpha_mut(), da1, &src.alpha(), sa1);
244 }
245
246 fn composite_channels_alpha<O>(
248 &mut self,
249 src: &Self,
250 op: O,
251 alpha: &Self::Chan,
252 ) where
253 Self: Pixel<Alpha = Premultiplied, Gamma = Linear>,
254 O: Blend,
255 {
256 let da1 = Self::Chan::MAX - self.alpha();
257 let sa1 = Self::Chan::MAX - *alpha;
258 let d_chan = &mut self.channels_mut()[Self::Model::CIRCULAR];
260 let s_chan = &src.channels()[Self::Model::CIRCULAR];
261 d_chan
262 .iter_mut()
263 .zip(s_chan)
264 .for_each(|(d, s)| circ_composite(d, da1, *s * *alpha, sa1, op));
265 let d_chan = &mut self.channels_mut()[Self::Model::LINEAR];
267 let s_chan = &src.channels()[Self::Model::LINEAR];
268 d_chan
269 .iter_mut()
270 .zip(s_chan)
271 .for_each(|(d, s)| O::composite(d, da1, &(*s * *alpha), sa1));
272 O::composite(self.alpha_mut(), da1, &(src.alpha() * *alpha), sa1);
273 }
274}
275
276#[inline]
278fn circ_composite<C, O>(d: &mut C, da1: C, mut s: C, sa1: C, _op: O)
279where
280 C: Channel,
281 O: Blend,
282{
283 let mut t = C::MIN;
286 O::composite(&mut t, da1, &(C::MAX - sa1), sa1);
287 let rotate = s.max(*d) - s.min(*d) > C::MID;
289 if rotate {
290 if s > *d {
291 s = s - C::MID;
292 *d = *d + C::MID;
293 } else {
294 s = s + C::MID;
295 *d = *d - C::MID;
296 }
297 }
298 *d = d.lerp(s, t);
300 if rotate {
302 if *d < C::MID {
303 *d = *d + C::MID;
304 } else {
305 *d = *d - C::MID;
306 }
307 }
308}
309
310pub type PixRgba<P> =
312 Pix4<<P as Pixel>::Chan, Rgb, <P as Pixel>::Alpha, <P as Pixel>::Gamma>;
313
314fn convert_same_model<D, S>(src: S) -> D
320where
321 D: Pixel,
322 S: Pixel,
323 D::Chan: From<S::Chan>,
324{
325 let mut dst = D::from_bit_depth(src);
326 if TypeId::of::<S::Alpha>() != TypeId::of::<D::Alpha>()
327 || TypeId::of::<S::Gamma>() != TypeId::of::<D::Gamma>()
328 {
329 let alpha = dst.alpha();
330 let channels = dst.channels_mut();
331 convert_alpha_gamma::<D, S>(channels, alpha);
332 }
333 dst
334}
335
336fn convert_alpha_gamma<D, S>(channels: &mut [D::Chan], alpha: D::Chan)
338where
339 D: Pixel,
340 S: Pixel,
341{
342 for c in channels[D::Model::LINEAR].iter_mut() {
343 *c = S::Gamma::to_linear(*c);
344 if TypeId::of::<S::Alpha>() != TypeId::of::<D::Alpha>() {
345 *c = S::Alpha::decode(*c, alpha);
346 *c = D::Alpha::encode(*c, alpha);
347 }
348 *c = D::Gamma::from_linear(*c);
349 }
350}
351
352fn convert_thru_rgba<D, S>(src: S) -> D
358where
359 D: Pixel,
360 S: Pixel,
361 D::Chan: From<S::Chan>,
362{
363 let rgba = S::Model::into_rgba::<S>(src);
364 let rgba = convert_same_model::<PixRgba<D>, PixRgba<S>>(rgba);
365 D::Model::from_rgba::<D>(rgba)
366}
367
368#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
374#[repr(C)]
375pub struct Pix1<C, M, A, G>
376where
377 C: Channel,
378 M: ColorModel,
379 A: Alpha,
380 G: Gamma,
381{
382 channels: [C; 1],
383 _model: PhantomData<M>,
384 _alpha: PhantomData<A>,
385 _gamma: PhantomData<G>,
386}
387
388impl<C, M, A, G> Pix1<C, M, A, G>
389where
390 C: Channel,
391 M: ColorModel,
392 A: Alpha,
393 G: Gamma,
394{
395 pub fn new<H>(one: H) -> Self
404 where
405 C: From<H>,
406 {
407 let channels = [C::from(one); 1];
408 Pix1 {
409 channels,
410 _model: PhantomData,
411 _alpha: PhantomData,
412 _gamma: PhantomData,
413 }
414 }
415}
416
417impl<C, M, A, G> Pixel for Pix1<C, M, A, G>
418where
419 C: Channel,
420 M: ColorModel,
421 A: Alpha,
422 G: Gamma,
423{
424 type Chan = C;
425 type Model = M;
426 type Alpha = A;
427 type Gamma = G;
428
429 fn from_channels(ch: &[C]) -> Self {
430 let one = ch[0];
431 Self::new::<C>(one)
432 }
433
434 fn from_bit_depth<P>(p: P) -> Self
435 where
436 P: Pixel,
437 Self::Chan: From<P::Chan>,
438 {
439 debug_assert_eq!(TypeId::of::<Self::Model>(), TypeId::of::<P::Model>());
440 let one = Self::Chan::from(p.one());
441 Self::new::<Self::Chan>(one)
442 }
443
444 fn channels(&self) -> &[Self::Chan] {
445 &self.channels
446 }
447
448 fn channels_mut(&mut self) -> &mut [Self::Chan] {
449 &mut self.channels
450 }
451}
452
453#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
459#[repr(C)]
460pub struct Pix2<C, M, A, G>
461where
462 C: Channel,
463 M: ColorModel,
464 A: Alpha,
465 G: Gamma,
466{
467 channels: [C; 2],
468 _model: PhantomData<M>,
469 _alpha: PhantomData<A>,
470 _gamma: PhantomData<G>,
471}
472
473impl<C, M, A, G> Pix2<C, M, A, G>
474where
475 C: Channel,
476 M: ColorModel,
477 A: Alpha,
478 G: Gamma,
479{
480 pub fn new<H>(one: H, two: H) -> Self
489 where
490 C: From<H>,
491 {
492 let one = C::from(one);
493 let two = C::from(two);
494 let channels = [one, two];
495 Pix2 {
496 channels,
497 _model: PhantomData,
498 _alpha: PhantomData,
499 _gamma: PhantomData,
500 }
501 }
502}
503
504impl<C, M, A, G> Pixel for Pix2<C, M, A, G>
505where
506 C: Channel,
507 M: ColorModel,
508 A: Alpha,
509 G: Gamma,
510{
511 type Chan = C;
512 type Model = M;
513 type Alpha = A;
514 type Gamma = G;
515
516 fn from_channels(ch: &[C]) -> Self {
517 let one = ch[0];
518 let two = ch[1];
519 Self::new::<C>(one, two)
520 }
521
522 fn from_bit_depth<P>(p: P) -> Self
523 where
524 P: Pixel,
525 Self::Chan: From<P::Chan>,
526 {
527 debug_assert_eq!(TypeId::of::<Self::Model>(), TypeId::of::<P::Model>());
528 let one = Self::Chan::from(p.one());
529 let two = Self::Chan::from(p.two());
530 Self::new::<Self::Chan>(one, two)
531 }
532
533 fn channels(&self) -> &[Self::Chan] {
534 &self.channels
535 }
536
537 fn channels_mut(&mut self) -> &mut [Self::Chan] {
538 &mut self.channels
539 }
540}
541
542#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
548#[repr(C)]
549pub struct Pix3<C, M, A, G>
550where
551 C: Channel,
552 M: ColorModel,
553 A: Alpha,
554 G: Gamma,
555{
556 channels: [C; 3],
557 _model: PhantomData<M>,
558 _alpha: PhantomData<A>,
559 _gamma: PhantomData<G>,
560}
561
562impl<C, M, A, G> Pix3<C, M, A, G>
563where
564 C: Channel,
565 M: ColorModel,
566 A: Alpha,
567 G: Gamma,
568{
569 pub fn new<H>(one: H, two: H, three: H) -> Self
578 where
579 C: From<H>,
580 {
581 let one = C::from(one);
582 let two = C::from(two);
583 let three = C::from(three);
584 let channels = [one, two, three];
585 Pix3 {
586 channels,
587 _model: PhantomData,
588 _alpha: PhantomData,
589 _gamma: PhantomData,
590 }
591 }
592}
593
594impl<C, M, A, G> Pixel for Pix3<C, M, A, G>
595where
596 C: Channel,
597 M: ColorModel,
598 A: Alpha,
599 G: Gamma,
600{
601 type Chan = C;
602 type Model = M;
603 type Alpha = A;
604 type Gamma = G;
605
606 fn from_channels(ch: &[C]) -> Self {
607 let one = ch[0];
608 let two = ch[1];
609 let three = ch[2];
610 Self::new::<C>(one, two, three)
611 }
612
613 fn from_bit_depth<P>(p: P) -> Self
614 where
615 P: Pixel,
616 Self::Chan: From<P::Chan>,
617 {
618 debug_assert_eq!(TypeId::of::<Self::Model>(), TypeId::of::<P::Model>());
619 let one = Self::Chan::from(p.one());
620 let two = Self::Chan::from(p.two());
621 let three = Self::Chan::from(p.three());
622 Self::new::<Self::Chan>(one, two, three)
623 }
624
625 fn channels(&self) -> &[Self::Chan] {
626 &self.channels
627 }
628
629 fn channels_mut(&mut self) -> &mut [Self::Chan] {
630 &mut self.channels
631 }
632}
633
634#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
640#[repr(C)]
641pub struct Pix4<C, M, A, G>
642where
643 C: Channel,
644 M: ColorModel,
645 A: Alpha,
646 G: Gamma,
647{
648 channels: [C; 4],
649 _model: PhantomData<M>,
650 _alpha: PhantomData<A>,
651 _gamma: PhantomData<G>,
652}
653
654impl<C, M, A, G> Pix4<C, M, A, G>
655where
656 C: Channel,
657 M: ColorModel,
658 A: Alpha,
659 G: Gamma,
660{
661 pub fn new<H>(one: H, two: H, three: H, four: H) -> Self
670 where
671 C: From<H>,
672 {
673 let one = C::from(one);
674 let two = C::from(two);
675 let three = C::from(three);
676 let four = C::from(four);
677 let channels = [one, two, three, four];
678 Pix4 {
679 channels,
680 _model: PhantomData,
681 _alpha: PhantomData,
682 _gamma: PhantomData,
683 }
684 }
685}
686
687impl<C, M, A, G> Pixel for Pix4<C, M, A, G>
688where
689 C: Channel,
690 M: ColorModel,
691 A: Alpha,
692 G: Gamma,
693{
694 type Chan = C;
695 type Model = M;
696 type Alpha = A;
697 type Gamma = G;
698
699 fn from_channels(ch: &[C]) -> Self {
700 let one = ch[0];
701 let two = ch[1];
702 let three = ch[2];
703 let four = ch[3];
704 Self::new::<C>(one, two, three, four)
705 }
706
707 fn from_bit_depth<P>(p: P) -> Self
708 where
709 P: Pixel,
710 Self::Chan: From<P::Chan>,
711 {
712 debug_assert_eq!(TypeId::of::<Self::Model>(), TypeId::of::<P::Model>());
713 let one = Self::Chan::from(p.one());
714 let two = Self::Chan::from(p.two());
715 let three = Self::Chan::from(p.three());
716 let four = Self::Chan::from(p.four());
717 Self::new::<Self::Chan>(one, two, three, four)
718 }
719
720 fn channels(&self) -> &[Self::Chan] {
721 &self.channels
722 }
723
724 fn channels_mut(&mut self) -> &mut [Self::Chan] {
725 &mut self.channels
726 }
727}
728
729#[cfg(test)]
730mod test {
731 use crate::el::*;
732 use crate::gray::*;
733 use crate::matte::*;
734 use crate::rgb::*;
735
736 #[test]
737 fn check_sizes() {
738 assert_eq!(std::mem::size_of::<Matte8>(), 1);
739 assert_eq!(std::mem::size_of::<Matte16>(), 2);
740 assert_eq!(std::mem::size_of::<Matte32>(), 4);
741 assert_eq!(std::mem::size_of::<SGray8>(), 1);
742 assert_eq!(std::mem::size_of::<SGray16>(), 2);
743 assert_eq!(std::mem::size_of::<SGray32>(), 4);
744 assert_eq!(std::mem::size_of::<SGraya8>(), 2);
745 assert_eq!(std::mem::size_of::<SGraya16>(), 4);
746 assert_eq!(std::mem::size_of::<SGraya32>(), 8);
747 assert_eq!(std::mem::size_of::<Rgb8>(), 3);
748 assert_eq!(std::mem::size_of::<Rgb16>(), 6);
749 assert_eq!(std::mem::size_of::<Rgb32>(), 12);
750 assert_eq!(std::mem::size_of::<Rgba8>(), 4);
751 assert_eq!(std::mem::size_of::<Rgba16>(), 8);
752 assert_eq!(std::mem::size_of::<Rgba32>(), 16);
753 }
754
755 #[test]
756 fn gray_to_rgb() {
757 assert_eq!(SRgb8::new(0xD9, 0xD9, 0xD9), SGray8::new(0xD9).convert(),);
758 assert_eq!(
759 SRgb8::new(0x33, 0x33, 0x33),
760 SGray16::new(0x337F).convert(),
761 );
762 assert_eq!(SRgb8::new(0x40, 0x40, 0x40), SGray32::new(0.25).convert(),);
763 assert_eq!(
764 SRgb16::new(0x2929, 0x2929, 0x2929),
765 SGray8::new(0x29).convert(),
766 );
767 assert_eq!(
768 SRgb16::new(0x5593, 0x5593, 0x5593),
769 SGray16::new(0x5593).convert(),
770 );
771 assert_eq!(
772 SRgb16::new(0xFFFF, 0xFFFF, 0xFFFF),
773 SGray32::new(1.0).convert(),
774 );
775 assert_eq!(
776 SRgb32::new(0.5019608, 0.5019608, 0.5019608),
777 SGray8::new(0x80).convert(),
778 );
779 assert_eq!(
780 SRgb32::new(0.75001144, 0.75001144, 0.75001144),
781 SGray16::new(0xC000).convert(),
782 );
783 assert_eq!(SRgb32::new(0.33, 0.33, 0.33), SGray32::new(0.33).convert(),);
784 }
785
786 #[test]
787 fn linear_to_srgb() {
788 assert_eq!(
789 SRgb8::new(0xEF, 0x8C, 0xC7),
790 Rgb8::new(0xDC, 0x43, 0x91).convert()
791 );
792 assert_eq!(
793 SRgb8::new(0x66, 0xF4, 0xB5),
794 Rgb16::new(0x2205, 0xE699, 0x7654).convert()
795 );
796 assert_eq!(
797 SRgb8::new(0xBC, 0x89, 0xE0),
798 Rgb32::new(0.5, 0.25, 0.75).convert()
799 );
800 }
801
802 #[test]
803 fn srgb_to_linear() {
804 assert_eq!(
805 Rgb8::new(0xDC, 0x43, 0x92),
806 SRgb8::new(0xEF, 0x8C, 0xC7).convert(),
807 );
808 assert_eq!(
809 Rgb8::new(0x22, 0xE7, 0x76),
810 SRgb16::new(0x6673, 0xF453, 0xB593).convert(),
811 );
812 assert_eq!(
813 Rgb8::new(0x37, 0x0D, 0x85),
814 SRgb32::new(0.5, 0.25, 0.75).convert(),
815 );
816 }
817
818 #[test]
819 fn straight_to_premultiplied() {
820 assert_eq!(
821 Rgba8p::new(0x10, 0x20, 0x40, 0x80),
822 Rgba8::new(0x20, 0x40, 0x80, 0x80).convert(),
823 );
824 assert_eq!(
825 Rgba8p::new(0x04, 0x10, 0x20, 0x40),
826 Rgba16::new(0x1000, 0x4000, 0x8000, 0x4000).convert(),
827 );
828 assert_eq!(
829 Rgba8p::new(0x60, 0xBF, 0x8F, 0xBF),
830 Rgba32::new(0.5, 1.0, 0.75, 0.75).convert(),
831 );
832 }
833
834 #[test]
835 fn premultiplied_to_straight() {
836 assert_eq!(
837 Rgba8::new(0x40, 0x80, 0xFF, 0x80),
838 Rgba8p::new(0x20, 0x40, 0x80, 0x80).convert(),
839 );
840 assert_eq!(
841 Rgba8::new(0x40, 0xFF, 0x80, 0x40),
842 Rgba16p::new(0x1000, 0x4000, 0x2000, 0x4000).convert(),
843 );
844 assert_eq!(
845 Rgba8::new(0xAB, 0x55, 0xFF, 0xBF),
846 Rgba32p::new(0.5, 0.25, 0.75, 0.75).convert(),
847 );
848 }
849
850 #[test]
851 fn straight_to_premultiplied_srgb() {
852 assert_eq!(
853 SRgba8p::new(0x16, 0x2A, 0x5C, 0x80),
854 SRgba8::new(0x20, 0x40, 0x80, 0x80).convert(),
855 );
856 assert_eq!(
857 SRgba8p::new(0x0D, 0x1C, 0x40, 0x40),
858 SRgba16::new(0x2000, 0x4000, 0x8000, 0x4000).convert(),
859 );
860 assert_eq!(
861 SRgba8p::new(0x70, 0xE0, 0xA7, 0xBF),
862 SRgba32::new(0.5, 1.0, 0.75, 0.75).convert(),
863 );
864 }
865}