1use super::pixel::*;
2use crate::alt::*;
3use crate::{RGB, RGBA};
4use core::fmt;
5
6impl<T, A> RGBA<T, A> {
7 #[inline(always)]
8 pub const fn new_alpha(r: T, g: T, b: T, a: A) -> Self {
11 Self { r, g, b, a }
12 }
13}
14
15impl<T> BGRA<T> {
16 #[inline(always)]
17 #[deprecated(note = "This function has a misleading order of arguments. Use BGRA{} literal instead")]
20 pub const fn new(r: T, g: T, b: T, a: T) -> Self {
21 Self { b, g, r, a }
22 }
23}
24
25impl<T, A> BGRA<T, A> {
29 #[inline(always)]
30 #[deprecated(note = "This function has a misleading order of arguments. Use BGRA{} literal instead")]
33 pub const fn new_alpha(r: T, g: T, b: T, a: A) -> Self {
34 Self { b, g, r, a }
35 }
36}
37
38impl<T> ARGB<T> {
39 #[inline(always)]
40 #[deprecated(note = "This function has a misleading order of arguments. Use ARGB{} literal instead")]
43 pub const fn new(r: T, g: T, b: T, a: T) -> Self {
44 Self { r, g, b, a }
45 }
46}
47
48impl<T, A> ARGB<T, A> {
49 #[inline(always)]
50 #[deprecated(note = "This function has a misleading order of arguments. Use ARGB{} literal instead")]
53 pub const fn new_alpha(r: T, g: T, b: T, a: A) -> Self {
54 Self { r, g, b, a }
55 }
56}
57
58impl<T> ABGR<T> {
59 #[inline(always)]
60 #[deprecated(note = "This function has a misleading order of arguments. Use ABGR{} literal instead")]
63 pub const fn new(r: T, g: T, b: T, a: T) -> Self {
64 Self { r, g, b, a }
65 }
66}
67
68impl<T, A> ABGR<T, A> {
69 #[inline(always)]
70 #[deprecated(note = "This function has a misleading order of arguments. Use ABGR{} literal instead")]
73 pub const fn new_alpha(r: T, g: T, b: T, a: A) -> Self {
74 Self { r, g, b, a }
75 }
76}
77
78macro_rules! impl_rgba {
79 ($RGBA:ident) => {
80 impl<T: Clone> $RGBA<T> {
81 #[inline(always)]
83 pub fn iter(&self) -> core::iter::Cloned<core::slice::Iter<'_, T>> {
84 self.as_slice().iter().cloned()
85 }
86 }
87
88 impl<T: Clone, A> $RGBA<T, A> {
89 #[inline(always)]
93 pub fn bgr(&self) -> BGR<T> {
94 BGR {
95 r: self.r.clone(),
96 g: self.g.clone(),
97 b: self.b.clone(),
98 }
99 }
100 }
101
102 impl<T: Copy, A: Clone> $RGBA<T, A> {
103 #[deprecated(note = "Renamed to map_colors()")]
105 pub fn map_rgb<F, U, B>(&self, mut f: F) -> $RGBA<U, B>
106 where F: FnMut(T) -> U, U: Clone, B: From<A> + Clone
107 {
108 $RGBA {
109 r: f(self.r),
110 g: f(self.g),
111 b: f(self.b),
112 a: self.a.clone().into(),
113 }
114 }
115
116 #[doc(hidden)]
117 #[deprecated(note = "use .with_alpha(a) instead")]
118 pub fn alpha(&self, a: A) -> Self {
120 self.with_alpha(a)
121 }
122
123 #[inline(always)]
124 pub fn with_alpha(&self, a: A) -> Self {
126 Self { r: self.r, g: self.g, b: self.b, a }
127 }
128
129 #[inline]
132 pub fn map_alpha<F, B>(&self, f: F) -> $RGBA<T, B>
133 where F: FnOnce(A) -> B {
134 $RGBA {
135 r: self.r,
136 g: self.g,
137 b: self.b,
138 a: f(self.a.clone()),
139 }
140 }
141 }
142
143 impl<T: Copy, B> ComponentMap<$RGBA<B>, T, B> for $RGBA<T> {
144 #[inline(always)]
145 fn map<F>(&self, mut f: F) -> $RGBA<B>
146 where F: FnMut(T) -> B {
147 $RGBA {
148 r: f(self.r),
149 g: f(self.g),
150 b: f(self.b),
151 a: f(self.a),
152 }
153 }
154 }
155
156 impl<T: Copy, A: Copy, B> ColorComponentMap<$RGBA<B, A>, T, B> for $RGBA<T, A> {
157 #[inline(always)]
158 fn map_colors<F>(&self, mut f: F) -> $RGBA<B, A>
159 where F: FnMut(T) -> B {
160 $RGBA {
161 r: f(self.r),
162 g: f(self.g),
163 b: f(self.b),
164 a: self.a,
165 }
166 }
167 }
168
169 impl<T> ComponentSlice<T> for $RGBA<T> {
170 #[inline(always)]
171 fn as_slice(&self) -> &[T] {
172 unsafe {
173 core::slice::from_raw_parts(self as *const Self as *const T, 4)
174 }
175 }
176
177 #[inline(always)]
178 fn as_mut_slice(&mut self) -> &mut [T] {
179 unsafe {
180 core::slice::from_raw_parts_mut(self as *mut Self as *mut T, 4)
181 }
182 }
183 }
184
185 impl<T> ComponentSlice<T> for [$RGBA<T>] {
186 #[inline]
187 fn as_slice(&self) -> &[T] {
188 unsafe {
189 core::slice::from_raw_parts(self.as_ptr() as *const _, self.len() * 4)
190 }
191 }
192
193 #[inline]
194 fn as_mut_slice(&mut self) -> &mut [T] {
195 unsafe {
196 core::slice::from_raw_parts_mut(self.as_mut_ptr() as *mut _, self.len() * 4)
197 }
198 }
199 }
200
201 #[cfg(feature = "as-bytes")]
202 impl<T: crate::Pod> ComponentBytes<T> for [$RGBA<T>] {}
203 };
204}
205
206macro_rules! impl_alpha_conv {
207 ($RGB:ident, $RGBA:ident) => {
208 impl<T: Copy> From<$RGB<T>> for $RGBA<T, u8> {
210 #[inline(always)]
211 fn from(other: $RGB<T>) -> Self {
212 Self {
213 r: other.r,
214 g: other.g,
215 b: other.b,
216 a: 0xFF,
217 }
218 }
219 }
220
221 impl<T: Copy> From<$RGB<T>> for $RGBA<T, u16> {
223 #[inline(always)]
224 fn from(other: $RGB<T>) -> Self {
225 Self {
226 r: other.r,
227 g: other.g,
228 b: other.b,
229 a: 0xFFFF,
230 }
231 }
232 }
233 };
234}
235
236impl<T, A> RGBA<T, A> {
237 #[inline(always)]
240 pub fn rgb_mut(&mut self) -> &mut RGB<T> {
241 unsafe { &mut *(self as *mut _ as *mut RGB<T>) }
242 }
243}
244
245impl<T, A> BGRA<T, A> {
246 #[deprecated(note = "This function will change. Use bgr_mut()")]
249 pub fn rgb_mut(&mut self) -> &mut BGR<T> {
250 unsafe { &mut *(self as *mut _ as *mut BGR<T>) }
251 }
252
253 #[inline(always)]
256 pub fn bgr_mut(&mut self) -> &mut BGR<T> {
257 unsafe { &mut *(self as *mut _ as *mut BGR<T>) }
258 }
259}
260
261impl<T> core::iter::FromIterator<T> for RGBA<T> {
262 #[inline(always)]
263 fn from_iter<I: IntoIterator<Item = T>>(into_iter: I) -> Self {
266 let mut iter = into_iter.into_iter();
267 Self {
268 r: iter.next().unwrap(),
269 g: iter.next().unwrap(),
270 b: iter.next().unwrap(),
271 a: iter.next().unwrap(),
272 }
273 }
274}
275
276impl<T: Clone, A> RGBA<T, A> {
277 #[inline(always)]
281 pub fn rgb(&self) -> RGB<T> {
282 RGB {
283 r: self.r.clone(),
284 g: self.g.clone(),
285 b: self.b.clone(),
286 }
287 }
288}
289
290impl<T: Clone, A> ARGB<T, A> {
291 #[inline(always)]
295 pub fn rgb(&self) -> RGB<T> {
296 RGB {
297 r: self.r.clone(),
298 g: self.g.clone(),
299 b: self.b.clone(),
300 }
301 }
302}
303
304impl<T: Clone, A> BGRA<T, A> {
305 #[deprecated(note = "This function will change. Use bgr()")]
309 pub fn rgb(&self) -> BGR<T> {
310 BGR {
311 r: self.r.clone(),
312 g: self.g.clone(),
313 b: self.b.clone(),
314 }
315 }
316}
317
318impl_rgba! {RGBA}
319impl_rgba! {BGRA}
320impl_rgba! {ARGB}
321impl_rgba! {ABGR}
322
323impl_alpha_conv! {BGR, BGRA}
324impl_alpha_conv! {RGB, BGRA}
325impl_alpha_conv! {BGR, RGBA}
326impl_alpha_conv! {RGB, RGBA}
327impl_alpha_conv! {BGR, ABGR}
328impl_alpha_conv! {RGB, ABGR}
329impl_alpha_conv! {BGR, ARGB}
330impl_alpha_conv! {RGB, ARGB}
331
332impl<T: fmt::Display, A: fmt::Display> fmt::Display for RGBA<T, A> {
333 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
334 write!(f, "rgba({},{},{},{})", self.r, self.g, self.b, self.a)
335 }
336}
337
338impl<T: fmt::Display, A: fmt::Display> fmt::Display for BGRA<T, A> {
339 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
340 write!(f, "bgra({},{},{},{})", self.r, self.g, self.b, self.a)
341 }
342}
343
344#[test]
345fn rgba_test() {
346 let neg = RGBA::new(1,2,3i32,1000).map(|x| -x);
347 assert_eq!(neg.r, -1);
348 assert_eq!(neg.rgb().r, -1);
349 assert_eq!(neg.g, -2);
350 assert_eq!(neg.rgb().g, -2);
351 assert_eq!(neg.b, -3);
352 assert_eq!(neg.rgb().b, -3);
353 assert_eq!(neg.a, -1000);
354 assert_eq!(neg.map_alpha(|x| x+1).a, -999);
355 assert_eq!(neg, neg.as_slice().iter().copied().collect());
356 assert!(neg < RGBA::new(0,0,0,0));
357
358 let neg = RGBA::new(1u8,2,3,4).map_rgb(|c| -(c as i16));
359 assert_eq!(-1i16, neg.r);
360 assert_eq!(4i16, neg.a);
361 let neg = RGBA::new(1u8,2,3,4).map_colors(|c| -(c as i16));
362 assert_eq!(-1i16, neg.r);
363 assert_eq!(4u8, neg.a);
364
365 let mut px = RGBA{r:1,g:2,b:3,a:4};
366 px.as_mut_slice()[3] = 100;
367 assert_eq!(1, px.rgb_mut().r);
368 assert_eq!(2, px.rgb_mut().g);
369 px.rgb_mut().b = 4;
370 assert_eq!(4, px.rgb_mut().b);
371 assert_eq!(100, px.a);
372
373 #[cfg(feature = "as-bytes")]
374 {
375 let v = vec![RGBA::new(1u8,2,3,4), RGBA::new(5,6,7,8)];
376 assert_eq!(&[1,2,3,4,5,6,7,8], v.as_bytes());
377 }
378}
379
380#[test]
381#[cfg(feature = "as-bytes")]
382fn abgr_test() {
383 let abgr = ABGR {r:1,g:2,b:3,a:4};
384 assert_eq!(4, abgr.as_slice()[0]);
385 use crate::AsPixels;
386 assert_eq!(abgr, [abgr].as_bytes().as_pixels()[0]);
387}
388
389#[test]
390#[allow(deprecated)]
391fn bgra_test() {
392 let neg = BGRA::new(1, 2, 3i32, 1000).map(|x| -x);
393 let _ = neg.as_slice();
394
395 #[cfg(feature = "as-bytes")]
396 {
397 let _ = [neg].as_bytes();
398 }
399 assert_eq!(neg.r, -1);
400 assert_eq!(neg.bgr().r, -1);
401 assert_eq!(neg.g, -2);
402 assert_eq!(neg.bgr().g, -2);
403 assert_eq!(neg.b, -3);
404 assert_eq!(neg.bgr().b, -3);
405 assert_eq!(neg.a, -1000);
406 assert_eq!(&[-3,-2,-1,-1000], neg.as_slice());
407 assert!(neg < BGRA::new(0, 0, 0, 0));
408
409 let neg = BGRA::new(1u8, 2u8, 3u8, 4u8).map_rgb(|c| -(c as i16));
410 assert_eq!(-1i16, neg.r);
411 assert_eq!(4i16, neg.a);
412 #[allow(deprecated)]
413 let neg = BGRA::new(1u8, 2u8, 3u8, 4u8).map_c(|c| -(c as i16));
414 assert_eq!(-1i16, neg.r);
415 assert_eq!(4u8, neg.a);
416
417 let mut px = BGRA{r:1,g:2,b:3,a:-9}.alpha(4);
418 px.as_mut_slice()[3] = 100;
419 assert_eq!(1, px.bgr_mut().r);
420 assert_eq!(2, px.bgr_mut().g);
421 px.bgr_mut().b = 4;
422 assert_eq!(4, px.bgr_mut().b);
423 assert_eq!(100, px.a);
424
425
426 #[cfg(feature = "as-bytes")]
427 {
428 let v = vec![BGRA::new(3u8, 2, 1, 4), BGRA::new(7, 6, 5, 8)];
429 assert_eq!(&[1,2,3,4,5,6,7,8], v.as_bytes());
430 }
431}