1use crate::internal::pixel::*;
2use core::ops;
3use core::slice;
4
5#[repr(C)]
6#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
8/// RGB in reverse byte order
9pub struct BGR<ComponentType> {
10 /// Blue first
11 pub b: ComponentType,
12 /// Green
13 pub g: ComponentType,
14 /// Red last
15 pub r: ComponentType,
16}
17
18#[repr(C)]
19#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
20#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
21/// BGR+A
22pub struct BGRA<ComponentType, AlphaComponentType = ComponentType> {
23 /// Blue first
24 pub b: ComponentType,
25 /// Green
26 pub g: ComponentType,
27 /// Red
28 pub r: ComponentType,
29 /// Alpha last
30 pub a: AlphaComponentType,
31}
32
33#[cfg(feature = "argb")]
34#[repr(C)]
35#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
36#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
37/// A+BGR
38pub struct ABGR<ComponentType, AlphaComponentType = ComponentType> {
39 /// Alpha first
40 pub a: AlphaComponentType,
41 /// Blue
42 pub b: ComponentType,
43 /// Green
44 pub g: ComponentType,
45 /// Red last
46 pub r: ComponentType,
47}
48
49#[cfg(feature = "argb")]
50#[repr(C)]
51#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
52#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
53/// A+RGB
54pub struct ARGB<ComponentType, AlphaComponentType = ComponentType> {
55 /// Alpha first
56 pub a: AlphaComponentType,
57 /// Red
58 pub r: ComponentType,
59 /// Green
60 pub g: ComponentType,
61 /// Blue last
62 pub b: ComponentType,
63}
64
65/// 8-bit BGR
66pub type BGR8 = BGR<u8>;
67
68/// 16-bit BGR in machine's native endian
69pub type BGR16 = BGR<u16>;
70
71/// 8-bit BGRA
72pub type BGRA8 = BGRA<u8>;
73
74/// 8-bit ABGR, alpha is first. 0 = transparent, 255 = opaque.
75#[cfg(feature = "argb")]
76pub type ABGR8 = ABGR<u8>;
77
78/// 8-bit ARGB, alpha is first. 0 = transparent, 255 = opaque.
79#[cfg(feature = "argb")]
80pub type ARGB8 = ARGB<u8>;
81
82/// 16-bit BGR in machine's native endian
83pub type BGRA16 = BGRA<u16>;
84
85/// 16-bit ABGR in machine's native endian. 0 = transparent, 65535 = opaque.
86#[cfg(feature = "argb")]
87pub type ABGR16 = ABGR<u16>;
88
89/// 16-bit ARGB in machine's native endian. 0 = transparent, 65535 = opaque.
90#[cfg(feature = "argb")]
91pub type ARGB16 = ARGB<u16>;
92
93#[cfg(feature = "grb")]
94#[repr(C)]
95#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
96#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
97/// RGB with red-green swapped (may be useful for LEDs)
98pub struct GRB<ComponentType> {
99 /// Green first
100 pub g: ComponentType,
101 /// Red
102 pub r: ComponentType,
103 /// Blue last
104 pub b: ComponentType,
105}
106
107/// 8-bit GRB
108#[cfg(feature = "grb")]
109pub type GRB8 = GRB<u8>;
110
111////////////////////////////////////////
112
113#[repr(C)]
114#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
115#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
116/// Grayscale. Use `.0` or `*` (deref) to access the value.
117pub struct Gray<ComponentType>(
118 /// brightness level
119 pub ComponentType,
120);
121
122#[repr(C)]
123#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
124#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
125/// Grayscale with alpha. Use `.0`/`.1` to access.
126pub struct GrayAlpha<ComponentType, AlphaComponentType = ComponentType>(
127 /// brightness level
128 pub ComponentType,
129 /// alpha
130 pub AlphaComponentType,
131);
132
133#[cfg(feature = "as-bytes")]
134unsafe impl<T> crate::Pod for Gray<T> where T: crate::Pod {}
135#[cfg(feature = "as-bytes")]
136unsafe impl<T, A> crate::Pod for GrayAlpha<T, A> where T: crate::Pod, A: crate::Pod {}
137#[cfg(feature = "as-bytes")]
138unsafe impl<T> crate::Zeroable for Gray<T> where T: crate::Zeroable {}
139#[cfg(feature = "as-bytes")]
140unsafe impl<T, A> crate::Zeroable for GrayAlpha<T, A> where T: crate::Zeroable, A: crate::Zeroable {}
141
142/// 8-bit gray
143pub type GRAY8 = Gray<u8>;
144
145/// 16-bit gray in machine's native endian
146pub type GRAY16 = Gray<u16>;
147
148/// 8-bit gray with alpha in machine's native endian
149pub type GRAYA8 = GrayAlpha<u8>;
150
151/// 16-bit gray with alpha in machine's native endian
152pub type GRAYA16 = GrayAlpha<u16>;
153
154impl<T> Gray<T> {
155 /// New grayscale pixel
156 #[inline(always)]
157 pub const fn new(brightness: T) -> Self {
158 Self(brightness)
159 }
160}
161
162impl<T> ops::Deref for Gray<T> {
163 type Target = T;
164 #[inline(always)]
165 fn deref(&self) -> &T {
166 &self.0
167 }
168}
169
170impl<T: Copy> From<T> for Gray<T> {
171 #[inline(always)]
172 fn from(component: T) -> Self {
173 Gray(component)
174 }
175}
176
177impl<T: Clone, A> GrayAlpha<T, A> {
178 /// Copy `Gray` component out of the `GrayAlpha` struct
179 #[inline(always)]
180 pub fn gray(&self) -> Gray<T> {
181 Gray(self.0.clone())
182 }
183}
184
185impl<T, A> GrayAlpha<T, A> {
186 /// New grayscale+alpha pixel
187 #[inline(always)]
188 pub const fn new(brightness: T, alpha: A) -> Self {
189 Self(brightness, alpha)
190 }
191
192 /// Provide a mutable view of only `Gray` component (leaving out alpha).
193 #[inline(always)]
194 pub fn gray_mut(&mut self) -> &mut Gray<T> {
195 unsafe {
196 &mut *(self as *mut _ as *mut _)
197 }
198 }
199}
200
201impl<T: Copy, A: Clone> GrayAlpha<T, A> {
202 /// Create a new `GrayAlpha` with the new alpha value, but same gray value
203 #[inline(always)]
204 pub fn alpha(&self, a: A) -> Self {
205 Self(self.0, a)
206 }
207
208 /// Create a new `GrayAlpha` with a new alpha value created by the callback.
209 #[inline(always)]
210 pub fn map_alpha<F, B>(&self, f: F) -> GrayAlpha<T, B>
211 where F: FnOnce(A) -> B
212 {
213 GrayAlpha (self.0, f(self.1.clone()))
214 }
215
216 /// Create new `GrayAlpha` with the same alpha value, but different `Gray` value
217 #[inline(always)]
218 pub fn map_gray<F, U, B>(&self, f: F) -> GrayAlpha<U, B>
219 where F: FnOnce(T) -> U, U: Clone, B: From<A> + Clone {
220 GrayAlpha(f(self.0), self.1.clone().into())
221 }
222}
223
224impl<T: Copy, B> ComponentMap<Gray<B>, T, B> for Gray<T> {
225 #[inline(always)]
226 fn map<F>(&self, mut f: F) -> Gray<B> where F: FnMut(T) -> B {
227 Gray(f(self.0))
228 }
229}
230
231impl<T: Copy, B> ColorComponentMap<Gray<B>, T, B> for Gray<T> {
232 #[inline(always)]
233 fn map_c<F>(&self, mut f: F) -> Gray<B> where F: FnMut(T) -> B {
234 Gray(f(self.0))
235 }
236}
237
238impl<T: Copy, B> ComponentMap<GrayAlpha<B>, T, B> for GrayAlpha<T> {
239 #[inline(always)]
240 fn map<F>(&self, mut f: F) -> GrayAlpha<B>
241 where
242 F: FnMut(T) -> B,
243 {
244 GrayAlpha(f(self.0), f(self.1))
245 }
246}
247
248impl<T: Copy, A: Copy, B> ColorComponentMap<GrayAlpha<B, A>, T, B> for GrayAlpha<T, A> {
249 #[inline(always)]
250 fn map_c<F>(&self, mut f: F) -> GrayAlpha<B, A>
251 where
252 F: FnMut(T) -> B,
253 {
254 GrayAlpha(f(self.0), self.1)
255 }
256}
257
258impl<T> ComponentSlice<T> for GrayAlpha<T> {
259 #[inline(always)]
260 fn as_slice(&self) -> &[T] {
261 unsafe {
262 slice::from_raw_parts(self as *const Self as *const T, len:2)
263 }
264 }
265
266 #[inline(always)]
267 fn as_mut_slice(&mut self) -> &mut [T] {
268 unsafe {
269 slice::from_raw_parts_mut(self as *mut Self as *mut T, len:2)
270 }
271 }
272}
273
274impl<T> ComponentSlice<T> for [GrayAlpha<T>] {
275 #[inline]
276 fn as_slice(&self) -> &[T] {
277 unsafe {
278 slice::from_raw_parts(self.as_ptr() as *const _, self.len() * 2)
279 }
280 }
281
282 #[inline]
283 fn as_mut_slice(&mut self) -> &mut [T] {
284 unsafe {
285 slice::from_raw_parts_mut(self.as_ptr() as *mut _, self.len() * 2)
286 }
287 }
288}
289
290#[cfg(feature = "as-bytes")]
291impl<T: crate::Pod> ComponentBytes<T> for [GrayAlpha<T>] {}
292
293impl<T> ComponentSlice<T> for Gray<T> {
294 #[inline(always)]
295 fn as_slice(&self) -> &[T] {
296 slice::from_ref(&self.0)
297 }
298
299 #[inline(always)]
300 fn as_mut_slice(&mut self) -> &mut [T] {
301 slice::from_mut(&mut self.0)
302 }
303}
304
305impl<T> ComponentSlice<T> for [Gray<T>] {
306 #[inline]
307 fn as_slice(&self) -> &[T] {
308 unsafe {
309 slice::from_raw_parts(self.as_ptr() as *const _, self.len())
310 }
311 }
312
313 #[inline]
314 fn as_mut_slice(&mut self) -> &mut [T] {
315 unsafe {
316 slice::from_raw_parts_mut(self.as_ptr() as *mut _, self.len())
317 }
318 }
319}
320
321#[cfg(feature = "as-bytes")]
322impl<T: crate::Pod> ComponentBytes<T> for [Gray<T>] {}
323
324/// Assumes 255 is opaque
325impl<T: Copy> From<Gray<T>> for GrayAlpha<T, u8> {
326 #[inline(always)]
327 fn from(other: Gray<T>) -> Self {
328 GrayAlpha(other.0, 0xFF)
329 }
330}
331
332/// Assumes 65535 is opaque
333impl<T: Copy> From<Gray<T>> for GrayAlpha<T, u16> {
334 #[inline(always)]
335 fn from(other: Gray<T>) -> Self {
336 GrayAlpha(other.0, 0xFFFF)
337 }
338}
339
340#[test]
341fn gray() {
342 let rgb: crate::RGB<_> = Gray(1).into();
343 assert_eq!(rgb.r, 1);
344 assert_eq!(rgb.g, 1);
345 assert_eq!(rgb.b, 1);
346
347 let rgba: crate::RGBA<_> = Gray(1u8).into();
348 assert_eq!(rgba.r, 1);
349 assert_eq!(rgba.g, 1);
350 assert_eq!(rgba.b, 1);
351 assert_eq!(rgba.a, 255);
352
353 let g: GRAY8 = 200.into();
354 let g = g.map(|c| c/2);
355 assert_eq!(110, *g + 10);
356 assert_eq!(110, 10 + Gray(100).as_ref());
357
358 let ga: GRAYA8 = GrayAlpha(1, 2);
359 assert_eq!(ga.gray(), Gray::new(1));
360 let mut g2 = ga.clone();
361 *g2.gray_mut() = Gray(3);
362 assert_eq!(g2.map_gray(|g| g+1), GRAYA8::new(4, 2));
363 assert_eq!(g2.map(|g| g+1), GrayAlpha(4, 3));
364 assert_eq!(g2.0, 3);
365 assert_eq!(g2.as_slice(), &[3, 2]);
366 assert_eq!(g2.as_mut_slice(), &[3, 2]);
367 assert_eq!(g2.alpha(13), GrayAlpha(3, 13));
368 assert_eq!(g2.map_alpha(|x| x+3), GrayAlpha(3, 5));
369
370 assert_eq!((&[Gray(1u16), Gray(2)][..]).as_slice(), &[1, 2]);
371 assert_eq!((&[GrayAlpha(1u16, 2), GrayAlpha(3, 4)][..]).as_slice(), &[1, 2, 3, 4]);
372
373 let rgba: crate::RGBA<_> = ga.into();
374 assert_eq!(rgba.r, 1);
375 assert_eq!(rgba.g, 1);
376 assert_eq!(rgba.b, 1);
377 assert_eq!(rgba.a, 2);
378
379 let ga: GRAYA16 = GrayAlpha(1,2);
380 let rgba: crate::RGBA<u16, u16> = ga.into();
381 assert_eq!(rgba.r, 1);
382 assert_eq!(rgba.g, 1);
383 assert_eq!(rgba.b, 1);
384 assert_eq!(rgba.a, 2);
385}
386
387