rgb/legacy/internal/
pixel.rs

1/// Casting the struct to slices of its components
2pub trait ComponentSlice<T> {
3    /// The components interpreted as an array, e.g. one `RGB` expands to 3 elements.
4    ///
5    /// It's implemented for individual pixels as well as slices of pixels.
6    fn as_slice(&self) -> &[T];
7
8    /// The components interpreted as a mutable array, e.g. one `RGB` expands to 3 elements.
9    ///
10    /// It's implemented for individual pixels as well as slices of pixels.
11    ///
12    /// If you get an error when calling this on an array, add `[..]`
13    ///
14    /// > use of unstable library feature 'array_methods'
15    ///
16    /// ```rust,ignore
17    /// arr[..].as_mut_slice()
18    /// ```
19    fn as_mut_slice(&mut self) -> &mut [T];
20}
21
22/// Use [`::bytemuck::cast_slice()`] instead.
23///
24/// Casting a slice of `RGB/A` values to a slice of `u8`
25///
26/// If instead of `RGB8` you use `RGB<MyCustomType>`, and you want to cast from/to that custom type,
27/// implement the `Plain` trait for it:
28///
29/// ```rust
30/// # #[derive(Copy, Clone)]
31/// # struct MyCustomType;
32/// unsafe impl rgb::Pod for MyCustomType {}
33/// unsafe impl rgb::Zeroable for MyCustomType {}
34/// ```
35///
36/// Plain types are not allowed to contain struct padding, booleans, chars, enums, references or pointers.
37#[cfg(feature = "as-bytes")]
38pub trait ComponentBytes<T: crate::Pod> where Self: ComponentSlice<T> {
39    /// The components interpreted as raw bytes, in machine's native endian. In `RGB` bytes of the red component are first.
40    #[inline]
41    fn as_bytes(&self) -> &[u8] {
42        assert_ne!(0, core::mem::size_of::<T>());
43        let slice = self.as_slice();
44        unsafe {
45            core::slice::from_raw_parts(slice.as_ptr().cast(), core::mem::size_of_val(slice))
46        }
47    }
48
49    /// The components interpreted as raw bytes, in machine's native endian. In `RGB` bytes of the red component are first.
50    #[inline]
51    fn as_bytes_mut(&mut self) -> &mut [u8] {
52        assert_ne!(0, core::mem::size_of::<T>());
53        let slice = self.as_mut_slice();
54        unsafe {
55            core::slice::from_raw_parts_mut(slice.as_mut_ptr().cast(), core::mem::size_of_val(slice))
56        }
57    }
58}
59
60/// Applying operation to every component
61///
62/// ```rust
63/// use rgb::ComponentMap;
64/// # let pixel = rgb::RGB::new(0u8,0,0);
65/// let inverted = pixel.map(|c| 255 - c);
66///
67/// // For simple math there are Add/Sub/Mul implementations:
68/// let halved = pixel.map(|c| c / 2);
69/// let doubled = pixel * 2;
70/// ```
71pub trait ComponentMap<DestPixel, SrcComponent, DestComponent> {
72    /// Convenience function (equivalent of `self.iter().map().collect()`) for applying the same formula to every component.
73    ///
74    /// Note that it returns the pixel directly, not an Interator.
75    fn map<Callback>(&self, f: Callback) -> DestPixel
76        where Callback: FnMut(SrcComponent) -> DestComponent;
77}
78
79/// Same as `ComponentMap`, but doesn't change the alpha channel (if there's any alpha).
80pub trait ColorComponentMap<DestPixel, SrcComponent, DestComponent> {
81    /// Convenience function for applying the same formula to every rgb/gray component, but skipping the alpha component.
82    ///
83    /// Note that it returns the pixel directly, not an Interator.
84    #[doc(alias = "map_colors_same")]
85    fn map_colors<Callback>(&self, f: Callback) -> DestPixel
86        where Callback: FnMut(SrcComponent) -> DestComponent {
87            #[allow(deprecated)]
88            self.map_c(f)
89        }
90
91    /// Alias of `map_colors`
92    #[deprecated(note = "renamed to map_colors")]
93    fn map_c<Callback>(&self, f: Callback) -> DestPixel
94        where Callback: FnMut(SrcComponent) -> DestComponent {
95            self.map_colors(f)
96    }
97}