devela/media/color/rgb/impls/
u8.rs1use crate::{Norm, Rgb8, Rgb16, Rgba8, Rgba16};
4#[cfg(doc)]
5use crate::{Rgb, Rgba};
6
7#[cfg(feature = "_float_f32")]
8use crate::{RgbF32, RgbaF32};
9#[cfg(feature = "_float_f64")]
10use crate::{RgbF64, RgbaF64};
11
12#[allow(missing_docs)]
13#[rustfmt::skip]
14impl Rgb8 {
15 pub const fn new(r: u8, g: u8, b: u8) -> Rgb8 { Self { c: [r, g, b] } }
17 pub const fn red(self) -> u8 { self.c[0] }
19 pub const fn r(self) -> u8 { self.c[0] }
20 pub const fn green(self) -> u8 { self.c[1] }
22 pub const fn g(self) -> u8 { self.c[1] }
23 pub const fn blue(self) -> u8 { self.c[2] }
25 pub const fn b(self) -> u8 { self.c[2] }
26}
27
28impl Rgb8 {
30 pub const fn from_array(c: [u8; 3]) -> Rgb8 {
32 Rgb8 { c }
33 }
34 pub const fn as_array(self) -> [u8; 3] {
36 self.c
37 }
38 pub const fn from_tuple(c: (u8, u8, u8)) -> Rgb8 {
40 Rgb8::new(c.0, c.1, c.2)
41 }
42 pub const fn to_tuple(self) -> (u8, u8, u8) {
44 (self.r(), self.g(), self.b())
45 }
46
47 pub const fn from_rgba8(c: Rgba8) -> Rgb8 {
53 Rgb8::new(c.r(), c.g(), c.b())
54 }
55 pub const fn to_rgba8(self, alpha: u8) -> Rgba8 {
59 Rgba8::new(self.r(), self.g(), self.b(), alpha)
60 }
61
62 pub const fn from_rgb8_packed(packed: u32) -> Rgb8 {
68 Rgb8::from_array([
69 ((packed >> 16) & 0xFF) as u8,
70 ((packed >> 8) & 0xFF) as u8,
71 (packed & 0xFF) as u8,
72 ])
73 }
74 pub const fn to_rgb8_packed(self) -> u32 {
76 ((self.r() as u32) << 16) | ((self.g() as u32) << 8) | (self.b() as u32)
77 }
78
79 pub const fn from_rgba8_packed(packed: u32) -> Rgb8 {
81 Rgb8::from_array([
82 ((packed >> 24) & 0xFF) as u8,
83 ((packed >> 16) & 0xFF) as u8,
84 ((packed >> 8) & 0xFF) as u8,
85 ])
86 }
87 pub const fn to_rgba8_packed(self, alpha: u8) -> u32 {
89 ((self.r() as u32) << 24)
90 | ((self.g() as u32) << 16)
91 | ((self.b() as u32) << 8)
92 | (alpha as u32)
93 }
94
95 pub fn from_rgb16(from: Rgb16) -> Rgb8 {
99 Rgb8::new(
100 ((from.c[0] + 128) / 257) as u8, ((from.c[1] + 128) / 257) as u8,
102 ((from.c[2] + 128) / 257) as u8,
103 )
104 }
105 pub fn to_rgb16(self) -> Rgb16 {
107 Rgb16::new(
108 (self.c[0] as u16) * 257, (self.c[1] as u16) * 257,
110 (self.c[2] as u16) * 257,
111 )
112 }
113}
114#[rustfmt::skip]
115impl From<Rgba8> for Rgb8 { fn from(from: Rgba8) -> Rgb8 { Rgb8::from_rgba8(from) } }
116#[rustfmt::skip]
117impl From<Rgb16> for Rgb8 { fn from(from: Rgb16) -> Rgb8 { Rgb8::from_rgb16(from) } }
118
119#[cfg(feature = "_float_f32")]
121#[cfg_attr(nightly_doc, doc(cfg(feature = "_float_f32")))]
122impl Rgb8 {
123 pub const fn from_rgb_f32(c: RgbF32) -> Rgb8 {
125 Rgb8::new(Norm::f32_to_u8(c.r()), Norm::f32_to_u8(c.g()), Norm::f32_to_u8(c.b()))
126 }
127 pub const fn to_rgb_f32(self) -> RgbF32 {
129 RgbF32::new(Norm::u8_to_f32(self.r()), Norm::u8_to_f32(self.g()), Norm::u8_to_f32(self.b()))
130 }
131
132 pub const fn from_rgba_f32(c: RgbaF32) -> Rgb8 {
136 Rgb8::new(Norm::f32_to_u8(c.r()), Norm::f32_to_u8(c.g()), Norm::f32_to_u8(c.b()))
137 }
138 pub const fn to_rgba_f32(self, alpha: u8) -> RgbaF32 {
142 RgbaF32::new(
143 Norm::u8_to_f32(self.r()),
144 Norm::u8_to_f32(self.g()),
145 Norm::u8_to_f32(self.b()),
146 Norm::u8_to_f32(alpha),
147 )
148 }
149}
150
151#[cfg(feature = "_float_f64")]
153#[cfg_attr(nightly_doc, doc(cfg(feature = "_float_f64")))]
154impl Rgb8 {
155 pub const fn from_rgb_f64(c: RgbF64) -> Rgb8 {
157 Rgb8::new(Norm::f64_to_u8(c.r()), Norm::f64_to_u8(c.g()), Norm::f64_to_u8(c.b()))
158 }
159 pub const fn to_rgb_f64(self) -> RgbF64 {
161 RgbF64::new(Norm::u8_to_f64(self.r()), Norm::u8_to_f64(self.g()), Norm::u8_to_f64(self.b()))
162 }
163
164 pub const fn from_rgba_f64(c: RgbaF64) -> Rgb8 {
168 Rgb8::new(Norm::f64_to_u8(c.r()), Norm::f64_to_u8(c.g()), Norm::f64_to_u8(c.b()))
169 }
170 pub const fn to_rgba_f64(self, alpha: u8) -> RgbaF64 {
174 RgbaF64::new(
175 Norm::u8_to_f64(self.r()),
176 Norm::u8_to_f64(self.g()),
177 Norm::u8_to_f64(self.b()),
178 Norm::u8_to_f64(alpha),
179 )
180 }
181}
182
183#[cfg(test)]
184mod tests {
185 use super::*;
186
187 const C8: Rgb8 = Rgb8::new(10, 20, 30);
188 const CA8: Rgba8 = Rgba8::new(10, 20, 30, 40);
189 const C16: Rgb16 = Rgb16::new(2570, 5140, 7710);
190 const H8: u32 = 0x_0A_14_1E;
191 const HA8: u32 = 0x_0A_14_1E_28;
192
193 #[test]
194 fn general_conversions() {
195 assert_eq![Rgb8::from_array([10, 20, 30]), C8];
197 assert_eq![C8.as_array(), [10, 20, 30]];
198 assert_eq![Rgb8::from_tuple((10, 20, 30)), C8];
199 assert_eq![C8.to_tuple(), (10, 20, 30)];
200 assert_eq![Rgb8::from_rgba8(CA8), C8];
202 assert_eq![C8.to_rgba8(40), CA8];
203 assert_eq![Rgb8::from_rgb8_packed(H8), C8];
205 assert_eq![C8.to_rgb8_packed(), H8];
206 assert_eq![Rgb8::from_rgba8_packed(HA8), C8];
208 assert_eq![C8.to_rgba8_packed(40), HA8];
209 assert_eq![Rgb8::from_rgb16(C16), C8];
211 assert_eq![C8.to_rgb16(), C16];
212 }
213
214 #[test]
215 #[cfg(feature = "_float_f32")]
216 fn f32_conversions() {
217 let f = RgbF32::new(0.039215688, 0.078431375, 0.11764706);
218 let fa = RgbaF32::new(0.039215688, 0.078431375, 0.11764706, 0.15686275);
219 assert_eq![Rgb8::from_rgb_f32(f), C8];
220 assert_eq![C8.to_rgb_f32(), f];
221 assert_eq![Rgb8::from_rgba_f32(fa), C8];
222 assert_eq![C8.to_rgba_f32(40), fa];
223 }
224
225 #[test]
226 #[cfg(feature = "_float_f64")]
227 fn f64_conversions() {
228 let f = RgbF64::new(0.0392156862745098, 0.0784313725490196, 0.11764705882352941);
229 let fa = RgbaF64::new(
230 0.0392156862745098,
231 0.0784313725490196,
232 0.11764705882352941,
233 0.1568627450980392,
234 );
235 assert_eq![Rgb8::from_rgb_f64(f), C8];
236 assert_eq![C8.to_rgb_f64(), f];
237 assert_eq![Rgb8::from_rgba_f64(fa), C8];
238 assert_eq![C8.to_rgba_f64(40), fa];
239 }
240}