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