| 1 | /// Casting the struct to slices of its components |
| 2 | pub 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" )] |
| 38 | pub 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: &[T] = self.as_slice(); |
| 44 | unsafe { |
| 45 | core::slice::from_raw_parts(data:slice.as_ptr().cast(), len: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: &mut [T] = self.as_mut_slice(); |
| 54 | unsafe { |
| 55 | core::slice::from_raw_parts_mut(data:slice.as_mut_ptr().cast(), len: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 | /// ``` |
| 71 | pub 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). |
| 80 | pub 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 | } |
| 98 | |