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

Provided by KDAB

Privacy Policy