1#![cfg_attr(feature = "as-bytes", doc = "```rust")]
12#![cfg_attr(not(feature = "as-bytes"), doc = "```ignore")]
13#![doc(html_logo_url = "https://kornel.ski/rgb-logo.png")]
29#![warn(missing_docs)]
30#![cfg_attr(docsrs, feature(doc_auto_cfg))]
31#![no_std]
32
33#[cfg(test)]
35#[macro_use] extern crate std;
36#[cfg(feature = "bytemuck")]
41#[doc(alias = "ComponentSlice")]
42#[doc(alias = "as_bytes")]
43#[doc(alias = "Pod")]
44pub use ::bytemuck;
45
46pub(crate) mod formats {
47 pub mod abgr;
48 pub mod argb;
49 pub mod bgr;
50 pub mod bgra;
51 pub mod gray;
52 pub mod gray_a;
53 pub mod gray_alpha;
54 pub mod grb;
55 pub mod rgb;
56 pub mod rgba;
57}
58
59pub mod prelude {
61 pub use crate::legacy::internal::pixel::ComponentMap;
62 pub use crate::legacy::internal::pixel::ColorComponentMap;
63}
64
65pub use formats::abgr::Abgr;
66pub use formats::argb::Argb;
67pub use formats::bgr::Bgr;
68pub use formats::bgra::Bgra;
69#[cfg(not(feature = "unstable-experimental"))]
70pub use formats::gray_alpha::GrayAlpha_v08 as GrayAlpha;
71#[cfg(not(feature = "unstable-experimental"))]
72pub use formats::gray::Gray_v08 as Gray;
73pub use formats::grb::Grb;
74pub use formats::rgb::Rgb;
75pub use formats::rgba::Rgba;
76
77mod inherent_impls;
78
79pub(crate) mod legacy {
80 pub(crate) mod internal {
81 pub mod convert;
82 pub mod ops;
83 pub mod pixel;
84 pub mod rgb;
85 pub mod rgba;
86 }
87 pub mod alt;
91}
92
93pub use legacy::alt;
94
95#[cfg(all(feature = "bytemuck", not(feature = "as-bytes")))]
96mod bytemuck_impl;
97#[cfg(feature = "as-bytes")]
98mod as_bytes;
99
100#[cfg(feature = "as-bytes")]
102pub use ::bytemuck::Pod;
103#[cfg(feature = "as-bytes")]
105pub use ::bytemuck::Zeroable;
106
107pub use crate::legacy::internal::convert::*;
108pub use crate::legacy::internal::pixel::*;
109
110#[doc(hidden)]
111pub use formats::rgb::Rgb as RGB;
113#[doc(hidden)]
114pub use formats::rgba::Rgba as RGBA;
116
117#[doc(hidden)]
118pub use formats::gray_a::GrayA;
120
121#[cfg(feature = "unstable-experimental")]
122pub use formats::gray::Gray_v09 as Gray;
123
124pub type RGB8 = RGB<u8>;
128
129pub type RGB16 = RGB<u16>;
133
134pub type RGBA8 = RGBA<u8>;
136
137pub type RGBA16 = RGBA<u16>;
141
142#[test]
143fn rgb_works() {
144 let rgb = RGB{r:0u8,g:128,b:255}.clone();
145 assert_eq!(rgb.b, 255);
146
147 assert_eq!(rgb, rgb.iter().map(|ch| ch).collect());
148
149 #[cfg(feature = "as-bytes")]
150 {
151 assert_eq!(0, [rgb].as_bytes()[0]);
152 assert_eq!(128, [rgb].as_bytes()[1]);
153 assert_eq!(255, [rgb].as_bytes()[2]);
154 }
155
156 let rgb = RGB16{r:0u16,g:0x7F7F,b:65535};
157 assert_eq!(rgb.b, 65535);
158 assert_eq!(rgb.as_slice()[1], 0x7F7F);
159
160 #[cfg(feature = "as-bytes")]
161 {
162 assert_eq!(0, [rgb].as_bytes()[0]);
163 assert_eq!(0, [rgb].as_bytes()[1]);
164 assert_eq!(0x7F, [rgb].as_bytes()[2]);
165 assert_eq!(0x7F, [rgb].as_bytes()[3]);
166 assert_eq!(0xFF, [rgb].as_bytes()[4]);
167 assert_eq!(0xFF, [rgb].as_bytes()[5]);
168 }
169
170 assert_eq!("rgb(1,2,3)", format!("{}", RGB::new(1,2,3)));
171}
172
173#[test]
174fn sub_floats() {
175 assert_eq!(RGBA{r:2.5_f64, g:-1.5, b:0., a:5.}, RGBA{r:3.5_f64, g:-0.5, b:-2., a:0.} - RGBA{r:1.0_f64, g:1., b:-2., a:-5.});
176}
177
178#[test]
179fn into() {
180 let a:RGB8 = RGB{r:0,g:1,b:2};
181 let b:RGB<i16> = a.into();
182 let c:RGB<f32> = b.into();
183 let d:RGB<f32> = a.into();
184 assert_eq!(c, d);
185}
186
187#[test]
188fn rgba_works() {
189 let rgba = RGBA{r:0u8,g:128,b:255,a:33}.clone();
190 assert_eq!(rgba.b, 255);
191 assert_eq!(rgba.a, 33);
192
193 assert_eq!(rgba, rgba.iter().map(|ch| ch).collect());
194
195 assert_eq!("rgba(1,2,3,4)", format!("{}", RGBA::new(1,2,3,4)));
196
197 assert_eq!(rgba - rgba, RGBA::new(0,0,0,0));
198}
199
200#[test]
201fn bytes() {
202 let rgb = RGB8::new(1,2,3);
203
204 #[cfg(feature = "as-bytes")]
205 {
206 let rgb_arr = [rgb];
207 let rgb_bytes = rgb_arr.as_bytes();
208 assert_eq!(&[1,2,3], rgb_bytes);
209 assert_eq!(rgb_bytes.as_rgba().len(), 0);
210 assert_eq!({let t: &[RGBA8] = rgb_bytes.as_pixels(); t}.len(), 0);
211 assert_eq!(rgb, rgb_bytes.into_iter().cloned().collect());
212 assert_eq!(&[rgb], rgb_bytes.as_rgb());
213 assert_eq!(&[rgb], rgb_bytes.as_pixels());
214 }
215 let mut rgb2 = [rgb];
216 assert_eq!(rgb2[..].as_mut_slice().as_rgb_mut(), &mut [rgb]);
217 assert_eq!(&mut [rgb], rgb2[..].as_mut_slice().as_pixels_mut());
218
219
220 #[cfg(feature = "as-bytes")]
221 {
222 let rgba = RGBA8::new(1,2,3,4);
223 let mut rgba_arr = [rgba];
224 let rgba_bytes = rgba_arr.as_bytes_mut();
225 assert_eq!(&[1,2,3,4], rgba_bytes);
226 assert_eq!(&[rgba], rgba_bytes.as_rgba());
227 rgba_bytes[3] = 99;
228 assert_eq!(RGBA8::new(1,2,3,99), rgba_arr.as_bytes().into_iter().cloned().collect());
229 }
230
231 let rgb = RGB16::new(1,2,3);
232 let rgb_slice = rgb.as_slice();
233 assert_eq!(&[1,2,3], rgb_slice);
234 assert_eq!(rgb_slice.as_rgba(), &[]);
235 assert_eq!(&[rgb], rgb_slice.as_rgb());
236 assert_eq!(rgb, rgb_slice.into_iter().cloned().collect());
237
238 let rgba = RGBA16::new(1,2,3,4);
239 let rgba_slice = rgba.as_slice();
240 assert_eq!(&[1,2,3,4], rgba_slice);
241 assert_eq!(&[1,2,3], rgba_slice.as_rgb()[0].as_slice());
242 assert_eq!(&[rgba], rgba_slice.as_rgba());
243 assert_eq!(rgba, rgba_slice.iter().copied().collect());
244 let mut rgba2 = [rgba];
245 assert_eq!(rgba2[..].as_mut_slice().as_rgba_mut(), &mut [rgba]);
246
247 let mut foo = vec![0u8; 8];
248 foo.as_rgba_mut()[1] = RGBA::new(1,2,3,4);
249 assert_eq!(&[0u8,0,0,0,1,2,3,4], &foo[..]);
250}