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