use crate::bidirectional::{BidirectionalStore, InPlaceStore};
use crate::mla::fmla;
use crate::util::{DctSample, define_in_place_butterfly};
use crate::{PxdctError, PxdctExecutor};
use num_traits::AsPrimitive;
use std::marker::PhantomData;
#[derive(Debug, Clone)]
pub(crate) struct Dct4Butterfly3<T> {
_phantom_data: PhantomData<T>,
}
impl<T: DctSample> Default for Dct4Butterfly3<T>
where
f64: AsPrimitive<T>,
{
fn default() -> Self {
Self {
_phantom_data: PhantomData {},
}
}
}
impl<T: DctSample> Dct4Butterfly3<T>
where
f64: AsPrimitive<T>,
{
#[inline(always)]
pub(crate) fn exec<S: BidirectionalStore<T>>(&self, data: &mut S) {
let identity = T::FRAC_1_SQRT_2;
let a = data[1] * identity;
let c = (data[0] + data[2]) * identity;
let s = (data[0] - data[2]) * identity;
let u0 = fmla(c, T::SQRT_3_OVER_2, s * T::HALF);
let mut v0 = fmla(c, T::HALF, -s * T::SQRT_3_OVER_2);
let mut u1 = u0 * T::HALF;
v0 *= T::SQRT_3_OVER_2;
u1 = u1 - a;
data[0] = u0 + a;
data[1] = u1 - v0;
data[2] = v0 + u1;
}
}
define_in_place_butterfly!(Dct4Butterfly3, 3);
pub(crate) trait Dct4MixedRadix5Sample {
const D4_R5_ROT_TWIDDLE_0: Self;
const D4_R5_ROT_TWIDDLE_1: Self;
const D4_R5_ROT_TWIDDLE_2: Self;
const D4_R5_ROT_TWIDDLE_3: Self;
}
impl Dct4MixedRadix5Sample for f32 {
const D4_R5_ROT_TWIDDLE_0: f32 = f32::from_bits(0x3f4f1bbd);
const D4_R5_ROT_TWIDDLE_1: f32 = f32::from_bits(0x3f167918);
const D4_R5_ROT_TWIDDLE_2: f32 = f32::from_bits(0x3f737871);
const D4_R5_ROT_TWIDDLE_3: f32 = f32::from_bits(0x3e9e377a);
}
impl Dct4MixedRadix5Sample for f64 {
const D4_R5_ROT_TWIDDLE_0: f64 = f64::from_bits(0x3fe9e3779b97f4a8);
const D4_R5_ROT_TWIDDLE_1: f64 = f64::from_bits(0x3fe2cf2304755a5e);
const D4_R5_ROT_TWIDDLE_2: f64 = f64::from_bits(0x3fee6f0e134454ff);
const D4_R5_ROT_TWIDDLE_3: f64 = f64::from_bits(0x3fd3c6ef372fe950);
}
#[derive(Debug, Clone)]
pub(crate) struct Dct4Butterfly5<T> {
_phantom_data: PhantomData<T>,
}
impl<T: DctSample> Default for Dct4Butterfly5<T>
where
f64: AsPrimitive<T>,
{
fn default() -> Self {
Self {
_phantom_data: PhantomData {},
}
}
}
impl<T: DctSample + Dct4MixedRadix5Sample> Dct4Butterfly5<T> {
#[inline(always)]
pub(crate) fn exec<S: BidirectionalStore<T>>(&self, data: &mut S) {
let a_buffer = [data[2] * T::FRAC_1_SQRT_2];
let c_buffer = [
(data[0] + data[4]) * T::FRAC_1_SQRT_2,
(data[1] + data[3]) * T::FRAC_1_SQRT_2,
];
let s_buffer = [
(data[0] - data[4]) * T::FRAC_1_SQRT_2,
(data[1] - data[3]) * T::FRAC_1_SQRT_2,
];
let c0 = c_buffer[0];
let s0 = s_buffer[0];
let s0_tw0 = s0 * T::D4_R5_ROT_TWIDDLE_1;
let s0_tw1 = -s0 * T::D4_R5_ROT_TWIDDLE_0;
let iq0 = fmla(c0, T::D4_R5_ROT_TWIDDLE_0, s0_tw0);
let siq0 = fmla(c0, T::D4_R5_ROT_TWIDDLE_1, s0_tw1);
let mut u0 = iq0;
let mut u1 = u0;
let mut v0 = siq0;
u1 *= T::D4_R5_ROT_TWIDDLE_0;
v0 *= T::D4_R5_ROT_TWIDDLE_1;
let c1 = c_buffer[1];
let s1 = s_buffer[1];
let iq1 = fmla(c1, T::D4_R5_ROT_TWIDDLE_2, s1 * T::D4_R5_ROT_TWIDDLE_3);
let siq1 = fmla(c1, T::D4_R5_ROT_TWIDDLE_3, -s1 * T::D4_R5_ROT_TWIDDLE_2);
u0 += iq1;
u1 = fmla(iq1, -T::D4_R5_ROT_TWIDDLE_3, u1);
v0 = fmla(siq1, T::D4_R5_ROT_TWIDDLE_2, v0);
let a0 = a_buffer[0];
u0 += a0;
u1 = u1 - a0;
data[0] = u0;
data[1] = u1 - v0;
data[2] = u1 + v0;
let mut u2 = iq0;
let mut v2 = siq0;
u2 *= T::D4_R5_ROT_TWIDDLE_3;
v2 *= T::D4_R5_ROT_TWIDDLE_2;
u2 = fmla(iq1, -T::D4_R5_ROT_TWIDDLE_0, u2);
v2 = fmla(siq1, -T::D4_R5_ROT_TWIDDLE_1, v2);
u2 += a0;
data[3] = u2 - v2;
data[4] = u2 + v2;
}
}
impl<T: DctSample + Dct4MixedRadix5Sample> PxdctExecutor<T> for Dct4Butterfly5<T>
where
f64: AsPrimitive<T>,
{
fn execute(&self, data: &mut [T]) -> Result<(), PxdctError> {
if !data.len().is_multiple_of(5) {
return Err(PxdctError::InvalidSizeMultiplier(data.len(), self.length()));
}
for chunk in data.as_chunks_mut::<5>().0.iter_mut() {
self.exec(&mut InPlaceStore::new(chunk));
}
Ok(())
}
fn execute_with_scratch(&self, data: &mut [T], _: &mut [T]) -> Result<(), PxdctError> {
self.execute(data)
}
fn execute_into(&self, input: &[T], output: &mut [T]) -> Result<(), PxdctError> {
self.execute_into_with_scratch(input, output, &mut [])
}
fn execute_into_with_scratch(
&self,
input: &[T],
output: &mut [T],
_: &mut [T],
) -> Result<(), PxdctError> {
use crate::util::validate_oof_sizes;
validate_oof_sizes!(input, output, 5);
use crate::bidirectional::BiStore;
for (src, dst) in input
.as_chunks::<5>()
.0
.iter()
.zip(output.as_chunks_mut::<5>().0.iter_mut())
{
self.exec(&mut BiStore::new(src, dst));
}
Ok(())
}
fn length(&self) -> usize {
5
}
fn scratch_size(&self) -> usize {
0
}
}
pub(crate) trait Dct4MixedRadix7Sample {
const D4_R7_ROT_TWIDDLE_0: Self;
const D4_R7_ROT_TWIDDLE_1: Self;
const D4_R7_ROT_TWIDDLE_2: Self;
const D4_R7_ROT_TWIDDLE_3: Self;
const D4_R7_ROT_TWIDDLE_4: Self;
const D4_R7_ROT_TWIDDLE_5: Self;
}
impl Dct4MixedRadix7Sample for f32 {
const D4_R7_ROT_TWIDDLE_0: f32 = f32::from_bits(0x3f48261c);
const D4_R7_ROT_TWIDDLE_1: f32 = f32::from_bits(0x3f1f9d07);
const D4_R7_ROT_TWIDDLE_2: f32 = f32::from_bits(0x3f66a5e5);
const D4_R7_ROT_TWIDDLE_3: f32 = f32::from_bits(0x3ede2602);
const D4_R7_ROT_TWIDDLE_4: f32 = f32::from_bits(0x3e63dc87);
const D4_R7_ROT_TWIDDLE_5: f32 = f32::from_bits(0x3f7994e0);
}
impl Dct4MixedRadix7Sample for f64 {
const D4_R7_ROT_TWIDDLE_0: f64 = f64::from_bits(0x3fe904c37505de4b);
const D4_R7_ROT_TWIDDLE_1: f64 = f64::from_bits(0x3fe3f3a0e28bedd1);
const D4_R7_ROT_TWIDDLE_2: f64 = f64::from_bits(0x3fecd4bca9cb5c71);
const D4_R7_ROT_TWIDDLE_3: f64 = f64::from_bits(0x3fdbc4c04d71abc1);
const D4_R7_ROT_TWIDDLE_4: f64 = f64::from_bits(0x3fcc7b90e3024585);
const D4_R7_ROT_TWIDDLE_5: f64 = f64::from_bits(0x3fef329c0558e969);
}
#[derive(Debug, Clone)]
pub(crate) struct Dct4Butterfly7<T> {
_phantom: PhantomData<T>,
}
impl<T: DctSample> Default for Dct4Butterfly7<T>
where
f64: AsPrimitive<T>,
{
fn default() -> Self {
Self {
_phantom: PhantomData,
}
}
}
impl<T: DctSample + Dct4MixedRadix7Sample> Dct4Butterfly7<T> {
#[inline(always)]
pub(crate) fn exec<S: BidirectionalStore<T>>(&self, data: &mut S) {
let a_buffer = [data[3] * T::FRAC_1_SQRT_2];
let c_buffer = [
(data[0] + data[6]) * T::FRAC_1_SQRT_2,
(data[1] + data[5]) * T::FRAC_1_SQRT_2,
(data[2] + data[4]) * T::FRAC_1_SQRT_2,
];
let s_buffer = [
(data[0] - data[6]) * T::FRAC_1_SQRT_2,
(data[1] - data[5]) * T::FRAC_1_SQRT_2,
(data[2] - data[4]) * T::FRAC_1_SQRT_2,
];
let c0 = c_buffer[0];
let s0 = s_buffer[0];
let s0_tw0 = s0 * T::D4_R7_ROT_TWIDDLE_1;
let s0_tw1 = -s0 * T::D4_R7_ROT_TWIDDLE_0;
let iq0 = fmla(c0, T::D4_R7_ROT_TWIDDLE_0, s0_tw0);
let siq0 = fmla(c0, T::D4_R7_ROT_TWIDDLE_1, s0_tw1);
let mut u0 = iq0;
let mut u1 = u0;
let mut v0 = siq0;
u1 *= T::D4_R7_ROT_TWIDDLE_2;
v0 *= T::D4_R7_ROT_TWIDDLE_3;
let c1 = c_buffer[1];
let s1 = s_buffer[1];
let iq1 = fmla(c1, T::D4_R7_ROT_TWIDDLE_2, s1 * T::D4_R7_ROT_TWIDDLE_3);
let siq1 = fmla(c1, T::D4_R7_ROT_TWIDDLE_3, -s1 * T::D4_R7_ROT_TWIDDLE_2);
u0 += iq1;
u1 = fmla(iq1, T::D4_R7_ROT_TWIDDLE_4, u1);
v0 = fmla(siq1, T::D4_R7_ROT_TWIDDLE_5, v0);
let c2 = c_buffer[2];
let s2 = s_buffer[2];
let iq2 = fmla(c2, T::D4_R7_ROT_TWIDDLE_5, s2 * T::D4_R7_ROT_TWIDDLE_4);
let siq2 = fmla(c2, T::D4_R7_ROT_TWIDDLE_4, -s2 * T::D4_R7_ROT_TWIDDLE_5);
u0 += iq2;
u1 = fmla(iq2, -T::D4_R7_ROT_TWIDDLE_1, u1);
v0 = fmla(siq2, T::D4_R7_ROT_TWIDDLE_0, v0);
let a0 = a_buffer[0];
u0 += a0;
u1 = u1 - a0;
data[0] = u0;
data[1] = u1 - v0;
data[2] = u1 + v0;
let mut u2 = iq0;
let mut v2 = siq0;
u2 *= T::D4_R7_ROT_TWIDDLE_1;
v2 *= T::D4_R7_ROT_TWIDDLE_0;
u2 = fmla(iq1, -T::D4_R7_ROT_TWIDDLE_2, u2);
v2 = fmla(siq1, T::D4_R7_ROT_TWIDDLE_3, v2);
u2 = fmla(iq2, -T::D4_R7_ROT_TWIDDLE_4, u2);
v2 = fmla(siq2, -T::D4_R7_ROT_TWIDDLE_5, v2);
u2 += a0;
data[3] = u2 - v2;
data[4] = u2 + v2;
let mut u3 = iq0;
let mut v3 = siq0;
u3 *= T::D4_R7_ROT_TWIDDLE_4;
v3 *= T::D4_R7_ROT_TWIDDLE_5;
u3 = fmla(iq1, -T::D4_R7_ROT_TWIDDLE_1, u3);
v3 = fmla(siq1, -T::D4_R7_ROT_TWIDDLE_0, v3);
u3 = fmla(iq2, T::D4_R7_ROT_TWIDDLE_2, u3);
v3 = fmla(siq2, T::D4_R7_ROT_TWIDDLE_3, v3);
u3 = u3 - a0;
data[5] = u3 - v3;
data[6] = u3 + v3;
}
}
impl<T: DctSample + Dct4MixedRadix7Sample> PxdctExecutor<T> for Dct4Butterfly7<T>
where
f64: AsPrimitive<T>,
{
fn execute(&self, data: &mut [T]) -> Result<(), PxdctError> {
if !data.len().is_multiple_of(7) {
return Err(PxdctError::InvalidSizeMultiplier(data.len(), self.length()));
}
for chunk in data.as_chunks_mut::<7>().0.iter_mut() {
self.exec(&mut InPlaceStore::new(chunk));
}
Ok(())
}
fn execute_with_scratch(&self, data: &mut [T], _: &mut [T]) -> Result<(), PxdctError> {
self.execute(data)
}
fn execute_into(&self, input: &[T], output: &mut [T]) -> Result<(), PxdctError> {
self.execute_into_with_scratch(input, output, &mut [])
}
fn execute_into_with_scratch(
&self,
input: &[T],
output: &mut [T],
_: &mut [T],
) -> Result<(), PxdctError> {
use crate::util::validate_oof_sizes;
validate_oof_sizes!(input, output, 7);
use crate::bidirectional::BiStore;
for (src, dst) in input
.as_chunks::<7>()
.0
.iter()
.zip(output.as_chunks_mut::<7>().0.iter_mut())
{
self.exec(&mut BiStore::new(src, dst));
}
Ok(())
}
fn length(&self) -> usize {
7
}
fn scratch_size(&self) -> usize {
0
}
}
pub(crate) trait Dct4MixedRadix11Sample {
const D4_R11_ROT_TWIDDLE_0: Self;
const D4_R11_ROT_TWIDDLE_1: Self;
const D4_R11_ROT_TWIDDLE_2: Self;
const D4_R11_ROT_TWIDDLE_3: Self;
const D4_R11_ROT_TWIDDLE_4: Self;
const D4_R11_ROT_TWIDDLE_5: Self;
const D4_R11_ROT_TWIDDLE_6: Self;
const D4_R11_ROT_TWIDDLE_7: Self;
const D4_R11_ROT_TWIDDLE_8: Self;
const D4_R11_ROT_TWIDDLE_9: Self;
}
impl Dct4MixedRadix11Sample for f32 {
const D4_R11_ROT_TWIDDLE_0: f32 = f32::from_bits(0x3f4178ce);
const D4_R11_ROT_TWIDDLE_1: f32 = f32::from_bits(0x3f27a4f4);
const D4_R11_ROT_TWIDDLE_2: f32 = f32::from_bits(0x3f75a155);
const D4_R11_ROT_TWIDDLE_3: f32 = f32::from_bits(0x3e903f40);
const D4_R11_ROT_TWIDDLE_4: f32 = f32::from_bits(0x3f575c64);
const D4_R11_ROT_TWIDDLE_5: f32 = f32::from_bits(0x3f0a6770);
const D4_R11_ROT_TWIDDLE_6: f32 = f32::from_bits(0x3f68dda4);
const D4_R11_ROT_TWIDDLE_7: f32 = f32::from_bits(0x3ed4b147);
const D4_R11_ROT_TWIDDLE_8: f32 = f32::from_bits(0x3e11bafb);
const D4_R11_ROT_TWIDDLE_9: f32 = f32::from_bits(0x3f7d64f0);
}
impl Dct4MixedRadix11Sample for f64 {
const D4_R11_ROT_TWIDDLE_0: f64 = f64::from_bits(0x3fe82f19bb3a28a1);
const D4_R11_ROT_TWIDDLE_1: f64 = f64::from_bits(0x3fe4f49e7f775887);
const D4_R11_ROT_TWIDDLE_2: f64 = f64::from_bits(0x3feeb42a9bcd5057);
const D4_R11_ROT_TWIDDLE_3: f64 = f64::from_bits(0x3fd207e7fd768dc0);
const D4_R11_ROT_TWIDDLE_4: f64 = f64::from_bits(0x3feaeb8c8764f0ba);
const D4_R11_ROT_TWIDDLE_5: f64 = f64::from_bits(0x3fe14cedf8bb580b);
const D4_R11_ROT_TWIDDLE_6: f64 = f64::from_bits(0x3fed1bb48eee2c13);
const D4_R11_ROT_TWIDDLE_7: f64 = f64::from_bits(0x3fda9628d9c712b5);
const D4_R11_ROT_TWIDDLE_8: f64 = f64::from_bits(0x3fc2375f640f44dd);
const D4_R11_ROT_TWIDDLE_9: f64 = f64::from_bits(0x3fefac9e043842ef);
}
#[derive(Debug, Clone)]
pub(crate) struct Dct4Butterfly11<T> {
_phantom: PhantomData<T>,
}
impl<T: DctSample> Default for Dct4Butterfly11<T>
where
f64: AsPrimitive<T>,
{
fn default() -> Self {
Self {
_phantom: PhantomData,
}
}
}
impl<T: DctSample + Dct4MixedRadix11Sample> Dct4Butterfly11<T> {
#[inline(always)]
pub(crate) fn exec<S: BidirectionalStore<T>>(&self, data: &mut S) {
let a_buffer = [data[5] * T::FRAC_1_SQRT_2];
let c_buffer = [
(data[0] + data[10]) * T::FRAC_1_SQRT_2,
(data[1] + data[9]) * T::FRAC_1_SQRT_2,
(data[2] + data[8]) * T::FRAC_1_SQRT_2,
(data[3] + data[7]) * T::FRAC_1_SQRT_2,
(data[4] + data[6]) * T::FRAC_1_SQRT_2,
];
let s_buffer = [
(data[0] - data[10]) * T::FRAC_1_SQRT_2,
(data[1] - data[9]) * T::FRAC_1_SQRT_2,
(data[2] - data[8]) * T::FRAC_1_SQRT_2,
(data[3] - data[7]) * T::FRAC_1_SQRT_2,
(data[4] - data[6]) * T::FRAC_1_SQRT_2,
];
let c0 = c_buffer[0];
let s0 = s_buffer[0];
let s0_tw0 = s0 * T::D4_R11_ROT_TWIDDLE_1;
let s0_tw1 = -s0 * T::D4_R11_ROT_TWIDDLE_0;
let iq0 = fmla(c0, T::D4_R11_ROT_TWIDDLE_0, s0_tw0);
let siq0 = fmla(c0, T::D4_R11_ROT_TWIDDLE_1, s0_tw1);
let mut u0 = iq0;
let mut u1 = u0;
let mut v0 = siq0;
u1 *= T::D4_R11_ROT_TWIDDLE_2;
v0 *= T::D4_R11_ROT_TWIDDLE_3;
let c1 = c_buffer[1];
let s1 = s_buffer[1];
let iq1 = fmla(c1, T::D4_R11_ROT_TWIDDLE_4, s1 * T::D4_R11_ROT_TWIDDLE_5);
let siq1 = fmla(c1, T::D4_R11_ROT_TWIDDLE_5, -s1 * T::D4_R11_ROT_TWIDDLE_4);
u0 += iq1;
u1 = fmla(iq1, T::D4_R11_ROT_TWIDDLE_1, u1);
v0 = fmla(siq1, T::D4_R11_ROT_TWIDDLE_0, v0);
let c2 = c_buffer[2];
let s2 = s_buffer[2];
let iq2 = fmla(c2, T::D4_R11_ROT_TWIDDLE_6, s2 * T::D4_R11_ROT_TWIDDLE_7);
let siq2 = fmla(c2, T::D4_R11_ROT_TWIDDLE_7, -s2 * T::D4_R11_ROT_TWIDDLE_6);
u0 += iq2;
u1 = fmla(iq2, T::D4_R11_ROT_TWIDDLE_8, u1);
v0 = fmla(siq2, T::D4_R11_ROT_TWIDDLE_9, v0);
let c3 = c_buffer[3];
let s3 = s_buffer[3];
let iq3 = fmla(c3, T::D4_R11_ROT_TWIDDLE_2, s3 * T::D4_R11_ROT_TWIDDLE_3);
let siq3 = fmla(c3, T::D4_R11_ROT_TWIDDLE_3, -s3 * T::D4_R11_ROT_TWIDDLE_2);
u0 += iq3;
u1 = fmla(iq3, -T::D4_R11_ROT_TWIDDLE_7, u1);
v0 = fmla(siq3, T::D4_R11_ROT_TWIDDLE_6, v0);
let c4 = c_buffer[4];
let s4 = s_buffer[4];
let iq4 = fmla(c4, T::D4_R11_ROT_TWIDDLE_9, s4 * T::D4_R11_ROT_TWIDDLE_8);
let siq4 = fmla(c4, T::D4_R11_ROT_TWIDDLE_8, -s4 * T::D4_R11_ROT_TWIDDLE_9);
u0 += iq4;
u1 = fmla(iq4, -T::D4_R11_ROT_TWIDDLE_4, u1);
v0 = fmla(siq4, T::D4_R11_ROT_TWIDDLE_5, v0);
let a0 = a_buffer[0];
u0 += a0;
u1 = u1 - a0;
data[0] = u0;
data[1] = u1 - v0;
data[2] = u1 + v0;
let mut u2 = iq0;
let mut v2 = siq0;
u2 *= T::D4_R11_ROT_TWIDDLE_4;
v2 *= T::D4_R11_ROT_TWIDDLE_5;
u2 = fmla(iq1, -T::D4_R11_ROT_TWIDDLE_8, u2);
v2 = fmla(siq1, T::D4_R11_ROT_TWIDDLE_9, v2);
u2 = fmla(iq2, -T::D4_R11_ROT_TWIDDLE_2, u2);
v2 = fmla(siq2, T::D4_R11_ROT_TWIDDLE_3, v2);
u2 = fmla(iq3, -T::D4_R11_ROT_TWIDDLE_1, u2);
v2 = fmla(siq3, -T::D4_R11_ROT_TWIDDLE_0, v2);
u2 = fmla(iq4, T::D4_R11_ROT_TWIDDLE_7, u2);
v2 = fmla(siq4, -T::D4_R11_ROT_TWIDDLE_6, v2);
u2 += a0;
data[3] = u2 - v2;
data[4] = u2 + v2;
let mut u3 = iq0;
let mut v3 = siq0;
u3 *= T::D4_R11_ROT_TWIDDLE_1;
v3 *= T::D4_R11_ROT_TWIDDLE_0;
u3 = fmla(iq1, -T::D4_R11_ROT_TWIDDLE_4, u3);
v3 = fmla(siq1, T::D4_R11_ROT_TWIDDLE_5, v3);
u3 = fmla(iq2, -T::D4_R11_ROT_TWIDDLE_7, u3);
v3 = fmla(siq2, -T::D4_R11_ROT_TWIDDLE_6, v3);
u3 = fmla(iq3, T::D4_R11_ROT_TWIDDLE_2, u3);
v3 = fmla(siq3, -T::D4_R11_ROT_TWIDDLE_3, v3);
u3 = fmla(iq4, T::D4_R11_ROT_TWIDDLE_8, u3);
v3 = fmla(siq4, T::D4_R11_ROT_TWIDDLE_9, v3);
u3 = u3 - a0;
data[5] = u3 - v3;
data[6] = u3 + v3;
let mut u4 = iq0;
let mut v4 = siq0;
u4 *= T::D4_R11_ROT_TWIDDLE_7;
v4 *= T::D4_R11_ROT_TWIDDLE_6;
u4 = fmla(iq1, -T::D4_R11_ROT_TWIDDLE_2, u4);
v4 = fmla(siq1, -T::D4_R11_ROT_TWIDDLE_3, v4);
u4 = fmla(iq2, T::D4_R11_ROT_TWIDDLE_4, u4);
v4 = fmla(siq2, -T::D4_R11_ROT_TWIDDLE_5, v4);
u4 = fmla(iq3, -T::D4_R11_ROT_TWIDDLE_8, u4);
v4 = fmla(siq3, T::D4_R11_ROT_TWIDDLE_9, v4);
u4 = fmla(iq4, -T::D4_R11_ROT_TWIDDLE_1, u4);
v4 = fmla(siq4, -T::D4_R11_ROT_TWIDDLE_0, v4);
u4 += a0;
data[7] = u4 - v4;
data[8] = u4 + v4;
let mut u5 = iq0;
let mut v5 = siq0;
u5 *= T::D4_R11_ROT_TWIDDLE_8;
v5 *= T::D4_R11_ROT_TWIDDLE_9;
u5 = fmla(iq1, -T::D4_R11_ROT_TWIDDLE_7, u5);
v5 = fmla(siq1, -T::D4_R11_ROT_TWIDDLE_6, v5);
u5 = fmla(iq2, T::D4_R11_ROT_TWIDDLE_1, u5);
v5 = fmla(siq2, T::D4_R11_ROT_TWIDDLE_0, v5);
u5 = fmla(iq3, -T::D4_R11_ROT_TWIDDLE_4, u5);
v5 = fmla(siq3, -T::D4_R11_ROT_TWIDDLE_5, v5);
u5 = fmla(iq4, T::D4_R11_ROT_TWIDDLE_2, u5);
v5 = fmla(siq4, T::D4_R11_ROT_TWIDDLE_3, v5);
u5 = u5 - a0;
data[9] = u5 - v5;
data[10] = u5 + v5;
}
}
impl<T: DctSample + Dct4MixedRadix11Sample> PxdctExecutor<T> for Dct4Butterfly11<T>
where
f64: AsPrimitive<T>,
{
fn execute(&self, data: &mut [T]) -> Result<(), PxdctError> {
if !data.len().is_multiple_of(11) {
return Err(PxdctError::InvalidSizeMultiplier(data.len(), self.length()));
}
for chunk in data.as_chunks_mut::<11>().0.iter_mut() {
self.exec(&mut InPlaceStore::new(chunk));
}
Ok(())
}
fn execute_with_scratch(&self, data: &mut [T], _: &mut [T]) -> Result<(), PxdctError> {
self.execute(data)
}
fn execute_into(&self, input: &[T], output: &mut [T]) -> Result<(), PxdctError> {
self.execute_into_with_scratch(input, output, &mut [])
}
fn execute_into_with_scratch(
&self,
input: &[T],
output: &mut [T],
_: &mut [T],
) -> Result<(), PxdctError> {
use crate::util::validate_oof_sizes;
validate_oof_sizes!(input, output, 11);
use crate::bidirectional::BiStore;
for (src, dst) in input
.as_chunks::<11>()
.0
.iter()
.zip(output.as_chunks_mut::<11>().0.iter_mut())
{
self.exec(&mut BiStore::new(src, dst));
}
Ok(())
}
fn length(&self) -> usize {
11
}
fn scratch_size(&self) -> usize {
0
}
}
pub(crate) trait Dct4MixedRadix13Sample {
const D4_R13_ROT_TWIDDLE_0: Self;
const D4_R13_ROT_TWIDDLE_1: Self;
const D4_R13_ROT_TWIDDLE_2: Self;
const D4_R13_ROT_TWIDDLE_3: Self;
const D4_R13_ROT_TWIDDLE_4: Self;
const D4_R13_ROT_TWIDDLE_5: Self;
const D4_R13_ROT_TWIDDLE_6: Self;
const D4_R13_ROT_TWIDDLE_7: Self;
const D4_R13_ROT_TWIDDLE_8: Self;
const D4_R13_ROT_TWIDDLE_9: Self;
const D4_R13_ROT_TWIDDLE_10: Self;
const D4_R13_ROT_TWIDDLE_11: Self;
}
impl Dct4MixedRadix13Sample for f32 {
const D4_R13_ROT_TWIDDLE_0: f32 = f32::from_bits(0x3f3f9e67);
const D4_R13_ROT_TWIDDLE_1: f32 = f32::from_bits(0x3f29c268);
const D4_R13_ROT_TWIDDLE_2: f32 = f32::from_bits(0x3f788fa5);
const D4_R13_ROT_TWIDDLE_3: f32 = f32::from_bits(0x3e750f2a);
const D4_R13_ROT_TWIDDLE_4: f32 = f32::from_bits(0x3f52af12);
const D4_R13_ROT_TWIDDLE_5: f32 = f32::from_bits(0x3f116cb1);
const D4_R13_ROT_TWIDDLE_6: f32 = f32::from_bits(0x3f62ad3f);
const D4_R13_ROT_TWIDDLE_7: f32 = f32::from_bits(0x3eedf032);
const D4_R13_ROT_TWIDDLE_8: f32 = f32::from_bits(0x3eb58ec6);
const D4_R13_ROT_TWIDDLE_9: f32 = f32::from_bits(0x3f6f5d39);
const D4_R13_ROT_TWIDDLE_10: f32 = f32::from_bits(0xbdf6dbef);
const D4_R13_ROT_TWIDDLE_11: f32 = f32::from_bits(0x3f7e222b);
}
impl Dct4MixedRadix13Sample for f64 {
const D4_R13_ROT_TWIDDLE_0: f64 = f64::from_bits(0x3fe7f3ccd0032e0c);
const D4_R13_ROT_TWIDDLE_1: f64 = f64::from_bits(0x3fe5384d024c2f84);
const D4_R13_ROT_TWIDDLE_2: f64 = f64::from_bits(0x3fef11f493053d00);
const D4_R13_ROT_TWIDDLE_3: f64 = f64::from_bits(0x3fcea1e54bc48dbf);
const D4_R13_ROT_TWIDDLE_4: f64 = f64::from_bits(0x3fea55e242a4c3d2);
const D4_R13_ROT_TWIDDLE_5: f64 = f64::from_bits(0x3fe22d961ea71119);
const D4_R13_ROT_TWIDDLE_6: f64 = f64::from_bits(0x3fec55a7e00740e9);
const D4_R13_ROT_TWIDDLE_7: f64 = f64::from_bits(0x3fddbe064267c47c);
const D4_R13_ROT_TWIDDLE_8: f64 = f64::from_bits(0x3fd6b1d8b2365da0);
const D4_R13_ROT_TWIDDLE_9: f64 = f64::from_bits(0x3fedeba72ef20147);
const D4_R13_ROT_TWIDDLE_10: f64 = f64::from_bits(0xbfbedb7debaa3ed3);
const D4_R13_ROT_TWIDDLE_11: f64 = f64::from_bits(0x3fefc44566966769);
}
#[derive(Debug, Clone)]
pub(crate) struct Dct4Butterfly13<T> {
_phantom: PhantomData<T>,
}
impl<T: DctSample> Default for Dct4Butterfly13<T>
where
f64: AsPrimitive<T>,
{
fn default() -> Self {
Self {
_phantom: PhantomData,
}
}
}
impl<T: DctSample + Dct4MixedRadix13Sample> Dct4Butterfly13<T> {
#[inline(always)]
pub(crate) fn exec<S: BidirectionalStore<T>>(&self, data: &mut S) {
let a_buffer = [data[6] * T::FRAC_1_SQRT_2];
let c_buffer = [
(data[0] + data[12]) * T::FRAC_1_SQRT_2,
(data[1] + data[11]) * T::FRAC_1_SQRT_2,
(data[2] + data[10]) * T::FRAC_1_SQRT_2,
(data[3] + data[9]) * T::FRAC_1_SQRT_2,
(data[4] + data[8]) * T::FRAC_1_SQRT_2,
(data[5] + data[7]) * T::FRAC_1_SQRT_2,
];
let s_buffer = [
(data[0] - data[12]) * T::FRAC_1_SQRT_2,
(data[1] - data[11]) * T::FRAC_1_SQRT_2,
(data[2] - data[10]) * T::FRAC_1_SQRT_2,
(data[3] - data[9]) * T::FRAC_1_SQRT_2,
(data[4] - data[8]) * T::FRAC_1_SQRT_2,
(data[5] - data[7]) * T::FRAC_1_SQRT_2,
];
let c0 = c_buffer[0];
let s0 = s_buffer[0];
let s0_tw0 = s0 * T::D4_R13_ROT_TWIDDLE_1;
let s0_tw1 = -s0 * T::D4_R13_ROT_TWIDDLE_0;
let iq0 = fmla(c0, T::D4_R13_ROT_TWIDDLE_0, s0_tw0);
let siq0 = fmla(c0, T::D4_R13_ROT_TWIDDLE_1, s0_tw1);
let mut u0 = iq0;
let mut u1 = u0;
let mut v0 = siq0;
u1 *= T::D4_R13_ROT_TWIDDLE_2;
v0 *= T::D4_R13_ROT_TWIDDLE_3;
let c1 = c_buffer[1];
let s1 = s_buffer[1];
let iq1 = fmla(c1, T::D4_R13_ROT_TWIDDLE_4, s1 * T::D4_R13_ROT_TWIDDLE_5);
let siq1 = fmla(c1, T::D4_R13_ROT_TWIDDLE_5, -s1 * T::D4_R13_ROT_TWIDDLE_4);
u0 += iq1;
u1 = fmla(iq1, T::D4_R13_ROT_TWIDDLE_0, u1);
v0 = fmla(siq1, T::D4_R13_ROT_TWIDDLE_1, v0);
let c2 = c_buffer[2];
let s2 = s_buffer[2];
let iq2 = fmla(c2, T::D4_R13_ROT_TWIDDLE_6, s2 * T::D4_R13_ROT_TWIDDLE_7);
let siq2 = fmla(c2, T::D4_R13_ROT_TWIDDLE_7, -s2 * T::D4_R13_ROT_TWIDDLE_6);
u0 += iq2;
u1 = fmla(iq2, T::D4_R13_ROT_TWIDDLE_8, u1);
v0 = fmla(siq2, T::D4_R13_ROT_TWIDDLE_9, v0);
let c3 = c_buffer[3];
let s3 = s_buffer[3];
let iq3 = fmla(c3, T::D4_R13_ROT_TWIDDLE_9, s3 * T::D4_R13_ROT_TWIDDLE_8);
let siq3 = fmla(c3, T::D4_R13_ROT_TWIDDLE_8, -s3 * T::D4_R13_ROT_TWIDDLE_9);
u0 += iq3;
u1 = fmla(iq3, T::D4_R13_ROT_TWIDDLE_10, u1);
v0 = fmla(siq3, T::D4_R13_ROT_TWIDDLE_11, v0);
let c4 = c_buffer[4];
let s4 = s_buffer[4];
let iq4 = fmla(c4, T::D4_R13_ROT_TWIDDLE_2, s4 * T::D4_R13_ROT_TWIDDLE_3);
let siq4 = fmla(c4, T::D4_R13_ROT_TWIDDLE_3, -s4 * T::D4_R13_ROT_TWIDDLE_2);
u0 += iq4;
u1 = fmla(iq4, -T::D4_R13_ROT_TWIDDLE_5, u1);
v0 = fmla(siq4, T::D4_R13_ROT_TWIDDLE_4, v0);
let c5 = c_buffer[5];
let s5 = s_buffer[5];
let iq5 = fmla(c5, T::D4_R13_ROT_TWIDDLE_11, s5 * -T::D4_R13_ROT_TWIDDLE_10);
let siq5 = fmla(
c5,
-T::D4_R13_ROT_TWIDDLE_10,
-s5 * T::D4_R13_ROT_TWIDDLE_11,
);
u0 += iq5;
u1 = fmla(iq5, -T::D4_R13_ROT_TWIDDLE_6, u1);
v0 = fmla(siq5, T::D4_R13_ROT_TWIDDLE_7, v0);
let a0 = a_buffer[0];
u0 += a0;
u1 = u1 - a0;
data[0] = u0;
data[1] = u1 - v0;
data[2] = u1 + v0;
let mut u2 = iq0;
let mut v2 = siq0;
u2 *= T::D4_R13_ROT_TWIDDLE_6;
v2 *= T::D4_R13_ROT_TWIDDLE_7;
u2 = fmla(iq1, -T::D4_R13_ROT_TWIDDLE_10, u2);
v2 = fmla(siq1, T::D4_R13_ROT_TWIDDLE_11, v2);
u2 = fmla(iq2, -T::D4_R13_ROT_TWIDDLE_0, u2);
v2 = fmla(siq2, T::D4_R13_ROT_TWIDDLE_1, v2);
u2 = fmla(iq3, -T::D4_R13_ROT_TWIDDLE_2, u2);
v2 = fmla(siq3, -T::D4_R13_ROT_TWIDDLE_3, v2);
u2 = fmla(iq4, -T::D4_R13_ROT_TWIDDLE_8, u2);
v2 = fmla(siq4, -T::D4_R13_ROT_TWIDDLE_9, v2);
u2 = fmla(iq5, T::D4_R13_ROT_TWIDDLE_5, u2);
v2 = fmla(siq5, -T::D4_R13_ROT_TWIDDLE_4, v2);
u2 += a0;
data[3] = u2 - v2;
data[4] = u2 + v2;
let mut u3 = iq0;
let mut v3 = siq0;
u3 *= T::D4_R13_ROT_TWIDDLE_0;
v3 *= T::D4_R13_ROT_TWIDDLE_1;
u3 = fmla(iq1, -T::D4_R13_ROT_TWIDDLE_5, u3);
v3 = fmla(siq1, T::D4_R13_ROT_TWIDDLE_4, v3);
u3 = fmla(iq2, -T::D4_R13_ROT_TWIDDLE_6, u3);
v3 = fmla(siq2, -T::D4_R13_ROT_TWIDDLE_7, v3);
u3 = fmla(iq3, T::D4_R13_ROT_TWIDDLE_8, u3);
v3 = fmla(siq3, -T::D4_R13_ROT_TWIDDLE_9, v3);
u3 = fmla(iq4, T::D4_R13_ROT_TWIDDLE_2, u3);
v3 = fmla(siq4, T::D4_R13_ROT_TWIDDLE_3, v3);
u3 = fmla(iq5, T::D4_R13_ROT_TWIDDLE_10, u3);
v3 = fmla(siq5, T::D4_R13_ROT_TWIDDLE_11, v3);
u3 = u3 - a0;
data[5] = u3 - v3;
data[6] = u3 + v3;
let mut u4 = iq0;
let mut v4 = siq0;
u4 *= T::D4_R13_ROT_TWIDDLE_5;
v4 *= T::D4_R13_ROT_TWIDDLE_4;
u4 = fmla(iq1, -T::D4_R13_ROT_TWIDDLE_2, u4);
v4 = fmla(siq1, T::D4_R13_ROT_TWIDDLE_3, v4);
u4 = fmla(iq2, -T::D4_R13_ROT_TWIDDLE_10, u4);
v4 = fmla(siq2, -T::D4_R13_ROT_TWIDDLE_11, v4);
u4 = fmla(iq3, T::D4_R13_ROT_TWIDDLE_6, u4);
v4 = fmla(siq3, T::D4_R13_ROT_TWIDDLE_7, v4);
u4 = fmla(iq4, -T::D4_R13_ROT_TWIDDLE_0, u4);
v4 = fmla(siq4, T::D4_R13_ROT_TWIDDLE_1, v4);
u4 = fmla(iq5, -T::D4_R13_ROT_TWIDDLE_8, u4);
v4 = fmla(siq5, -T::D4_R13_ROT_TWIDDLE_9, v4);
u4 += a0;
data[7] = u4 - v4;
data[8] = u4 + v4;
let mut u5 = iq0;
let mut v5 = siq0;
u5 *= T::D4_R13_ROT_TWIDDLE_8;
v5 *= T::D4_R13_ROT_TWIDDLE_9;
u5 = fmla(iq1, -T::D4_R13_ROT_TWIDDLE_6, u5);
v5 = fmla(siq1, -T::D4_R13_ROT_TWIDDLE_7, v5);
u5 = fmla(iq2, T::D4_R13_ROT_TWIDDLE_2, u5);
v5 = fmla(siq2, -T::D4_R13_ROT_TWIDDLE_3, v5);
u5 = fmla(iq3, -T::D4_R13_ROT_TWIDDLE_5, u5);
v5 = fmla(siq3, T::D4_R13_ROT_TWIDDLE_4, v5);
u5 = fmla(iq4, T::D4_R13_ROT_TWIDDLE_10, u5);
v5 = fmla(siq4, -T::D4_R13_ROT_TWIDDLE_11, v5);
u5 = fmla(iq5, T::D4_R13_ROT_TWIDDLE_0, u5);
v5 = fmla(siq5, T::D4_R13_ROT_TWIDDLE_1, v5);
u5 = u5 - a0;
data[9] = u5 - v5;
data[10] = u5 + v5;
let mut u6 = iq0;
let mut v6 = siq0;
u6 *= -T::D4_R13_ROT_TWIDDLE_10;
v6 *= T::D4_R13_ROT_TWIDDLE_11;
u6 = fmla(iq1, -T::D4_R13_ROT_TWIDDLE_8, u6);
v6 = fmla(siq1, -T::D4_R13_ROT_TWIDDLE_9, v6);
u6 = fmla(iq2, T::D4_R13_ROT_TWIDDLE_5, u6);
v6 = fmla(siq2, T::D4_R13_ROT_TWIDDLE_4, v6);
u6 = fmla(iq3, -T::D4_R13_ROT_TWIDDLE_0, u6);
v6 = fmla(siq3, -T::D4_R13_ROT_TWIDDLE_1, v6);
u6 = fmla(iq4, T::D4_R13_ROT_TWIDDLE_6, u6);
v6 = fmla(siq4, T::D4_R13_ROT_TWIDDLE_7, v6);
u6 = fmla(iq5, -T::D4_R13_ROT_TWIDDLE_2, u6);
v6 = fmla(siq5, -T::D4_R13_ROT_TWIDDLE_3, v6);
u6 += a0;
data[11] = u6 - v6;
data[12] = u6 + v6;
}
}
impl<T: DctSample + Dct4MixedRadix13Sample> PxdctExecutor<T> for Dct4Butterfly13<T>
where
f64: AsPrimitive<T>,
{
fn execute(&self, data: &mut [T]) -> Result<(), PxdctError> {
if !data.len().is_multiple_of(13) {
return Err(PxdctError::InvalidSizeMultiplier(data.len(), self.length()));
}
for chunk in data.as_chunks_mut::<13>().0.iter_mut() {
self.exec(&mut InPlaceStore::new(chunk));
}
Ok(())
}
fn execute_with_scratch(&self, data: &mut [T], _: &mut [T]) -> Result<(), PxdctError> {
self.execute(data)
}
fn execute_into(&self, input: &[T], output: &mut [T]) -> Result<(), PxdctError> {
self.execute_into_with_scratch(input, output, &mut [])
}
fn execute_into_with_scratch(
&self,
input: &[T],
output: &mut [T],
_: &mut [T],
) -> Result<(), PxdctError> {
use crate::util::validate_oof_sizes;
validate_oof_sizes!(input, output, 13);
use crate::bidirectional::BiStore;
for (src, dst) in input
.as_chunks::<13>()
.0
.iter()
.zip(output.as_chunks_mut::<13>().0.iter_mut())
{
self.exec(&mut BiStore::new(src, dst));
}
Ok(())
}
fn length(&self) -> usize {
13
}
fn scratch_size(&self) -> usize {
0
}
}
pub(crate) trait Dct4MixedRadix17Sample {
const D4_R17_ROT_TWIDDLE_0: Self;
const D4_R17_ROT_TWIDDLE_1: Self;
const D4_R17_ROT_TWIDDLE_2: Self;
const D4_R17_ROT_TWIDDLE_3: Self;
const D4_R17_ROT_TWIDDLE_4: Self;
const D4_R17_ROT_TWIDDLE_5: Self;
const D4_R17_ROT_TWIDDLE_6: Self;
const D4_R17_ROT_TWIDDLE_7: Self;
const D4_R17_ROT_TWIDDLE_8: Self;
const D4_R17_ROT_TWIDDLE_9: Self;
const D4_R17_ROT_TWIDDLE_10: Self;
const D4_R17_ROT_TWIDDLE_11: Self;
const D4_R17_ROT_TWIDDLE_12: Self;
const D4_R17_ROT_TWIDDLE_13: Self;
const D4_R17_ROT_TWIDDLE_14: Self;
const D4_R17_ROT_TWIDDLE_15: Self;
}
impl Dct4MixedRadix17Sample for f32 {
const D4_R17_ROT_TWIDDLE_0: f32 = f32::from_bits(0x3f3d2fb0);
const D4_R17_ROT_TWIDDLE_1: f32 = f32::from_bits(0x3f2c7751);
const D4_R17_ROT_TWIDDLE_2: f32 = f32::from_bits(0x3f7ba420);
const D4_R17_ROT_TWIDDLE_3: f32 = f32::from_bits(0x3e3c28d5);
const D4_R17_ROT_TWIDDLE_4: f32 = f32::from_bits(0x3f4c4adb);
const D4_R17_ROT_TWIDDLE_5: f32 = f32::from_bits(0x3f1a4643);
const D4_R17_ROT_TWIDDLE_6: f32 = f32::from_bits(0x3f59a7d5);
const D4_R17_ROT_TWIDDLE_7: f32 = f32::from_bits(0x3f06c442);
const D4_R17_ROT_TWIDDLE_8: f32 = f32::from_bits(0x3f65296c);
const D4_R17_ROT_TWIDDLE_9: f32 = f32::from_bits(0x3ee437d1);
const D4_R17_ROT_TWIDDLE_10: f32 = f32::from_bits(0x3e8c1d8e);
const D4_R17_ROT_TWIDDLE_11: f32 = f32::from_bits(0x3f763a35);
const D4_R17_ROT_TWIDDLE_12: f32 = f32::from_bits(0x3f6eb680);
const D4_R17_ROT_TWIDDLE_13: f32 = f32::from_bits(0x3eb8f4ab);
const D4_R17_ROT_TWIDDLE_14: f32 = f32::from_bits(0xbdbcf732);
const D4_R17_ROT_TWIDDLE_15: f32 = f32::from_bits(0x3f7ee86f);
}
impl Dct4MixedRadix17Sample for f64 {
const D4_R17_ROT_TWIDDLE_0: f64 = f64::from_bits(0x3fe7a5f6075d4884);
const D4_R17_ROT_TWIDDLE_1: f64 = f64::from_bits(0x3fe58eea2a9d6da3);
const D4_R17_ROT_TWIDDLE_2: f64 = f64::from_bits(0x3fef7484007faef3);
const D4_R17_ROT_TWIDDLE_3: f64 = f64::from_bits(0x3fc7851aacd6c6b4);
const D4_R17_ROT_TWIDDLE_4: f64 = f64::from_bits(0x3fe9895b6c9a05f6);
const D4_R17_ROT_TWIDDLE_5: f64 = f64::from_bits(0x3fe348c86ed5f1bb);
const D4_R17_ROT_TWIDDLE_6: f64 = f64::from_bits(0x3feb34fa910ea3b9);
const D4_R17_ROT_TWIDDLE_7: f64 = f64::from_bits(0x3fe0d8884363dd80);
const D4_R17_ROT_TWIDDLE_8: f64 = f64::from_bits(0x3feca52d7c9e640b);
const D4_R17_ROT_TWIDDLE_9: f64 = f64::from_bits(0x3fdc86fa2b2883ce);
const D4_R17_ROT_TWIDDLE_10: f64 = f64::from_bits(0x3fd183b1c61f0d02);
const D4_R17_ROT_TWIDDLE_11: f64 = f64::from_bits(0x3feec746923c349f);
const D4_R17_ROT_TWIDDLE_12: f64 = f64::from_bits(0x3fedd6d000370991);
const D4_R17_ROT_TWIDDLE_13: f64 = f64::from_bits(0x3fd71e955d8e7cdc);
const D4_R17_ROT_TWIDDLE_14: f64 = f64::from_bits(0xbfb79ee63259b75f);
const D4_R17_ROT_TWIDDLE_15: f64 = f64::from_bits(0x3fefdd0deb564b22);
}
#[derive(Debug, Clone)]
pub(crate) struct Dct4Butterfly17<T> {
_phantom: PhantomData<T>,
}
impl<T: DctSample> Default for Dct4Butterfly17<T>
where
f64: AsPrimitive<T>,
{
fn default() -> Self {
Self {
_phantom: PhantomData,
}
}
}
impl<T: DctSample + Dct4MixedRadix17Sample> Dct4Butterfly17<T> {
#[inline(always)]
pub(crate) fn exec<S: BidirectionalStore<T>>(&self, data: &mut S) {
let a_buffer = [data[8] * T::FRAC_1_SQRT_2];
let c_buffer = [
(data[0] + data[16]) * T::FRAC_1_SQRT_2,
(data[1] + data[15]) * T::FRAC_1_SQRT_2,
(data[2] + data[14]) * T::FRAC_1_SQRT_2,
(data[3] + data[13]) * T::FRAC_1_SQRT_2,
(data[4] + data[12]) * T::FRAC_1_SQRT_2,
(data[5] + data[11]) * T::FRAC_1_SQRT_2,
(data[6] + data[10]) * T::FRAC_1_SQRT_2,
(data[7] + data[9]) * T::FRAC_1_SQRT_2,
];
let s_buffer = [
(data[0] - data[16]) * T::FRAC_1_SQRT_2,
(data[1] - data[15]) * T::FRAC_1_SQRT_2,
(data[2] - data[14]) * T::FRAC_1_SQRT_2,
(data[3] - data[13]) * T::FRAC_1_SQRT_2,
(data[4] - data[12]) * T::FRAC_1_SQRT_2,
(data[5] - data[11]) * T::FRAC_1_SQRT_2,
(data[6] - data[10]) * T::FRAC_1_SQRT_2,
(data[7] - data[9]) * T::FRAC_1_SQRT_2,
];
let c0 = c_buffer[0];
let s0 = s_buffer[0];
let s0_tw0 = s0 * T::D4_R17_ROT_TWIDDLE_1;
let s0_tw1 = -s0 * T::D4_R17_ROT_TWIDDLE_0;
let iq0 = fmla(c0, T::D4_R17_ROT_TWIDDLE_0, s0_tw0);
let siq0 = fmla(c0, T::D4_R17_ROT_TWIDDLE_1, s0_tw1);
let mut u0 = iq0;
let mut u1 = u0;
let mut v0 = siq0;
u1 *= T::D4_R17_ROT_TWIDDLE_2;
v0 *= T::D4_R17_ROT_TWIDDLE_3;
let c1 = c_buffer[1];
let s1 = s_buffer[1];
let iq1 = fmla(c1, T::D4_R17_ROT_TWIDDLE_4, s1 * T::D4_R17_ROT_TWIDDLE_5);
let siq1 = fmla(c1, T::D4_R17_ROT_TWIDDLE_5, -s1 * T::D4_R17_ROT_TWIDDLE_4);
u0 += iq1;
u1 = fmla(iq1, T::D4_R17_ROT_TWIDDLE_6, u1);
v0 = fmla(siq1, T::D4_R17_ROT_TWIDDLE_7, v0);
let c2 = c_buffer[2];
let s2 = s_buffer[2];
let iq2 = fmla(c2, T::D4_R17_ROT_TWIDDLE_6, s2 * T::D4_R17_ROT_TWIDDLE_7);
let siq2 = fmla(c2, T::D4_R17_ROT_TWIDDLE_7, -s2 * T::D4_R17_ROT_TWIDDLE_6);
u0 += iq2;
u1 = fmla(iq2, T::D4_R17_ROT_TWIDDLE_5, u1);
v0 = fmla(siq2, T::D4_R17_ROT_TWIDDLE_4, v0);
let c3 = c_buffer[3];
let s3 = s_buffer[3];
let iq3 = fmla(c3, T::D4_R17_ROT_TWIDDLE_8, s3 * T::D4_R17_ROT_TWIDDLE_9);
let siq3 = fmla(c3, T::D4_R17_ROT_TWIDDLE_9, -s3 * T::D4_R17_ROT_TWIDDLE_8);
u0 += iq3;
u1 = fmla(iq3, T::D4_R17_ROT_TWIDDLE_10, u1);
v0 = fmla(siq3, T::D4_R17_ROT_TWIDDLE_11, v0);
let c4 = c_buffer[4];
let s4 = s_buffer[4];
let iq4 = fmla(c4, T::D4_R17_ROT_TWIDDLE_12, s4 * T::D4_R17_ROT_TWIDDLE_13);
let siq4 = fmla(c4, T::D4_R17_ROT_TWIDDLE_13, -s4 * T::D4_R17_ROT_TWIDDLE_12);
u0 += iq4;
u1 = fmla(iq4, T::D4_R17_ROT_TWIDDLE_14, u1);
v0 = fmla(siq4, T::D4_R17_ROT_TWIDDLE_15, v0);
let c5 = c_buffer[5];
let s5 = s_buffer[5];
let iq5 = fmla(c5, T::D4_R17_ROT_TWIDDLE_11, s5 * T::D4_R17_ROT_TWIDDLE_10);
let siq5 = fmla(c5, T::D4_R17_ROT_TWIDDLE_10, -s5 * T::D4_R17_ROT_TWIDDLE_11);
u0 += iq5;
u1 = fmla(iq5, -T::D4_R17_ROT_TWIDDLE_9, u1);
v0 = fmla(siq5, T::D4_R17_ROT_TWIDDLE_8, v0);
let c6 = c_buffer[6];
let s6 = s_buffer[6];
let iq6 = fmla(c6, T::D4_R17_ROT_TWIDDLE_2, s6 * T::D4_R17_ROT_TWIDDLE_3);
let siq6 = fmla(c6, T::D4_R17_ROT_TWIDDLE_3, -s6 * T::D4_R17_ROT_TWIDDLE_2);
u0 += iq6;
u1 = fmla(iq6, -T::D4_R17_ROT_TWIDDLE_0, u1);
v0 = fmla(siq6, T::D4_R17_ROT_TWIDDLE_1, v0);
let c7 = c_buffer[7];
let s7 = s_buffer[7];
let iq7 = fmla(c7, T::D4_R17_ROT_TWIDDLE_15, s7 * -T::D4_R17_ROT_TWIDDLE_14);
let siq7 = fmla(
c7,
-T::D4_R17_ROT_TWIDDLE_14,
-s7 * T::D4_R17_ROT_TWIDDLE_15,
);
u0 += iq7;
u1 = fmla(iq7, -T::D4_R17_ROT_TWIDDLE_12, u1);
v0 = fmla(siq7, T::D4_R17_ROT_TWIDDLE_13, v0);
let a0 = a_buffer[0];
u0 += a0;
u1 = u1 - a0;
data[0] = u0;
data[1] = u1 - v0;
data[2] = u1 + v0;
let mut u2 = iq0;
let mut v2 = siq0;
u2 *= T::D4_R17_ROT_TWIDDLE_12;
v2 *= T::D4_R17_ROT_TWIDDLE_13;
u2 = fmla(iq1, T::D4_R17_ROT_TWIDDLE_9, u2);
v2 = fmla(siq1, T::D4_R17_ROT_TWIDDLE_8, v2);
u2 = fmla(iq2, -T::D4_R17_ROT_TWIDDLE_10, u2);
v2 = fmla(siq2, T::D4_R17_ROT_TWIDDLE_11, v2);
u2 = fmla(iq3, -T::D4_R17_ROT_TWIDDLE_6, u2);
v2 = fmla(siq3, T::D4_R17_ROT_TWIDDLE_7, v2);
u2 = fmla(iq4, -T::D4_R17_ROT_TWIDDLE_2, u2);
v2 = fmla(siq4, -T::D4_R17_ROT_TWIDDLE_3, v2);
u2 = fmla(iq5, -T::D4_R17_ROT_TWIDDLE_5, u2);
v2 = fmla(siq5, -T::D4_R17_ROT_TWIDDLE_4, v2);
u2 = fmla(iq6, -T::D4_R17_ROT_TWIDDLE_14, u2);
v2 = fmla(siq6, -T::D4_R17_ROT_TWIDDLE_15, v2);
u2 = fmla(iq7, T::D4_R17_ROT_TWIDDLE_0, u2);
v2 = fmla(siq7, -T::D4_R17_ROT_TWIDDLE_1, v2);
u2 += a0;
data[3] = u2 - v2;
data[4] = u2 + v2;
let mut u3 = iq0;
let mut v3 = siq0;
u3 *= T::D4_R17_ROT_TWIDDLE_6;
v3 *= T::D4_R17_ROT_TWIDDLE_7;
u3 = fmla(iq1, T::D4_R17_ROT_TWIDDLE_14, u3);
v3 = fmla(siq1, T::D4_R17_ROT_TWIDDLE_15, v3);
u3 = fmla(iq2, -T::D4_R17_ROT_TWIDDLE_12, u3);
v3 = fmla(siq2, T::D4_R17_ROT_TWIDDLE_13, v3);
u3 = fmla(iq3, -T::D4_R17_ROT_TWIDDLE_0, u3);
v3 = fmla(siq3, -T::D4_R17_ROT_TWIDDLE_1, v3);
u3 = fmla(iq4, T::D4_R17_ROT_TWIDDLE_10, u3);
v3 = fmla(siq4, -T::D4_R17_ROT_TWIDDLE_11, v3);
u3 = fmla(iq5, T::D4_R17_ROT_TWIDDLE_2, u3);
v3 = fmla(siq5, -T::D4_R17_ROT_TWIDDLE_3, v3);
u3 = fmla(iq6, T::D4_R17_ROT_TWIDDLE_5, u3);
v3 = fmla(siq6, T::D4_R17_ROT_TWIDDLE_4, v3);
u3 = fmla(iq7, -T::D4_R17_ROT_TWIDDLE_9, u3);
v3 = fmla(siq7, T::D4_R17_ROT_TWIDDLE_8, v3);
u3 = u3 - a0;
data[5] = u3 - v3;
data[6] = u3 + v3;
let mut u4 = iq0;
let mut v4 = siq0;
u4 *= T::D4_R17_ROT_TWIDDLE_0;
v4 *= T::D4_R17_ROT_TWIDDLE_1;
u4 = fmla(iq1, -T::D4_R17_ROT_TWIDDLE_5, u4);
v4 = fmla(siq1, T::D4_R17_ROT_TWIDDLE_4, v4);
u4 = fmla(iq2, -T::D4_R17_ROT_TWIDDLE_6, u4);
v4 = fmla(siq2, -T::D4_R17_ROT_TWIDDLE_7, v4);
u4 = fmla(iq3, T::D4_R17_ROT_TWIDDLE_9, u4);
v4 = fmla(siq3, -T::D4_R17_ROT_TWIDDLE_8, v4);
u4 = fmla(iq4, T::D4_R17_ROT_TWIDDLE_12, u4);
v4 = fmla(siq4, T::D4_R17_ROT_TWIDDLE_13, v4);
u4 = fmla(iq5, -T::D4_R17_ROT_TWIDDLE_10, u4);
v4 = fmla(siq5, T::D4_R17_ROT_TWIDDLE_11, v4);
u4 = fmla(iq6, -T::D4_R17_ROT_TWIDDLE_2, u4);
v4 = fmla(siq6, -T::D4_R17_ROT_TWIDDLE_3, v4);
u4 = fmla(iq7, -T::D4_R17_ROT_TWIDDLE_14, u4);
v4 = fmla(siq7, -T::D4_R17_ROT_TWIDDLE_15, v4);
u4 += a0;
data[7] = u4 - v4;
data[8] = u4 + v4;
let mut u5 = iq0;
let mut v5 = siq0;
u5 *= T::D4_R17_ROT_TWIDDLE_5;
v5 *= T::D4_R17_ROT_TWIDDLE_4;
u5 = fmla(iq1, -T::D4_R17_ROT_TWIDDLE_12, u5);
v5 = fmla(siq1, T::D4_R17_ROT_TWIDDLE_13, v5);
u5 = fmla(iq2, T::D4_R17_ROT_TWIDDLE_14, u5);
v5 = fmla(siq2, -T::D4_R17_ROT_TWIDDLE_15, v5);
u5 = fmla(iq3, T::D4_R17_ROT_TWIDDLE_2, u5);
v5 = fmla(siq3, T::D4_R17_ROT_TWIDDLE_3, v5);
u5 = fmla(iq4, -T::D4_R17_ROT_TWIDDLE_9, u5);
v5 = fmla(siq4, T::D4_R17_ROT_TWIDDLE_8, v5);
u5 = fmla(iq5, -T::D4_R17_ROT_TWIDDLE_0, u5);
v5 = fmla(siq5, -T::D4_R17_ROT_TWIDDLE_1, v5);
u5 = fmla(iq6, T::D4_R17_ROT_TWIDDLE_6, u5);
v5 = fmla(siq6, -T::D4_R17_ROT_TWIDDLE_7, v5);
u5 = fmla(iq7, T::D4_R17_ROT_TWIDDLE_10, u5);
v5 = fmla(siq7, T::D4_R17_ROT_TWIDDLE_11, v5);
u5 = u5 - a0;
data[9] = u5 - v5;
data[10] = u5 + v5;
let mut u6 = iq0;
let mut v6 = siq0;
u6 *= T::D4_R17_ROT_TWIDDLE_9;
v6 *= T::D4_R17_ROT_TWIDDLE_8;
u6 = fmla(iq1, -T::D4_R17_ROT_TWIDDLE_2, u6);
v6 = fmla(siq1, -T::D4_R17_ROT_TWIDDLE_3, v6);
u6 = fmla(iq2, T::D4_R17_ROT_TWIDDLE_0, u6);
v6 = fmla(siq2, -T::D4_R17_ROT_TWIDDLE_1, v6);
u6 = fmla(iq3, -T::D4_R17_ROT_TWIDDLE_14, u6);
v6 = fmla(siq3, T::D4_R17_ROT_TWIDDLE_15, v6);
u6 = fmla(iq4, -T::D4_R17_ROT_TWIDDLE_6, u6);
v6 = fmla(siq4, -T::D4_R17_ROT_TWIDDLE_7, v6);
u6 = fmla(iq5, T::D4_R17_ROT_TWIDDLE_12, u6);
v6 = fmla(siq5, -T::D4_R17_ROT_TWIDDLE_13, v6);
u6 = fmla(iq6, -T::D4_R17_ROT_TWIDDLE_10, u6);
v6 = fmla(siq6, T::D4_R17_ROT_TWIDDLE_11, v6);
u6 = fmla(iq7, -T::D4_R17_ROT_TWIDDLE_5, u6);
v6 = fmla(siq7, -T::D4_R17_ROT_TWIDDLE_4, v6);
u6 += a0;
data[11] = u6 - v6;
data[12] = u6 + v6;
let mut u7 = iq0;
let mut v7 = siq0;
u7 *= T::D4_R17_ROT_TWIDDLE_10;
v7 *= T::D4_R17_ROT_TWIDDLE_11;
u7 = fmla(iq1, -T::D4_R17_ROT_TWIDDLE_0, u7);
v7 = fmla(siq1, -T::D4_R17_ROT_TWIDDLE_1, v7);
u7 = fmla(iq2, T::D4_R17_ROT_TWIDDLE_2, u7);
v7 = fmla(siq2, T::D4_R17_ROT_TWIDDLE_3, v7);
u7 = fmla(iq3, -T::D4_R17_ROT_TWIDDLE_12, u7);
v7 = fmla(siq3, T::D4_R17_ROT_TWIDDLE_13, v7);
u7 = fmla(iq4, T::D4_R17_ROT_TWIDDLE_5, u7);
v7 = fmla(siq4, -T::D4_R17_ROT_TWIDDLE_4, v7);
u7 = fmla(iq5, T::D4_R17_ROT_TWIDDLE_14, u7);
v7 = fmla(siq5, T::D4_R17_ROT_TWIDDLE_15, v7);
u7 = fmla(iq6, -T::D4_R17_ROT_TWIDDLE_9, u7);
v7 = fmla(siq6, -T::D4_R17_ROT_TWIDDLE_8, v7);
u7 = fmla(iq7, T::D4_R17_ROT_TWIDDLE_6, u7);
v7 = fmla(siq7, T::D4_R17_ROT_TWIDDLE_7, v7);
u7 = u7 - a0;
data[13] = u7 - v7;
data[14] = u7 + v7;
let mut u8 = iq0;
let mut v8 = siq0;
u8 *= -T::D4_R17_ROT_TWIDDLE_14;
v8 *= T::D4_R17_ROT_TWIDDLE_15;
u8 = fmla(iq1, -T::D4_R17_ROT_TWIDDLE_10, u8);
v8 = fmla(siq1, -T::D4_R17_ROT_TWIDDLE_11, v8);
u8 = fmla(iq2, T::D4_R17_ROT_TWIDDLE_9, u8);
v8 = fmla(siq2, T::D4_R17_ROT_TWIDDLE_8, v8);
u8 = fmla(iq3, -T::D4_R17_ROT_TWIDDLE_5, u8);
v8 = fmla(siq3, -T::D4_R17_ROT_TWIDDLE_4, v8);
u8 = fmla(iq4, T::D4_R17_ROT_TWIDDLE_0, u8);
v8 = fmla(siq4, T::D4_R17_ROT_TWIDDLE_1, v8);
u8 = fmla(iq5, -T::D4_R17_ROT_TWIDDLE_6, u8);
v8 = fmla(siq5, -T::D4_R17_ROT_TWIDDLE_7, v8);
u8 = fmla(iq6, T::D4_R17_ROT_TWIDDLE_12, u8);
v8 = fmla(siq6, T::D4_R17_ROT_TWIDDLE_13, v8);
u8 = fmla(iq7, -T::D4_R17_ROT_TWIDDLE_2, u8);
v8 = fmla(siq7, -T::D4_R17_ROT_TWIDDLE_3, v8);
u8 += a0;
data[15] = u8 - v8;
data[16] = u8 + v8;
}
}
impl<T: DctSample + Dct4MixedRadix17Sample> PxdctExecutor<T> for Dct4Butterfly17<T>
where
f64: AsPrimitive<T>,
{
fn execute(&self, data: &mut [T]) -> Result<(), PxdctError> {
if !data.len().is_multiple_of(17) {
return Err(PxdctError::InvalidSizeMultiplier(data.len(), self.length()));
}
for chunk in data.as_chunks_mut::<17>().0.iter_mut() {
self.exec(&mut InPlaceStore::new(chunk));
}
Ok(())
}
fn execute_with_scratch(&self, data: &mut [T], _: &mut [T]) -> Result<(), PxdctError> {
self.execute(data)
}
fn execute_into(&self, input: &[T], output: &mut [T]) -> Result<(), PxdctError> {
self.execute_into_with_scratch(input, output, &mut [])
}
fn execute_into_with_scratch(
&self,
input: &[T],
output: &mut [T],
_: &mut [T],
) -> Result<(), PxdctError> {
use crate::util::validate_oof_sizes;
validate_oof_sizes!(input, output, 17);
use crate::bidirectional::BiStore;
for (src, dst) in input
.as_chunks::<17>()
.0
.iter()
.zip(output.as_chunks_mut::<17>().0.iter_mut())
{
self.exec(&mut BiStore::new(src, dst));
}
Ok(())
}
fn length(&self) -> usize {
17
}
fn scratch_size(&self) -> usize {
0
}
}
pub(crate) trait Dct4MixedRadix19Sample {
const D4_R19_ROT_TWIDDLE_0: Self;
const D4_R19_ROT_TWIDDLE_1: Self;
const D4_R19_ROT_TWIDDLE_2: Self;
const D4_R19_ROT_TWIDDLE_3: Self;
const D4_R19_ROT_TWIDDLE_4: Self;
const D4_R19_ROT_TWIDDLE_5: Self;
const D4_R19_ROT_TWIDDLE_6: Self;
const D4_R19_ROT_TWIDDLE_7: Self;
const D4_R19_ROT_TWIDDLE_8: Self;
const D4_R19_ROT_TWIDDLE_9: Self;
const D4_R19_ROT_TWIDDLE_10: Self;
const D4_R19_ROT_TWIDDLE_11: Self;
const D4_R19_ROT_TWIDDLE_12: Self;
const D4_R19_ROT_TWIDDLE_13: Self;
const D4_R19_ROT_TWIDDLE_14: Self;
const D4_R19_ROT_TWIDDLE_15: Self;
const D4_R19_ROT_TWIDDLE_16: Self;
const D4_R19_ROT_TWIDDLE_17: Self;
}
impl Dct4MixedRadix19Sample for f32 {
const D4_R19_ROT_TWIDDLE_0: f32 = f32::from_bits(0x3f3c5867);
const D4_R19_ROT_TWIDDLE_1: f32 = f32::from_bits(0x3f2d6253);
const D4_R19_ROT_TWIDDLE_2: f32 = f32::from_bits(0x3f7c822d);
const D4_R19_ROT_TWIDDLE_3: f32 = f32::from_bits(0x3e288b7c);
const D4_R19_ROT_TWIDDLE_4: f32 = f32::from_bits(0x3f4a051d);
const D4_R19_ROT_TWIDDLE_5: f32 = f32::from_bits(0x3f1d3d0b);
const D4_R19_ROT_TWIDDLE_6: f32 = f32::from_bits(0x3f612531);
const D4_R19_ROT_TWIDDLE_7: f32 = f32::from_bits(0x3ef3af60);
const D4_R19_ROT_TWIDDLE_8: f32 = f32::from_bits(0x3f56508b);
const D4_R19_ROT_TWIDDLE_9: f32 = f32::from_bits(0x3f0c04cb);
const D4_R19_ROT_TWIDDLE_10: f32 = f32::from_bits(0x3ecdab06);
const D4_R19_ROT_TWIDDLE_11: f32 = f32::from_bits(0x3f6a701f);
const D4_R19_ROT_TWIDDLE_12: f32 = f32::from_bits(0x3da91f5c);
const D4_R19_ROT_TWIDDLE_13: f32 = f32::from_bits(0x3f7f2029);
const D4_R19_ROT_TWIDDLE_14: f32 = f32::from_bits(0x3f722114);
const D4_R19_ROT_TWIDDLE_15: f32 = f32::from_bits(0x3ea63f02);
const D4_R19_ROT_TWIDDLE_16: f32 = f32::from_bits(0xbe7b608c);
const D4_R19_ROT_TWIDDLE_17: f32 = f32::from_bits(0x3f782a9e);
}
impl Dct4MixedRadix19Sample for f64 {
const D4_R19_ROT_TWIDDLE_0: f64 = f64::from_bits(0x3fe78b0cdee73e10);
const D4_R19_ROT_TWIDDLE_1: f64 = f64::from_bits(0x3fe5ac4a670a1cff);
const D4_R19_ROT_TWIDDLE_2: f64 = f64::from_bits(0x3fef90459484f2b2);
const D4_R19_ROT_TWIDDLE_3: f64 = f64::from_bits(0x3fc5116f7f2d58c5);
const D4_R19_ROT_TWIDDLE_4: f64 = f64::from_bits(0x3fe940a398f9cd23);
const D4_R19_ROT_TWIDDLE_5: f64 = f64::from_bits(0x3fe3a7a16b394423);
const D4_R19_ROT_TWIDDLE_6: f64 = f64::from_bits(0x3fec24a622e3e9f9);
const D4_R19_ROT_TWIDDLE_7: f64 = f64::from_bits(0x3fde75ec0ded7bed);
const D4_R19_ROT_TWIDDLE_8: f64 = f64::from_bits(0x3feaca115aae3de4);
const D4_R19_ROT_TWIDDLE_9: f64 = f64::from_bits(0x3fe180996c77c8c9);
const D4_R19_ROT_TWIDDLE_10: f64 = f64::from_bits(0x3fd9b560b9f596eb);
const D4_R19_ROT_TWIDDLE_11: f64 = f64::from_bits(0x3fed4e03dd110b08);
const D4_R19_ROT_TWIDDLE_12: f64 = f64::from_bits(0x3fb523eb8420f5fb);
const D4_R19_ROT_TWIDDLE_13: f64 = f64::from_bits(0x3fefe40529a542aa);
const D4_R19_ROT_TWIDDLE_14: f64 = f64::from_bits(0x3fee442285231be1);
const D4_R19_ROT_TWIDDLE_15: f64 = f64::from_bits(0x3fd4c7e04850cfa9);
const D4_R19_ROT_TWIDDLE_16: f64 = f64::from_bits(0xbfcf6c118574c840);
const D4_R19_ROT_TWIDDLE_17: f64 = f64::from_bits(0x3fef0553b4de2e18);
}
#[derive(Debug, Clone)]
pub(crate) struct Dct4Butterfly19<T> {
_phantom: PhantomData<T>,
}
impl<T: DctSample> Default for Dct4Butterfly19<T>
where
f64: AsPrimitive<T>,
{
fn default() -> Self {
Self {
_phantom: PhantomData,
}
}
}
impl<T: DctSample + Dct4MixedRadix19Sample> Dct4Butterfly19<T> {
#[inline(always)]
pub(crate) fn exec<S: BidirectionalStore<T>>(&self, data: &mut S) {
let a_buffer = [data[9] * T::FRAC_1_SQRT_2];
let c_buffer = [
(data[0] + data[18]) * T::FRAC_1_SQRT_2,
(data[1] + data[17]) * T::FRAC_1_SQRT_2,
(data[2] + data[16]) * T::FRAC_1_SQRT_2,
(data[3] + data[15]) * T::FRAC_1_SQRT_2,
(data[4] + data[14]) * T::FRAC_1_SQRT_2,
(data[5] + data[13]) * T::FRAC_1_SQRT_2,
(data[6] + data[12]) * T::FRAC_1_SQRT_2,
(data[7] + data[11]) * T::FRAC_1_SQRT_2,
(data[8] + data[10]) * T::FRAC_1_SQRT_2,
];
let s_buffer = [
(data[0] - data[18]) * T::FRAC_1_SQRT_2,
(data[1] - data[17]) * T::FRAC_1_SQRT_2,
(data[2] - data[16]) * T::FRAC_1_SQRT_2,
(data[3] - data[15]) * T::FRAC_1_SQRT_2,
(data[4] - data[14]) * T::FRAC_1_SQRT_2,
(data[5] - data[13]) * T::FRAC_1_SQRT_2,
(data[6] - data[12]) * T::FRAC_1_SQRT_2,
(data[7] - data[11]) * T::FRAC_1_SQRT_2,
(data[8] - data[10]) * T::FRAC_1_SQRT_2,
];
let c0 = c_buffer[0];
let s0 = s_buffer[0];
let s0_tw0 = s0 * T::D4_R19_ROT_TWIDDLE_1;
let s0_tw1 = -s0 * T::D4_R19_ROT_TWIDDLE_0;
let iq0 = fmla(c0, T::D4_R19_ROT_TWIDDLE_0, s0_tw0);
let siq0 = fmla(c0, T::D4_R19_ROT_TWIDDLE_1, s0_tw1);
let mut u0 = iq0;
let mut u1 = u0;
let mut v0 = siq0;
u1 *= T::D4_R19_ROT_TWIDDLE_2;
v0 *= T::D4_R19_ROT_TWIDDLE_3;
let c1 = c_buffer[1];
let s1 = s_buffer[1];
let iq1 = fmla(c1, T::D4_R19_ROT_TWIDDLE_4, s1 * T::D4_R19_ROT_TWIDDLE_5);
let siq1 = fmla(c1, T::D4_R19_ROT_TWIDDLE_5, -s1 * T::D4_R19_ROT_TWIDDLE_4);
u0 += iq1;
u1 = fmla(iq1, T::D4_R19_ROT_TWIDDLE_6, u1);
v0 = fmla(siq1, T::D4_R19_ROT_TWIDDLE_7, v0);
let c2 = c_buffer[2];
let s2 = s_buffer[2];
let iq2 = fmla(c2, T::D4_R19_ROT_TWIDDLE_8, s2 * T::D4_R19_ROT_TWIDDLE_9);
let siq2 = fmla(c2, T::D4_R19_ROT_TWIDDLE_9, -s2 * T::D4_R19_ROT_TWIDDLE_8);
u0 += iq2;
u1 = fmla(iq2, T::D4_R19_ROT_TWIDDLE_1, u1);
v0 = fmla(siq2, T::D4_R19_ROT_TWIDDLE_0, v0);
let c3 = c_buffer[3];
let s3 = s_buffer[3];
let iq3 = fmla(c3, T::D4_R19_ROT_TWIDDLE_6, s3 * T::D4_R19_ROT_TWIDDLE_7);
let siq3 = fmla(c3, T::D4_R19_ROT_TWIDDLE_7, -s3 * T::D4_R19_ROT_TWIDDLE_6);
u0 += iq3;
u1 = fmla(iq3, T::D4_R19_ROT_TWIDDLE_10, u1);
v0 = fmla(siq3, T::D4_R19_ROT_TWIDDLE_11, v0);
let c4 = c_buffer[4];
let s4 = s_buffer[4];
let iq4 = fmla(c4, T::D4_R19_ROT_TWIDDLE_11, s4 * T::D4_R19_ROT_TWIDDLE_10);
let siq4 = fmla(c4, T::D4_R19_ROT_TWIDDLE_10, -s4 * T::D4_R19_ROT_TWIDDLE_11);
u0 += iq4;
u1 = fmla(iq4, T::D4_R19_ROT_TWIDDLE_12, u1);
v0 = fmla(siq4, T::D4_R19_ROT_TWIDDLE_13, v0);
let c5 = c_buffer[5];
let s5 = s_buffer[5];
let iq5 = fmla(c5, T::D4_R19_ROT_TWIDDLE_14, s5 * T::D4_R19_ROT_TWIDDLE_15);
let siq5 = fmla(c5, T::D4_R19_ROT_TWIDDLE_15, -s5 * T::D4_R19_ROT_TWIDDLE_14);
u0 += iq5;
u1 = fmla(iq5, T::D4_R19_ROT_TWIDDLE_16, u1);
v0 = fmla(siq5, T::D4_R19_ROT_TWIDDLE_17, v0);
let c6 = c_buffer[6];
let s6 = s_buffer[6];
let iq6 = fmla(c6, T::D4_R19_ROT_TWIDDLE_17, s6 * -T::D4_R19_ROT_TWIDDLE_16);
let siq6 = fmla(
c6,
-T::D4_R19_ROT_TWIDDLE_16,
-s6 * T::D4_R19_ROT_TWIDDLE_17,
);
u0 += iq6;
u1 = fmla(iq6, -T::D4_R19_ROT_TWIDDLE_9, u1);
v0 = fmla(siq6, T::D4_R19_ROT_TWIDDLE_8, v0);
let c7 = c_buffer[7];
let s7 = s_buffer[7];
let iq7 = fmla(c7, T::D4_R19_ROT_TWIDDLE_2, s7 * T::D4_R19_ROT_TWIDDLE_3);
let siq7 = fmla(c7, T::D4_R19_ROT_TWIDDLE_3, -s7 * T::D4_R19_ROT_TWIDDLE_2);
u0 += iq7;
u1 = fmla(iq7, -T::D4_R19_ROT_TWIDDLE_4, u1);
v0 = fmla(siq7, T::D4_R19_ROT_TWIDDLE_5, v0);
let c8 = c_buffer[8];
let s8 = s_buffer[8];
let iq8 = fmla(c8, T::D4_R19_ROT_TWIDDLE_13, s8 * T::D4_R19_ROT_TWIDDLE_12);
let siq8 = fmla(c8, T::D4_R19_ROT_TWIDDLE_12, -s8 * T::D4_R19_ROT_TWIDDLE_13);
u0 += iq8;
u1 = fmla(iq8, -T::D4_R19_ROT_TWIDDLE_14, u1);
v0 = fmla(siq8, T::D4_R19_ROT_TWIDDLE_15, v0);
let a0 = a_buffer[0];
u0 += a0;
u1 = u1 - a0;
data[0] = u0;
data[1] = u1 - v0;
data[2] = u1 + v0;
let mut u2 = iq0;
let mut v2 = siq0;
u2 *= T::D4_R19_ROT_TWIDDLE_14;
v2 *= T::D4_R19_ROT_TWIDDLE_15;
u2 = fmla(iq1, T::D4_R19_ROT_TWIDDLE_9, u2);
v2 = fmla(siq1, T::D4_R19_ROT_TWIDDLE_8, v2);
u2 = fmla(iq2, -T::D4_R19_ROT_TWIDDLE_12, u2);
v2 = fmla(siq2, T::D4_R19_ROT_TWIDDLE_13, v2);
u2 = fmla(iq3, -T::D4_R19_ROT_TWIDDLE_1, u2);
v2 = fmla(siq3, T::D4_R19_ROT_TWIDDLE_0, v2);
u2 = fmla(iq4, -T::D4_R19_ROT_TWIDDLE_2, u2);
v2 = fmla(siq4, T::D4_R19_ROT_TWIDDLE_3, v2);
u2 = fmla(iq5, -T::D4_R19_ROT_TWIDDLE_6, u2);
v2 = fmla(siq5, -T::D4_R19_ROT_TWIDDLE_7, v2);
u2 = fmla(iq6, -T::D4_R19_ROT_TWIDDLE_10, u2);
v2 = fmla(siq6, -T::D4_R19_ROT_TWIDDLE_11, v2);
u2 = fmla(iq7, -T::D4_R19_ROT_TWIDDLE_16, u2);
v2 = fmla(siq7, -T::D4_R19_ROT_TWIDDLE_17, v2);
u2 = fmla(iq8, T::D4_R19_ROT_TWIDDLE_4, u2);
v2 = fmla(siq8, -T::D4_R19_ROT_TWIDDLE_5, v2);
u2 += a0;
data[3] = u2 - v2;
data[4] = u2 + v2;
let mut u3 = iq0;
let mut v3 = siq0;
u3 *= T::D4_R19_ROT_TWIDDLE_6;
v3 *= T::D4_R19_ROT_TWIDDLE_7;
u3 = fmla(iq1, T::D4_R19_ROT_TWIDDLE_12, u3);
v3 = fmla(siq1, T::D4_R19_ROT_TWIDDLE_13, v3);
u3 = fmla(iq2, -T::D4_R19_ROT_TWIDDLE_4, u3);
v3 = fmla(siq2, T::D4_R19_ROT_TWIDDLE_5, v3);
u3 = fmla(iq3, -T::D4_R19_ROT_TWIDDLE_14, u3);
v3 = fmla(siq3, -T::D4_R19_ROT_TWIDDLE_15, v3);
u3 = fmla(iq4, T::D4_R19_ROT_TWIDDLE_16, u3);
v3 = fmla(siq4, -T::D4_R19_ROT_TWIDDLE_17, v3);
u3 = fmla(iq5, T::D4_R19_ROT_TWIDDLE_1, u3);
v3 = fmla(siq5, -T::D4_R19_ROT_TWIDDLE_0, v3);
u3 = fmla(iq6, T::D4_R19_ROT_TWIDDLE_2, u3);
v3 = fmla(siq6, T::D4_R19_ROT_TWIDDLE_3, v3);
u3 = fmla(iq7, T::D4_R19_ROT_TWIDDLE_10, u3);
v3 = fmla(siq7, T::D4_R19_ROT_TWIDDLE_11, v3);
u3 = fmla(iq8, -T::D4_R19_ROT_TWIDDLE_9, u3);
v3 = fmla(siq8, T::D4_R19_ROT_TWIDDLE_8, v3);
u3 = u3 - a0;
data[5] = u3 - v3;
data[6] = u3 + v3;
let mut u4 = iq0;
let mut v4 = siq0;
u4 *= T::D4_R19_ROT_TWIDDLE_4;
v4 *= T::D4_R19_ROT_TWIDDLE_5;
u4 = fmla(iq1, -T::D4_R19_ROT_TWIDDLE_10, u4);
v4 = fmla(siq1, T::D4_R19_ROT_TWIDDLE_11, v4);
u4 = fmla(iq2, -T::D4_R19_ROT_TWIDDLE_2, u4);
v4 = fmla(siq2, -T::D4_R19_ROT_TWIDDLE_3, v4);
u4 = fmla(iq3, -T::D4_R19_ROT_TWIDDLE_12, u4);
v4 = fmla(siq3, -T::D4_R19_ROT_TWIDDLE_13, v4);
u4 = fmla(iq4, T::D4_R19_ROT_TWIDDLE_14, u4);
v4 = fmla(siq4, -T::D4_R19_ROT_TWIDDLE_15, v4);
u4 = fmla(iq5, T::D4_R19_ROT_TWIDDLE_9, u4);
v4 = fmla(siq5, T::D4_R19_ROT_TWIDDLE_8, v4);
u4 = fmla(iq6, -T::D4_R19_ROT_TWIDDLE_1, u4);
v4 = fmla(siq6, T::D4_R19_ROT_TWIDDLE_0, v4);
u4 = fmla(iq7, -T::D4_R19_ROT_TWIDDLE_6, u4);
v4 = fmla(siq7, -T::D4_R19_ROT_TWIDDLE_7, v4);
u4 = fmla(iq8, -T::D4_R19_ROT_TWIDDLE_16, u4);
v4 = fmla(siq8, -T::D4_R19_ROT_TWIDDLE_17, v4);
u4 += a0;
data[7] = u4 - v4;
data[8] = u4 + v4;
let mut u5 = iq0;
let mut v5 = siq0;
u5 *= T::D4_R19_ROT_TWIDDLE_1;
v5 *= T::D4_R19_ROT_TWIDDLE_0;
u5 = fmla(iq1, -T::D4_R19_ROT_TWIDDLE_4, u5);
v5 = fmla(siq1, T::D4_R19_ROT_TWIDDLE_5, v5);
u5 = fmla(iq2, -T::D4_R19_ROT_TWIDDLE_9, u5);
v5 = fmla(siq2, -T::D4_R19_ROT_TWIDDLE_8, v5);
u5 = fmla(iq3, T::D4_R19_ROT_TWIDDLE_6, u5);
v5 = fmla(siq3, -T::D4_R19_ROT_TWIDDLE_7, v5);
u5 = fmla(iq4, T::D4_R19_ROT_TWIDDLE_10, u5);
v5 = fmla(siq4, T::D4_R19_ROT_TWIDDLE_11, v5);
u5 = fmla(iq5, -T::D4_R19_ROT_TWIDDLE_14, u5);
v5 = fmla(siq5, T::D4_R19_ROT_TWIDDLE_15, v5);
u5 = fmla(iq6, T::D4_R19_ROT_TWIDDLE_16, u5);
v5 = fmla(siq6, -T::D4_R19_ROT_TWIDDLE_17, v5);
u5 = fmla(iq7, T::D4_R19_ROT_TWIDDLE_2, u5);
v5 = fmla(siq7, -T::D4_R19_ROT_TWIDDLE_3, v5);
u5 = fmla(iq8, T::D4_R19_ROT_TWIDDLE_12, u5);
v5 = fmla(siq8, T::D4_R19_ROT_TWIDDLE_13, v5);
u5 = u5 - a0;
data[9] = u5 - v5;
data[10] = u5 + v5;
let mut u6 = iq0;
let mut v6 = siq0;
u6 *= T::D4_R19_ROT_TWIDDLE_9;
v6 *= T::D4_R19_ROT_TWIDDLE_8;
u6 = fmla(iq1, -T::D4_R19_ROT_TWIDDLE_2, u6);
v6 = fmla(siq1, T::D4_R19_ROT_TWIDDLE_3, v6);
u6 = fmla(iq2, -T::D4_R19_ROT_TWIDDLE_16, u6);
v6 = fmla(siq2, -T::D4_R19_ROT_TWIDDLE_17, v6);
u6 = fmla(iq3, T::D4_R19_ROT_TWIDDLE_4, u6);
v6 = fmla(siq3, T::D4_R19_ROT_TWIDDLE_5, v6);
u6 = fmla(iq4, -T::D4_R19_ROT_TWIDDLE_6, u6);
v6 = fmla(siq4, T::D4_R19_ROT_TWIDDLE_7, v6);
u6 = fmla(iq5, -T::D4_R19_ROT_TWIDDLE_12, u6);
v6 = fmla(siq5, -T::D4_R19_ROT_TWIDDLE_13, v6);
u6 = fmla(iq6, T::D4_R19_ROT_TWIDDLE_14, u6);
v6 = fmla(siq6, T::D4_R19_ROT_TWIDDLE_15, v6);
u6 = fmla(iq7, -T::D4_R19_ROT_TWIDDLE_1, u6);
v6 = fmla(siq7, T::D4_R19_ROT_TWIDDLE_0, v6);
u6 = fmla(iq8, -T::D4_R19_ROT_TWIDDLE_10, u6);
v6 = fmla(siq8, -T::D4_R19_ROT_TWIDDLE_11, v6);
u6 += a0;
data[11] = u6 - v6;
data[12] = u6 + v6;
let mut u7 = iq0;
let mut v7 = siq0;
u7 *= T::D4_R19_ROT_TWIDDLE_10;
v7 *= T::D4_R19_ROT_TWIDDLE_11;
u7 = fmla(iq1, -T::D4_R19_ROT_TWIDDLE_14, u7);
v7 = fmla(siq1, -T::D4_R19_ROT_TWIDDLE_15, v7);
u7 = fmla(iq2, T::D4_R19_ROT_TWIDDLE_6, u7);
v7 = fmla(siq2, -T::D4_R19_ROT_TWIDDLE_7, v7);
u7 = fmla(iq3, T::D4_R19_ROT_TWIDDLE_16, u7);
v7 = fmla(siq3, T::D4_R19_ROT_TWIDDLE_17, v7);
u7 = fmla(iq4, -T::D4_R19_ROT_TWIDDLE_9, u7);
v7 = fmla(siq4, -T::D4_R19_ROT_TWIDDLE_8, v7);
u7 = fmla(iq5, T::D4_R19_ROT_TWIDDLE_2, u7);
v7 = fmla(siq5, T::D4_R19_ROT_TWIDDLE_3, v7);
u7 = fmla(iq6, -T::D4_R19_ROT_TWIDDLE_4, u7);
v7 = fmla(siq6, T::D4_R19_ROT_TWIDDLE_5, v7);
u7 = fmla(iq7, T::D4_R19_ROT_TWIDDLE_12, u7);
v7 = fmla(siq7, -T::D4_R19_ROT_TWIDDLE_13, v7);
u7 = fmla(iq8, T::D4_R19_ROT_TWIDDLE_1, u7);
v7 = fmla(siq8, T::D4_R19_ROT_TWIDDLE_0, v7);
u7 = u7 - a0;
data[13] = u7 - v7;
data[14] = u7 + v7;
let mut u8 = iq0;
let mut v8 = siq0;
u8 *= -T::D4_R19_ROT_TWIDDLE_16;
v8 *= T::D4_R19_ROT_TWIDDLE_17;
u8 = fmla(iq1, -T::D4_R19_ROT_TWIDDLE_1, u8);
v8 = fmla(siq1, -T::D4_R19_ROT_TWIDDLE_0, v8);
u8 = fmla(iq2, T::D4_R19_ROT_TWIDDLE_14, u8);
v8 = fmla(siq2, T::D4_R19_ROT_TWIDDLE_15, v8);
u8 = fmla(iq3, -T::D4_R19_ROT_TWIDDLE_2, u8);
v8 = fmla(siq3, T::D4_R19_ROT_TWIDDLE_3, v8);
u8 = fmla(iq4, T::D4_R19_ROT_TWIDDLE_4, u8);
v8 = fmla(siq4, -T::D4_R19_ROT_TWIDDLE_5, v8);
u8 = fmla(iq5, -T::D4_R19_ROT_TWIDDLE_10, u8);
v8 = fmla(siq5, T::D4_R19_ROT_TWIDDLE_11, v8);
u8 = fmla(iq6, -T::D4_R19_ROT_TWIDDLE_12, u8);
v8 = fmla(siq6, -T::D4_R19_ROT_TWIDDLE_13, v8);
u8 = fmla(iq7, T::D4_R19_ROT_TWIDDLE_9, u8);
v8 = fmla(siq7, T::D4_R19_ROT_TWIDDLE_8, v8);
u8 = fmla(iq8, -T::D4_R19_ROT_TWIDDLE_6, u8);
v8 = fmla(siq8, -T::D4_R19_ROT_TWIDDLE_7, v8);
u8 += a0;
data[15] = u8 - v8;
data[16] = u8 + v8;
let mut u9 = iq0;
let mut v9 = siq0;
u9 *= T::D4_R19_ROT_TWIDDLE_12;
v9 *= T::D4_R19_ROT_TWIDDLE_13;
u9 = fmla(iq1, T::D4_R19_ROT_TWIDDLE_16, u9);
v9 = fmla(siq1, -T::D4_R19_ROT_TWIDDLE_17, v9);
u9 = fmla(iq2, T::D4_R19_ROT_TWIDDLE_10, u9);
v9 = fmla(siq2, T::D4_R19_ROT_TWIDDLE_11, v9);
u9 = fmla(iq3, -T::D4_R19_ROT_TWIDDLE_9, u9);
v9 = fmla(siq3, -T::D4_R19_ROT_TWIDDLE_8, v9);
u9 = fmla(iq4, T::D4_R19_ROT_TWIDDLE_1, u9);
v9 = fmla(siq4, T::D4_R19_ROT_TWIDDLE_0, v9);
u9 = fmla(iq5, -T::D4_R19_ROT_TWIDDLE_4, u9);
v9 = fmla(siq5, -T::D4_R19_ROT_TWIDDLE_5, v9);
u9 = fmla(iq6, T::D4_R19_ROT_TWIDDLE_6, u9);
v9 = fmla(siq6, T::D4_R19_ROT_TWIDDLE_7, v9);
u9 = fmla(iq7, -T::D4_R19_ROT_TWIDDLE_14, u9);
v9 = fmla(siq7, -T::D4_R19_ROT_TWIDDLE_15, v9);
u9 = fmla(iq8, T::D4_R19_ROT_TWIDDLE_2, u9);
v9 = fmla(siq8, T::D4_R19_ROT_TWIDDLE_3, v9);
u9 = u9 - a0;
data[17] = u9 - v9;
data[18] = u9 + v9;
}
}
impl<T: DctSample + Dct4MixedRadix19Sample> PxdctExecutor<T> for Dct4Butterfly19<T>
where
f64: AsPrimitive<T>,
{
fn execute(&self, data: &mut [T]) -> Result<(), PxdctError> {
if !data.len().is_multiple_of(19) {
return Err(PxdctError::InvalidSizeMultiplier(data.len(), self.length()));
}
for chunk in data.as_chunks_mut::<19>().0.iter_mut() {
self.exec(&mut InPlaceStore::new(chunk));
}
Ok(())
}
fn execute_with_scratch(&self, data: &mut [T], _: &mut [T]) -> Result<(), PxdctError> {
self.execute(data)
}
fn execute_into(&self, input: &[T], output: &mut [T]) -> Result<(), PxdctError> {
self.execute_into_with_scratch(input, output, &mut [])
}
fn execute_into_with_scratch(
&self,
input: &[T],
output: &mut [T],
_: &mut [T],
) -> Result<(), PxdctError> {
use crate::util::validate_oof_sizes;
validate_oof_sizes!(input, output, 19);
use crate::bidirectional::BiStore;
for (src, dst) in input
.as_chunks::<19>()
.0
.iter()
.zip(output.as_chunks_mut::<19>().0.iter_mut())
{
self.exec(&mut BiStore::new(src, dst));
}
Ok(())
}
fn length(&self) -> usize {
19
}
fn scratch_size(&self) -> usize {
0
}
}
pub(crate) trait Dct4MixedRadix23Sample {
const D4_R23_ROT_TWIDDLE_0: Self;
const D4_R23_ROT_TWIDDLE_1: Self;
const D4_R23_ROT_TWIDDLE_2: Self;
const D4_R23_ROT_TWIDDLE_3: Self;
const D4_R23_ROT_TWIDDLE_4: Self;
const D4_R23_ROT_TWIDDLE_5: Self;
const D4_R23_ROT_TWIDDLE_6: Self;
const D4_R23_ROT_TWIDDLE_7: Self;
const D4_R23_ROT_TWIDDLE_8: Self;
const D4_R23_ROT_TWIDDLE_9: Self;
const D4_R23_ROT_TWIDDLE_10: Self;
const D4_R23_ROT_TWIDDLE_11: Self;
const D4_R23_ROT_TWIDDLE_12: Self;
const D4_R23_ROT_TWIDDLE_13: Self;
const D4_R23_ROT_TWIDDLE_14: Self;
const D4_R23_ROT_TWIDDLE_15: Self;
const D4_R23_ROT_TWIDDLE_16: Self;
const D4_R23_ROT_TWIDDLE_17: Self;
const D4_R23_ROT_TWIDDLE_18: Self;
const D4_R23_ROT_TWIDDLE_19: Self;
const D4_R23_ROT_TWIDDLE_20: Self;
const D4_R23_ROT_TWIDDLE_21: Self;
}
impl Dct4MixedRadix23Sample for f32 {
const D4_R23_ROT_TWIDDLE_0: f32 = f32::from_bits(0x3f3b1811);
const D4_R23_ROT_TWIDDLE_1: f32 = f32::from_bits(0x3f2ebbce);
const D4_R23_ROT_TWIDDLE_2: f32 = f32::from_bits(0x3f7d9d98);
const D4_R23_ROT_TWIDDLE_3: f32 = f32::from_bits(0x3e0b6f45);
const D4_R23_ROT_TWIDDLE_4: f32 = f32::from_bits(0x3f469504);
const D4_R23_ROT_TWIDDLE_5: f32 = f32::from_bits(0x3f218efb);
const D4_R23_ROT_TWIDDLE_6: f32 = f32::from_bits(0x3f6ace5c);
const D4_R23_ROT_TWIDDLE_7: f32 = f32::from_bits(0x3ecbfb3a);
const D4_R23_ROT_TWIDDLE_8: f32 = f32::from_bits(0x3f5124f0);
const D4_R23_ROT_TWIDDLE_9: f32 = f32::from_bits(0x3f13a152);
const D4_R23_ROT_TWIDDLE_10: f32 = f32::from_bits(0x3f5abb3b);
const D4_R23_ROT_TWIDDLE_11: f32 = f32::from_bits(0x3f050374);
const D4_R23_ROT_TWIDDLE_12: f32 = f32::from_bits(0x3f634c72);
const D4_R23_ROT_TWIDDLE_13: f32 = f32::from_bits(0x3eeb8da5);
const D4_R23_ROT_TWIDDLE_14: f32 = f32::from_bits(0x3eab7557);
const D4_R23_ROT_TWIDDLE_15: f32 = f32::from_bits(0x3f713803);
const D4_R23_ROT_TWIDDLE_16: f32 = f32::from_bits(0x3d8bc2ae);
const D4_R23_ROT_TWIDDLE_17: f32 = f32::from_bits(0x3f7f6738);
const D4_R23_ROT_TWIDDLE_18: f32 = f32::from_bits(0xbe5056c6);
const D4_R23_ROT_TWIDDLE_19: f32 = f32::from_bits(0x3f7aa541);
const D4_R23_ROT_TWIDDLE_20: f32 = f32::from_bits(0x3f7681bf);
const D4_R23_ROT_TWIDDLE_21: f32 = f32::from_bits(0x3e8a22cd);
}
impl Dct4MixedRadix23Sample for f64 {
const D4_R23_ROT_TWIDDLE_0: f64 = f64::from_bits(0x3fe763021aaa15da);
const D4_R23_ROT_TWIDDLE_1: f64 = f64::from_bits(0x3fe5d779b07cfef7);
const D4_R23_ROT_TWIDDLE_2: f64 = f64::from_bits(0x3fefb3b3035aa6cd);
const D4_R23_ROT_TWIDDLE_3: f64 = f64::from_bits(0x3fc16de8a4564f0a);
const D4_R23_ROT_TWIDDLE_4: f64 = f64::from_bits(0x3fe8d2a07c16d46f);
const D4_R23_ROT_TWIDDLE_5: f64 = f64::from_bits(0x3fe431df5838f7ef);
const D4_R23_ROT_TWIDDLE_6: f64 = f64::from_bits(0x3fed59cb83ef99bc);
const D4_R23_ROT_TWIDDLE_7: f64 = f64::from_bits(0x3fd97f6748e524b2);
const D4_R23_ROT_TWIDDLE_8: f64 = f64::from_bits(0x3fea249e0b897ca9);
const D4_R23_ROT_TWIDDLE_9: f64 = f64::from_bits(0x3fe2742a4a775cfb);
const D4_R23_ROT_TWIDDLE_10: f64 = f64::from_bits(0x3feb57675cf309ee);
const D4_R23_ROT_TWIDDLE_11: f64 = f64::from_bits(0x3fe0a06e851db7ca);
const D4_R23_ROT_TWIDDLE_12: f64 = f64::from_bits(0x3fec698e42f47b09);
const D4_R23_ROT_TWIDDLE_13: f64 = f64::from_bits(0x3fdd71b4a0c5a6c8);
const D4_R23_ROT_TWIDDLE_14: f64 = f64::from_bits(0x3fd56eaae597c775);
const D4_R23_ROT_TWIDDLE_15: f64 = f64::from_bits(0x3fee270060999288);
const D4_R23_ROT_TWIDDLE_16: f64 = f64::from_bits(0x3fb17855b599f3b6);
const D4_R23_ROT_TWIDDLE_17: f64 = f64::from_bits(0x3fefece70dfd3efb);
const D4_R23_ROT_TWIDDLE_18: f64 = f64::from_bits(0xbfca0ad8bd1e287e);
const D4_R23_ROT_TWIDDLE_19: f64 = f64::from_bits(0x3fef54a827142577);
const D4_R23_ROT_TWIDDLE_20: f64 = f64::from_bits(0x3feed037ea3d2dbb);
const D4_R23_ROT_TWIDDLE_21: f64 = f64::from_bits(0x3fd14459ad2be466);
}
#[derive(Debug, Clone)]
pub(crate) struct Dct4Butterfly23<T> {
_phantom: PhantomData<T>,
}
impl<T: DctSample> Default for Dct4Butterfly23<T>
where
f64: AsPrimitive<T>,
{
fn default() -> Self {
Self {
_phantom: PhantomData,
}
}
}
impl<T: DctSample + Dct4MixedRadix23Sample> Dct4Butterfly23<T> {
#[inline(always)]
pub(crate) fn exec<S: BidirectionalStore<T>>(&self, data: &mut S) {
let a_buffer = [data[11] * T::FRAC_1_SQRT_2];
let c_buffer = [
(data[0] + data[22]) * T::FRAC_1_SQRT_2,
(data[1] + data[21]) * T::FRAC_1_SQRT_2,
(data[2] + data[20]) * T::FRAC_1_SQRT_2,
(data[3] + data[19]) * T::FRAC_1_SQRT_2,
(data[4] + data[18]) * T::FRAC_1_SQRT_2,
(data[5] + data[17]) * T::FRAC_1_SQRT_2,
(data[6] + data[16]) * T::FRAC_1_SQRT_2,
(data[7] + data[15]) * T::FRAC_1_SQRT_2,
(data[8] + data[14]) * T::FRAC_1_SQRT_2,
(data[9] + data[13]) * T::FRAC_1_SQRT_2,
(data[10] + data[12]) * T::FRAC_1_SQRT_2,
];
let s_buffer = [
(data[0] - data[22]) * T::FRAC_1_SQRT_2,
(data[1] - data[21]) * T::FRAC_1_SQRT_2,
(data[2] - data[20]) * T::FRAC_1_SQRT_2,
(data[3] - data[19]) * T::FRAC_1_SQRT_2,
(data[4] - data[18]) * T::FRAC_1_SQRT_2,
(data[5] - data[17]) * T::FRAC_1_SQRT_2,
(data[6] - data[16]) * T::FRAC_1_SQRT_2,
(data[7] - data[15]) * T::FRAC_1_SQRT_2,
(data[8] - data[14]) * T::FRAC_1_SQRT_2,
(data[9] - data[13]) * T::FRAC_1_SQRT_2,
(data[10] - data[12]) * T::FRAC_1_SQRT_2,
];
let c0 = c_buffer[0];
let s0 = s_buffer[0];
let s0_tw0 = s0 * T::D4_R23_ROT_TWIDDLE_1;
let s0_tw1 = -s0 * T::D4_R23_ROT_TWIDDLE_0;
let iq0 = fmla(c0, T::D4_R23_ROT_TWIDDLE_0, s0_tw0);
let siq0 = fmla(c0, T::D4_R23_ROT_TWIDDLE_1, s0_tw1);
let mut u0 = iq0;
let mut u1 = u0;
let mut v0 = siq0;
u1 *= T::D4_R23_ROT_TWIDDLE_2;
v0 *= T::D4_R23_ROT_TWIDDLE_3;
let c1 = c_buffer[1];
let s1 = s_buffer[1];
let iq1 = fmla(c1, T::D4_R23_ROT_TWIDDLE_4, s1 * T::D4_R23_ROT_TWIDDLE_5);
let siq1 = fmla(c1, T::D4_R23_ROT_TWIDDLE_5, -s1 * T::D4_R23_ROT_TWIDDLE_4);
u0 += iq1;
u1 = fmla(iq1, T::D4_R23_ROT_TWIDDLE_6, u1);
v0 = fmla(siq1, T::D4_R23_ROT_TWIDDLE_7, v0);
let c2 = c_buffer[2];
let s2 = s_buffer[2];
let iq2 = fmla(c2, T::D4_R23_ROT_TWIDDLE_8, s2 * T::D4_R23_ROT_TWIDDLE_9);
let siq2 = fmla(c2, T::D4_R23_ROT_TWIDDLE_9, -s2 * T::D4_R23_ROT_TWIDDLE_8);
u0 += iq2;
u1 = fmla(iq2, T::D4_R23_ROT_TWIDDLE_4, u1);
v0 = fmla(siq2, T::D4_R23_ROT_TWIDDLE_5, v0);
let c3 = c_buffer[3];
let s3 = s_buffer[3];
let iq3 = fmla(c3, T::D4_R23_ROT_TWIDDLE_10, s3 * T::D4_R23_ROT_TWIDDLE_11);
let siq3 = fmla(c3, T::D4_R23_ROT_TWIDDLE_11, -s3 * T::D4_R23_ROT_TWIDDLE_10);
u0 += iq3;
u1 = fmla(iq3, T::D4_R23_ROT_TWIDDLE_9, u1);
v0 = fmla(siq3, T::D4_R23_ROT_TWIDDLE_8, v0);
let c4 = c_buffer[4];
let s4 = s_buffer[4];
let iq4 = fmla(c4, T::D4_R23_ROT_TWIDDLE_12, s4 * T::D4_R23_ROT_TWIDDLE_13);
let siq4 = fmla(c4, T::D4_R23_ROT_TWIDDLE_13, -s4 * T::D4_R23_ROT_TWIDDLE_12);
u0 += iq4;
u1 = fmla(iq4, T::D4_R23_ROT_TWIDDLE_14, u1);
v0 = fmla(siq4, T::D4_R23_ROT_TWIDDLE_15, v0);
let c5 = c_buffer[5];
let s5 = s_buffer[5];
let iq5 = fmla(c5, T::D4_R23_ROT_TWIDDLE_6, s5 * T::D4_R23_ROT_TWIDDLE_7);
let siq5 = fmla(c5, T::D4_R23_ROT_TWIDDLE_7, -s5 * T::D4_R23_ROT_TWIDDLE_6);
u0 += iq5;
u1 = fmla(iq5, T::D4_R23_ROT_TWIDDLE_16, u1);
v0 = fmla(siq5, T::D4_R23_ROT_TWIDDLE_17, v0);
let c6 = c_buffer[6];
let s6 = s_buffer[6];
let iq6 = fmla(c6, T::D4_R23_ROT_TWIDDLE_15, s6 * T::D4_R23_ROT_TWIDDLE_14);
let siq6 = fmla(c6, T::D4_R23_ROT_TWIDDLE_14, -s6 * T::D4_R23_ROT_TWIDDLE_15);
u0 += iq6;
u1 = fmla(iq6, T::D4_R23_ROT_TWIDDLE_18, u1);
v0 = fmla(siq6, T::D4_R23_ROT_TWIDDLE_19, v0);
let c7 = c_buffer[7];
let s7 = s_buffer[7];
let iq7 = fmla(c7, T::D4_R23_ROT_TWIDDLE_20, s7 * T::D4_R23_ROT_TWIDDLE_21);
let siq7 = fmla(c7, T::D4_R23_ROT_TWIDDLE_21, -s7 * T::D4_R23_ROT_TWIDDLE_20);
u0 += iq7;
u1 = fmla(iq7, -T::D4_R23_ROT_TWIDDLE_13, u1);
v0 = fmla(siq7, T::D4_R23_ROT_TWIDDLE_12, v0);
let c8 = c_buffer[8];
let s8 = s_buffer[8];
let iq8 = fmla(c8, T::D4_R23_ROT_TWIDDLE_19, s8 * -T::D4_R23_ROT_TWIDDLE_18);
let siq8 = fmla(
c8,
-T::D4_R23_ROT_TWIDDLE_18,
-s8 * T::D4_R23_ROT_TWIDDLE_19,
);
u0 += iq8;
u1 = fmla(iq8, -T::D4_R23_ROT_TWIDDLE_1, u1);
v0 = fmla(siq8, T::D4_R23_ROT_TWIDDLE_0, v0);
let c9 = c_buffer[9];
let s9 = s_buffer[9];
let iq9 = fmla(c9, T::D4_R23_ROT_TWIDDLE_2, s9 * T::D4_R23_ROT_TWIDDLE_3);
let siq9 = fmla(c9, T::D4_R23_ROT_TWIDDLE_3, -s9 * T::D4_R23_ROT_TWIDDLE_2);
u0 += iq9;
u1 = fmla(iq9, -T::D4_R23_ROT_TWIDDLE_10, u1);
v0 = fmla(siq9, T::D4_R23_ROT_TWIDDLE_11, v0);
let c10 = c_buffer[10];
let s10 = s_buffer[10];
let iq10 = fmla(
c10,
T::D4_R23_ROT_TWIDDLE_17,
s10 * T::D4_R23_ROT_TWIDDLE_16,
);
let siq10 = fmla(
c10,
T::D4_R23_ROT_TWIDDLE_16,
-s10 * T::D4_R23_ROT_TWIDDLE_17,
);
u0 += iq10;
u1 = fmla(iq10, -T::D4_R23_ROT_TWIDDLE_20, u1);
v0 = fmla(siq10, T::D4_R23_ROT_TWIDDLE_21, v0);
let a0 = a_buffer[0];
u0 += a0;
u1 = u1 - a0;
data[0] = u0;
data[1] = u1 - v0;
data[2] = u1 + v0;
let mut u2 = iq0;
let mut v2 = siq0;
u2 *= T::D4_R23_ROT_TWIDDLE_20;
v2 *= T::D4_R23_ROT_TWIDDLE_21;
u2 = fmla(iq1, T::D4_R23_ROT_TWIDDLE_1, u2);
v2 = fmla(siq1, T::D4_R23_ROT_TWIDDLE_0, v2);
u2 = fmla(iq2, -T::D4_R23_ROT_TWIDDLE_18, u2);
v2 = fmla(siq2, T::D4_R23_ROT_TWIDDLE_19, v2);
u2 = fmla(iq3, -T::D4_R23_ROT_TWIDDLE_14, u2);
v2 = fmla(siq3, T::D4_R23_ROT_TWIDDLE_15, v2);
u2 = fmla(iq4, -T::D4_R23_ROT_TWIDDLE_4, u2);
v2 = fmla(siq4, T::D4_R23_ROT_TWIDDLE_5, v2);
u2 = fmla(iq5, -T::D4_R23_ROT_TWIDDLE_2, u2);
v2 = fmla(siq5, T::D4_R23_ROT_TWIDDLE_3, v2);
u2 = fmla(iq6, -T::D4_R23_ROT_TWIDDLE_6, u2);
v2 = fmla(siq6, -T::D4_R23_ROT_TWIDDLE_7, v2);
u2 = fmla(iq7, -T::D4_R23_ROT_TWIDDLE_9, u2);
v2 = fmla(siq7, -T::D4_R23_ROT_TWIDDLE_8, v2);
u2 = fmla(iq8, -T::D4_R23_ROT_TWIDDLE_16, u2);
v2 = fmla(siq8, -T::D4_R23_ROT_TWIDDLE_17, v2);
u2 = fmla(iq9, T::D4_R23_ROT_TWIDDLE_13, u2);
v2 = fmla(siq9, -T::D4_R23_ROT_TWIDDLE_12, v2);
u2 = fmla(iq10, T::D4_R23_ROT_TWIDDLE_10, u2);
v2 = fmla(siq10, -T::D4_R23_ROT_TWIDDLE_11, v2);
u2 += a0;
data[3] = u2 - v2;
data[4] = u2 + v2;
let mut u3 = iq0;
let mut v3 = siq0;
u3 *= T::D4_R23_ROT_TWIDDLE_6;
v3 *= T::D4_R23_ROT_TWIDDLE_7;
u3 = fmla(iq1, T::D4_R23_ROT_TWIDDLE_14, u3);
v3 = fmla(siq1, T::D4_R23_ROT_TWIDDLE_15, v3);
u3 = fmla(iq2, -T::D4_R23_ROT_TWIDDLE_13, u3);
v3 = fmla(siq2, T::D4_R23_ROT_TWIDDLE_12, v3);
u3 = fmla(iq3, -T::D4_R23_ROT_TWIDDLE_20, u3);
v3 = fmla(siq3, T::D4_R23_ROT_TWIDDLE_21, v3);
u3 = fmla(iq4, -T::D4_R23_ROT_TWIDDLE_10, u3);
v3 = fmla(siq4, -T::D4_R23_ROT_TWIDDLE_11, v3);
u3 = fmla(iq5, T::D4_R23_ROT_TWIDDLE_18, u3);
v3 = fmla(siq5, -T::D4_R23_ROT_TWIDDLE_19, v3);
u3 = fmla(iq6, T::D4_R23_ROT_TWIDDLE_9, u3);
v3 = fmla(siq6, -T::D4_R23_ROT_TWIDDLE_8, v3);
u3 = fmla(iq7, T::D4_R23_ROT_TWIDDLE_2, u3);
v3 = fmla(siq7, -T::D4_R23_ROT_TWIDDLE_3, v3);
u3 = fmla(iq8, T::D4_R23_ROT_TWIDDLE_4, u3);
v3 = fmla(siq8, T::D4_R23_ROT_TWIDDLE_5, v3);
u3 = fmla(iq9, T::D4_R23_ROT_TWIDDLE_16, u3);
v3 = fmla(siq9, T::D4_R23_ROT_TWIDDLE_17, v3);
u3 = fmla(iq10, -T::D4_R23_ROT_TWIDDLE_1, u3);
v3 = fmla(siq10, T::D4_R23_ROT_TWIDDLE_0, v3);
u3 = u3 - a0;
data[5] = u3 - v3;
data[6] = u3 + v3;
let mut u4 = iq0;
let mut v4 = siq0;
u4 *= T::D4_R23_ROT_TWIDDLE_10;
v4 *= T::D4_R23_ROT_TWIDDLE_11;
u4 = fmla(iq1, -T::D4_R23_ROT_TWIDDLE_16, u4);
v4 = fmla(siq1, T::D4_R23_ROT_TWIDDLE_17, v4);
u4 = fmla(iq2, -T::D4_R23_ROT_TWIDDLE_6, u4);
v4 = fmla(siq2, T::D4_R23_ROT_TWIDDLE_7, v4);
u4 = fmla(iq3, -T::D4_R23_ROT_TWIDDLE_4, u4);
v4 = fmla(siq3, -T::D4_R23_ROT_TWIDDLE_5, v4);
u4 = fmla(iq4, -T::D4_R23_ROT_TWIDDLE_18, u4);
v4 = fmla(siq4, -T::D4_R23_ROT_TWIDDLE_19, v4);
u4 = fmla(iq5, T::D4_R23_ROT_TWIDDLE_20, u4);
v4 = fmla(siq5, -T::D4_R23_ROT_TWIDDLE_21, v4);
u4 = fmla(iq6, T::D4_R23_ROT_TWIDDLE_1, u4);
v4 = fmla(siq6, T::D4_R23_ROT_TWIDDLE_0, v4);
u4 = fmla(iq7, -T::D4_R23_ROT_TWIDDLE_14, u4);
v4 = fmla(siq7, T::D4_R23_ROT_TWIDDLE_15, v4);
u4 = fmla(iq8, -T::D4_R23_ROT_TWIDDLE_2, u4);
v4 = fmla(siq8, T::D4_R23_ROT_TWIDDLE_3, v4);
u4 = fmla(iq9, -T::D4_R23_ROT_TWIDDLE_9, u4);
v4 = fmla(siq9, -T::D4_R23_ROT_TWIDDLE_8, v4);
u4 = fmla(iq10, T::D4_R23_ROT_TWIDDLE_13, u4);
v4 = fmla(siq10, -T::D4_R23_ROT_TWIDDLE_12, v4);
u4 += a0;
data[7] = u4 - v4;
data[8] = u4 + v4;
let mut u5 = iq0;
let mut v5 = siq0;
u5 *= T::D4_R23_ROT_TWIDDLE_4;
v5 *= T::D4_R23_ROT_TWIDDLE_5;
u5 = fmla(iq1, -T::D4_R23_ROT_TWIDDLE_13, u5);
v5 = fmla(siq1, T::D4_R23_ROT_TWIDDLE_12, v5);
u5 = fmla(iq2, -T::D4_R23_ROT_TWIDDLE_20, u5);
v5 = fmla(siq2, -T::D4_R23_ROT_TWIDDLE_21, v5);
u5 = fmla(iq3, T::D4_R23_ROT_TWIDDLE_16, u5);
v5 = fmla(siq3, -T::D4_R23_ROT_TWIDDLE_17, v5);
u5 = fmla(iq4, T::D4_R23_ROT_TWIDDLE_2, u5);
v5 = fmla(siq4, -T::D4_R23_ROT_TWIDDLE_3, v5);
u5 = fmla(iq5, T::D4_R23_ROT_TWIDDLE_14, u5);
v5 = fmla(siq5, T::D4_R23_ROT_TWIDDLE_15, v5);
u5 = fmla(iq6, -T::D4_R23_ROT_TWIDDLE_10, u5);
v5 = fmla(siq6, T::D4_R23_ROT_TWIDDLE_11, v5);
u5 = fmla(iq7, -T::D4_R23_ROT_TWIDDLE_1, u5);
v5 = fmla(siq7, -T::D4_R23_ROT_TWIDDLE_0, v5);
u5 = fmla(iq8, T::D4_R23_ROT_TWIDDLE_9, u5);
v5 = fmla(siq8, -T::D4_R23_ROT_TWIDDLE_8, v5);
u5 = fmla(iq9, T::D4_R23_ROT_TWIDDLE_6, u5);
v5 = fmla(siq9, T::D4_R23_ROT_TWIDDLE_7, v5);
u5 = fmla(iq10, T::D4_R23_ROT_TWIDDLE_18, u5);
v5 = fmla(siq10, T::D4_R23_ROT_TWIDDLE_19, v5);
u5 = u5 - a0;
data[9] = u5 - v5;
data[10] = u5 + v5;
let mut u6 = iq0;
let mut v6 = siq0;
u6 *= T::D4_R23_ROT_TWIDDLE_1;
v6 *= T::D4_R23_ROT_TWIDDLE_0;
u6 = fmla(iq1, -T::D4_R23_ROT_TWIDDLE_4, u6);
v6 = fmla(siq1, T::D4_R23_ROT_TWIDDLE_5, v6);
u6 = fmla(iq2, -T::D4_R23_ROT_TWIDDLE_9, u6);
v6 = fmla(siq2, -T::D4_R23_ROT_TWIDDLE_8, v6);
u6 = fmla(iq3, T::D4_R23_ROT_TWIDDLE_10, u6);
v6 = fmla(siq3, -T::D4_R23_ROT_TWIDDLE_11, v6);
u6 = fmla(iq4, T::D4_R23_ROT_TWIDDLE_13, u6);
v6 = fmla(siq4, T::D4_R23_ROT_TWIDDLE_12, v6);
u6 = fmla(iq5, -T::D4_R23_ROT_TWIDDLE_6, u6);
v6 = fmla(siq5, T::D4_R23_ROT_TWIDDLE_7, v6);
u6 = fmla(iq6, -T::D4_R23_ROT_TWIDDLE_14, u6);
v6 = fmla(siq6, -T::D4_R23_ROT_TWIDDLE_15, v6);
u6 = fmla(iq7, T::D4_R23_ROT_TWIDDLE_20, u6);
v6 = fmla(siq7, -T::D4_R23_ROT_TWIDDLE_21, v6);
u6 = fmla(iq8, -T::D4_R23_ROT_TWIDDLE_18, u6);
v6 = fmla(siq8, T::D4_R23_ROT_TWIDDLE_19, v6);
u6 = fmla(iq9, -T::D4_R23_ROT_TWIDDLE_2, u6);
v6 = fmla(siq9, T::D4_R23_ROT_TWIDDLE_3, v6);
u6 = fmla(iq10, -T::D4_R23_ROT_TWIDDLE_16, u6);
v6 = fmla(siq10, -T::D4_R23_ROT_TWIDDLE_17, v6);
u6 += a0;
data[11] = u6 - v6;
data[12] = u6 + v6;
let mut u7 = iq0;
let mut v7 = siq0;
u7 *= T::D4_R23_ROT_TWIDDLE_9;
v7 *= T::D4_R23_ROT_TWIDDLE_8;
u7 = fmla(iq1, -T::D4_R23_ROT_TWIDDLE_20, u7);
v7 = fmla(siq1, T::D4_R23_ROT_TWIDDLE_21, v7);
u7 = fmla(iq2, T::D4_R23_ROT_TWIDDLE_16, u7);
v7 = fmla(siq2, -T::D4_R23_ROT_TWIDDLE_17, v7);
u7 = fmla(iq3, T::D4_R23_ROT_TWIDDLE_6, u7);
v7 = fmla(siq3, T::D4_R23_ROT_TWIDDLE_7, v7);
u7 = fmla(iq4, -T::D4_R23_ROT_TWIDDLE_1, u7);
v7 = fmla(siq4, T::D4_R23_ROT_TWIDDLE_0, v7);
u7 = fmla(iq5, -T::D4_R23_ROT_TWIDDLE_13, u7);
v7 = fmla(siq5, -T::D4_R23_ROT_TWIDDLE_12, v7);
u7 = fmla(iq6, T::D4_R23_ROT_TWIDDLE_2, u7);
v7 = fmla(siq6, -T::D4_R23_ROT_TWIDDLE_3, v7);
u7 = fmla(iq7, T::D4_R23_ROT_TWIDDLE_18, u7);
v7 = fmla(siq7, T::D4_R23_ROT_TWIDDLE_19, v7);
u7 = fmla(iq8, -T::D4_R23_ROT_TWIDDLE_10, u7);
v7 = fmla(siq8, -T::D4_R23_ROT_TWIDDLE_11, v7);
u7 = fmla(iq9, T::D4_R23_ROT_TWIDDLE_4, u7);
v7 = fmla(siq9, -T::D4_R23_ROT_TWIDDLE_5, v7);
u7 = fmla(iq10, T::D4_R23_ROT_TWIDDLE_14, u7);
v7 = fmla(siq10, T::D4_R23_ROT_TWIDDLE_15, v7);
u7 = u7 - a0;
data[13] = u7 - v7;
data[14] = u7 + v7;
let mut u8 = iq0;
let mut v8 = siq0;
u8 *= T::D4_R23_ROT_TWIDDLE_13;
v8 *= T::D4_R23_ROT_TWIDDLE_12;
u8 = fmla(iq1, -T::D4_R23_ROT_TWIDDLE_2, u8);
v8 = fmla(siq1, -T::D4_R23_ROT_TWIDDLE_3, v8);
u8 = fmla(iq2, T::D4_R23_ROT_TWIDDLE_1, u8);
v8 = fmla(siq2, -T::D4_R23_ROT_TWIDDLE_0, v8);
u8 = fmla(iq3, -T::D4_R23_ROT_TWIDDLE_18, u8);
v8 = fmla(siq3, T::D4_R23_ROT_TWIDDLE_19, v8);
u8 = fmla(iq4, -T::D4_R23_ROT_TWIDDLE_6, u8);
v8 = fmla(siq4, -T::D4_R23_ROT_TWIDDLE_7, v8);
u8 = fmla(iq5, T::D4_R23_ROT_TWIDDLE_10, u8);
v8 = fmla(siq5, -T::D4_R23_ROT_TWIDDLE_11, v8);
u8 = fmla(iq6, -T::D4_R23_ROT_TWIDDLE_16, u8);
v8 = fmla(siq6, T::D4_R23_ROT_TWIDDLE_17, v8);
u8 = fmla(iq7, -T::D4_R23_ROT_TWIDDLE_4, u8);
v8 = fmla(siq7, -T::D4_R23_ROT_TWIDDLE_5, v8);
u8 = fmla(iq8, T::D4_R23_ROT_TWIDDLE_20, u8);
v8 = fmla(siq8, -T::D4_R23_ROT_TWIDDLE_21, v8);
u8 = fmla(iq9, -T::D4_R23_ROT_TWIDDLE_14, u8);
v8 = fmla(siq9, T::D4_R23_ROT_TWIDDLE_15, v8);
u8 = fmla(iq10, -T::D4_R23_ROT_TWIDDLE_9, u8);
v8 = fmla(siq10, -T::D4_R23_ROT_TWIDDLE_8, v8);
u8 += a0;
data[15] = u8 - v8;
data[16] = u8 + v8;
let mut u9 = iq0;
let mut v9 = siq0;
u9 *= T::D4_R23_ROT_TWIDDLE_14;
v9 *= T::D4_R23_ROT_TWIDDLE_15;
u9 = fmla(iq1, -T::D4_R23_ROT_TWIDDLE_10, u9);
v9 = fmla(siq1, -T::D4_R23_ROT_TWIDDLE_11, v9);
u9 = fmla(iq2, T::D4_R23_ROT_TWIDDLE_2, u9);
v9 = fmla(siq2, -T::D4_R23_ROT_TWIDDLE_3, v9);
u9 = fmla(iq3, -T::D4_R23_ROT_TWIDDLE_1, u9);
v9 = fmla(siq3, T::D4_R23_ROT_TWIDDLE_0, v9);
u9 = fmla(iq4, T::D4_R23_ROT_TWIDDLE_16, u9);
v9 = fmla(siq4, -T::D4_R23_ROT_TWIDDLE_17, v9);
u9 = fmla(iq5, T::D4_R23_ROT_TWIDDLE_9, u9);
v9 = fmla(siq5, T::D4_R23_ROT_TWIDDLE_8, v9);
u9 = fmla(iq6, -T::D4_R23_ROT_TWIDDLE_20, u9);
v9 = fmla(siq6, -T::D4_R23_ROT_TWIDDLE_21, v9);
u9 = fmla(iq7, T::D4_R23_ROT_TWIDDLE_6, u9);
v9 = fmla(siq7, -T::D4_R23_ROT_TWIDDLE_7, v9);
u9 = fmla(iq8, -T::D4_R23_ROT_TWIDDLE_13, u9);
v9 = fmla(siq8, T::D4_R23_ROT_TWIDDLE_12, v9);
u9 = fmla(iq9, T::D4_R23_ROT_TWIDDLE_18, u9);
v9 = fmla(siq9, -T::D4_R23_ROT_TWIDDLE_19, v9);
u9 = fmla(iq10, T::D4_R23_ROT_TWIDDLE_4, u9);
v9 = fmla(siq10, T::D4_R23_ROT_TWIDDLE_5, v9);
u9 = u9 - a0;
data[17] = u9 - v9;
data[18] = u9 + v9;
let mut u10 = iq0;
let mut v10 = siq0;
u10 *= -T::D4_R23_ROT_TWIDDLE_18;
v10 *= T::D4_R23_ROT_TWIDDLE_19;
u10 = fmla(iq1, -T::D4_R23_ROT_TWIDDLE_9, u10);
v10 = fmla(siq1, -T::D4_R23_ROT_TWIDDLE_8, v10);
u10 = fmla(iq2, T::D4_R23_ROT_TWIDDLE_10, u10);
v10 = fmla(siq2, T::D4_R23_ROT_TWIDDLE_11, v10);
u10 = fmla(iq3, -T::D4_R23_ROT_TWIDDLE_2, u10);
v10 = fmla(siq3, -T::D4_R23_ROT_TWIDDLE_3, v10);
u10 = fmla(iq4, T::D4_R23_ROT_TWIDDLE_20, u10);
v10 = fmla(siq4, -T::D4_R23_ROT_TWIDDLE_21, v10);
u10 = fmla(iq5, -T::D4_R23_ROT_TWIDDLE_4, u10);
v10 = fmla(siq5, T::D4_R23_ROT_TWIDDLE_5, v10);
u10 = fmla(iq6, T::D4_R23_ROT_TWIDDLE_13, u10);
v10 = fmla(siq6, -T::D4_R23_ROT_TWIDDLE_12, v10);
u10 = fmla(iq7, -T::D4_R23_ROT_TWIDDLE_16, u10);
v10 = fmla(siq7, T::D4_R23_ROT_TWIDDLE_17, v10);
u10 = fmla(iq8, -T::D4_R23_ROT_TWIDDLE_14, u10);
v10 = fmla(siq8, -T::D4_R23_ROT_TWIDDLE_15, v10);
u10 = fmla(iq9, T::D4_R23_ROT_TWIDDLE_1, u10);
v10 = fmla(siq9, T::D4_R23_ROT_TWIDDLE_0, v10);
u10 = fmla(iq10, -T::D4_R23_ROT_TWIDDLE_6, u10);
v10 = fmla(siq10, -T::D4_R23_ROT_TWIDDLE_7, v10);
u10 += a0;
data[19] = u10 - v10;
data[20] = u10 + v10;
let mut u11 = iq0;
let mut v11 = siq0;
u11 *= T::D4_R23_ROT_TWIDDLE_16;
v11 *= T::D4_R23_ROT_TWIDDLE_17;
u11 = fmla(iq1, T::D4_R23_ROT_TWIDDLE_18, u11);
v11 = fmla(siq1, -T::D4_R23_ROT_TWIDDLE_19, v11);
u11 = fmla(iq2, T::D4_R23_ROT_TWIDDLE_14, u11);
v11 = fmla(siq2, T::D4_R23_ROT_TWIDDLE_15, v11);
u11 = fmla(iq3, -T::D4_R23_ROT_TWIDDLE_13, u11);
v11 = fmla(siq3, -T::D4_R23_ROT_TWIDDLE_12, v11);
u11 = fmla(iq4, T::D4_R23_ROT_TWIDDLE_9, u11);
v11 = fmla(siq4, T::D4_R23_ROT_TWIDDLE_8, v11);
u11 = fmla(iq5, -T::D4_R23_ROT_TWIDDLE_1, u11);
v11 = fmla(siq5, -T::D4_R23_ROT_TWIDDLE_0, v11);
u11 = fmla(iq6, T::D4_R23_ROT_TWIDDLE_4, u11);
v11 = fmla(siq6, T::D4_R23_ROT_TWIDDLE_5, v11);
u11 = fmla(iq7, -T::D4_R23_ROT_TWIDDLE_10, u11);
v11 = fmla(siq7, -T::D4_R23_ROT_TWIDDLE_11, v11);
u11 = fmla(iq8, T::D4_R23_ROT_TWIDDLE_6, u11);
v11 = fmla(siq8, T::D4_R23_ROT_TWIDDLE_7, v11);
u11 = fmla(iq9, -T::D4_R23_ROT_TWIDDLE_20, u11);
v11 = fmla(siq9, -T::D4_R23_ROT_TWIDDLE_21, v11);
u11 = fmla(iq10, T::D4_R23_ROT_TWIDDLE_2, u11);
v11 = fmla(siq10, T::D4_R23_ROT_TWIDDLE_3, v11);
u11 = u11 - a0;
data[21] = u11 - v11;
data[22] = u11 + v11;
}
}
impl<T: DctSample + Dct4MixedRadix23Sample> PxdctExecutor<T> for Dct4Butterfly23<T>
where
f64: AsPrimitive<T>,
{
fn execute(&self, data: &mut [T]) -> Result<(), PxdctError> {
if !data.len().is_multiple_of(23) {
return Err(PxdctError::InvalidSizeMultiplier(data.len(), self.length()));
}
for chunk in data.as_chunks_mut::<23>().0.iter_mut() {
self.exec(&mut InPlaceStore::new(chunk));
}
Ok(())
}
fn execute_with_scratch(&self, data: &mut [T], _: &mut [T]) -> Result<(), PxdctError> {
self.execute(data)
}
fn execute_into(&self, input: &[T], output: &mut [T]) -> Result<(), PxdctError> {
self.execute_into_with_scratch(input, output, &mut [])
}
fn execute_into_with_scratch(
&self,
input: &[T],
output: &mut [T],
_: &mut [T],
) -> Result<(), PxdctError> {
use crate::util::validate_oof_sizes;
validate_oof_sizes!(input, output, 23);
use crate::bidirectional::BiStore;
for (src, dst) in input
.as_chunks::<23>()
.0
.iter()
.zip(output.as_chunks_mut::<23>().0.iter_mut())
{
self.exec(&mut BiStore::new(src, dst));
}
Ok(())
}
fn length(&self) -> usize {
23
}
fn scratch_size(&self) -> usize {
0
}
}
pub(crate) trait Dct4MixedRadix29Sample {
const D4_R29_ROT_TWIDDLE_0: Self;
const D4_R29_ROT_TWIDDLE_1: Self;
const D4_R29_ROT_TWIDDLE_2: Self;
const D4_R29_ROT_TWIDDLE_3: Self;
const D4_R29_ROT_TWIDDLE_4: Self;
const D4_R29_ROT_TWIDDLE_5: Self;
const D4_R29_ROT_TWIDDLE_6: Self;
const D4_R29_ROT_TWIDDLE_7: Self;
const D4_R29_ROT_TWIDDLE_8: Self;
const D4_R29_ROT_TWIDDLE_9: Self;
const D4_R29_ROT_TWIDDLE_10: Self;
const D4_R29_ROT_TWIDDLE_11: Self;
const D4_R29_ROT_TWIDDLE_12: Self;
const D4_R29_ROT_TWIDDLE_13: Self;
const D4_R29_ROT_TWIDDLE_14: Self;
const D4_R29_ROT_TWIDDLE_15: Self;
const D4_R29_ROT_TWIDDLE_16: Self;
const D4_R29_ROT_TWIDDLE_17: Self;
const D4_R29_ROT_TWIDDLE_18: Self;
const D4_R29_ROT_TWIDDLE_19: Self;
const D4_R29_ROT_TWIDDLE_20: Self;
const D4_R29_ROT_TWIDDLE_21: Self;
const D4_R29_ROT_TWIDDLE_22: Self;
const D4_R29_ROT_TWIDDLE_23: Self;
const D4_R29_ROT_TWIDDLE_24: Self;
const D4_R29_ROT_TWIDDLE_25: Self;
const D4_R29_ROT_TWIDDLE_26: Self;
const D4_R29_ROT_TWIDDLE_27: Self;
}
impl Dct4MixedRadix29Sample for f32 {
const D4_R29_ROT_TWIDDLE_0: f32 = f32::from_bits(0x3f39dad7);
const D4_R29_ROT_TWIDDLE_1: f32 = f32::from_bits(0x3f300d12);
const D4_R29_ROT_TWIDDLE_2: f32 = f32::from_bits(0x3f7e7fd3);
const D4_R29_ROT_TWIDDLE_3: f32 = f32::from_bits(0x3ddd6d81);
const D4_R29_ROT_TWIDDLE_4: f32 = f32::from_bits(0x3f431d0d);
const D4_R29_ROT_TWIDDLE_5: f32 = f32::from_bits(0x3f25bb1c);
const D4_R29_ROT_TWIDDLE_6: f32 = f32::from_bits(0x3f729966);
const D4_R29_ROT_TWIDDLE_7: f32 = f32::from_bits(0x3ea37b7d);
const D4_R29_ROT_TWIDDLE_8: f32 = f32::from_bits(0x3f4bccc1);
const D4_R29_ROT_TWIDDLE_9: f32 = f32::from_bits(0x3f1aecb3);
const D4_R29_ROT_TWIDDLE_10: f32 = f32::from_bits(0x3f5b5afe);
const D4_R29_ROT_TWIDDLE_11: f32 = f32::from_bits(0x3f03fb56);
const D4_R29_ROT_TWIDDLE_12: f32 = f32::from_bits(0x3f53e36d);
const D4_R29_ROT_TWIDDLE_13: f32 = f32::from_bits(0x3f0fa9f5);
const D4_R29_ROT_TWIDDLE_14: f32 = f32::from_bits(0x3f622dd8);
const D4_R29_ROT_TWIDDLE_15: f32 = f32::from_bits(0x3eefd33b);
const D4_R29_ROT_TWIDDLE_16: f32 = f32::from_bits(0x3ebd82c0);
const D4_R29_ROT_TWIDDLE_17: f32 = f32::from_bits(0x3f6dd16b);
const D4_R29_ROT_TWIDDLE_18: f32 = f32::from_bits(0x3f6856dd);
const D4_R29_ROT_TWIDDLE_19: f32 = f32::from_bits(0x3ed6fbb4);
const D4_R29_ROT_TWIDDLE_20: f32 = f32::from_bits(0x3e25aa2e);
const D4_R29_ROT_TWIDDLE_21: f32 = f32::from_bits(0x3f7ca0aa);
const D4_R29_ROT_TWIDDLE_22: f32 = f32::from_bits(0xbd5dc0c3);
const D4_R29_ROT_TWIDDLE_23: f32 = f32::from_bits(0x3f7f9fe3);
const D4_R29_ROT_TWIDDLE_24: f32 = f32::from_bits(0xbe88f979);
const D4_R29_ROT_TWIDDLE_25: f32 = f32::from_bits(0x3f76ab36);
const D4_R29_ROT_TWIDDLE_26: f32 = f32::from_bits(0x3f7a03ce);
const D4_R29_ROT_TWIDDLE_27: f32 = f32::from_bits(0x3e5c2136);
}
impl Dct4MixedRadix29Sample for f64 {
const D4_R29_ROT_TWIDDLE_0: f64 = f64::from_bits(0x3fe73b5ae5db4e10);
const D4_R29_ROT_TWIDDLE_1: f64 = f64::from_bits(0x3fe601a24ba81342);
const D4_R29_ROT_TWIDDLE_2: f64 = f64::from_bits(0x3fefcffa67b61650);
const D4_R29_ROT_TWIDDLE_3: f64 = f64::from_bits(0x3fbbadb02034d9ff);
const D4_R29_ROT_TWIDDLE_4: f64 = f64::from_bits(0x3fe863a1ada0cfa6);
const D4_R29_ROT_TWIDDLE_5: f64 = f64::from_bits(0x3fe4b76371208a62);
const D4_R29_ROT_TWIDDLE_6: f64 = f64::from_bits(0x3fee532cbe45c954);
const D4_R29_ROT_TWIDDLE_7: f64 = f64::from_bits(0x3fd46f6faf5fcb72);
const D4_R29_ROT_TWIDDLE_8: f64 = f64::from_bits(0x3fe979982a38e65a);
const D4_R29_ROT_TWIDDLE_9: f64 = f64::from_bits(0x3fe35d9650d47852);
const D4_R29_ROT_TWIDDLE_10: f64 = f64::from_bits(0x3feb6b5fbd9f7255);
const D4_R29_ROT_TWIDDLE_11: f64 = f64::from_bits(0x3fe07f6acd7cdce2);
const D4_R29_ROT_TWIDDLE_12: f64 = f64::from_bits(0x3fea7c6da34af89f);
const D4_R29_ROT_TWIDDLE_13: f64 = f64::from_bits(0x3fe1f53e93956dbf);
const D4_R29_ROT_TWIDDLE_14: f64 = f64::from_bits(0x3fec45bb0d10918c);
const D4_R29_ROT_TWIDDLE_15: f64 = f64::from_bits(0x3fddfa67657e7608);
const D4_R29_ROT_TWIDDLE_16: f64 = f64::from_bits(0x3fd7b057f20bf2e5);
const D4_R29_ROT_TWIDDLE_17: f64 = f64::from_bits(0x3fedba2d62cb789f);
const D4_R29_ROT_TWIDDLE_18: f64 = f64::from_bits(0x3fed0adb9b447ccf);
const D4_R29_ROT_TWIDDLE_19: f64 = f64::from_bits(0x3fdadf7689c97b6f);
const D4_R29_ROT_TWIDDLE_20: f64 = f64::from_bits(0x3fc4b545c0234a70);
const D4_R29_ROT_TWIDDLE_21: f64 = f64::from_bits(0x3fef941537248537);
const D4_R29_ROT_TWIDDLE_22: f64 = f64::from_bits(0xbfabb81853a18987);
const D4_R29_ROT_TWIDDLE_23: f64 = f64::from_bits(0x3feff3fc588e859d);
const D4_R29_ROT_TWIDDLE_24: f64 = f64::from_bits(0xbfd11f2f2e2f1e38);
const D4_R29_ROT_TWIDDLE_25: f64 = f64::from_bits(0x3feed566cb3dcba2);
const D4_R29_ROT_TWIDDLE_26: f64 = f64::from_bits(0x3fef4079c06c0992);
const D4_R29_ROT_TWIDDLE_27: f64 = f64::from_bits(0x3fcb8426c12812bc);
}
#[derive(Debug, Clone)]
pub(crate) struct Dct4Butterfly29<T> {
_phantom: PhantomData<T>,
}
impl<T: DctSample> Default for Dct4Butterfly29<T>
where
f64: AsPrimitive<T>,
{
fn default() -> Self {
Self {
_phantom: PhantomData,
}
}
}
impl<T: DctSample + Dct4MixedRadix29Sample> Dct4Butterfly29<T> {
#[inline(always)]
pub(crate) fn exec<S: BidirectionalStore<T>>(&self, data: &mut S) {
let a_buffer = [data[14] * T::FRAC_1_SQRT_2];
let c_buffer = [
(data[0] + data[28]) * T::FRAC_1_SQRT_2,
(data[1] + data[27]) * T::FRAC_1_SQRT_2,
(data[2] + data[26]) * T::FRAC_1_SQRT_2,
(data[3] + data[25]) * T::FRAC_1_SQRT_2,
(data[4] + data[24]) * T::FRAC_1_SQRT_2,
(data[5] + data[23]) * T::FRAC_1_SQRT_2,
(data[6] + data[22]) * T::FRAC_1_SQRT_2,
(data[7] + data[21]) * T::FRAC_1_SQRT_2,
(data[8] + data[20]) * T::FRAC_1_SQRT_2,
(data[9] + data[19]) * T::FRAC_1_SQRT_2,
(data[10] + data[18]) * T::FRAC_1_SQRT_2,
(data[11] + data[17]) * T::FRAC_1_SQRT_2,
(data[12] + data[16]) * T::FRAC_1_SQRT_2,
(data[13] + data[15]) * T::FRAC_1_SQRT_2,
];
let s_buffer = [
(data[0] - data[28]) * T::FRAC_1_SQRT_2,
(data[1] - data[27]) * T::FRAC_1_SQRT_2,
(data[2] - data[26]) * T::FRAC_1_SQRT_2,
(data[3] - data[25]) * T::FRAC_1_SQRT_2,
(data[4] - data[24]) * T::FRAC_1_SQRT_2,
(data[5] - data[23]) * T::FRAC_1_SQRT_2,
(data[6] - data[22]) * T::FRAC_1_SQRT_2,
(data[7] - data[21]) * T::FRAC_1_SQRT_2,
(data[8] - data[20]) * T::FRAC_1_SQRT_2,
(data[9] - data[19]) * T::FRAC_1_SQRT_2,
(data[10] - data[18]) * T::FRAC_1_SQRT_2,
(data[11] - data[17]) * T::FRAC_1_SQRT_2,
(data[12] - data[16]) * T::FRAC_1_SQRT_2,
(data[13] - data[15]) * T::FRAC_1_SQRT_2,
];
let c0 = c_buffer[0];
let s0 = s_buffer[0];
let s0_tw0 = s0 * T::D4_R29_ROT_TWIDDLE_1;
let s0_tw1 = -s0 * T::D4_R29_ROT_TWIDDLE_0;
let iq0 = fmla(c0, T::D4_R29_ROT_TWIDDLE_0, s0_tw0);
let siq0 = fmla(c0, T::D4_R29_ROT_TWIDDLE_1, s0_tw1);
let mut u0 = iq0;
let mut u1 = u0;
let mut v0 = siq0;
u1 *= T::D4_R29_ROT_TWIDDLE_2;
v0 *= T::D4_R29_ROT_TWIDDLE_3;
let c1 = c_buffer[1];
let s1 = s_buffer[1];
let iq1 = fmla(c1, T::D4_R29_ROT_TWIDDLE_4, s1 * T::D4_R29_ROT_TWIDDLE_5);
let siq1 = fmla(c1, T::D4_R29_ROT_TWIDDLE_5, -s1 * T::D4_R29_ROT_TWIDDLE_4);
u0 += iq1;
u1 = fmla(iq1, T::D4_R29_ROT_TWIDDLE_6, u1);
v0 = fmla(siq1, T::D4_R29_ROT_TWIDDLE_7, v0);
let c2 = c_buffer[2];
let s2 = s_buffer[2];
let iq2 = fmla(c2, T::D4_R29_ROT_TWIDDLE_8, s2 * T::D4_R29_ROT_TWIDDLE_9);
let siq2 = fmla(c2, T::D4_R29_ROT_TWIDDLE_9, -s2 * T::D4_R29_ROT_TWIDDLE_8);
u0 += iq2;
u1 = fmla(iq2, T::D4_R29_ROT_TWIDDLE_10, u1);
v0 = fmla(siq2, T::D4_R29_ROT_TWIDDLE_11, v0);
let c3 = c_buffer[3];
let s3 = s_buffer[3];
let iq3 = fmla(c3, T::D4_R29_ROT_TWIDDLE_12, s3 * T::D4_R29_ROT_TWIDDLE_13);
let siq3 = fmla(c3, T::D4_R29_ROT_TWIDDLE_13, -s3 * T::D4_R29_ROT_TWIDDLE_12);
u0 += iq3;
u1 = fmla(iq3, T::D4_R29_ROT_TWIDDLE_0, u1);
v0 = fmla(siq3, T::D4_R29_ROT_TWIDDLE_1, v0);
let c4 = c_buffer[4];
let s4 = s_buffer[4];
let iq4 = fmla(c4, T::D4_R29_ROT_TWIDDLE_10, s4 * T::D4_R29_ROT_TWIDDLE_11);
let siq4 = fmla(c4, T::D4_R29_ROT_TWIDDLE_11, -s4 * T::D4_R29_ROT_TWIDDLE_10);
u0 += iq4;
u1 = fmla(iq4, T::D4_R29_ROT_TWIDDLE_13, u1);
v0 = fmla(siq4, T::D4_R29_ROT_TWIDDLE_12, v0);
let c5 = c_buffer[5];
let s5 = s_buffer[5];
let iq5 = fmla(c5, T::D4_R29_ROT_TWIDDLE_14, s5 * T::D4_R29_ROT_TWIDDLE_15);
let siq5 = fmla(c5, T::D4_R29_ROT_TWIDDLE_15, -s5 * T::D4_R29_ROT_TWIDDLE_14);
u0 += iq5;
u1 = fmla(iq5, T::D4_R29_ROT_TWIDDLE_16, u1);
v0 = fmla(siq5, T::D4_R29_ROT_TWIDDLE_17, v0);
let c6 = c_buffer[6];
let s6 = s_buffer[6];
let iq6 = fmla(c6, T::D4_R29_ROT_TWIDDLE_18, s6 * T::D4_R29_ROT_TWIDDLE_19);
let siq6 = fmla(c6, T::D4_R29_ROT_TWIDDLE_19, -s6 * T::D4_R29_ROT_TWIDDLE_18);
u0 += iq6;
u1 = fmla(iq6, T::D4_R29_ROT_TWIDDLE_20, u1);
v0 = fmla(siq6, T::D4_R29_ROT_TWIDDLE_21, v0);
let c7 = c_buffer[7];
let s7 = s_buffer[7];
let iq7 = fmla(c7, T::D4_R29_ROT_TWIDDLE_17, s7 * T::D4_R29_ROT_TWIDDLE_16);
let siq7 = fmla(c7, T::D4_R29_ROT_TWIDDLE_16, -s7 * T::D4_R29_ROT_TWIDDLE_17);
u0 += iq7;
u1 = fmla(iq7, T::D4_R29_ROT_TWIDDLE_22, u1);
v0 = fmla(siq7, T::D4_R29_ROT_TWIDDLE_23, v0);
let c8 = c_buffer[8];
let s8 = s_buffer[8];
let iq8 = fmla(c8, T::D4_R29_ROT_TWIDDLE_6, s8 * T::D4_R29_ROT_TWIDDLE_7);
let siq8 = fmla(c8, T::D4_R29_ROT_TWIDDLE_7, -s8 * T::D4_R29_ROT_TWIDDLE_6);
u0 += iq8;
u1 = fmla(iq8, T::D4_R29_ROT_TWIDDLE_24, u1);
v0 = fmla(siq8, T::D4_R29_ROT_TWIDDLE_25, v0);
let c9 = c_buffer[9];
let s9 = s_buffer[9];
let iq9 = fmla(c9, T::D4_R29_ROT_TWIDDLE_25, s9 * -T::D4_R29_ROT_TWIDDLE_24);
let siq9 = fmla(
c9,
-T::D4_R29_ROT_TWIDDLE_24,
-s9 * T::D4_R29_ROT_TWIDDLE_25,
);
u0 += iq9;
u1 = fmla(iq9, -T::D4_R29_ROT_TWIDDLE_15, u1);
v0 = fmla(siq9, T::D4_R29_ROT_TWIDDLE_14, v0);
let c10 = c_buffer[10];
let s10 = s_buffer[10];
let iq10 = fmla(
c10,
T::D4_R29_ROT_TWIDDLE_26,
s10 * T::D4_R29_ROT_TWIDDLE_27,
);
let siq10 = fmla(
c10,
T::D4_R29_ROT_TWIDDLE_27,
-s10 * T::D4_R29_ROT_TWIDDLE_26,
);
u0 += iq10;
u1 = fmla(iq10, -T::D4_R29_ROT_TWIDDLE_5, u1);
v0 = fmla(siq10, T::D4_R29_ROT_TWIDDLE_4, v0);
let c11 = c_buffer[11];
let s11 = s_buffer[11];
let iq11 = fmla(
c11,
T::D4_R29_ROT_TWIDDLE_21,
s11 * T::D4_R29_ROT_TWIDDLE_20,
);
let siq11 = fmla(
c11,
T::D4_R29_ROT_TWIDDLE_20,
-s11 * T::D4_R29_ROT_TWIDDLE_21,
);
u0 += iq11;
u1 = fmla(iq11, -T::D4_R29_ROT_TWIDDLE_8, u1);
v0 = fmla(siq11, T::D4_R29_ROT_TWIDDLE_9, v0);
let c12 = c_buffer[12];
let s12 = s_buffer[12];
let iq12 = fmla(c12, T::D4_R29_ROT_TWIDDLE_2, s12 * T::D4_R29_ROT_TWIDDLE_3);
let siq12 = fmla(c12, T::D4_R29_ROT_TWIDDLE_3, -s12 * T::D4_R29_ROT_TWIDDLE_2);
u0 += iq12;
u1 = fmla(iq12, -T::D4_R29_ROT_TWIDDLE_18, u1);
v0 = fmla(siq12, T::D4_R29_ROT_TWIDDLE_19, v0);
let c13 = c_buffer[13];
let s13 = s_buffer[13];
let iq13 = fmla(
c13,
T::D4_R29_ROT_TWIDDLE_23,
s13 * -T::D4_R29_ROT_TWIDDLE_22,
);
let siq13 = fmla(
c13,
-T::D4_R29_ROT_TWIDDLE_22,
-s13 * T::D4_R29_ROT_TWIDDLE_23,
);
u0 += iq13;
u1 = fmla(iq13, -T::D4_R29_ROT_TWIDDLE_26, u1);
v0 = fmla(siq13, T::D4_R29_ROT_TWIDDLE_27, v0);
let a0 = a_buffer[0];
u0 += a0;
u1 = u1 - a0;
data[0] = u0;
data[1] = u1 - v0;
data[2] = u1 + v0;
let mut u2 = iq0;
let mut v2 = siq0;
u2 *= T::D4_R29_ROT_TWIDDLE_26;
v2 *= T::D4_R29_ROT_TWIDDLE_27;
u2 = fmla(iq1, T::D4_R29_ROT_TWIDDLE_8, u2);
v2 = fmla(siq1, T::D4_R29_ROT_TWIDDLE_9, v2);
u2 = fmla(iq2, T::D4_R29_ROT_TWIDDLE_15, u2);
v2 = fmla(siq2, T::D4_R29_ROT_TWIDDLE_14, v2);
u2 = fmla(iq3, -T::D4_R29_ROT_TWIDDLE_22, u2);
v2 = fmla(siq3, T::D4_R29_ROT_TWIDDLE_23, v2);
u2 = fmla(iq4, -T::D4_R29_ROT_TWIDDLE_16, u2);
v2 = fmla(siq4, T::D4_R29_ROT_TWIDDLE_17, v2);
u2 = fmla(iq5, -T::D4_R29_ROT_TWIDDLE_0, u2);
v2 = fmla(siq5, T::D4_R29_ROT_TWIDDLE_1, v2);
u2 = fmla(iq6, -T::D4_R29_ROT_TWIDDLE_6, u2);
v2 = fmla(siq6, T::D4_R29_ROT_TWIDDLE_7, v2);
u2 = fmla(iq7, -T::D4_R29_ROT_TWIDDLE_2, u2);
v2 = fmla(siq7, -T::D4_R29_ROT_TWIDDLE_3, v2);
u2 = fmla(iq8, -T::D4_R29_ROT_TWIDDLE_10, u2);
v2 = fmla(siq8, -T::D4_R29_ROT_TWIDDLE_11, v2);
u2 = fmla(iq9, -T::D4_R29_ROT_TWIDDLE_13, u2);
v2 = fmla(siq9, -T::D4_R29_ROT_TWIDDLE_12, v2);
u2 = fmla(iq10, -T::D4_R29_ROT_TWIDDLE_20, u2);
v2 = fmla(siq10, -T::D4_R29_ROT_TWIDDLE_21, v2);
u2 = fmla(iq11, -T::D4_R29_ROT_TWIDDLE_24, u2);
v2 = fmla(siq11, -T::D4_R29_ROT_TWIDDLE_25, v2);
u2 = fmla(iq12, T::D4_R29_ROT_TWIDDLE_5, u2);
v2 = fmla(siq12, -T::D4_R29_ROT_TWIDDLE_4, v2);
u2 = fmla(iq13, T::D4_R29_ROT_TWIDDLE_18, u2);
v2 = fmla(siq13, -T::D4_R29_ROT_TWIDDLE_19, v2);
u2 += a0;
data[3] = u2 - v2;
data[4] = u2 + v2;
let mut u3 = iq0;
let mut v3 = siq0;
u3 *= T::D4_R29_ROT_TWIDDLE_6;
v3 *= T::D4_R29_ROT_TWIDDLE_7;
u3 = fmla(iq1, T::D4_R29_ROT_TWIDDLE_13, u3);
v3 = fmla(siq1, T::D4_R29_ROT_TWIDDLE_12, v3);
u3 = fmla(iq2, T::D4_R29_ROT_TWIDDLE_22, u3);
v3 = fmla(siq2, T::D4_R29_ROT_TWIDDLE_23, v3);
u3 = fmla(iq3, -T::D4_R29_ROT_TWIDDLE_5, u3);
v3 = fmla(siq3, T::D4_R29_ROT_TWIDDLE_4, v3);
u3 = fmla(iq4, -T::D4_R29_ROT_TWIDDLE_26, u3);
v3 = fmla(siq4, T::D4_R29_ROT_TWIDDLE_27, v3);
u3 = fmla(iq5, -T::D4_R29_ROT_TWIDDLE_18, u3);
v3 = fmla(siq5, -T::D4_R29_ROT_TWIDDLE_19, v3);
u3 = fmla(iq6, -T::D4_R29_ROT_TWIDDLE_15, u3);
v3 = fmla(siq6, -T::D4_R29_ROT_TWIDDLE_14, v3);
u3 = fmla(iq7, T::D4_R29_ROT_TWIDDLE_20, u3);
v3 = fmla(siq7, -T::D4_R29_ROT_TWIDDLE_21, v3);
u3 = fmla(iq8, T::D4_R29_ROT_TWIDDLE_0, u3);
v3 = fmla(siq8, -T::D4_R29_ROT_TWIDDLE_1, v3);
u3 = fmla(iq9, T::D4_R29_ROT_TWIDDLE_2, u3);
v3 = fmla(siq9, -T::D4_R29_ROT_TWIDDLE_3, v3);
u3 = fmla(iq10, T::D4_R29_ROT_TWIDDLE_10, u3);
v3 = fmla(siq10, T::D4_R29_ROT_TWIDDLE_11, v3);
u3 = fmla(iq11, T::D4_R29_ROT_TWIDDLE_16, u3);
v3 = fmla(siq11, T::D4_R29_ROT_TWIDDLE_17, v3);
u3 = fmla(iq12, T::D4_R29_ROT_TWIDDLE_24, u3);
v3 = fmla(siq12, T::D4_R29_ROT_TWIDDLE_25, v3);
u3 = fmla(iq13, -T::D4_R29_ROT_TWIDDLE_8, u3);
v3 = fmla(siq13, T::D4_R29_ROT_TWIDDLE_9, v3);
u3 = u3 - a0;
data[5] = u3 - v3;
data[6] = u3 + v3;
let mut u4 = iq0;
let mut v4 = siq0;
u4 *= T::D4_R29_ROT_TWIDDLE_18;
v4 *= T::D4_R29_ROT_TWIDDLE_19;
u4 = fmla(iq1, -T::D4_R29_ROT_TWIDDLE_24, u4);
v4 = fmla(siq1, T::D4_R29_ROT_TWIDDLE_25, v4);
u4 = fmla(iq2, -T::D4_R29_ROT_TWIDDLE_13, u4);
v4 = fmla(siq2, T::D4_R29_ROT_TWIDDLE_12, v4);
u4 = fmla(iq3, -T::D4_R29_ROT_TWIDDLE_2, u4);
v4 = fmla(siq3, T::D4_R29_ROT_TWIDDLE_3, v4);
u4 = fmla(iq4, -T::D4_R29_ROT_TWIDDLE_0, u4);
v4 = fmla(siq4, -T::D4_R29_ROT_TWIDDLE_1, v4);
u4 = fmla(iq5, -T::D4_R29_ROT_TWIDDLE_22, u4);
v4 = fmla(siq5, -T::D4_R29_ROT_TWIDDLE_23, v4);
u4 = fmla(iq6, T::D4_R29_ROT_TWIDDLE_8, u4);
v4 = fmla(siq6, -T::D4_R29_ROT_TWIDDLE_9, v4);
u4 = fmla(iq7, T::D4_R29_ROT_TWIDDLE_26, u4);
v4 = fmla(siq7, T::D4_R29_ROT_TWIDDLE_27, v4);
u4 = fmla(iq8, T::D4_R29_ROT_TWIDDLE_15, u4);
v4 = fmla(siq8, T::D4_R29_ROT_TWIDDLE_14, v4);
u4 = fmla(iq9, -T::D4_R29_ROT_TWIDDLE_16, u4);
v4 = fmla(siq9, T::D4_R29_ROT_TWIDDLE_17, v4);
u4 = fmla(iq10, -T::D4_R29_ROT_TWIDDLE_6, u4);
v4 = fmla(siq10, T::D4_R29_ROT_TWIDDLE_7, v4);
u4 = fmla(iq11, -T::D4_R29_ROT_TWIDDLE_10, u4);
v4 = fmla(siq11, -T::D4_R29_ROT_TWIDDLE_11, v4);
u4 = fmla(iq12, -T::D4_R29_ROT_TWIDDLE_20, u4);
v4 = fmla(siq12, -T::D4_R29_ROT_TWIDDLE_21, v4);
u4 = fmla(iq13, T::D4_R29_ROT_TWIDDLE_5, u4);
v4 = fmla(siq13, -T::D4_R29_ROT_TWIDDLE_4, v4);
u4 += a0;
data[7] = u4 - v4;
data[8] = u4 + v4;
let mut u5 = iq0;
let mut v5 = siq0;
u5 *= T::D4_R29_ROT_TWIDDLE_10;
v5 *= T::D4_R29_ROT_TWIDDLE_11;
u5 = fmla(iq1, T::D4_R29_ROT_TWIDDLE_22, u5);
v5 = fmla(siq1, T::D4_R29_ROT_TWIDDLE_23, v5);
u5 = fmla(iq2, -T::D4_R29_ROT_TWIDDLE_18, u5);
v5 = fmla(siq2, T::D4_R29_ROT_TWIDDLE_19, v5);
u5 = fmla(iq3, -T::D4_R29_ROT_TWIDDLE_8, u5);
v5 = fmla(siq3, -T::D4_R29_ROT_TWIDDLE_9, v5);
u5 = fmla(iq4, T::D4_R29_ROT_TWIDDLE_20, u5);
v5 = fmla(siq4, -T::D4_R29_ROT_TWIDDLE_21, v5);
u5 = fmla(iq5, T::D4_R29_ROT_TWIDDLE_6, u5);
v5 = fmla(siq5, -T::D4_R29_ROT_TWIDDLE_7, v5);
u5 = fmla(iq6, T::D4_R29_ROT_TWIDDLE_0, u5);
v5 = fmla(siq6, T::D4_R29_ROT_TWIDDLE_1, v5);
u5 = fmla(iq7, T::D4_R29_ROT_TWIDDLE_24, u5);
v5 = fmla(siq7, T::D4_R29_ROT_TWIDDLE_25, v5);
u5 = fmla(iq8, -T::D4_R29_ROT_TWIDDLE_26, u5);
v5 = fmla(siq8, T::D4_R29_ROT_TWIDDLE_27, v5);
u5 = fmla(iq9, -T::D4_R29_ROT_TWIDDLE_5, u5);
v5 = fmla(siq9, -T::D4_R29_ROT_TWIDDLE_4, v5);
u5 = fmla(iq10, T::D4_R29_ROT_TWIDDLE_16, u5);
v5 = fmla(siq10, -T::D4_R29_ROT_TWIDDLE_17, v5);
u5 = fmla(iq11, T::D4_R29_ROT_TWIDDLE_2, u5);
v5 = fmla(siq11, -T::D4_R29_ROT_TWIDDLE_3, v5);
u5 = fmla(iq12, T::D4_R29_ROT_TWIDDLE_13, u5);
v5 = fmla(siq12, T::D4_R29_ROT_TWIDDLE_12, v5);
u5 = fmla(iq13, -T::D4_R29_ROT_TWIDDLE_15, u5);
v5 = fmla(siq13, T::D4_R29_ROT_TWIDDLE_14, v5);
u5 = u5 - a0;
data[9] = u5 - v5;
data[10] = u5 + v5;
let mut u6 = iq0;
let mut v6 = siq0;
u6 *= T::D4_R29_ROT_TWIDDLE_8;
v6 *= T::D4_R29_ROT_TWIDDLE_9;
u6 = fmla(iq1, -T::D4_R29_ROT_TWIDDLE_16, u6);
v6 = fmla(siq1, T::D4_R29_ROT_TWIDDLE_17, v6);
u6 = fmla(iq2, -T::D4_R29_ROT_TWIDDLE_2, u6);
v6 = fmla(siq2, -T::D4_R29_ROT_TWIDDLE_3, v6);
u6 = fmla(iq3, -T::D4_R29_ROT_TWIDDLE_20, u6);
v6 = fmla(siq3, -T::D4_R29_ROT_TWIDDLE_21, v6);
u6 = fmla(iq4, T::D4_R29_ROT_TWIDDLE_18, u6);
v6 = fmla(siq4, -T::D4_R29_ROT_TWIDDLE_19, v6);
u6 = fmla(iq5, T::D4_R29_ROT_TWIDDLE_5, u6);
v6 = fmla(siq5, T::D4_R29_ROT_TWIDDLE_4, v6);
u6 = fmla(iq6, -T::D4_R29_ROT_TWIDDLE_13, u6);
v6 = fmla(siq6, T::D4_R29_ROT_TWIDDLE_12, v6);
u6 = fmla(iq7, -T::D4_R29_ROT_TWIDDLE_6, u6);
v6 = fmla(siq7, -T::D4_R29_ROT_TWIDDLE_7, v6);
u6 = fmla(iq8, -T::D4_R29_ROT_TWIDDLE_22, u6);
v6 = fmla(siq8, -T::D4_R29_ROT_TWIDDLE_23, v6);
u6 = fmla(iq9, T::D4_R29_ROT_TWIDDLE_26, u6);
v6 = fmla(siq9, -T::D4_R29_ROT_TWIDDLE_27, v6);
u6 = fmla(iq10, T::D4_R29_ROT_TWIDDLE_15, u6);
v6 = fmla(siq10, T::D4_R29_ROT_TWIDDLE_14, v6);
u6 = fmla(iq11, -T::D4_R29_ROT_TWIDDLE_0, u6);
v6 = fmla(siq11, T::D4_R29_ROT_TWIDDLE_1, v6);
u6 = fmla(iq12, -T::D4_R29_ROT_TWIDDLE_10, u6);
v6 = fmla(siq12, -T::D4_R29_ROT_TWIDDLE_11, v6);
u6 = fmla(iq13, -T::D4_R29_ROT_TWIDDLE_24, u6);
v6 = fmla(siq13, -T::D4_R29_ROT_TWIDDLE_25, v6);
u6 += a0;
data[11] = u6 - v6;
data[12] = u6 + v6;
let mut u7 = iq0;
let mut v7 = siq0;
u7 *= T::D4_R29_ROT_TWIDDLE_0;
v7 *= T::D4_R29_ROT_TWIDDLE_1;
u7 = fmla(iq1, -T::D4_R29_ROT_TWIDDLE_5, u7);
v7 = fmla(siq1, T::D4_R29_ROT_TWIDDLE_4, v7);
u7 = fmla(iq2, -T::D4_R29_ROT_TWIDDLE_8, u7);
v7 = fmla(siq2, -T::D4_R29_ROT_TWIDDLE_9, v7);
u7 = fmla(iq3, T::D4_R29_ROT_TWIDDLE_13, u7);
v7 = fmla(siq3, -T::D4_R29_ROT_TWIDDLE_12, v7);
u7 = fmla(iq4, T::D4_R29_ROT_TWIDDLE_10, u7);
v7 = fmla(siq4, T::D4_R29_ROT_TWIDDLE_11, v7);
u7 = fmla(iq5, -T::D4_R29_ROT_TWIDDLE_15, u7);
v7 = fmla(siq5, T::D4_R29_ROT_TWIDDLE_14, v7);
u7 = fmla(iq6, -T::D4_R29_ROT_TWIDDLE_18, u7);
v7 = fmla(siq6, -T::D4_R29_ROT_TWIDDLE_19, v7);
u7 = fmla(iq7, T::D4_R29_ROT_TWIDDLE_16, u7);
v7 = fmla(siq7, -T::D4_R29_ROT_TWIDDLE_17, v7);
u7 = fmla(iq8, T::D4_R29_ROT_TWIDDLE_6, u7);
v7 = fmla(siq8, T::D4_R29_ROT_TWIDDLE_7, v7);
u7 = fmla(iq9, T::D4_R29_ROT_TWIDDLE_24, u7);
v7 = fmla(siq9, T::D4_R29_ROT_TWIDDLE_25, v7);
u7 = fmla(iq10, -T::D4_R29_ROT_TWIDDLE_26, u7);
v7 = fmla(siq10, -T::D4_R29_ROT_TWIDDLE_27, v7);
u7 = fmla(iq11, T::D4_R29_ROT_TWIDDLE_20, u7);
v7 = fmla(siq11, -T::D4_R29_ROT_TWIDDLE_21, v7);
u7 = fmla(iq12, T::D4_R29_ROT_TWIDDLE_2, u7);
v7 = fmla(siq12, T::D4_R29_ROT_TWIDDLE_3, v7);
u7 = fmla(iq13, T::D4_R29_ROT_TWIDDLE_22, u7);
v7 = fmla(siq13, T::D4_R29_ROT_TWIDDLE_23, v7);
u7 = u7 - a0;
data[13] = u7 - v7;
data[14] = u7 + v7;
let mut u8 = iq0;
let mut v8 = siq0;
u8 *= T::D4_R29_ROT_TWIDDLE_5;
v8 *= T::D4_R29_ROT_TWIDDLE_4;
u8 = fmla(iq1, -T::D4_R29_ROT_TWIDDLE_10, u8);
v8 = fmla(siq1, T::D4_R29_ROT_TWIDDLE_11, v8);
u8 = fmla(iq2, -T::D4_R29_ROT_TWIDDLE_16, u8);
v8 = fmla(siq2, -T::D4_R29_ROT_TWIDDLE_17, v8);
u8 = fmla(iq3, T::D4_R29_ROT_TWIDDLE_26, u8);
v8 = fmla(siq3, -T::D4_R29_ROT_TWIDDLE_27, v8);
u8 = fmla(iq4, -T::D4_R29_ROT_TWIDDLE_22, u8);
v8 = fmla(siq4, T::D4_R29_ROT_TWIDDLE_23, v8);
u8 = fmla(iq5, -T::D4_R29_ROT_TWIDDLE_2, u8);
v8 = fmla(siq5, -T::D4_R29_ROT_TWIDDLE_3, v8);
u8 = fmla(iq6, -T::D4_R29_ROT_TWIDDLE_24, u8);
v8 = fmla(siq6, -T::D4_R29_ROT_TWIDDLE_25, v8);
u8 = fmla(iq7, T::D4_R29_ROT_TWIDDLE_18, u8);
v8 = fmla(siq7, T::D4_R29_ROT_TWIDDLE_19, v8);
u8 = fmla(iq8, -T::D4_R29_ROT_TWIDDLE_13, u8);
v8 = fmla(siq8, T::D4_R29_ROT_TWIDDLE_12, v8);
u8 = fmla(iq9, -T::D4_R29_ROT_TWIDDLE_0, u8);
v8 = fmla(siq9, -T::D4_R29_ROT_TWIDDLE_1, v8);
u8 = fmla(iq10, T::D4_R29_ROT_TWIDDLE_8, u8);
v8 = fmla(siq10, -T::D4_R29_ROT_TWIDDLE_9, v8);
u8 = fmla(iq11, T::D4_R29_ROT_TWIDDLE_15, u8);
v8 = fmla(siq11, T::D4_R29_ROT_TWIDDLE_14, v8);
u8 = fmla(iq12, -T::D4_R29_ROT_TWIDDLE_6, u8);
v8 = fmla(siq12, T::D4_R29_ROT_TWIDDLE_7, v8);
u8 = fmla(iq13, -T::D4_R29_ROT_TWIDDLE_20, u8);
v8 = fmla(siq13, -T::D4_R29_ROT_TWIDDLE_21, v8);
u8 += a0;
data[15] = u8 - v8;
data[16] = u8 + v8;
let mut u9 = iq0;
let mut v9 = siq0;
u9 *= T::D4_R29_ROT_TWIDDLE_13;
v9 *= T::D4_R29_ROT_TWIDDLE_12;
u9 = fmla(iq1, -T::D4_R29_ROT_TWIDDLE_26, u9);
v9 = fmla(siq1, T::D4_R29_ROT_TWIDDLE_27, v9);
u9 = fmla(iq2, T::D4_R29_ROT_TWIDDLE_20, u9);
v9 = fmla(siq2, -T::D4_R29_ROT_TWIDDLE_21, v9);
u9 = fmla(iq3, T::D4_R29_ROT_TWIDDLE_10, u9);
v9 = fmla(siq3, T::D4_R29_ROT_TWIDDLE_11, v9);
u9 = fmla(iq4, -T::D4_R29_ROT_TWIDDLE_8, u9);
v9 = fmla(siq4, T::D4_R29_ROT_TWIDDLE_9, v9);
u9 = fmla(iq5, T::D4_R29_ROT_TWIDDLE_24, u9);
v9 = fmla(siq5, -T::D4_R29_ROT_TWIDDLE_25, v9);
u9 = fmla(iq6, T::D4_R29_ROT_TWIDDLE_2, u9);
v9 = fmla(siq6, T::D4_R29_ROT_TWIDDLE_3, v9);
u9 = fmla(iq7, -T::D4_R29_ROT_TWIDDLE_15, u9);
v9 = fmla(siq7, T::D4_R29_ROT_TWIDDLE_14, v9);
u9 = fmla(iq8, -T::D4_R29_ROT_TWIDDLE_5, u9);
v9 = fmla(siq8, -T::D4_R29_ROT_TWIDDLE_4, v9);
u9 = fmla(iq9, T::D4_R29_ROT_TWIDDLE_6, u9);
v9 = fmla(siq9, -T::D4_R29_ROT_TWIDDLE_7, v9);
u9 = fmla(iq10, T::D4_R29_ROT_TWIDDLE_22, u9);
v9 = fmla(siq10, T::D4_R29_ROT_TWIDDLE_23, v9);
u9 = fmla(iq11, -T::D4_R29_ROT_TWIDDLE_18, u9);
v9 = fmla(siq11, -T::D4_R29_ROT_TWIDDLE_19, v9);
u9 = fmla(iq12, T::D4_R29_ROT_TWIDDLE_0, u9);
v9 = fmla(siq12, -T::D4_R29_ROT_TWIDDLE_1, v9);
u9 = fmla(iq13, T::D4_R29_ROT_TWIDDLE_16, u9);
v9 = fmla(siq13, T::D4_R29_ROT_TWIDDLE_17, v9);
u9 = u9 - a0;
data[17] = u9 - v9;
data[18] = u9 + v9;
let mut u10 = iq0;
let mut v10 = siq0;
u10 *= T::D4_R29_ROT_TWIDDLE_15;
v10 *= T::D4_R29_ROT_TWIDDLE_14;
u10 = fmla(iq1, -T::D4_R29_ROT_TWIDDLE_2, u10);
v10 = fmla(siq1, -T::D4_R29_ROT_TWIDDLE_3, v10);
u10 = fmla(iq2, T::D4_R29_ROT_TWIDDLE_5, u10);
v10 = fmla(siq2, -T::D4_R29_ROT_TWIDDLE_4, v10);
u10 = fmla(iq3, -T::D4_R29_ROT_TWIDDLE_24, u10);
v10 = fmla(siq3, T::D4_R29_ROT_TWIDDLE_25, v10);
u10 = fmla(iq4, -T::D4_R29_ROT_TWIDDLE_6, u10);
v10 = fmla(siq4, -T::D4_R29_ROT_TWIDDLE_7, v10);
u10 = fmla(iq5, T::D4_R29_ROT_TWIDDLE_8, u10);
v10 = fmla(siq5, -T::D4_R29_ROT_TWIDDLE_9, v10);
u10 = fmla(iq6, -T::D4_R29_ROT_TWIDDLE_22, u10);
v10 = fmla(siq6, T::D4_R29_ROT_TWIDDLE_23, v10);
u10 = fmla(iq7, -T::D4_R29_ROT_TWIDDLE_10, u10);
v10 = fmla(siq7, -T::D4_R29_ROT_TWIDDLE_11, v10);
u10 = fmla(iq8, T::D4_R29_ROT_TWIDDLE_18, u10);
v10 = fmla(siq8, -T::D4_R29_ROT_TWIDDLE_19, v10);
u10 = fmla(iq9, -T::D4_R29_ROT_TWIDDLE_20, u10);
v10 = fmla(siq9, T::D4_R29_ROT_TWIDDLE_21, v10);
u10 = fmla(iq10, -T::D4_R29_ROT_TWIDDLE_0, u10);
v10 = fmla(siq10, -T::D4_R29_ROT_TWIDDLE_1, v10);
u10 = fmla(iq11, T::D4_R29_ROT_TWIDDLE_26, u10);
v10 = fmla(siq11, -T::D4_R29_ROT_TWIDDLE_27, v10);
u10 = fmla(iq12, -T::D4_R29_ROT_TWIDDLE_16, u10);
v10 = fmla(siq12, T::D4_R29_ROT_TWIDDLE_17, v10);
u10 = fmla(iq13, -T::D4_R29_ROT_TWIDDLE_13, u10);
v10 = fmla(siq13, -T::D4_R29_ROT_TWIDDLE_12, v10);
u10 += a0;
data[19] = u10 - v10;
data[20] = u10 + v10;
let mut u11 = iq0;
let mut v11 = siq0;
u11 *= T::D4_R29_ROT_TWIDDLE_16;
v11 *= T::D4_R29_ROT_TWIDDLE_17;
u11 = fmla(iq1, -T::D4_R29_ROT_TWIDDLE_18, u11);
v11 = fmla(siq1, -T::D4_R29_ROT_TWIDDLE_19, v11);
u11 = fmla(iq2, T::D4_R29_ROT_TWIDDLE_6, u11);
v11 = fmla(siq2, -T::D4_R29_ROT_TWIDDLE_7, v11);
u11 = fmla(iq3, -T::D4_R29_ROT_TWIDDLE_15, u11);
v11 = fmla(siq3, T::D4_R29_ROT_TWIDDLE_14, v11);
u11 = fmla(iq4, T::D4_R29_ROT_TWIDDLE_24, u11);
v11 = fmla(siq4, -T::D4_R29_ROT_TWIDDLE_25, v11);
u11 = fmla(iq5, T::D4_R29_ROT_TWIDDLE_10, u11);
v11 = fmla(siq5, T::D4_R29_ROT_TWIDDLE_11, v11);
u11 = fmla(iq6, -T::D4_R29_ROT_TWIDDLE_26, u11);
v11 = fmla(siq6, T::D4_R29_ROT_TWIDDLE_27, v11);
u11 = fmla(iq7, T::D4_R29_ROT_TWIDDLE_13, u11);
v11 = fmla(siq7, -T::D4_R29_ROT_TWIDDLE_12, v11);
u11 = fmla(iq8, T::D4_R29_ROT_TWIDDLE_20, u11);
v11 = fmla(siq8, T::D4_R29_ROT_TWIDDLE_21, v11);
u11 = fmla(iq9, -T::D4_R29_ROT_TWIDDLE_8, u11);
v11 = fmla(siq9, -T::D4_R29_ROT_TWIDDLE_9, v11);
u11 = fmla(iq10, T::D4_R29_ROT_TWIDDLE_2, u11);
v11 = fmla(siq10, -T::D4_R29_ROT_TWIDDLE_3, v11);
u11 = fmla(iq11, -T::D4_R29_ROT_TWIDDLE_5, u11);
v11 = fmla(siq11, T::D4_R29_ROT_TWIDDLE_4, v11);
u11 = fmla(iq12, T::D4_R29_ROT_TWIDDLE_22, u11);
v11 = fmla(siq12, -T::D4_R29_ROT_TWIDDLE_23, v11);
u11 = fmla(iq13, T::D4_R29_ROT_TWIDDLE_0, u11);
v11 = fmla(siq13, T::D4_R29_ROT_TWIDDLE_1, v11);
u11 = u11 - a0;
data[21] = u11 - v11;
data[22] = u11 + v11;
let mut u12 = iq0;
let mut v12 = siq0;
u12 *= -T::D4_R29_ROT_TWIDDLE_24;
v12 *= T::D4_R29_ROT_TWIDDLE_25;
u12 = fmla(iq1, -T::D4_R29_ROT_TWIDDLE_0, u12);
v12 = fmla(siq1, -T::D4_R29_ROT_TWIDDLE_1, v12);
u12 = fmla(iq2, T::D4_R29_ROT_TWIDDLE_26, u12);
v12 = fmla(siq2, T::D4_R29_ROT_TWIDDLE_27, v12);
u12 = fmla(iq3, -T::D4_R29_ROT_TWIDDLE_6, u12);
v12 = fmla(siq3, T::D4_R29_ROT_TWIDDLE_7, v12);
u12 = fmla(iq4, T::D4_R29_ROT_TWIDDLE_5, u12);
v12 = fmla(siq4, -T::D4_R29_ROT_TWIDDLE_4, v12);
u12 = fmla(iq5, -T::D4_R29_ROT_TWIDDLE_20, u12);
v12 = fmla(siq5, T::D4_R29_ROT_TWIDDLE_21, v12);
u12 = fmla(iq6, -T::D4_R29_ROT_TWIDDLE_16, u12);
v12 = fmla(siq6, -T::D4_R29_ROT_TWIDDLE_17, v12);
u12 = fmla(iq7, T::D4_R29_ROT_TWIDDLE_8, u12);
v12 = fmla(siq7, T::D4_R29_ROT_TWIDDLE_9, v12);
u12 = fmla(iq8, -T::D4_R29_ROT_TWIDDLE_2, u12);
v12 = fmla(siq8, -T::D4_R29_ROT_TWIDDLE_3, v12);
u12 = fmla(iq9, T::D4_R29_ROT_TWIDDLE_18, u12);
v12 = fmla(siq9, -T::D4_R29_ROT_TWIDDLE_19, v12);
u12 = fmla(iq10, -T::D4_R29_ROT_TWIDDLE_13, u12);
v12 = fmla(siq10, T::D4_R29_ROT_TWIDDLE_12, v12);
u12 = fmla(iq11, -T::D4_R29_ROT_TWIDDLE_22, u12);
v12 = fmla(siq11, -T::D4_R29_ROT_TWIDDLE_23, v12);
u12 = fmla(iq12, T::D4_R29_ROT_TWIDDLE_15, u12);
v12 = fmla(siq12, T::D4_R29_ROT_TWIDDLE_14, v12);
u12 = fmla(iq13, -T::D4_R29_ROT_TWIDDLE_10, u12);
v12 = fmla(siq13, -T::D4_R29_ROT_TWIDDLE_11, v12);
u12 += a0;
data[23] = u12 - v12;
data[24] = u12 + v12;
let mut u13 = iq0;
let mut v13 = siq0;
u13 *= T::D4_R29_ROT_TWIDDLE_20;
v13 *= T::D4_R29_ROT_TWIDDLE_21;
u13 = fmla(iq1, -T::D4_R29_ROT_TWIDDLE_15, u13);
v13 = fmla(siq1, -T::D4_R29_ROT_TWIDDLE_14, v13);
u13 = fmla(iq2, T::D4_R29_ROT_TWIDDLE_0, u13);
v13 = fmla(siq2, T::D4_R29_ROT_TWIDDLE_1, v13);
u13 = fmla(iq3, -T::D4_R29_ROT_TWIDDLE_18, u13);
v13 = fmla(siq3, -T::D4_R29_ROT_TWIDDLE_19, v13);
u13 = fmla(iq4, T::D4_R29_ROT_TWIDDLE_2, u13);
v13 = fmla(siq4, T::D4_R29_ROT_TWIDDLE_3, v13);
u13 = fmla(iq5, -T::D4_R29_ROT_TWIDDLE_26, u13);
v13 = fmla(siq5, T::D4_R29_ROT_TWIDDLE_27, v13);
u13 = fmla(iq6, T::D4_R29_ROT_TWIDDLE_10, u13);
v13 = fmla(siq6, -T::D4_R29_ROT_TWIDDLE_11, v13);
u13 = fmla(iq7, -T::D4_R29_ROT_TWIDDLE_5, u13);
v13 = fmla(siq7, T::D4_R29_ROT_TWIDDLE_4, v13);
u13 = fmla(iq8, T::D4_R29_ROT_TWIDDLE_16, u13);
v13 = fmla(siq8, -T::D4_R29_ROT_TWIDDLE_17, v13);
u13 = fmla(iq9, T::D4_R29_ROT_TWIDDLE_22, u13);
v13 = fmla(siq9, T::D4_R29_ROT_TWIDDLE_23, v13);
u13 = fmla(iq10, T::D4_R29_ROT_TWIDDLE_24, u13);
v13 = fmla(siq10, -T::D4_R29_ROT_TWIDDLE_25, v13);
u13 = fmla(iq11, T::D4_R29_ROT_TWIDDLE_13, u13);
v13 = fmla(siq11, T::D4_R29_ROT_TWIDDLE_12, v13);
u13 = fmla(iq12, -T::D4_R29_ROT_TWIDDLE_8, u13);
v13 = fmla(siq12, -T::D4_R29_ROT_TWIDDLE_9, v13);
u13 = fmla(iq13, T::D4_R29_ROT_TWIDDLE_6, u13);
v13 = fmla(siq13, T::D4_R29_ROT_TWIDDLE_7, v13);
u13 = u13 - a0;
data[25] = u13 - v13;
data[26] = u13 + v13;
let mut u14 = iq0;
let mut v14 = siq0;
u14 *= -T::D4_R29_ROT_TWIDDLE_22;
v14 *= T::D4_R29_ROT_TWIDDLE_23;
u14 = fmla(iq1, -T::D4_R29_ROT_TWIDDLE_20, u14);
v14 = fmla(siq1, -T::D4_R29_ROT_TWIDDLE_21, v14);
u14 = fmla(iq2, -T::D4_R29_ROT_TWIDDLE_24, u14);
v14 = fmla(siq2, T::D4_R29_ROT_TWIDDLE_25, v14);
u14 = fmla(iq3, -T::D4_R29_ROT_TWIDDLE_16, u14);
v14 = fmla(siq3, -T::D4_R29_ROT_TWIDDLE_17, v14);
u14 = fmla(iq4, T::D4_R29_ROT_TWIDDLE_15, u14);
v14 = fmla(siq4, T::D4_R29_ROT_TWIDDLE_14, v14);
u14 = fmla(iq5, -T::D4_R29_ROT_TWIDDLE_13, u14);
v14 = fmla(siq5, -T::D4_R29_ROT_TWIDDLE_12, v14);
u14 = fmla(iq6, T::D4_R29_ROT_TWIDDLE_5, u14);
v14 = fmla(siq6, T::D4_R29_ROT_TWIDDLE_4, v14);
u14 = fmla(iq7, -T::D4_R29_ROT_TWIDDLE_0, u14);
v14 = fmla(siq7, -T::D4_R29_ROT_TWIDDLE_1, v14);
u14 = fmla(iq8, T::D4_R29_ROT_TWIDDLE_8, u14);
v14 = fmla(siq8, T::D4_R29_ROT_TWIDDLE_9, v14);
u14 = fmla(iq9, -T::D4_R29_ROT_TWIDDLE_10, u14);
v14 = fmla(siq9, -T::D4_R29_ROT_TWIDDLE_11, v14);
u14 = fmla(iq10, T::D4_R29_ROT_TWIDDLE_18, u14);
v14 = fmla(siq10, T::D4_R29_ROT_TWIDDLE_19, v14);
u14 = fmla(iq11, -T::D4_R29_ROT_TWIDDLE_6, u14);
v14 = fmla(siq11, -T::D4_R29_ROT_TWIDDLE_7, v14);
u14 = fmla(iq12, T::D4_R29_ROT_TWIDDLE_26, u14);
v14 = fmla(siq12, T::D4_R29_ROT_TWIDDLE_27, v14);
u14 = fmla(iq13, -T::D4_R29_ROT_TWIDDLE_2, u14);
v14 = fmla(siq13, -T::D4_R29_ROT_TWIDDLE_3, v14);
u14 += a0;
data[27] = u14 - v14;
data[28] = u14 + v14;
}
}
impl<T: DctSample + Dct4MixedRadix29Sample> PxdctExecutor<T> for Dct4Butterfly29<T>
where
f64: AsPrimitive<T>,
{
fn execute(&self, data: &mut [T]) -> Result<(), PxdctError> {
if !data.len().is_multiple_of(29) {
return Err(PxdctError::InvalidSizeMultiplier(data.len(), self.length()));
}
for chunk in data.as_chunks_mut::<29>().0.iter_mut() {
self.exec(&mut InPlaceStore::new(chunk));
}
Ok(())
}
fn execute_with_scratch(&self, data: &mut [T], _: &mut [T]) -> Result<(), PxdctError> {
self.execute(data)
}
fn execute_into(&self, input: &[T], output: &mut [T]) -> Result<(), PxdctError> {
self.execute_into_with_scratch(input, output, &mut [])
}
fn execute_into_with_scratch(
&self,
input: &[T],
output: &mut [T],
_: &mut [T],
) -> Result<(), PxdctError> {
use crate::util::validate_oof_sizes;
validate_oof_sizes!(input, output, 29);
use crate::bidirectional::BiStore;
for (src, dst) in input
.as_chunks::<29>()
.0
.iter()
.zip(output.as_chunks_mut::<29>().0.iter_mut())
{
self.exec(&mut BiStore::new(src, dst));
}
Ok(())
}
fn length(&self) -> usize {
29
}
fn scratch_size(&self) -> usize {
0
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::butterflies::gen_test_butterfly;
gen_test_butterfly!(test_bf_dct4_3, f64, Dct4Butterfly3, 3, 1e-7, naive_dct4);
gen_test_butterfly!(test_bf_dct4_5, f64, Dct4Butterfly5, 5, 1e-7, naive_dct4);
gen_test_butterfly!(test_bf_dct4_7, f64, Dct4Butterfly7, 7, 1e-7, naive_dct4);
gen_test_butterfly!(test_bf_dct4_11, f64, Dct4Butterfly11, 11, 1e-7, naive_dct4);
gen_test_butterfly!(test_bf_dct4_13, f64, Dct4Butterfly13, 13, 1e-7, naive_dct4);
gen_test_butterfly!(test_bf_dct4_17, f64, Dct4Butterfly17, 17, 1e-7, naive_dct4);
gen_test_butterfly!(test_bf_dct4_19, f64, Dct4Butterfly19, 19, 1e-7, naive_dct4);
gen_test_butterfly!(test_bf_dct4_23, f64, Dct4Butterfly23, 23, 1e-7, naive_dct4);
gen_test_butterfly!(test_bf_dct4_29, f64, Dct4Butterfly29, 29, 1e-7, naive_dct4);
}