color/
alpha.rs

1// Copyright 2013 The color-rs developers. For a full listing of the authors,
2// refer to the AUTHORS file at the top-level directory of this distribution.
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8//     http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16use 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    /// Clamps the components of the color to the range `(lo,hi)`.
41    #[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    /// Clamps the components of the color component-wise between `lo` and `hi`.
50    #[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    /// Inverts the color.
59    #[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}