rgb/legacy/internal/convert/
mod.rs

1#[allow(deprecated)]
2use super::pixel::ComponentSlice;
3use super::pixel::ComponentMap;
4use crate::alt::{BGR, BGRA, GRB, ARGB, ABGR};
5use crate::{RGB, RGBA, Gray, GrayAlpha};
6use core::{mem, slice};
7
8mod array;
9mod tuple;
10
11/// Use [`::bytemuck::cast_slice()`] instead.
12///
13/// Casts a slice of bytes into a slice of pixels, e.g. `[u8]` to `[RGB8]`.
14///
15/// See also `FromSlice`
16pub trait AsPixels<PixelType> {
17    /// Use [`::bytemuck::cast_slice()`] instead.
18    ///
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`.
27    fn as_pixels(&self) -> &[PixelType];
28    /// Use [`::bytemuck::cast_slice_mut()`] instead.
29    ///
30    /// Reinterpret the slice as a mutable/exclusive slice of pixels.
31    /// Multiple consecutive elements in the slice are intepreted as a single pixel
32    /// (depending on format, e.g. 3 for RGB, 4 for RGBA).
33    ///
34    /// Leftover elements are ignored if the slice isn't evenly divisible into pixels.
35    ///
36    /// Use this method only when the type is known from context.
37    /// See also `FromSlice`.
38    fn as_pixels_mut(&mut self) -> &mut [PixelType];
39}
40
41macro_rules! as_pixels_impl {
42    ($typ:ident, $elems:expr) => {
43        impl<T> AsPixels<$typ<T>> for [T] {
44            fn as_pixels(&self) -> &[$typ<T>] {
45                unsafe {
46                    slice::from_raw_parts(self.as_ptr() as *const _, self.len() / $elems)
47                }
48            }
49
50            fn as_pixels_mut(&mut self) -> &mut [$typ<T>] {
51                unsafe {
52                    slice::from_raw_parts_mut(self.as_mut_ptr() as *mut _, self.len() / $elems)
53                }
54            }
55        }
56    };
57}
58
59as_pixels_impl! {RGB, 3}
60as_pixels_impl! {RGBA, 4}
61as_pixels_impl! {BGR, 3}
62as_pixels_impl! {BGRA, 4}
63as_pixels_impl! {GRB, 3}
64as_pixels_impl! {Gray, 1}
65as_pixels_impl! {GrayAlpha, 2}
66as_pixels_impl! {ARGB, 4}
67as_pixels_impl! {ABGR, 4}
68
69/// Use [`::bytemuck::cast_slice()`] or [`::bytemuck::from_bytes()`] to convert
70///
71/// Cast a slice of component values (bytes) as a slice of RGB/RGBA pixels
72///
73/// If there's any incomplete pixel at the end of the slice it is ignored.
74pub trait FromSlice<T: Copy> {
75    /// Reinterpert slice as RGB pixels
76    fn as_rgb(&self) -> &[RGB<T>];
77    /// Reinterpert slice as RGBA pixels
78    fn as_rgba(&self) -> &[RGBA<T>];
79    /// Reinterpert slice as alpha-first ARGB pixels
80    fn as_argb(&self) -> &[ARGB<T>];
81    /// Reinterpert mutable slice as RGB pixels
82    fn as_rgb_mut(&mut self) -> &mut [RGB<T>];
83    /// Reinterpert mutable slice as RGBA pixels
84    fn as_rgba_mut(&mut self) -> &mut [RGBA<T>];
85    /// Reinterpert mutable slice as alpha-first ARGB pixels
86    fn as_argb_mut(&mut self) -> &mut [ARGB<T>];
87
88    /// Reinterpert mutable slice as grayscale pixels
89    fn as_gray(&self) -> &[Gray<T>];
90    /// Reinterpert mutable slice as grayscale pixels with alpha
91    fn as_gray_alpha(&self) -> &[GrayAlpha<T>];
92    /// Reinterpert mutable slice as grayscale pixels
93    fn as_gray_mut(&mut self) -> &mut [Gray<T>];
94    /// Reinterpert mutable slice as grayscale pixels with alpha
95    fn as_gray_alpha_mut(&mut self) -> &mut [GrayAlpha<T>];
96
97    /// Reinterpert slice as reverse-order BGR pixels
98    fn as_bgr(&self) -> &[BGR<T>];
99    /// Reinterpert slice as reverse-order BGRA pixels
100    fn as_bgra(&self) -> &[BGRA<T>];
101    /// Reinterpert slice as reverse-order ABGR pixels
102    fn as_abgr(&self) -> &[ABGR<T>];
103    /// Reinterpert ntable slice as reverse-order BGR pixels
104    fn as_bgr_mut(&mut self) -> &mut [BGR<T>];
105    /// Reinterpert mutable slice as reverse-order alpha-last BGRA pixels
106    fn as_bgra_mut(&mut self) -> &mut [BGRA<T>];
107    /// Reinterpert mutable slice as reverse-order alpha-first ABGR pixels
108    fn as_abgr_mut(&mut self) -> &mut [ABGR<T>];
109}
110
111impl<T: Copy> FromSlice<T> for [T] {
112    #[inline]
113    fn as_rgb(&self) -> &[RGB<T>] {
114        unsafe { from_items_to_struct(self) }
115    }
116
117    #[inline]
118    fn as_rgba(&self) -> &[RGBA<T>] {
119        unsafe { from_items_to_struct(self) }
120    }
121
122    #[inline]
123    fn as_argb(&self) -> &[ARGB<T>] {
124        unsafe { from_items_to_struct(self) }
125    }
126
127    #[inline]
128    fn as_rgb_mut(&mut self) -> &mut [RGB<T>] {
129        unsafe { from_items_to_struct_mut(self) }
130    }
131
132    #[inline]
133    fn as_rgba_mut(&mut self) -> &mut [RGBA<T>] {
134        unsafe { from_items_to_struct_mut(self) }
135    }
136
137    #[inline]
138    fn as_argb_mut(&mut self) -> &mut [ARGB<T>] {
139        unsafe { from_items_to_struct_mut(self) }
140    }
141
142    #[inline]
143    fn as_gray(&self) -> &[Gray<T>] {
144        unsafe { from_items_to_struct(self) }
145    }
146
147    #[inline]
148    fn as_gray_alpha(&self) -> &[GrayAlpha<T>] {
149        unsafe { from_items_to_struct(self) }
150    }
151
152    #[inline]
153    fn as_gray_mut(&mut self) -> &mut [Gray<T>] {
154        unsafe { from_items_to_struct_mut(self) }
155    }
156
157    #[inline]
158    fn as_gray_alpha_mut(&mut self) -> &mut [GrayAlpha<T>] {
159        unsafe { from_items_to_struct_mut(self) }
160    }
161
162    #[inline]
163    fn as_bgr(&self) -> &[BGR<T>] {
164        unsafe { from_items_to_struct(self) }
165    }
166
167    #[inline]
168    fn as_abgr(&self) -> &[ABGR<T>] {
169        unsafe { from_items_to_struct(self) }
170    }
171
172    #[inline]
173    fn as_bgra(&self) -> &[BGRA<T>] {
174        unsafe { from_items_to_struct(self) }
175    }
176
177    #[inline]
178    fn as_bgr_mut(&mut self) -> &mut [BGR<T>] {
179        unsafe { from_items_to_struct_mut(self) }
180    }
181
182    #[inline]
183    fn as_bgra_mut(&mut self) -> &mut [BGRA<T>] {
184        unsafe { from_items_to_struct_mut(self) }
185    }
186
187    #[inline]
188    fn as_abgr_mut(&mut self) -> &mut [ABGR<T>] {
189        unsafe { from_items_to_struct_mut(self) }
190    }
191}
192
193#[inline(always)]
194unsafe fn from_items_to_struct<F, T>(from: &[F]) -> &[T] {
195    debug_assert_eq!(0, mem::size_of::<T>() % mem::size_of::<F>());
196    let len = from.len() / (mem::size_of::<T>() / mem::size_of::<F>());
197    slice::from_raw_parts(from.as_ptr().cast::<T>(), len)
198}
199
200#[inline(always)]
201unsafe fn from_items_to_struct_mut<F, T>(from: &mut [F]) -> &mut [T] {
202    debug_assert_eq!(0, mem::size_of::<T>() % mem::size_of::<F>());
203    let len = from.len() / (mem::size_of::<T>() / mem::size_of::<F>());
204    slice::from_raw_parts_mut(from.as_mut_ptr().cast::<T>(), len)
205}
206
207macro_rules! rgb_impl_from {
208    ($typename:ident, $from:ty, $to:ty) => {
209        impl From<$typename<$from>> for $typename<$to> {
210            #[inline(always)]
211            fn from(other: $typename<$from>) -> Self {
212                other.map(core::convert::Into::into)
213            }
214        }
215    };
216}
217
218rgb_impl_from! {RGB, u8,i16}
219rgb_impl_from! {RGB, u8,i32}
220rgb_impl_from! {RGB, u8,u16}
221rgb_impl_from! {RGB, u8,u32}
222rgb_impl_from! {RGB, u16,i32}
223rgb_impl_from! {RGB, u16,u32}
224rgb_impl_from! {RGB, u16,u64}
225
226rgb_impl_from! {RGB, u8,f32}
227rgb_impl_from! {RGB, u8,f64}
228rgb_impl_from! {RGB, u16,f32}
229rgb_impl_from! {RGB, u16,f64}
230
231rgb_impl_from! {RGB, i16,f32}
232rgb_impl_from! {RGB, i16,f64}
233
234rgb_impl_from! {RGB, i32,f64}
235rgb_impl_from! {RGB, f32,f64}
236
237rgb_impl_from! {RGBA, u16,i32}
238rgb_impl_from! {RGBA, u16,u32}
239rgb_impl_from! {RGBA, u16,u64}
240
241rgb_impl_from! {RGBA, u8,i16}
242rgb_impl_from! {RGBA, u8,u16}
243rgb_impl_from! {RGBA, u8,u32}
244rgb_impl_from! {RGBA, u8,f32}
245rgb_impl_from! {RGBA, u8,f64}
246rgb_impl_from! {RGBA, u16,f32}
247rgb_impl_from! {RGBA, u16,f64}
248
249rgb_impl_from! {RGBA, i16,f32}
250rgb_impl_from! {RGBA, i16,f64}
251
252rgb_impl_from! {RGBA, i32,f64}
253rgb_impl_from! {RGBA, f32,f64}
254
255macro_rules! reorder_impl_from {
256    (@rgb $t1:ident, $t2:ident) => {
257        reorder_impl_from!(@once $t1, $t2, r, g, b);
258        reorder_impl_from!(@once $t2, $t1, r, g, b);
259    };
260    (@rgba $t1:ident, $t2:ident) => {
261        reorder_impl_from!(@once $t1, $t2, r, g, b, a);
262        reorder_impl_from!(@once $t2, $t1, r, g, b, a);
263    };
264    (@once $t1:ident, $t2:ident, $($component:ident),+) => {
265        impl<T> From<$t1<T>> for $t2<T> where T: ::core::clone::Clone {
266            fn from(other: $t1<T>) -> Self {
267                let $t1 { $($component),+ } = other;
268                Self {
269                    $($component),+
270                }
271            }
272        }
273    }
274}
275
276reorder_impl_from!(@rgba RGBA, ARGB);
277reorder_impl_from!(@rgba ABGR, ARGB);
278reorder_impl_from!(@rgba BGRA, ARGB);
279reorder_impl_from!(@rgba BGRA, ABGR);
280
281reorder_impl_from!(@rgb RGB, BGR);
282reorder_impl_from!(@rgba BGRA, RGBA);
283reorder_impl_from!(@rgba ABGR, RGBA);
284reorder_impl_from!(@rgb RGB, GRB);
285
286impl<T: Clone> From<Gray<T>> for RGB<T> {
287    #[inline(always)]
288    #[allow(deprecated)]
289    fn from(other: Gray<T>) -> Self {
290        Self {
291            r: other.clone().value(),
292            g: other.clone().value(),
293            b: other.value(),
294        }
295    }
296}
297
298impl<T: Clone> From<Gray<T>> for RGBA<T, u8> {
299    #[inline(always)]
300    #[allow(deprecated)]
301    fn from(other: Gray<T>) -> Self {
302        Self {
303            r: other.clone().value(),
304            g: other.clone().value(),
305            b: other.value(),
306            a: 255,
307        }
308    }
309}
310
311impl<T: Clone, A: Clone> From<GrayAlpha<T, A>> for RGBA<T, A> {
312    #[inline(always)]
313    #[allow(deprecated)]
314    fn from(other: GrayAlpha<T, A>) -> Self {
315        Self {
316            r: other.v.clone(),
317            g: other.v.clone(),
318            b: other.v.clone(),
319            a: other.a.clone(),
320        }
321    }
322}
323
324#[cfg(not(feature = "unstable-experimental"))]
325impl<T> AsRef<T> for Gray<T> {
326    #[inline(always)]
327    #[allow(deprecated)]
328    fn as_ref(&self) -> &T {
329        &self.0
330    }
331}
332
333#[cfg(not(feature = "unstable-experimental"))]
334impl<T> AsRef<[T]> for RGB<T> {
335    #[inline(always)]
336    fn as_ref(&self) -> &[T] {
337        #[allow(deprecated)]
338        ComponentSlice::as_slice(self)
339    }
340}
341
342#[cfg(feature = "unstable-experimental")]
343impl<T> AsRef<[T; 3]> for RGB<T> {
344    fn as_ref(&self) -> &[T; 3] {
345        unsafe { &*(self as *const Self).cast() }
346    }
347}
348
349#[cfg(not(feature = "unstable-experimental"))]
350impl<T> AsRef<[T]> for RGBA<T> {
351    #[inline(always)]
352    fn as_ref(&self) -> &[T] {
353        #[allow(deprecated)]
354        ComponentSlice::as_slice(self)
355    }
356}
357
358#[cfg(feature = "unstable-experimental")]
359impl<T> AsRef<[T; 4]> for RGBA<T> {
360    fn as_ref(&self) -> &[T; 4] {
361        unsafe { &*(self as *const Self).cast() }
362    }
363}
364
365impl<T> AsRef<[T; 4]> for ARGB<T> {
366    fn as_ref(&self) -> &[T; 4] {
367        unsafe { &*(self as *const Self).cast() }
368    }
369}
370
371impl<T> AsRef<[T; 4]> for BGRA<T> {
372    fn as_ref(&self) -> &[T; 4] {
373        unsafe { &*(self as *const Self).cast() }
374    }
375}
376
377impl<T> AsRef<[T; 4]> for ABGR<T> {
378    fn as_ref(&self) -> &[T; 4] {
379        unsafe { &*(self as *const Self).cast() }
380    }
381}
382
383#[cfg(not(feature = "unstable-experimental"))]
384impl<T> AsRef<T> for GrayAlpha<T> {
385    #[inline(always)]
386    #[allow(deprecated)]
387    fn as_ref(&self) -> &T {
388        &self.0
389    }
390}
391
392#[cfg(feature = "unstable-experimental")]
393impl<T> AsRef<[T; 2]> for GrayAlpha<T> {
394    fn as_ref(&self) -> &[T; 2] {
395        unsafe { &*(self as *const Self).cast() }
396    }
397}
398
399#[cfg(not(feature = "unstable-experimental"))]
400impl<T> AsMut<T> for Gray<T> {
401    #[inline(always)]
402    #[allow(deprecated)]
403    fn as_mut(&mut self) -> &mut T {
404        &mut self.0
405    }
406}
407
408#[cfg(not(feature = "unstable-experimental"))]
409impl<T> AsMut<[T]> for RGB<T> {
410    #[inline(always)]
411    fn as_mut(&mut self) -> &mut [T] {
412        #[allow(deprecated)]
413        ComponentSlice::as_mut_slice(self)
414    }
415}
416
417#[cfg(feature = "unstable-experimental")]
418impl<T> AsMut<[T; 3]> for RGB<T> {
419    fn as_mut(&mut self) -> &mut [T; 3] {
420        unsafe { &mut *(self as *mut Self).cast() }
421    }
422}
423
424#[cfg(not(feature = "unstable-experimental"))]
425impl<T> AsMut<[T]> for RGBA<T> {
426    #[inline(always)]
427    fn as_mut(&mut self) -> &mut [T] {
428        #[allow(deprecated)]
429        ComponentSlice::as_mut_slice(self)
430    }
431}
432
433#[cfg(feature = "unstable-experimental")]
434impl<T> AsMut<[T; 4]> for RGBA<T> {
435    fn as_mut(&mut self) -> &mut [T; 4] {
436        unsafe { &mut *(self as *mut Self).cast() }
437    }
438}
439
440#[cfg(not(feature = "unstable-experimental"))]
441impl<T> AsMut<T> for GrayAlpha<T> {
442    #[inline(always)]
443    #[allow(deprecated)]
444    fn as_mut(&mut self) -> &mut T {
445        &mut self.0
446    }
447}
448
449#[cfg(feature = "unstable-experimental")]
450impl<T> AsMut<[T; 2]> for GrayAlpha<T> {
451    fn as_mut(&mut self) -> &mut [T; 2] {
452        unsafe { &mut *(self as *mut Self).cast() }
453    }
454}