1use std::{borrow::{Borrow, BorrowMut}, ops::{Mul, Div, Add, Sub, Index, IndexMut}};
17use color_space::TransferFunction;
18use num_traits::Saturating;
19use std::mem;
20use {Color, Channel};
21use {Rgb, Rg, ToRgb, Hsv, YCbCr};
22use color_space::{Srgb, LinearRgb};
23use luma::{Luma, ToLuma};
24
25#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Debug)]
26pub struct AlphaColor<T, C> { pub c: C, pub a: T }
27
28pub type Rgba<T = u8, S = Srgb> = AlphaColor<T, Rgb<T,S>>;
29pub type LumaA<T = f32, S = Srgb> = AlphaColor<T, Luma<T,S>>;
30pub type Hsva<T = f32, S = Srgb> = AlphaColor<T, Hsv<T,S>>;
31pub type YCbCra<T> = AlphaColor<T, YCbCr<T>>;
32
33impl<T, C> AlphaColor<T, C>{
34 pub const fn new(c: C, a: T) -> AlphaColor<T,C>{
35 AlphaColor{c, a}
36 }
37}
38
39impl<T: Channel, C: Color<T>> Color<T> for AlphaColor<T, C> {
40 #[inline]
42 fn clamp_s(self, lo: T, hi: T) -> AlphaColor<T, C> {
43 AlphaColor {
44 c: self.c.clamp_s(lo, hi),
45 a: self.a.clamp(lo, hi),
46 }
47 }
48
49 #[inline]
51 fn clamp_c(self, lo: AlphaColor<T, C>, hi: AlphaColor<T, C>) -> AlphaColor<T, C> {
52 AlphaColor {
53 c: self.c.clamp_c(lo.c, hi.c),
54 a: self.a.clamp(lo.a, hi.a),
55 }
56 }
57
58 #[inline]
60 fn inverse(self) -> AlphaColor<T, C> {
61 AlphaColor {
62 c: self.c.inverse(),
63 a: self.a.invert_channel(),
64 }
65 }
66
67 #[inline]
68 fn mix(self, other: Self, value: T) -> Self {
69 AlphaColor {
70 c: self.c.mix(other.c, value),
71 a: self.a.mix(other.a, value)
72 }
73 }
74}
75
76#[macro_export]
77macro_rules! rgba{
78 ( $r: expr, $g: expr, $b: expr, $a: expr ) => ({
79 use $crate::{Rgba, Rgb};
80 Rgba{ c: Rgb::<_,$crate::color_space::Srgb>::new($r, $g, $b), a: $a }
81 });
82 ( $to_rgb: expr, $a: expr ) => ({
83 use $crate::{Rgba,ToRgb};
84 Rgba{ c: $to_rgb.to_rgb(), a: $a }
85 });
86}
87
88#[macro_export]
89macro_rules! rgba_linear{
90 ( $r: expr, $g: expr, $b: expr, $a: expr ) => ({
91 use $crate::{Rgba, Rgb};
92 Rgba{ c: Rgb::<_,$crate::color_space::LinearRgb>::new($r, $g, $b), a: $a }
93 });
94 ( $to_rgb: expr, $a: expr ) => ({
95 use $crate::{Rgba,ToRgb};
96 Rgba{ c: $to_rgb.to_rgb().to_linear(), a: $a }
97 });
98}
99
100impl<T:Channel, S: TransferFunction> Rgba<T, S> {
101 pub fn from_hex(hex: u32) -> Rgba<T, S> {
102 let r = hex >> 24 & 0xFF;
103 let g = hex >> 16 & 0xFF;
104 let b = hex >> 8 & 0xFF;
105 let a = hex & 0xFF;
106 Rgba{c: Rgb::new(r as u8, g as u8, b as u8), a: a as u8}.to_rgba()
107 }
108
109 #[inline]
110 pub fn rg(&self) -> Rg<T, S> {
111 self.c.rg()
112 }
113
114 #[inline]
115 pub fn rb(&self) -> Rg<T, S> {
116 self.c.rb()
117 }
118
119 #[inline]
120 pub fn gr(&self) -> Rg<T, S> {
121 self.c.gr()
122 }
123
124 #[inline]
125 pub fn gb(&self) -> Rg<T, S> {
126 self.c.gb()
127 }
128
129 #[inline]
130 pub fn br(&self) -> Rg<T, S> {
131 self.c.br()
132 }
133
134 #[inline]
135 pub fn bg(&self) -> Rg<T, S> {
136 self.c.bg()
137 }
138
139 #[inline]
140 pub fn ar(&self) -> Rg<T, S> {
141 Rg::new(self.a, self.c.r)
142 }
143
144 #[inline]
145 pub fn ag(&self) -> Rg<T, S> {
146 Rg::new(self.a, self.c.g)
147 }
148
149 #[inline]
150 pub fn ab(&self) -> Rg<T, S> {
151 Rg::new(self.a, self.c.b)
152 }
153
154 #[inline]
155 pub fn ra(&self) -> Rg<T, S> {
156 Rg::new(self.c.r, self.a)
157 }
158
159 #[inline]
160 pub fn ga(&self) -> Rg<T, S> {
161 Rg::new(self.c.g, self.a)
162 }
163
164 #[inline]
165 pub fn ba(&self) -> Rg<T, S> {
166 Rg::new(self.c.b, self.a)
167 }
168
169 #[inline]
170 pub fn rgb(&self) -> Rgb<T, S> {
171 self.c.rgb()
172 }
173
174 #[inline]
175 pub fn rbg(&self) -> Rgb<T, S> {
176 self.c.rbg()
177 }
178
179 #[inline]
180 pub fn bgr(&self) -> Rgb<T, S> {
181 self.c.bgr()
182 }
183
184 #[inline]
185 pub fn brg(&self) -> Rgb<T, S> {
186 self.c.brg()
187 }
188
189 #[inline]
190 pub fn grb(&self) -> Rgb<T, S> {
191 self.c.grb()
192 }
193
194 #[inline]
195 pub fn gbr(&self) -> Rgb<T, S> {
196 self.c.gbr()
197 }
198
199 #[inline]
200 pub fn rga(&self) -> Rgb<T, S> {
201 Rgb::new(self.c.r,self.c.g,self.a)
202 }
203
204 #[inline]
205 pub fn rba(&self) -> Rgb<T, S> {
206 Rgb::new(self.c.r,self.c.b,self.a)
207 }
208
209 #[inline]
210 pub fn bra(&self) -> Rgb<T, S> {
211 Rgb::new(self.c.b,self.c.r,self.a)
212 }
213
214 #[inline]
215 pub fn bga(&self) -> Rgb<T, S> {
216 Rgb::new(self.c.b,self.c.g,self.a)
217 }
218
219 #[inline]
220 pub fn gra(&self) -> Rgb<T, S> {
221 Rgb::new(self.c.g,self.c.r,self.a)
222 }
223
224 #[inline]
225 pub fn gba(&self) -> Rgb<T, S> {
226 Rgb::new(self.c.g,self.c.b,self.a)
227 }
228
229 #[inline]
230 pub fn arg(&self) -> Rgb<T, S> {
231 Rgb::new(self.a,self.c.r,self.c.g)
232 }
233
234 #[inline]
235 pub fn arb(&self) -> Rgb<T, S> {
236 Rgb::new(self.a,self.c.r,self.c.b)
237 }
238
239 #[inline]
240 pub fn agr(&self) -> Rgb<T, S> {
241 Rgb::new(self.a,self.c.g,self.c.r)
242 }
243
244 #[inline]
245 pub fn agb(&self) -> Rgb<T, S> {
246 Rgb::new(self.a,self.c.g,self.c.b)
247 }
248
249 #[inline]
250 pub fn abr(&self) -> Rgb<T, S> {
251 Rgb::new(self.a,self.c.b,self.c.r)
252 }
253
254 #[inline]
255 pub fn abg(&self) -> Rgb<T, S> {
256 Rgb::new(self.a,self.c.b,self.c.g)
257 }
258
259 #[inline]
260 pub fn rag(&self) -> Rgb<T, S> {
261 Rgb::new(self.c.r,self.a,self.c.g)
262 }
263
264 #[inline]
265 pub fn rab(&self) -> Rgb<T, S> {
266 Rgb::new(self.c.r,self.a,self.c.b)
267 }
268
269 #[inline]
270 pub fn gar(&self) -> Rgb<T, S> {
271 Rgb::new(self.c.g,self.a,self.c.r)
272 }
273
274 #[inline]
275 pub fn gab(&self) -> Rgb<T, S> {
276 Rgb::new(self.c.g,self.a,self.c.b)
277 }
278
279 #[inline]
280 pub fn bar(&self) -> Rgb<T, S> {
281 Rgb::new(self.c.b,self.a,self.c.r)
282 }
283
284 #[inline]
285 pub fn bag(&self) -> Rgb<T, S> {
286 Rgb::new(self.c.b,self.a,self.c.g)
287 }
288
289 #[inline]
290 pub fn rgba(&self) -> Rgba<T, S> {
291 rgba!(self.c, self.a)
292 }
293
294 #[inline]
295 pub fn rbga(&self) -> Rgba<T, S> {
296 Rgba::new(Rgb::new(self.c.r, self.c.b, self.c.g), self.a)
297 }
298
299 #[inline]
300 pub fn grba(&self) -> Rgba<T, S> {
301 Rgba::new(Rgb::new(self.c.g, self.c.r, self.c.b), self.a)
302 }
303
304 #[inline]
305 pub fn gbra(&self) -> Rgba<T, S> {
306 Rgba::new(Rgb::new(self.c.g, self.c.b, self.c.r), self.a)
307 }
308
309 #[inline]
310 pub fn brga(&self) -> Rgba<T, S> {
311 Rgba::new(Rgb::new(self.c.b, self.c.r, self.c.g), self.a)
312 }
313
314 #[inline]
315 pub fn bgra(&self) -> Rgba<T, S> {
316 Rgba::new(Rgb::new(self.c.b, self.c.g, self.c.r), self.a)
317 }
318
319 #[inline]
320 pub fn argb(&self) -> Rgba<T, S> {
321 Rgba::new(Rgb::new(self.a, self.c.r, self.c.g), self.c.b)
322 }
323
324 #[inline]
325 pub fn arbg(&self) -> Rgba<T, S> {
326 Rgba::new(Rgb::new(self.a, self.c.r, self.c.b), self.c.g)
327 }
328
329 #[inline]
330 pub fn agrb(&self) -> Rgba<T, S> {
331 Rgba::new(Rgb::new(self.a, self.c.g, self.c.r), self.c.b)
332 }
333
334 #[inline]
335 pub fn agbr(&self) -> Rgba<T, S> {
336 Rgba::new(Rgb::new(self.a, self.c.g, self.c.b), self.c.r)
337 }
338
339 #[inline]
340 pub fn abrg(&self) -> Rgba<T, S> {
341 Rgba::new(Rgb::new(self.a, self.c.b, self.c.r), self.c.g)
342 }
343
344 #[inline]
345 pub fn abgr(&self) -> Rgba<T, S> {
346 Rgba::new(Rgb::new(self.a, self.c.b, self.c.g), self.c.r)
347 }
348
349 #[inline]
350 pub fn ragb(&self) -> Rgba<T, S> {
351 Rgba::new(Rgb::new(self.c.r, self.a, self.c.g), self.c.b)
352 }
353
354 #[inline]
355 pub fn rabg(&self) -> Rgba<T, S> {
356 Rgba::new(Rgb::new(self.c.r, self.a, self.c.b), self.c.g)
357 }
358
359 #[inline]
360 pub fn garb(&self) -> Rgba<T, S> {
361 Rgba::new(Rgb::new(self.c.g, self.a, self.c.r), self.c.b)
362 }
363
364 #[inline]
365 pub fn gabr(&self) -> Rgba<T, S> {
366 Rgba::new(Rgb::new(self.c.g, self.a, self.c.b), self.c.r)
367 }
368
369 #[inline]
370 pub fn barg(&self) -> Rgba<T, S> {
371 Rgba::new(Rgb::new(self.c.b, self.a, self.c.r), self.c.g)
372 }
373
374 #[inline]
375 pub fn bagr(&self) -> Rgba<T, S> {
376 Rgba::new(Rgb::new(self.c.b, self.a, self.c.g), self.c.r)
377 }
378
379 #[inline]
380 pub fn rgab(&self) -> Rgba<T, S> {
381 Rgba::new(Rgb::new(self.c.r, self.c.g, self.a), self.c.b)
382 }
383
384 #[inline]
385 pub fn rbag(&self) -> Rgba<T, S> {
386 Rgba::new(Rgb::new(self.c.r, self.c.b, self.a), self.c.g)
387 }
388
389 #[inline]
390 pub fn grab(&self) -> Rgba<T, S> {
391 Rgba::new(Rgb::new(self.c.g, self.c.r, self.a), self.c.b)
392 }
393
394 #[inline]
395 pub fn gbar(&self) -> Rgba<T, S> {
396 Rgba::new(Rgb::new(self.c.g, self.c.b, self.a), self.c.r)
397 }
398
399 #[inline]
400 pub fn brag(&self) -> Rgba<T, S> {
401 Rgba::new(Rgb::new(self.c.b, self.c.r, self.a), self.c.g)
402 }
403
404 #[inline]
405 pub fn bgar(&self) -> Rgba<T, S> {
406 Rgba::new(Rgb::new(self.c.b, self.c.g, self.a), self.c.r)
407 }
408}
409
410impl<T: Channel, S: TransferFunction> Rgba<T, S> {
411 pub fn to_standard<S2: TransferFunction>(&self) -> Rgba<T, S2>{
412 let c = self.c.to_standard();
413 Rgba{c, a: self.a}
414 }
415
416 pub fn to_linear(&self) -> Rgba<T, LinearRgb>{
417 let c = self.c.to_linear();
418 Rgba{c, a: self.a}
419 }
420}
421
422
423pub trait ToRgba{
424 type Standard: TransferFunction;
425 fn to_rgba<T: Channel>(&self) -> Rgba<T, Self::Standard>;
426}
427
428impl<T: Channel, C: ToRgb> ToRgba for AlphaColor<T,C>{
429 type Standard = <C as ToRgb>::Standard;
430 #[inline]
431 fn to_rgba<U: Channel>(&self) -> Rgba<U, Self::Standard>{
432 Rgba{c: self.c.to_rgb(), a: self.a.to_channel()}
433 }
434}
435
436impl<T, C: ToRgb> ToRgb for AlphaColor<T, C> {
437 type Standard = <C as ToRgb>::Standard;
438 #[inline]
439 fn to_rgb<U:Channel>(&self) -> Rgb<U, Self::Standard> {
440 self.c.to_rgb()
441 }
442}
443
444impl<T, C: ToLuma> ToLuma for AlphaColor<T, C> {
445 type Standard = <C as ToLuma>::Standard;
446 #[inline]
447 fn to_luma<U:Channel>(&self) -> Luma<U, Self::Standard> {
448 self.c.to_luma()
449 }
450}
451
452impl<T:Channel, C: Mul<Output=C>> Mul for AlphaColor<T,C> {
453 type Output = AlphaColor<T,C>;
454
455 #[inline]
456 fn mul(self, rhs: AlphaColor<T,C>) -> AlphaColor<T,C> {
457 AlphaColor{ c: self.c.mul(rhs.c),
458 a: self.a.normalized_mul(rhs.a) }
459 }
460}
461
462impl<T:Channel + Mul<T,Output=T>, C: Mul<T,Output=C>> Mul<T> for AlphaColor<T,C> {
463 type Output = AlphaColor<T,C>;
464
465 #[inline]
466 fn mul(self, rhs: T) -> AlphaColor<T,C> {
467 let color = self.c * rhs;
468 AlphaColor{ c: color,
469 a: self.a * rhs }
470 }
471}
472
473impl<T:Channel, C: Div<Output=C>> Div for AlphaColor<T,C> {
474 type Output = AlphaColor<T,C>;
475
476 #[inline]
477 fn div(self, rhs: AlphaColor<T,C>) -> AlphaColor<T,C> {
478 AlphaColor{ c: self.c.div(rhs.c),
479 a: self.a.normalized_div(rhs.a) }
480 }
481}
482
483impl<T:Channel + Div<T,Output=T>, C: Div<T,Output=C>> Div<T> for AlphaColor<T,C> {
484 type Output = AlphaColor<T,C>;
485
486 #[inline]
487 fn div(self, rhs: T) -> AlphaColor<T,C> {
488 let color = self.c / rhs;
489 AlphaColor{ c: color,
490 a: self.a / rhs }
491 }
492}
493
494impl<T:Channel + Add<T,Output=T>, C: Add<Output=C>> Add for AlphaColor<T,C>{
495 type Output = AlphaColor<T,C>;
496
497 #[inline]
498 fn add(self, rhs: AlphaColor<T,C>) -> AlphaColor<T,C> {
499 AlphaColor{ c: self.c + rhs.c,
500 a: self.a + rhs.a }
501 }
502}
503
504impl<T:Channel + Sub<T,Output=T>, C: Sub<Output=C>> Sub for AlphaColor<T,C>{
505 type Output = AlphaColor<T,C>;
506
507 #[inline]
508 fn sub(self, rhs: AlphaColor<T,C>) -> AlphaColor<T,C> {
509 AlphaColor{ c: self.c - rhs.c,
510 a: self.a - rhs.a }
511 }
512}
513
514impl<T:Channel + Saturating, C: Saturating> Saturating for AlphaColor<T,C>{
515 fn saturating_add(self, v: AlphaColor<T,C>) -> AlphaColor<T,C> {
516 AlphaColor{ c: self.c.saturating_add(v.c),
517 a: self.a.saturating_add(v.a) }
518 }
519
520 fn saturating_sub(self, v: AlphaColor<T,C>) -> AlphaColor<T,C> {
521 AlphaColor{ c: self.c.saturating_sub(v.c),
522 a: self.a.saturating_sub(v.a) }
523 }
524}
525
526impl<T, C: AsRef<[T;3]>> Index<usize> for AlphaColor<T,C> {
527 type Output = T;
528 fn index<'a>(&'a self, index: usize) -> &'a T {
529 self.as_ref().index(index)
530 }
531}
532
533impl<T, C: AsRef<[T;3]> + AsMut<[T;3]>> IndexMut<usize> for AlphaColor<T,C> {
534 fn index_mut<'a>(&'a mut self, index: usize) -> &'a mut T {
535 self.as_mut().index_mut(index)
536 }
537}
538
539impl<T, C: AsRef<[T;3]>> AsRef<[T;4]> for AlphaColor<T,C> {
540 fn as_ref(&self) -> &[T;4] {
541 unsafe{ mem::transmute(self)}
542 }
543}
544
545impl<T, C: AsMut<[T;3]>> AsMut<[T;4]> for AlphaColor<T,C> {
546 fn as_mut(&mut self) -> &mut [T;4] {
547 unsafe{ mem::transmute(self)}
548 }
549}
550
551impl<T, C: Borrow<[T;3]>> Borrow<[T;4]> for AlphaColor<T,C> {
552 fn borrow(&self) -> &[T;4] {
553 unsafe{ mem::transmute(self)}
554 }
555}
556
557impl<T, C: BorrowMut<[T;3]>> BorrowMut<[T;4]> for AlphaColor<T,C> {
558 fn borrow_mut(&mut self) -> &mut [T;4] {
559 unsafe{ mem::transmute(self)}
560 }
561}