|
1 | 1 | #![cfg_attr(feature = "nightly", feature(portable_simd))]
|
| 2 | +#![cfg_attr(feature = "nightly", feature(slice_as_chunks))] |
2 | 3 | #![warn(missing_docs)]
|
3 | 4 |
|
4 | 5 | //! Simple colorspace conversions in pure Rust.
|
@@ -133,6 +134,41 @@ where
|
133 | 134 | }
|
134 | 135 | }
|
135 | 136 |
|
| 137 | +#[cfg(feature = "nightly")] |
| 138 | +/// Create an array of separate channel buffers from a single interwoven buffer. |
| 139 | +/// Copies the data. |
| 140 | +pub fn unweave_simd<'a, const C: usize, const L: usize>(slice: &[f32]) -> [(Box<[f32]>, Box<[Simd<f32, L>]>); C] |
| 141 | +where |
| 142 | + LaneCount<L>: SupportedLaneCount, |
| 143 | +{ |
| 144 | + let len = slice.len() / (C * L); |
| 145 | + let mut result: [Vec<Simd<f32, L>>; C] = (0..C) |
| 146 | + .map(|_| Vec::with_capacity(len)) |
| 147 | + .collect::<Vec<Vec<_>>>() |
| 148 | + .try_into() |
| 149 | + .unwrap(); |
| 150 | + |
| 151 | + //let chunks = slice.as_chunks::<C>(); |
| 152 | + //for chunk in chunks.0. |
| 153 | + //let mut remainders: [Box<[f32]>; C] = [Box::new([]), Box::new([]), Box::new([])]; |
| 154 | + for chunk in slice.chunks(C * L) { |
| 155 | + if chunk.len() == C * L { |
| 156 | + for c in 0..C { |
| 157 | + result[c].push(Simd::from_slice( |
| 158 | + &(0..L).map(|l| chunk[c + l * c]).collect::<Vec<f32>>(), |
| 159 | + )); |
| 160 | + } |
| 161 | + } |
| 162 | + } |
| 163 | + |
| 164 | + result |
| 165 | + .into_iter() |
| 166 | + .map(|v| (Vec::new().into_boxed_slice(), v.into_boxed_slice())) |
| 167 | + .collect::<Vec<(Box<[f32]>, Box<[Simd<f32, L>]>)>>() |
| 168 | + .try_into() |
| 169 | + .unwrap() |
| 170 | +} |
| 171 | + |
136 | 172 | /// Create an array of separate channel buffers from a single interwoven buffer.
|
137 | 173 | /// Copies the data.
|
138 | 174 | pub fn unweave<const N: usize>(slice: &[f32]) -> [Box<[f32]>; N] {
|
|
0 commit comments