Skip to main content

colr_types/
layout.rs

1//! Channel layout types for RGB, luma, and YCbCr color models.
2
3use core::marker::PhantomData;
4
5use crate::{AlphaState, BackingStore, ChannelMap, Straight};
6
7// RGB layouts
8
9macro_rules! define_layout_4 {
10    ($name:ident, [$r:expr, $g:expr, $b:expr, $a:expr], $doc:literal) => {
11        #[doc = $doc]
12        #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
13        pub struct $name<A: AlphaState = Straight>(PhantomData<A>);
14        impl<A: AlphaState> BackingStore<[f32; 4]> for $name<A> {}
15        impl<A: AlphaState> BackingStore<[u8; 4]> for $name<A> {}
16        #[cfg(feature = "glam")]
17        impl<A: AlphaState> BackingStore<glam::Vec4> for $name<A> {}
18        impl<A: AlphaState> ChannelMap<4> for $name<A> {
19            const INDICES: [usize; 4] = [$r, $g, $b, $a];
20        }
21    };
22}
23
24macro_rules! define_layout_3 {
25    ($name:ident, [$r:expr, $g:expr, $b:expr], $doc:literal) => {
26        #[doc = $doc]
27        #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
28        pub struct $name;
29        impl BackingStore<[f32; 3]> for $name {}
30        impl BackingStore<[u8; 3]> for $name {}
31        #[cfg(feature = "glam")]
32        impl BackingStore<glam::Vec3> for $name {}
33        #[cfg(feature = "glam")]
34        impl BackingStore<glam::Vec3A> for $name {}
35        impl ChannelMap<3> for $name {
36            const INDICES: [usize; 3] = [$r, $g, $b];
37        }
38    };
39}
40
41define_layout_4!(Rgba, [0, 1, 2, 3], "RGBA layout. R=0 G=1 B=2 A=3.");
42define_layout_4!(Bgra, [2, 1, 0, 3], "BGRA layout. B=0 G=1 R=2 A=3.");
43define_layout_4!(Argb, [1, 2, 3, 0], "ARGB layout. A=0 R=1 G=2 B=3.");
44define_layout_4!(Abgr, [3, 2, 1, 0], "ABGR layout. A=0 B=1 G=2 R=3.");
45define_layout_3!(Rgb, [0, 1, 2], "RGB layout. R=0 G=1 B=2.");
46define_layout_3!(Bgr, [2, 1, 0], "BGR layout. B=0 G=1 R=2.");
47
48// Luma layout
49
50/// Marks a layout as valid for use with a luma color model.
51pub trait LumaLayout: 'static {}
52
53/// Two-channel luma+alpha layout, generic over AlphaState. Y=0 A=1.
54#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
55pub struct LumaA<A: AlphaState = Straight>(PhantomData<A>);
56
57impl<A: AlphaState> BackingStore<[f32; 2]> for LumaA<A> {}
58
59impl<A: AlphaState> ChannelMap<2> for LumaA<A> {
60    const INDICES: [usize; 2] = [0, 1];
61}
62
63impl<A: AlphaState> LumaLayout for LumaA<A> {}
64
65#[cfg(feature = "glam")]
66impl<A: AlphaState> BackingStore<glam::Vec2> for LumaA<A> {}
67
68// YCbCr layouts
69
70/// Marks a layout as valid for use with a YCbCr color model.
71pub trait YCbCrLayout: 'static {}
72
73macro_rules! define_ycbcr_layout {
74    ($name:ident, [$y:expr, $cb:expr, $cr:expr], $doc:literal) => {
75        #[doc = $doc]
76        #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
77        pub struct $name;
78        impl BackingStore<[f32; 3]> for $name {}
79        impl ChannelMap<3> for $name {
80            const INDICES: [usize; 3] = [$y, $cb, $cr];
81        }
82        impl YCbCrLayout for $name {}
83    };
84}
85
86define_ycbcr_layout!(Ycbcr, [0, 1, 2], "YCbCr layout. Y=0 Cb=1 Cr=2.");
87define_ycbcr_layout!(Ycrcb, [0, 2, 1], "YCrCb layout. Y=0 Cr=1 Cb=2.");