use crate::avx::util::define_avx_butterfly;
use crate::avx::{AvxDct2Butterfly3, AvxDct2Butterfly4};
use crate::bidirectional::{BidirectionalStore, InPlaceStore};
use crate::util::DctSample;
use crate::{PxdctError, PxdctExecutor};
use num_traits::AsPrimitive;
#[derive(Debug, Clone)]
pub(crate) struct AvxDct2Butterfly12<T: DctSample> {
bf4: AvxDct2Butterfly4<T>,
bf3: AvxDct2Butterfly3<T>,
}
impl<T: DctSample> Default for AvxDct2Butterfly12<T>
where
f64: AsPrimitive<T>,
usize: AsPrimitive<T>,
{
fn default() -> Self {
Self {
bf4: AvxDct2Butterfly4::default(),
bf3: AvxDct2Butterfly3::default(),
}
}
}
impl<T: DctSample> AvxDct2Butterfly12<T>
where
f64: AsPrimitive<T>,
{
#[inline(always)]
fn exec<S: BidirectionalStore<T>>(&self, data: &mut S) {
let mut c0 = [data[0], data[7], data[8]];
let mut c1 = [data[6], data[1], data[9]];
let mut c2 = [data[5], data[10], data[2]];
let mut c3 = [data[11], data[4], data[3]];
self.bf3.exec(&mut InPlaceStore::new(&mut c0));
self.bf3.exec(&mut InPlaceStore::new(&mut c1));
self.bf3.exec(&mut InPlaceStore::new(&mut c2));
self.bf3.exec(&mut InPlaceStore::new(&mut c3));
let mut rows0 = [c0[0], c1[0], c2[0], c3[0]];
let mut rows1 = [c0[1], c1[1], c2[1], c3[1]];
let mut rows2 = [c0[2], c1[2], c2[2], c3[2]];
self.bf4.exec(&mut InPlaceStore::new(&mut rows0));
self.bf4.exec(&mut InPlaceStore::new(&mut rows1));
self.bf4.exec(&mut InPlaceStore::new(&mut rows2));
data[0] = rows0[0];
data[1] = rows1[1] + rows2[3];
data[2] = rows1[2] + rows2[2];
data[3] = rows0[1];
data[4] = rows1[0];
data[5] = rows1[3] + rows2[1];
data[6] = rows0[2];
data[7] = -rows2[3] + rows1[1];
data[8] = rows2[0];
data[9] = rows0[3];
data[10] = -rows2[2] + rows1[2];
data[11] = rows2[1] - rows1[3];
}
}
define_avx_butterfly!(AvxDct2Butterfly12, 12);