use crate::channel::Channel;
use crate::errors::ImageErrors;
fn swizzle_three_channels<T: Copy + Default>(r: &[&[T]], y: &mut [T]) {
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
{
if is_x86_feature_detected!("avx2") {
return unsafe { swizzle_three_channels_avx(r, y) };
}
}
swizzle_three_channels_fallback(r, y);
}
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
#[target_feature(enable = "avx2")]
unsafe fn swizzle_three_channels_avx<T: Copy + Default>(r: &[&[T]], y: &mut [T]) {
swizzle_three_channels_fallback(r, y); }
#[inline(always)]
fn swizzle_three_channels_fallback<T: Copy + Default>(r: &[&[T]], y: &mut [T]) {
assert_eq!(r.len(), 3);
for (((output, a), b), c) in y
.chunks_exact_mut(3)
.zip(r[0].iter())
.zip(r[1].iter())
.zip(r[2].iter())
{
output[0] = *a;
output[1] = *b;
output[2] = *c;
}
}
fn swizzle_four_channels<T: Copy + Default>(r: &[&[T]], y: &mut [T]) {
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
{
if is_x86_feature_detected!("avx2") {
return unsafe { swizzle_four_channels_avx(r, y) };
}
}
swizzle_four_channels_fallback(r, y);
}
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
#[target_feature(enable = "avx2")]
unsafe fn swizzle_four_channels_avx<T: Copy + Default>(r: &[&[T]], y: &mut [T]) {
swizzle_four_channels_fallback(r, y); }
#[inline(always)]
fn swizzle_four_channels_fallback<T: Copy + Default>(r: &[&[T]], y: &mut [T]) {
assert_eq!(r.len(), 4);
for ((((output, a), b), c), d) in y
.chunks_exact_mut(4)
.zip(r[0].iter())
.zip(r[1].iter())
.zip(r[2].iter())
.zip(r[3].iter())
{
output[0] = *a;
output[1] = *b;
output[2] = *c;
output[3] = *d;
}
}
pub fn swizzle_channels<T: Copy + Default + 'static>(
channels: &[Channel], output: &mut [T]
) -> Result<(), ImageErrors> {
match channels.len() {
1 => {
output.copy_from_slice(channels[0].reinterpret_as()?);
Ok(())
}
2 => {
for ((output, a), b) in output
.chunks_exact_mut(2)
.zip(channels[0].reinterpret_as()?.iter())
.zip(channels[1].reinterpret_as()?.iter())
{
output[0] = *a;
output[1] = *b;
}
Ok(())
}
3 => {
let mut r = vec![];
for c in channels {
r.push(c.reinterpret_as()?);
}
swizzle_three_channels(&r, output);
Ok(())
}
4 => {
let mut r = vec![];
for c in channels {
r.push(c.reinterpret_as()?);
}
swizzle_four_channels(&r, output);
Ok(())
}
_ => Err(ImageErrors::GenericStr(
"Image channels not in supported count, the library supports images from 1-4 channels"
))
}
}