1use crate::{cast::ComponentOrder, rgb};
4
5#[derive(Copy, Clone, Debug, PartialEq, Eq)]
9pub struct Abgr;
10
11impl<S, T> ComponentOrder<rgb::Rgba<S, T>, [T; 4]> for Abgr {
12 #[inline]
13 fn pack(color: rgb::Rgba<S, T>) -> [T; 4] {
14 let [red, green, blue, alpha]: [T; 4] = color.into();
15 [alpha, blue, green, red]
16 }
17
18 #[inline]
19 fn unpack(packed: [T; 4]) -> rgb::Rgba<S, T> {
20 let [alpha, blue, green, red] = packed;
21 rgb::Rgba::new(red, green, blue, alpha)
22 }
23}
24
25#[derive(Copy, Clone, Debug, PartialEq, Eq)]
29pub struct Argb;
30
31impl<S, T> ComponentOrder<rgb::Rgba<S, T>, [T; 4]> for Argb {
32 #[inline]
33 fn pack(color: rgb::Rgba<S, T>) -> [T; 4] {
34 let [red, green, blue, alpha]: [T; 4] = color.into();
35 [alpha, red, green, blue]
36 }
37
38 #[inline]
39 fn unpack(packed: [T; 4]) -> rgb::Rgba<S, T> {
40 let [alpha, red, green, blue] = packed;
41 rgb::Rgba::new(red, green, blue, alpha)
42 }
43}
44
45#[derive(Copy, Clone, Debug, PartialEq, Eq)]
49pub struct Bgra;
50
51impl<S, T> ComponentOrder<rgb::Rgba<S, T>, [T; 4]> for Bgra {
52 #[inline]
53 fn pack(color: rgb::Rgba<S, T>) -> [T; 4] {
54 let [red, green, blue, alpha]: [T; 4] = color.into();
55 [blue, green, red, alpha]
56 }
57
58 #[inline]
59 fn unpack(packed: [T; 4]) -> rgb::Rgba<S, T> {
60 let [blue, green, red, alpha] = packed;
61 rgb::Rgba::new(red, green, blue, alpha)
62 }
63}
64
65#[derive(Copy, Clone, Debug, PartialEq, Eq)]
69pub struct Rgba;
70
71impl<S, T> ComponentOrder<rgb::Rgba<S, T>, [T; 4]> for Rgba {
72 #[inline]
73 fn pack(color: rgb::Rgba<S, T>) -> [T; 4] {
74 let [red, green, blue, alpha]: [T; 4] = color.into();
75 [red, green, blue, alpha]
76 }
77
78 #[inline]
79 fn unpack(packed: [T; 4]) -> rgb::Rgba<S, T> {
80 let [red, green, blue, alpha] = packed;
81 rgb::Rgba::new(red, green, blue, alpha)
82 }
83}
84
85#[cfg(feature = "approx")]
86#[cfg(test)]
87mod test {
88 use super::{Abgr, Argb, Bgra, Rgba};
89 use crate::{cast::Packed, Srgb, Srgba};
90
91 #[test]
92 fn rgba() {
93 let a1: Packed<Rgba, u32> = Srgb::new(0.5, 0.0, 0.0).into_format().into();
94 let a2: Packed<Rgba, u32> = Srgb::new(0.0, 1.0, 0.0).into_format().into();
95 let a3: Packed<Rgba, u32> = Srgb::new(0.0, 0.0, 0.5).into_format().into();
96 let x1: u32 = 0x8000_00FF;
97 let x2: u32 = 0x00FF_00FF;
98 let x3: u32 = 0x0000_80FF;
99 assert_eq!(a1.color, x1);
100 assert_eq!(a2.color, x2);
101 assert_eq!(a3.color, x3);
102
103 let unpacked: Srgb<u8> = Packed::<Rgba, u32>::from(0x80FF_80FF).into();
104 assert_relative_eq!(
105 Srgb::new(0.5, 1.0, 0.5),
106 unpacked.into_format(),
107 epsilon = 0.01
108 );
109
110 let b1: Packed<Rgba, u32> = Srgba::new(0.5, 0.0, 0.0, 0.0).into_format().into();
111 let b2: Packed<Rgba, u32> = Srgba::new(0.0, 1.0, 0.0, 0.0).into_format().into();
112 let b3: Packed<Rgba, u32> = Srgba::new(0.0, 0.0, 0.5, 0.0).into_format().into();
113 let b4: Packed<Rgba, u32> = Srgba::new(0.0, 0.0, 0.0, 1.0).into_format().into();
114 let y1: u32 = 0x8000_0000;
115 let y2: u32 = 0x00FF_0000;
116 let y3: u32 = 0x0000_8000;
117 let y4: u32 = 0x0000_00FF;
118 assert_eq!(b1.color, y1);
119 assert_eq!(b2.color, y2);
120 assert_eq!(b3.color, y3);
121 assert_eq!(b4.color, y4);
122
123 let unpacked: Srgba<u8> = Packed::<Rgba, u32>::from(0x80FF_80FF).into();
124 assert_relative_eq!(
125 Srgba::new(0.5, 1.0, 0.5, 1.0),
126 unpacked.into_format(),
127 epsilon = 0.01
128 );
129 }
130
131 #[test]
132 fn argb() {
133 let a1: Packed<Argb, u32> = Srgb::new(0.5, 0.0, 0.0).into_format().into();
134 let a2: Packed<Argb, u32> = Srgb::new(0.0, 1.0, 0.0).into_format().into();
135 let a3: Packed<Argb, u32> = Srgb::new(0.0, 0.0, 0.5).into_format().into();
136 let x1: u32 = 0xFF80_0000;
137 let x2: u32 = 0xFF00_FF00;
138 let x3: u32 = 0xFF00_0080;
139 assert_eq!(a1.color, x1);
140 assert_eq!(a2.color, x2);
141 assert_eq!(a3.color, x3);
142
143 let unpacked: Srgb<u8> = Packed::<Argb, u32>::from(0x80FF_80FF).into();
144 assert_relative_eq!(
145 Srgb::new(1.0, 0.5, 1.0),
146 unpacked.into_format(),
147 epsilon = 0.01
148 );
149
150 let b1: Packed<Argb, u32> = Srgba::new(0.5, 0.0, 0.0, 0.0).into_format().into();
151 let b2: Packed<Argb, u32> = Srgba::new(0.0, 1.0, 0.0, 0.0).into_format().into();
152 let b3: Packed<Argb, u32> = Srgba::new(0.0, 0.0, 0.5, 0.0).into_format().into();
153 let b4: Packed<Argb, u32> = Srgba::new(0.0, 0.0, 0.0, 1.0).into_format().into();
154 let y1: u32 = 0x0080_0000;
155 let y2: u32 = 0x0000_FF00;
156 let y3: u32 = 0x0000_0080;
157 let y4: u32 = 0xFF00_0000;
158 assert_eq!(b1.color, y1);
159 assert_eq!(b2.color, y2);
160 assert_eq!(b3.color, y3);
161 assert_eq!(b4.color, y4);
162
163 let unpacked: Srgba<u8> = Packed::<Argb, u32>::from(0x80FF_80FF).into();
164 assert_relative_eq!(
165 Srgba::new(1.0, 0.5, 1.0, 0.5),
166 unpacked.into_format(),
167 epsilon = 0.01
168 );
169 }
170
171 #[test]
172 fn bgra() {
173 let a1: Packed<Bgra, u32> = Srgb::new(0.5, 0.0, 0.0).into_format().into();
174 let a2: Packed<Bgra, u32> = Srgb::new(0.0, 1.0, 0.0).into_format().into();
175 let a3: Packed<Bgra, u32> = Srgb::new(0.0, 0.0, 0.5).into_format().into();
176 let x1: u32 = 0x0000_80FF;
177 let x2: u32 = 0x00FF_00FF;
178 let x3: u32 = 0x8000_00FF;
179 assert_eq!(a1.color, x1);
180 assert_eq!(a2.color, x2);
181 assert_eq!(a3.color, x3);
182
183 let unpacked: Srgb<u8> = Packed::<Bgra, u32>::from(0x80FF_FF80).into();
184 assert_relative_eq!(
185 Srgb::new(1.0, 1.0, 0.5),
186 unpacked.into_format(),
187 epsilon = 0.01
188 );
189
190 let b1: Packed<Bgra, u32> = Srgba::new(0.5, 0.0, 0.0, 0.0).into_format().into();
191 let b2: Packed<Bgra, u32> = Srgba::new(0.0, 1.0, 0.0, 0.0).into_format().into();
192 let b3: Packed<Bgra, u32> = Srgba::new(0.0, 0.0, 0.5, 0.0).into_format().into();
193 let b4: Packed<Bgra, u32> = Srgba::new(0.0, 0.0, 0.0, 1.0).into_format().into();
194 let y1: u32 = 0x0000_8000;
195 let y2: u32 = 0x00FF_0000;
196 let y3: u32 = 0x8000_0000;
197 let y4: u32 = 0x0000_00FF;
198 assert_eq!(b1.color, y1);
199 assert_eq!(b2.color, y2);
200 assert_eq!(b3.color, y3);
201 assert_eq!(b4.color, y4);
202
203 let unpacked: Srgba<u8> = Packed::<Bgra, u32>::from(0x80FF_FF80).into();
204 assert_relative_eq!(
205 Srgba::new(1.0, 1.0, 0.5, 0.5),
206 unpacked.into_format(),
207 epsilon = 0.01
208 );
209 }
210
211 #[test]
212 fn abgr() {
213 let a1: Packed<Abgr, u32> = Srgb::new(0.5, 0.0, 0.0).into_format().into();
214 let a2: Packed<Abgr, u32> = Srgb::new(0.0, 1.0, 0.0).into_format().into();
215 let a3: Packed<Abgr, u32> = Srgb::new(0.0, 0.0, 0.5).into_format().into();
216 let x1: u32 = 0xFF00_0080;
217 let x2: u32 = 0xFF00_FF00;
218 let x3: u32 = 0xFF80_0000;
219 assert_eq!(a1.color, x1);
220 assert_eq!(a2.color, x2);
221 assert_eq!(a3.color, x3);
222
223 let unpacked: Srgb<u8> = Packed::<Abgr, u32>::from(0x80FF_FF80).into();
224 assert_relative_eq!(
225 Srgb::new(0.5, 1.0, 1.0),
226 unpacked.into_format(),
227 epsilon = 0.01
228 );
229
230 let b1: Packed<Abgr, u32> = Srgba::new(0.5, 0.0, 0.0, 0.0).into_format().into();
231 let b2: Packed<Abgr, u32> = Srgba::new(0.0, 1.0, 0.0, 0.0).into_format().into();
232 let b3: Packed<Abgr, u32> = Srgba::new(0.0, 0.0, 0.5, 0.0).into_format().into();
233 let b4: Packed<Abgr, u32> = Srgba::new(0.0, 0.0, 0.0, 1.0).into_format().into();
234 let y1: u32 = 0x0000_0080;
235 let y2: u32 = 0x0000_FF00;
236 let y3: u32 = 0x0080_0000;
237 let y4: u32 = 0xFF00_0000;
238 assert_eq!(b1.color, y1);
239 assert_eq!(b2.color, y2);
240 assert_eq!(b3.color, y3);
241 assert_eq!(b4.color, y4);
242
243 let unpacked: Srgba<u8> = Packed::<Abgr, u32>::from(0x80FF_FF80).into();
244 assert_relative_eq!(
245 Srgba::new(0.5, 1.0, 1.0, 0.5),
246 unpacked.into_format(),
247 epsilon = 0.01
248 );
249 }
250
251 #[test]
252 fn u32_to_color() {
253 assert_eq!(0xFFFF_FF80, u32::from(Srgb::new(255u8, 255, 128)));
254 assert_eq!(0x7FFF_FF80, u32::from(Srgba::new(127u8, 255u8, 255, 128)));
255 }
256}