1 use super::pixel::*;
2 use crate::alt::Gray;
3 use crate::alt::GrayAlpha;
4 use crate::alt::BGR;
5 use crate::alt::BGRA;
6 use crate::RGB;
7 use crate::RGBA;
8 use core::convert::*;
9 use core::mem;
10 use core::slice;
11
12 mod array;
13 mod tuple;
14
15 /// Casts a slice of bytes into a slice of pixels, e.g. `[u8]` to `[RGB8]`.
16 ///
17 /// See also `FromSlice`
18 pub trait AsPixels<PixelType> {
19 /// Reinterpret the slice as a read-only/shared slice of pixels.
20 /// Multiple consecutive elements in the slice are intepreted as a single pixel
21 /// (depending on format, e.g. 3 for RGB, 4 for RGBA).
22 ///
23 /// Leftover elements are ignored if the slice isn't evenly divisible into pixels.
24 ///
25 /// Use this method only when the type is known from context.
26 /// See also `FromSlice`.
as_pixels(&self) -> &[PixelType]27 fn as_pixels(&self) -> &[PixelType];
28 /// Reinterpret the slice as a mutable/exclusive slice of pixels.
29 /// Multiple consecutive elements in the slice are intepreted as a single pixel
30 /// (depending on format, e.g. 3 for RGB, 4 for RGBA).
31 ///
32 /// Leftover elements are ignored if the slice isn't evenly divisible into pixels.
33 ///
34 /// Use this method only when the type is known from context.
35 /// See also `FromSlice`.
as_pixels_mut(&mut self) -> &mut [PixelType]36 fn as_pixels_mut(&mut self) -> &mut [PixelType];
37 }
38
39 macro_rules! as_pixels_impl {
40 ($typ:ident, $elems:expr) => {
41 impl<T> AsPixels<$typ<T>> for [T] {
42 fn as_pixels(&self) -> &[$typ<T>] {
43 unsafe {
44 slice::from_raw_parts(self.as_ptr() as *const _, self.len() / $elems)
45 }
46 }
47 fn as_pixels_mut(&mut self) -> &mut [$typ<T>] {
48 unsafe {
49 slice::from_raw_parts_mut(self.as_ptr() as *mut _, self.len() / $elems)
50 }
51 }
52 }
53 }
54 }
55
56 as_pixels_impl!{RGB, 3}
57 as_pixels_impl!{RGBA, 4}
58 as_pixels_impl!{BGR, 3}
59 as_pixels_impl!{BGRA, 3}
60 as_pixels_impl!{Gray, 1}
61 as_pixels_impl!{GrayAlpha, 2}
62
63 /// Cast a slice of component values (bytes) as a slice of RGB/RGBA pixels
64 ///
65 /// If there's any incomplete pixel at the end of the slice it is ignored.
66 pub trait FromSlice<T: Copy> {
67 /// Reinterpert slice as RGB pixels
as_rgb(&self) -> &[RGB<T>]68 fn as_rgb(&self) -> &[RGB<T>];
69 /// Reinterpert slice as RGBA pixels
as_rgba(&self) -> &[RGBA<T>]70 fn as_rgba(&self) -> &[RGBA<T>];
71 /// Reinterpert mutable slice as RGB pixels
as_rgb_mut(&mut self) -> &mut [RGB<T>]72 fn as_rgb_mut(&mut self) -> &mut [RGB<T>];
73 /// Reinterpert mutable slice as RGBA pixels
as_rgba_mut(&mut self) -> &mut [RGBA<T>]74 fn as_rgba_mut(&mut self) -> &mut [RGBA<T>];
75
76 /// Reinterpert slice as reverse-order BGR pixels
as_bgr(&self) -> &[BGR<T>]77 fn as_bgr(&self) -> &[BGR<T>];
78 /// Reinterpert slice as reverse-order BGRA pixels
as_bgra(&self) -> &[BGRA<T>]79 fn as_bgra(&self) -> &[BGRA<T>];
80 /// Reinterpert ntable slice as reverse-order BGR pixels
as_bgr_mut(&mut self) -> &mut [BGR<T>]81 fn as_bgr_mut(&mut self) -> &mut [BGR<T>];
82 /// Reinterpert mutable slice as reverse-order BGRA pixels
as_bgra_mut(&mut self) -> &mut [BGRA<T>]83 fn as_bgra_mut(&mut self) -> &mut [BGRA<T>];
84 }
85
86 impl<T: Copy> FromSlice<T> for [T] {
as_rgb(&self) -> &[RGB<T>]87 fn as_rgb(&self) -> &[RGB<T>] {
88 debug_assert_eq!(3, mem::size_of::<RGB<T>>() / mem::size_of::<T>());
89 unsafe {
90 slice::from_raw_parts(self.as_ptr() as *const _, self.len() / 3)
91 }
92 }
as_rgba(&self) -> &[RGBA<T>]93 fn as_rgba(&self) -> &[RGBA<T>] {
94 debug_assert_eq!(4, mem::size_of::<RGBA<T>>() / mem::size_of::<T>());
95 unsafe {
96 slice::from_raw_parts(self.as_ptr() as *const _, self.len() / 4)
97 }
98 }
as_rgb_mut(&mut self) -> &mut [RGB<T>]99 fn as_rgb_mut(&mut self) -> &mut [RGB<T>] {
100 debug_assert_eq!(3, mem::size_of::<RGB<T>>() / mem::size_of::<T>());
101 unsafe {
102 slice::from_raw_parts_mut(self.as_ptr() as *mut _, self.len() / 3)
103 }
104 }
as_rgba_mut(&mut self) -> &mut [RGBA<T>]105 fn as_rgba_mut(&mut self) -> &mut [RGBA<T>] {
106 debug_assert_eq!(4, mem::size_of::<RGBA<T>>() / mem::size_of::<T>());
107 unsafe {
108 slice::from_raw_parts_mut(self.as_ptr() as *mut _, self.len() / 4)
109 }
110 }
111
as_bgr(&self) -> &[BGR<T>]112 fn as_bgr(&self) -> &[BGR<T>] {
113 debug_assert_eq!(3, mem::size_of::<BGR<T>>() / mem::size_of::<T>());
114 unsafe {
115 slice::from_raw_parts(self.as_ptr() as *const _, self.len() / 3)
116 }
117 }
as_bgra(&self) -> &[BGRA<T>]118 fn as_bgra(&self) -> &[BGRA<T>] {
119 debug_assert_eq!(4, mem::size_of::<BGRA<T>>() / mem::size_of::<T>());
120 unsafe {
121 slice::from_raw_parts(self.as_ptr() as *const _, self.len() / 4)
122 }
123 }
as_bgr_mut(&mut self) -> &mut [BGR<T>]124 fn as_bgr_mut(&mut self) -> &mut [BGR<T>] {
125 debug_assert_eq!(3, mem::size_of::<BGR<T>>() / mem::size_of::<T>());
126 unsafe {
127 slice::from_raw_parts_mut(self.as_ptr() as *mut _, self.len() / 3)
128 }
129 }
as_bgra_mut(&mut self) -> &mut [BGRA<T>]130 fn as_bgra_mut(&mut self) -> &mut [BGRA<T>] {
131 debug_assert_eq!(4, mem::size_of::<BGRA<T>>() / mem::size_of::<T>());
132 unsafe {
133 slice::from_raw_parts_mut(self.as_ptr() as *mut _, self.len() / 4)
134 }
135 }
136 }
137
138 macro_rules! rgb_impl_from {
139 ($typename:ident, $from:ty, $to:ty) => {
140 impl From<$typename<$from>> for $typename<$to> {
141
142 #[inline(always)]
143 fn from(other: $typename<$from>) -> Self {
144 other.map(core::convert::Into::into)
145 }
146 }
147 }
148 }
149
150 rgb_impl_from!{RGB, u8,i16}
151 rgb_impl_from!{RGB, u16,i32}
152
153 rgb_impl_from!{RGB, u8,f32}
154 rgb_impl_from!{RGB, u8,f64}
155 rgb_impl_from!{RGB, u16,f32}
156 rgb_impl_from!{RGB, u16,f64}
157
158 rgb_impl_from!{RGB, i16,f32}
159 rgb_impl_from!{RGB, i16,f64}
160
161 rgb_impl_from!{RGB, i32,f64}
162 rgb_impl_from!{RGB, f32,f64}
163
164
165 rgb_impl_from!{RGBA, u16,i32}
166
167 rgb_impl_from!{RGBA, u8,f32}
168 rgb_impl_from!{RGBA, u8,f64}
169 rgb_impl_from!{RGBA, u16,f32}
170 rgb_impl_from!{RGBA, u16,f64}
171
172 rgb_impl_from!{RGBA, i16,f32}
173 rgb_impl_from!{RGBA, i16,f64}
174
175 rgb_impl_from!{RGBA, i32,f64}
176 rgb_impl_from!{RGBA, f32,f64}
177
178 impl<T: Clone> From<Gray<T>> for RGB<T> {
from(other: Gray<T>) -> Self179 fn from(other: Gray<T>) -> Self {
180 Self {
181 r: other.0.clone(),
182 g: other.0.clone(),
183 b: other.0,
184 }
185 }
186 }
187
188 impl<T: Clone,A> From<GrayAlpha<T,A>> for RGBA<T,A> {
from(other: GrayAlpha<T,A>) -> Self189 fn from(other: GrayAlpha<T,A>) -> Self {
190 Self {
191 r: other.0.clone(),
192 g: other.0.clone(),
193 b: other.0,
194 a: other.1,
195 }
196 }
197 }
198
199 impl<T> From<RGB<T>> for BGR<T> {
from(other: RGB<T>) -> Self200 fn from(other: RGB<T>) -> Self {
201 Self {
202 r: other.r,
203 g: other.g,
204 b: other.b,
205 }
206 }
207 }
208
209 impl<T> From<RGBA<T>> for BGRA<T> {
from(other: RGBA<T>) -> Self210 fn from(other: RGBA<T>) -> Self {
211 Self {
212 r: other.r,
213 g: other.g,
214 b: other.b,
215 a: other.a,
216 }
217 }
218 }
219
220 impl<T> From<BGR<T>> for RGB<T> {
from(other: BGR<T>) -> Self221 fn from(other: BGR<T>) -> Self {
222 Self {
223 r: other.r,
224 g: other.g,
225 b: other.b,
226 }
227 }
228 }
229
230 impl<T> From<BGRA<T>> for RGBA<T> {
from(other: BGRA<T>) -> Self231 fn from(other: BGRA<T>) -> Self {
232 Self {
233 r: other.r,
234 g: other.g,
235 b: other.b,
236 a: other.a,
237 }
238 }
239 }
240
241 impl<T> AsRef<T> for Gray<T> {
as_ref(&self) -> &T242 fn as_ref(&self) -> &T {
243 &self.0
244 }
245 }
246
247 impl<T> AsRef<[T]> for RGB<T> {
as_ref(&self) -> &[T]248 fn as_ref(&self) -> &[T] {
249 self.as_slice()
250 }
251 }
252
253 impl<T> AsRef<[T]> for RGBA<T> {
as_ref(&self) -> &[T]254 fn as_ref(&self) -> &[T] {
255 self.as_slice()
256 }
257 }
258
259 impl<T> AsRef<T> for GrayAlpha<T> {
as_ref(&self) -> &T260 fn as_ref(&self) -> &T {
261 &self.0
262 }
263 }
264
265
266 impl<T> AsMut<T> for Gray<T> {
as_mut(&mut self) -> &mut T267 fn as_mut(&mut self) -> &mut T {
268 &mut self.0
269 }
270 }
271
272 impl<T> AsMut<[T]> for RGB<T> {
as_mut(&mut self) -> &mut [T]273 fn as_mut(&mut self) -> &mut [T] {
274 self.as_mut_slice()
275 }
276 }
277
278 impl<T> AsMut<[T]> for RGBA<T> {
as_mut(&mut self) -> &mut [T]279 fn as_mut(&mut self) -> &mut [T] {
280 self.as_mut_slice()
281 }
282 }
283
284 impl<T> AsMut<T> for GrayAlpha<T> {
as_mut(&mut self) -> &mut T285 fn as_mut(&mut self) -> &mut T {
286 &mut self.0
287 }
288 }
289
290
291 #[test]
converts()292 fn converts() {
293 assert_eq!(RGBA::new(1u8,2,3,255), RGB::new(1u8,2,3).into());
294 assert_eq!(RGBA::new(1u16,2,3,65535), RGB::new(1u16,2,3).into());
295 assert_eq!(BGRA{r:1u8,g:2u8,b:3u8,a:255u8}, BGR{r:1u8,g:2u8,b:3u8}.into());
296 assert_eq!(BGRA{r:1u8,g:2u8,b:3u8,a:255u8}, RGB{r:1u8,g:2u8,b:3u8}.into());
297 assert_eq!(RGBA {r:1u8,g:2,b:3,a:4u8}, BGRA{r:1u8,g:2u8,b:3u8,a:4u8}.into());
298 assert_eq!(BGR {r:1u8,g:2,b:3u8}, RGB {r:1u8,g:2,b:3u8}.into());
299 assert_eq!(RGB {r:1u16,g:0x5678,b:0xABCDu16}, BGR {r:1u16,g:0x5678,b:0xABCDu16}.into());
300 assert_eq!(BGR {r:0x1234567u32,g:2,b:3u32}, RGB {r:0x1234567u32,g:2,b:3u32}.into());
301
302 assert_eq!(&[1u8,2,3,4], RGBA {r:1u8,g:2,b:3,a:4u8}.as_slice());
303 assert_eq!(&[1u8,2,3,4], RGBA {r:1u8,g:2,b:3,a:4u8}.as_ref());
304 assert_eq!(&[1u8,2,3], RGB {r:1u8,g:2,b:3}.as_slice());
305 assert_eq!(&[1u8,2,3], RGB {r:1u8,g:2,b:3}.as_ref());
306
307 assert_eq!(&[1u8,2,3], RGB {r:1u8,g:2,b:3}.as_mut_slice());
308 assert_eq!(&[1u8,2,3], RGB {r:1u8,g:2,b:3}.as_mut());
309 }
310
311