@ -8,430 +8,278 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward;
/// </content>
internal static partial class Av1ForwardTransformOperations
{
/// <summary>
/// Identifies coefficient positions whose final value resides in the first stage buffer.
/// </summary>
private const ulong Dct64Buffer0OutputMask =
( 1 UL < < 2 ) | ( 1 UL < < 6 ) | ( 1 UL < < 8 ) | ( 1 UL < < 1 0 ) | ( 1 UL < < 1 4 ) |
( 1 UL < < 1 8 ) | ( 1 UL < < 2 2 ) | ( 1 UL < < 2 4 ) | ( 1 UL < < 2 6 ) | ( 1 UL < < 3 0 ) |
( 1 UL < < 3 4 ) | ( 1 UL < < 3 8 ) | ( 1 UL < < 4 0 ) | ( 1 UL < < 4 2 ) | ( 1 UL < < 4 6 ) |
( 1 UL < < 5 0 ) | ( 1 UL < < 5 4 ) | ( 1 UL < < 5 6 ) | ( 1 UL < < 5 8 ) | ( 1 UL < < 6 2 ) ;
/// <summary>
/// Gets the stage-nine rotation order for the middle quarter of the sixty-four-point DCT.
/// </summary>
private static ReadOnlySpan < byte > Dct64Stage9RotationOrder = > [ 2 , 3 4 , 1 8 , 5 0 , 1 0 , 4 2 , 2 6 , 5 8 ] ;
/// <summary>
/// Gets the stage-ten rotation order for the upper half of the sixty-four-point DCT.
/// </summary>
private static ReadOnlySpan < byte > Dct64Stage10RotationOrder = > [ 1 , 3 3 , 1 7 , 4 9 , 9 , 4 1 , 2 5 , 5 7 , 5 , 3 7 , 2 1 , 5 3 , 1 3 , 4 5 , 2 9 , 6 1 ] ;
/// <summary>
/// Gets the mapping from coefficient order to the final staged value.
/// </summary>
private static ReadOnlySpan < byte > Dct64OutputOrder = >
[
0 , 3 2 , 1 6 , 4 8 , 8 , 4 0 , 2 4 , 5 6 , 4 , 3 6 , 2 0 , 5 2 , 1 2 , 4 4 , 2 8 , 6 0 ,
2 , 3 4 , 1 8 , 5 0 , 1 0 , 4 2 , 2 6 , 5 8 , 6 , 3 8 , 2 2 , 5 4 , 1 4 , 4 6 , 3 0 , 6 2 ,
1 , 3 3 , 1 7 , 4 9 , 9 , 4 1 , 2 5 , 5 7 , 5 , 3 7 , 2 1 , 5 3 , 1 3 , 4 5 , 2 9 , 6 1 ,
3 , 3 5 , 1 9 , 5 1 , 1 1 , 4 3 , 2 7 , 5 9 , 7 , 3 9 , 2 3 , 5 5 , 1 5 , 4 7 , 3 1 , 6 3 ,
] ;
/// <summary>
/// Applies the sixty-four-point forward discrete cosine transform to every independent lane.
/// </summary>
/// <typeparam name="TValue">The scalar or SIMD value containing the independent transform axes.</typeparam>
/// <param name="input">The spatial-domain values.</param>
/// <param name="output">The frequency-domain values.</param>
/// <param name="step">The fixed transform-stage buffer.</param>
/// <param name="values">The first value in the strided transform block.</param>
/// <param name="inputStride">The byte distance between consecutive input positions.</param>
/// <param name="outputStride">The byte distance between consecutive output positions.</param>
/// <param name="buffer0">The first fixed transform-stage buffer.</param>
/// <param name="buffer1">The second fixed transform-stage buffer.</param>
/// <param name="cosBit">The fixed-point precision of the cosine constants.</param>
public static void Dct64 < TValue > (
ref Av1TransformVector < TValue > input ,
ref Av1TransformVector < TValue > output ,
ref Av1TransformVector < TValue > step ,
ref byte values ,
nint inputStride ,
nint outputStride ,
ref Av1TransformVector < TValue > buffer0 ,
ref Av1TransformVector < TValue > buffer1 ,
int cosBit )
where TValue : struct
{
// Stage 1 forms mirror-symmetric sums and differences, separating the even and odd DCT terms.
for ( int index = 0 ; index < 3 2 ; index + + )
ReadOnlySpan < int > cospi = Av1SinusConstants . CosinusPi ( cosBit ) ;
Av1TransformRounding rounding = Av1ForwardTransformArithmetic < TValue > . CreateRounding ( cosBit ) ;
// Stage 1 consumes every spatial value before the strided block becomes available for final coefficients.
for ( int i = 0 ; i < 3 2 ; i + + )
{
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( input [ index ] , input [ 6 3 - index ] , out output [ index ] , out output [ 6 3 - index ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract (
Load < TValue > ( ref values , inputStride , i ) ,
Load < TValue > ( ref values , inputStride , 6 3 - i ) ,
out buffer0 [ i ] ,
out buffer0 [ 6 3 - i ] ) ;
}
// Stage 2 begins the recursive radix-2 factorization and rotates the central odd pairs.
ReadOnlySpan < int > cospi = Av1SinusConstants . CosinusPi ( cosBit ) ;
Av1TransformRounding rounding = Av1ForwardTransformArithmetic < TValue > . CreateRounding ( cosBit ) ;
for ( int index = 0 ; index < 1 6 ; index + + )
// Stage 2 begins the recursive radix-2 factorization and rotates the central odd-frequency pairs.
for ( int i = 0 ; i < 1 6 ; i + + )
{
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( output [ index ] , output [ 3 1 - index ] , out step [ index ] , out step [ 3 1 - index ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer0 [ i ] , buffer0 [ 3 1 - i ] , out buffer1 [ i ] , out buffer1 [ 3 1 - i ] ) ;
}
step [ 3 2 ] = output [ 3 2 ] ;
step [ 3 3 ] = output [ 3 3 ] ;
step [ 3 4 ] = output [ 3 4 ] ;
step [ 3 5 ] = output [ 3 5 ] ;
step [ 3 6 ] = output [ 3 6 ] ;
step [ 3 7 ] = output [ 3 7 ] ;
step [ 3 8 ] = output [ 3 8 ] ;
step [ 3 9 ] = output [ 3 9 ] ;
for ( int index = 0 ; index < 8 ; index + + )
for ( int i = 0 ; i < 8 ; i + + )
{
Av1ForwardTransformArithmetic < TValue > . Butterfly (
- cospi [ 3 2 ] , cospi [ 3 2 ] , output [ 4 0 + index ] , output [ 5 5 - index ] , out step [ 4 0 + index ] , out step [ 5 5 - index ] , cosBit , in rounding ) ;
Butterfly ( - cospi [ 3 2 ] , cospi [ 3 2 ] , buffer0 [ 4 0 + i ] , buffer0 [ 5 5 - i ] , ref buffer1 , 4 0 + i , 5 5 - i , cosBit , in rounding ) ;
}
step [ 5 6 ] = output [ 5 6 ] ;
step [ 5 7 ] = output [ 5 7 ] ;
step [ 5 8 ] = output [ 5 8 ] ;
step [ 5 9 ] = output [ 5 9 ] ;
step [ 6 0 ] = output [ 6 0 ] ;
step [ 6 1 ] = output [ 6 1 ] ;
step [ 6 2 ] = output [ 6 2 ] ;
step [ 6 3 ] = output [ 6 3 ] ;
// Stage 3 reduces the even half and folds the next odd-frequency groups into butterflies.
for ( int index = 0 ; index < 8 ; index + + )
// Stage 3 reduces the even half and folds the next odd-frequency groups into paired sums and differences.
for ( int i = 0 ; i < 8 ; i + + )
{
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( step [ index ] , step [ 1 5 - index ] , out output [ index ] , out output [ 1 5 - index ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer1 [ i ] , buffer1 [ 1 5 - i ] , out buffer0 [ i ] , out buffer0 [ 1 5 - i ] ) ;
}
output [ 1 6 ] = step [ 1 6 ] ;
output [ 1 7 ] = step [ 1 7 ] ;
output [ 1 8 ] = step [ 1 8 ] ;
output [ 1 9 ] = step [ 1 9 ] ;
for ( int index = 0 ; index < 4 ; index + + )
for ( int i = 0 ; i < 4 ; i + + )
{
Av1ForwardTransformArithmetic < TValue > . Butterfly (
- cospi [ 3 2 ] , cospi [ 3 2 ] , step [ 2 0 + index ] , step [ 2 7 - index ] , out output [ 2 0 + index ] , out output [ 2 7 - index ] , cosBit , in rounding ) ;
Butterfly ( - cospi [ 3 2 ] , cospi [ 3 2 ] , buffer1 [ 2 0 + i ] , buffer1 [ 2 7 - i ] , ref buffer0 , 2 0 + i , 2 7 - i , cosBit , in rounding ) ;
}
output [ 2 8 ] = step [ 2 8 ] ;
output [ 2 9 ] = step [ 2 9 ] ;
output [ 3 0 ] = step [ 3 0 ] ;
output [ 3 1 ] = step [ 3 1 ] ;
for ( int index = 0 ; index < 8 ; index + + )
for ( int i = 0 ; i < 8 ; i + + )
{
Av1ForwardTransformArithmetic < TValue > . AddSubtract (
step [ 3 2 + index ] , step [ 4 7 - index ] , out output [ 3 2 + index ] , out output [ 4 7 - index ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract (
step [ 6 3 - index ] , step [ 4 8 + index ] , out output [ 6 3 - index ] , out output [ 4 8 + index ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer0 [ 3 2 + i ] , buffer1 [ 4 7 - i ] , out buffer0 [ 3 2 + i ] , out buffer0 [ 4 7 - i ] ) ;
}
// Stage 4 continues the factorization as independent sixteen-sample groups.
for ( int index = 0 ; index < 4 ; index + + )
for ( int i = 0 ; i < 8 ; i + + )
{
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( output [ index ] , output [ 7 - index ] , out step [ index ] , out step [ 7 - index ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer0 [ 6 3 - i ] , buffer1 [ 4 8 + i ] , out buffer0 [ 6 3 - i ] , out buffer0 [ 4 8 + i ] ) ;
}
step [ 8 ] = output [ 8 ] ;
step [ 9 ] = output [ 9 ] ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( - cospi [ 3 2 ] , cospi [ 3 2 ] , output [ 1 0 ] , output [ 1 3 ] , out step [ 1 0 ] , out step [ 1 3 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( - cospi [ 3 2 ] , cospi [ 3 2 ] , output [ 1 1 ] , output [ 1 2 ] , out step [ 1 1 ] , out step [ 1 2 ] , cosBit , in rounding ) ;
step [ 1 4 ] = output [ 1 4 ] ;
step [ 1 5 ] = output [ 1 5 ] ;
for ( int index = 0 ; index < 4 ; index + + )
// Stage 4 continues the factorization as independent sixteen-value groups.
for ( int i = 0 ; i < 4 ; i + + )
{
Av1ForwardTransformArithmetic < TValue > . AddSubtract (
output [ 1 6 + index ] , output [ 2 3 - index ] , out step [ 1 6 + index ] , out step [ 2 3 - index ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract (
output [ 3 1 - index ] , output [ 2 4 + index ] , out step [ 3 1 - index ] , out step [ 2 4 + index ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer0 [ i ] , buffer0 [ 7 - i ] , out buffer1 [ i ] , out buffer1 [ 7 - i ] ) ;
}
step [ 3 2 ] = output [ 3 2 ] ;
step [ 3 3 ] = output [ 3 3 ] ;
step [ 3 4 ] = output [ 3 4 ] ;
step [ 3 5 ] = output [ 3 5 ] ;
for ( int index = 0 ; index < 4 ; index + + )
for ( int i = 0 ; i < 2 ; i + + )
{
Av1ForwardTransformArithmetic < TValue > . Butterfly (
- cospi [ 1 6 ] , cospi [ 4 8 ] , output [ 3 6 + index ] , output [ 5 9 - index ] , out step [ 3 6 + index ] , out step [ 5 9 - index ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly (
- cospi [ 4 8 ] , - cospi [ 1 6 ] , output [ 4 0 + index ] , output [ 5 5 - index ] , out step [ 4 0 + index ] , out step [ 5 5 - index ] , cosBit , in rounding ) ;
Butterfly ( - cospi [ 3 2 ] , cospi [ 3 2 ] , buffer0 [ 1 0 + i ] , buffer0 [ 1 3 - i ] , ref buffer1 , 1 0 + i , 1 3 - i , cosBit , in rounding ) ;
}
step [ 4 4 ] = output [ 4 4 ] ;
step [ 4 5 ] = output [ 4 5 ] ;
step [ 4 6 ] = output [ 4 6 ] ;
step [ 4 7 ] = output [ 4 7 ] ;
step [ 4 8 ] = output [ 4 8 ] ;
step [ 4 9 ] = output [ 4 9 ] ;
step [ 5 0 ] = output [ 5 0 ] ;
step [ 5 1 ] = output [ 5 1 ] ;
step [ 6 0 ] = output [ 6 0 ] ;
step [ 6 1 ] = output [ 6 1 ] ;
step [ 6 2 ] = output [ 6 2 ] ;
step [ 6 3 ] = output [ 6 3 ] ;
// Stage 5 reduces those groups into the eight-sample DCT and ADST building blocks.
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( step [ 0 ] , step [ 3 ] , out output [ 0 ] , out output [ 3 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( step [ 1 ] , step [ 2 ] , out output [ 1 ] , out output [ 2 ] ) ;
output [ 4 ] = step [ 4 ] ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( - cospi [ 3 2 ] , cospi [ 3 2 ] , step [ 5 ] , step [ 6 ] , out output [ 5 ] , out output [ 6 ] , cosBit , in rounding ) ;
output [ 7 ] = step [ 7 ] ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( step [ 8 ] , step [ 1 1 ] , out output [ 8 ] , out output [ 1 1 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( step [ 9 ] , step [ 1 0 ] , out output [ 9 ] , out output [ 1 0 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( step [ 1 4 ] , step [ 1 3 ] , out output [ 1 4 ] , out output [ 1 3 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( step [ 1 5 ] , step [ 1 2 ] , out output [ 1 5 ] , out output [ 1 2 ] ) ;
output [ 1 6 ] = step [ 1 6 ] ;
output [ 1 7 ] = step [ 1 7 ] ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( - cospi [ 1 6 ] , cospi [ 4 8 ] , step [ 1 8 ] , step [ 2 9 ] , out output [ 1 8 ] , out output [ 2 9 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( - cospi [ 1 6 ] , cospi [ 4 8 ] , step [ 1 9 ] , step [ 2 8 ] , out output [ 1 9 ] , out output [ 2 8 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( - cospi [ 4 8 ] , - cospi [ 1 6 ] , step [ 2 0 ] , step [ 2 7 ] , out output [ 2 0 ] , out output [ 2 7 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( - cospi [ 4 8 ] , - cospi [ 1 6 ] , step [ 2 1 ] , step [ 2 6 ] , out output [ 2 1 ] , out output [ 2 6 ] , cosBit , in rounding ) ;
output [ 2 2 ] = step [ 2 2 ] ;
output [ 2 3 ] = step [ 2 3 ] ;
output [ 2 4 ] = step [ 2 4 ] ;
output [ 2 5 ] = step [ 2 5 ] ;
output [ 3 0 ] = step [ 3 0 ] ;
output [ 3 1 ] = step [ 3 1 ] ;
for ( int index = 0 ; index < 4 ; index + + )
for ( int i = 0 ; i < 4 ; i + + )
{
Av1ForwardTransformArithmetic < TValue > . AddSubtract (
step [ 3 2 + index ] , step [ 3 9 - index ] , out output [ 3 2 + index ] , out output [ 3 9 - index ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract (
step [ 4 7 - index ] , step [ 4 0 + index ] , out output [ 4 7 - index ] , out output [ 4 0 + index ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract (
step [ 4 8 + index ] , step [ 5 5 - index ] , out output [ 4 8 + index ] , out output [ 5 5 - index ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract (
step [ 6 3 - index ] , step [ 5 6 + index ] , out output [ 6 3 - index ] , out output [ 5 6 + index ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer1 [ 1 6 + i ] , buffer0 [ 2 3 - i ] , out buffer1 [ 1 6 + i ] , out buffer1 [ 2 3 - i ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer1 [ 3 1 - i ] , buffer0 [ 2 4 + i ] , out buffer1 [ 3 1 - i ] , out buffer1 [ 2 4 + i ] ) ;
Butterfly ( - cospi [ 1 6 ] , cospi [ 4 8 ] , buffer0 [ 3 6 + i ] , buffer0 [ 5 9 - i ] , ref buffer1 , 3 6 + i , 5 9 - i , cosBit , in rounding ) ;
}
// Stage 6 completes the low-frequency DCT and rotates the first separated odd groups.
Av1ForwardTransformArithmetic < TValue > . Butterfly ( cospi [ 3 2 ] , cospi [ 3 2 ] , output [ 0 ] , output [ 1 ] , out step [ 0 ] , out step [ 1 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( cospi [ 1 6 ] , cospi [ 4 8 ] , output [ 3 ] , output [ 2 ] , out step [ 2 ] , out step [ 3 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( output [ 4 ] , output [ 5 ] , out step [ 4 ] , out step [ 5 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( output [ 7 ] , output [ 6 ] , out step [ 7 ] , out step [ 6 ] ) ;
step [ 8 ] = output [ 8 ] ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( - cospi [ 1 6 ] , cospi [ 4 8 ] , output [ 9 ] , output [ 1 4 ] , out step [ 9 ] , out step [ 1 4 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( - cospi [ 4 8 ] , - cospi [ 1 6 ] , output [ 1 0 ] , output [ 1 3 ] , out step [ 1 0 ] , out step [ 1 3 ] , cosBit , in rounding ) ;
step [ 1 1 ] = output [ 1 1 ] ;
step [ 1 2 ] = output [ 1 2 ] ;
step [ 1 5 ] = output [ 1 5 ] ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( output [ 1 6 ] , output [ 1 9 ] , out step [ 1 6 ] , out step [ 1 9 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( output [ 1 7 ] , output [ 1 8 ] , out step [ 1 7 ] , out step [ 1 8 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( output [ 2 3 ] , output [ 2 0 ] , out step [ 2 3 ] , out step [ 2 0 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( output [ 2 2 ] , output [ 2 1 ] , out step [ 2 2 ] , out step [ 2 1 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( output [ 2 4 ] , output [ 2 7 ] , out step [ 2 4 ] , out step [ 2 7 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( output [ 2 5 ] , output [ 2 6 ] , out step [ 2 5 ] , out step [ 2 6 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( output [ 3 1 ] , output [ 2 8 ] , out step [ 3 1 ] , out step [ 2 8 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( output [ 3 0 ] , output [ 2 9 ] , out step [ 3 0 ] , out step [ 2 9 ] ) ;
step [ 3 2 ] = output [ 3 2 ] ;
step [ 3 3 ] = output [ 3 3 ] ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( - cospi [ 8 ] , cospi [ 5 6 ] , output [ 3 4 ] , output [ 6 1 ] , out step [ 3 4 ] , out step [ 6 1 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( - cospi [ 8 ] , cospi [ 5 6 ] , output [ 3 5 ] , output [ 6 0 ] , out step [ 3 5 ] , out step [ 6 0 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( - cospi [ 5 6 ] , - cospi [ 8 ] , output [ 3 6 ] , output [ 5 9 ] , out step [ 3 6 ] , out step [ 5 9 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( - cospi [ 5 6 ] , - cospi [ 8 ] , output [ 3 7 ] , output [ 5 8 ] , out step [ 3 7 ] , out step [ 5 8 ] , cosBit , in rounding ) ;
step [ 3 8 ] = output [ 3 8 ] ;
step [ 3 9 ] = output [ 3 9 ] ;
step [ 4 0 ] = output [ 4 0 ] ;
step [ 4 1 ] = output [ 4 1 ] ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( - cospi [ 4 0 ] , cospi [ 2 4 ] , output [ 4 2 ] , output [ 5 3 ] , out step [ 4 2 ] , out step [ 5 3 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( - cospi [ 4 0 ] , cospi [ 2 4 ] , output [ 4 3 ] , output [ 5 2 ] , out step [ 4 3 ] , out step [ 5 2 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( - cospi [ 2 4 ] , - cospi [ 4 0 ] , output [ 4 4 ] , output [ 5 1 ] , out step [ 4 4 ] , out step [ 5 1 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( - cospi [ 2 4 ] , - cospi [ 4 0 ] , output [ 4 5 ] , output [ 5 0 ] , out step [ 4 5 ] , out step [ 5 0 ] , cosBit , in rounding ) ;
step [ 4 6 ] = output [ 4 6 ] ;
step [ 4 7 ] = output [ 4 7 ] ;
step [ 4 8 ] = output [ 4 8 ] ;
step [ 4 9 ] = output [ 4 9 ] ;
step [ 5 4 ] = output [ 5 4 ] ;
step [ 5 5 ] = output [ 5 5 ] ;
step [ 5 6 ] = output [ 5 6 ] ;
step [ 5 7 ] = output [ 5 7 ] ;
step [ 6 2 ] = output [ 6 2 ] ;
step [ 6 3 ] = output [ 6 3 ] ;
// Stage 7 merges adjacent odd-frequency terms with the required AV1 sign pattern.
output [ 0 ] = step [ 0 ] ;
output [ 1 ] = step [ 1 ] ;
output [ 2 ] = step [ 2 ] ;
output [ 3 ] = step [ 3 ] ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( cospi [ 8 ] , cospi [ 5 6 ] , step [ 7 ] , step [ 4 ] , out output [ 4 ] , out output [ 7 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( cospi [ 4 0 ] , cospi [ 2 4 ] , step [ 6 ] , step [ 5 ] , out output [ 5 ] , out output [ 6 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( step [ 8 ] , step [ 9 ] , out output [ 8 ] , out output [ 9 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( step [ 1 1 ] , step [ 1 0 ] , out output [ 1 1 ] , out output [ 1 0 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( step [ 1 2 ] , step [ 1 3 ] , out output [ 1 2 ] , out output [ 1 3 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( step [ 1 5 ] , step [ 1 4 ] , out output [ 1 5 ] , out output [ 1 4 ] ) ;
output [ 1 6 ] = step [ 1 6 ] ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( - cospi [ 8 ] , cospi [ 5 6 ] , step [ 1 7 ] , step [ 3 0 ] , out output [ 1 7 ] , out output [ 3 0 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( - cospi [ 5 6 ] , - cospi [ 8 ] , step [ 1 8 ] , step [ 2 9 ] , out output [ 1 8 ] , out output [ 2 9 ] , cosBit , in rounding ) ;
output [ 1 9 ] = step [ 1 9 ] ;
output [ 2 0 ] = step [ 2 0 ] ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( - cospi [ 4 0 ] , cospi [ 2 4 ] , step [ 2 1 ] , step [ 2 6 ] , out output [ 2 1 ] , out output [ 2 6 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( - cospi [ 2 4 ] , - cospi [ 4 0 ] , step [ 2 2 ] , step [ 2 5 ] , out output [ 2 2 ] , out output [ 2 5 ] , cosBit , in rounding ) ;
output [ 2 3 ] = step [ 2 3 ] ;
output [ 2 4 ] = step [ 2 4 ] ;
output [ 2 7 ] = step [ 2 7 ] ;
output [ 2 8 ] = step [ 2 8 ] ;
output [ 3 1 ] = step [ 3 1 ] ;
for ( int offset = 3 2 ; offset < 6 4 ; offset + = 8 )
for ( int i = 4 ; i < 8 ; i + + )
{
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( step [ offset ] , step [ offset + 3 ] , out output [ offset ] , out output [ offset + 3 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( step [ offset + 1 ] , step [ offset + 2 ] , out output [ offset + 1 ] , out output [ offset + 2 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( step [ offset + 7 ] , step [ offset + 4 ] , out output [ offset + 7 ] , out output [ offset + 4 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( step [ offset + 6 ] , step [ offset + 5 ] , out output [ offset + 6 ] , out output [ offset + 5 ] ) ;
Butterfly ( - cospi [ 4 8 ] , - cospi [ 1 6 ] , buffer0 [ 3 6 + i ] , buffer0 [ 5 9 - i ] , ref buffer1 , 3 6 + i , 5 9 - i , cosBit , in rounding ) ;
}
// Stage 8 applies the next level of odd-frequency rotations.
step [ 0 ] = output [ 0 ] ;
step [ 1 ] = output [ 1 ] ;
step [ 2 ] = output [ 2 ] ;
step [ 3 ] = output [ 3 ] ;
step [ 4 ] = output [ 4 ] ;
step [ 5 ] = output [ 5 ] ;
step [ 6 ] = output [ 6 ] ;
step [ 7 ] = output [ 7 ] ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( cospi [ 4 ] , cospi [ 6 0 ] , output [ 1 5 ] , output [ 8 ] , out step [ 8 ] , out step [ 1 5 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( cospi [ 3 6 ] , cospi [ 2 8 ] , output [ 1 4 ] , output [ 9 ] , out step [ 9 ] , out step [ 1 4 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( cospi [ 2 0 ] , cospi [ 4 4 ] , output [ 1 3 ] , output [ 1 0 ] , out step [ 1 0 ] , out step [ 1 3 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( cospi [ 5 2 ] , cospi [ 1 2 ] , output [ 1 2 ] , output [ 1 1 ] , out step [ 1 1 ] , out step [ 1 2 ] , cosBit , in rounding ) ;
for ( int offset = 1 6 ; offset < 3 2 ; offset + = 4 )
// Stage 5 reduces the sixteen-value groups into the eight-value DCT and ADST building blocks.
for ( int i = 0 ; i < 2 ; i + + )
{
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer1 [ i ] , buffer1 [ 3 - i ] , out buffer0 [ i ] , out buffer0 [ 3 - i ] ) ;
}
Butterfly ( - cospi [ 3 2 ] , cospi [ 3 2 ] , buffer1 [ 5 ] , buffer1 [ 6 ] , ref buffer0 , 5 , 6 , cosBit , in rounding ) ;
for ( int i = 0 ; i < 2 ; i + + )
{
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( output [ offset ] , output [ offset + 1 ] , out step [ offset ] , out step [ offset + 1 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( output [ offset + 3 ] , output [ offset + 2 ] , out step [ offset + 3 ] , out step [ offset + 2 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer0 [ 8 + i ] , buffer1 [ 1 1 - i ] , out buffer0 [ 8 + i ] , out buffer0 [ 1 1 - i ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer0 [ 1 5 - i ] , buffer1 [ 1 2 + i ] , out buffer0 [ 1 5 - i ] , out buffer0 [ 1 2 + i ] ) ;
Butterfly ( - cospi [ 1 6 ] , cospi [ 4 8 ] , buffer1 [ 1 8 + i ] , buffer1 [ 2 9 - i ] , ref buffer0 , 1 8 + i , 2 9 - i , cosBit , in rounding ) ;
}
step [ 3 2 ] = output [ 3 2 ] ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( - cospi [ 4 ] , cospi [ 6 0 ] , output [ 3 3 ] , output [ 6 2 ] , out step [ 3 3 ] , out step [ 6 2 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( - cospi [ 6 0 ] , - cospi [ 4 ] , output [ 3 4 ] , output [ 6 1 ] , out step [ 3 4 ] , out step [ 6 1 ] , cosBit , in rounding ) ;
step [ 3 5 ] = output [ 3 5 ] ;
step [ 3 6 ] = output [ 3 6 ] ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( - cospi [ 3 6 ] , cospi [ 2 8 ] , output [ 3 7 ] , output [ 5 8 ] , out step [ 3 7 ] , out step [ 5 8 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( - cospi [ 2 8 ] , - cospi [ 3 6 ] , output [ 3 8 ] , output [ 5 7 ] , out step [ 3 8 ] , out step [ 5 7 ] , cosBit , in rounding ) ;
step [ 3 9 ] = output [ 3 9 ] ;
step [ 4 0 ] = output [ 4 0 ] ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( - cospi [ 2 0 ] , cospi [ 4 4 ] , output [ 4 1 ] , output [ 5 4 ] , out step [ 4 1 ] , out step [ 5 4 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( - cospi [ 4 4 ] , - cospi [ 2 0 ] , output [ 4 2 ] , output [ 5 3 ] , out step [ 4 2 ] , out step [ 5 3 ] , cosBit , in rounding ) ;
step [ 4 3 ] = output [ 4 3 ] ;
step [ 4 4 ] = output [ 4 4 ] ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( - cospi [ 5 2 ] , cospi [ 1 2 ] , output [ 4 5 ] , output [ 5 0 ] , out step [ 4 5 ] , out step [ 5 0 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( - cospi [ 1 2 ] , - cospi [ 5 2 ] , output [ 4 6 ] , output [ 4 9 ] , out step [ 4 6 ] , out step [ 4 9 ] , cosBit , in rounding ) ;
step [ 4 7 ] = output [ 4 7 ] ;
step [ 4 8 ] = output [ 4 8 ] ;
step [ 5 1 ] = output [ 5 1 ] ;
step [ 5 2 ] = output [ 5 2 ] ;
step [ 5 5 ] = output [ 5 5 ] ;
step [ 5 6 ] = output [ 5 6 ] ;
step [ 5 9 ] = output [ 5 9 ] ;
step [ 6 0 ] = output [ 6 0 ] ;
step [ 6 3 ] = output [ 6 3 ] ;
// Stage 9 merges the remaining odd-frequency pairs before their terminal rotations.
output [ 0 ] = step [ 0 ] ;
output [ 1 ] = step [ 1 ] ;
output [ 2 ] = step [ 2 ] ;
output [ 3 ] = step [ 3 ] ;
output [ 4 ] = step [ 4 ] ;
output [ 5 ] = step [ 5 ] ;
output [ 6 ] = step [ 6 ] ;
output [ 7 ] = step [ 7 ] ;
output [ 8 ] = step [ 8 ] ;
output [ 9 ] = step [ 9 ] ;
output [ 1 0 ] = step [ 1 0 ] ;
output [ 1 1 ] = step [ 1 1 ] ;
output [ 1 2 ] = step [ 1 2 ] ;
output [ 1 3 ] = step [ 1 3 ] ;
output [ 1 4 ] = step [ 1 4 ] ;
output [ 1 5 ] = step [ 1 5 ] ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( cospi [ 2 ] , cospi [ 6 2 ] , step [ 3 1 ] , step [ 1 6 ] , out output [ 1 6 ] , out output [ 3 1 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( cospi [ 3 4 ] , cospi [ 3 0 ] , step [ 3 0 ] , step [ 1 7 ] , out output [ 1 7 ] , out output [ 3 0 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( cospi [ 1 8 ] , cospi [ 4 6 ] , step [ 2 9 ] , step [ 1 8 ] , out output [ 1 8 ] , out output [ 2 9 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( cospi [ 5 0 ] , cospi [ 1 4 ] , step [ 2 8 ] , step [ 1 9 ] , out output [ 1 9 ] , out output [ 2 8 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( cospi [ 1 0 ] , cospi [ 5 4 ] , step [ 2 7 ] , step [ 2 0 ] , out output [ 2 0 ] , out output [ 2 7 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( cospi [ 4 2 ] , cospi [ 2 2 ] , step [ 2 6 ] , step [ 2 1 ] , out output [ 2 1 ] , out output [ 2 6 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( cospi [ 2 6 ] , cospi [ 3 8 ] , step [ 2 5 ] , step [ 2 2 ] , out output [ 2 2 ] , out output [ 2 5 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( cospi [ 5 8 ] , cospi [ 6 ] , step [ 2 4 ] , step [ 2 3 ] , out output [ 2 3 ] , out output [ 2 4 ] , cosBit , in rounding ) ;
for ( int offset = 3 2 ; offset < 6 4 ; offset + = 4 )
for ( int i = 2 ; i < 4 ; i + + )
{
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( step [ offset ] , step [ offset + 1 ] , out output [ offset ] , out output [ offset + 1 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( step [ offset + 3 ] , step [ offset + 2 ] , out output [ offset + 3 ] , out output [ offset + 2 ] ) ;
Butterfly ( - cospi [ 4 8 ] , - cospi [ 1 6 ] , buffer1 [ 1 8 + i ] , buffer1 [ 2 9 - i ] , ref buffer0 , 1 8 + i , 2 9 - i , cosBit , in rounding ) ;
}
for ( int i = 0 ; i < 4 ; i + + )
{
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer0 [ 3 2 + i ] , buffer1 [ 3 9 - i ] , out buffer0 [ 3 2 + i ] , out buffer0 [ 3 9 - i ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer0 [ 4 7 - i ] , buffer1 [ 4 0 + i ] , out buffer0 [ 4 7 - i ] , out buffer0 [ 4 0 + i ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer0 [ 4 8 + i ] , buffer1 [ 5 5 - i ] , out buffer0 [ 4 8 + i ] , out buffer0 [ 5 5 - i ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer0 [ 6 3 - i ] , buffer1 [ 5 6 + i ] , out buffer0 [ 6 3 - i ] , out buffer0 [ 5 6 + i ] ) ;
}
// Stage 6 completes the low-frequency DCT and rotates the first separated odd-frequency groups.
Butterfly ( cospi [ 3 2 ] , cospi [ 3 2 ] , buffer0 [ 0 ] , buffer0 [ 1 ] , ref buffer1 , 0 , 1 , cosBit , in rounding ) ;
Butterfly ( cospi [ 1 6 ] , cospi [ 4 8 ] , buffer0 [ 3 ] , buffer0 [ 2 ] , ref buffer1 , 2 , 3 , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer1 [ 4 ] , buffer0 [ 5 ] , out buffer1 [ 4 ] , out buffer1 [ 5 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer1 [ 7 ] , buffer0 [ 6 ] , out buffer1 [ 7 ] , out buffer1 [ 6 ] ) ;
Butterfly ( - cospi [ 1 6 ] , cospi [ 4 8 ] , buffer0 [ 9 ] , buffer0 [ 1 4 ] , ref buffer1 , 9 , 1 4 , cosBit , in rounding ) ;
Butterfly ( - cospi [ 4 8 ] , - cospi [ 1 6 ] , buffer0 [ 1 0 ] , buffer0 [ 1 3 ] , ref buffer1 , 1 0 , 1 3 , cosBit , in rounding ) ;
for ( int i = 0 ; i < 2 ; i + + )
{
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer1 [ 1 6 + i ] , buffer0 [ 1 9 - i ] , out buffer1 [ 1 6 + i ] , out buffer1 [ 1 9 - i ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer1 [ 2 3 - i ] , buffer0 [ 2 0 + i ] , out buffer1 [ 2 3 - i ] , out buffer1 [ 2 0 + i ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer1 [ 2 4 + i ] , buffer0 [ 2 7 - i ] , out buffer1 [ 2 4 + i ] , out buffer1 [ 2 7 - i ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer1 [ 3 1 - i ] , buffer0 [ 2 8 + i ] , out buffer1 [ 3 1 - i ] , out buffer1 [ 2 8 + i ] ) ;
Butterfly ( - cospi [ 8 ] , cospi [ 5 6 ] , buffer0 [ 3 4 + i ] , buffer0 [ 6 1 - i ] , ref buffer1 , 3 4 + i , 6 1 - i , cosBit , in rounding ) ;
Butterfly ( - cospi [ 4 0 ] , cospi [ 2 4 ] , buffer0 [ 4 2 + i ] , buffer0 [ 5 3 - i ] , ref buffer1 , 4 2 + i , 5 3 - i , cosBit , in rounding ) ;
}
for ( int i = 2 ; i < 4 ; i + + )
{
Butterfly ( - cospi [ 5 6 ] , - cospi [ 8 ] , buffer0 [ 3 4 + i ] , buffer0 [ 6 1 - i ] , ref buffer1 , 3 4 + i , 6 1 - i , cosBit , in rounding ) ;
Butterfly ( - cospi [ 2 4 ] , - cospi [ 4 0 ] , buffer0 [ 4 2 + i ] , buffer0 [ 5 3 - i ] , ref buffer1 , 4 2 + i , 5 3 - i , cosBit , in rounding ) ;
}
// Stage 7 merges adjacent odd-frequency terms with the sign pattern required by the next rotations.
Butterfly ( cospi [ 8 ] , cospi [ 5 6 ] , buffer1 [ 7 ] , buffer1 [ 4 ] , ref buffer0 , 4 , 7 , cosBit , in rounding ) ;
Butterfly ( cospi [ 4 0 ] , cospi [ 2 4 ] , buffer1 [ 6 ] , buffer1 [ 5 ] , ref buffer0 , 5 , 6 , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer0 [ 8 ] , buffer1 [ 9 ] , out buffer0 [ 8 ] , out buffer0 [ 9 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer0 [ 1 1 ] , buffer1 [ 1 0 ] , out buffer0 [ 1 1 ] , out buffer0 [ 1 0 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer0 [ 1 2 ] , buffer1 [ 1 3 ] , out buffer0 [ 1 2 ] , out buffer0 [ 1 3 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer0 [ 1 5 ] , buffer1 [ 1 4 ] , out buffer0 [ 1 5 ] , out buffer0 [ 1 4 ] ) ;
Butterfly ( - cospi [ 8 ] , cospi [ 5 6 ] , buffer1 [ 1 7 ] , buffer1 [ 3 0 ] , ref buffer0 , 1 7 , 3 0 , cosBit , in rounding ) ;
Butterfly ( - cospi [ 5 6 ] , - cospi [ 8 ] , buffer1 [ 1 8 ] , buffer1 [ 2 9 ] , ref buffer0 , 1 8 , 2 9 , cosBit , in rounding ) ;
Butterfly ( - cospi [ 4 0 ] , cospi [ 2 4 ] , buffer1 [ 2 1 ] , buffer1 [ 2 6 ] , ref buffer0 , 2 1 , 2 6 , cosBit , in rounding ) ;
Butterfly ( - cospi [ 2 4 ] , - cospi [ 4 0 ] , buffer1 [ 2 2 ] , buffer1 [ 2 5 ] , ref buffer0 , 2 2 , 2 5 , cosBit , in rounding ) ;
for ( int group = 0 ; group < 4 ; group + + )
{
int offset = group * 8 ;
for ( int i = 0 ; i < 2 ; i + + )
{
Av1ForwardTransformArithmetic < TValue > . AddSubtract (
buffer0 [ 3 2 + offset + i ] ,
buffer1 [ 3 5 + offset - i ] ,
out buffer0 [ 3 2 + offset + i ] ,
out buffer0 [ 3 5 + offset - i ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract (
buffer0 [ 3 9 + offset - i ] ,
buffer1 [ 3 6 + offset + i ] ,
out buffer0 [ 3 9 + offset - i ] ,
out buffer0 [ 3 6 + offset + i ] ) ;
}
}
// Stage 8 applies the next level of odd-frequency rotations.
Butterfly ( cospi [ 4 ] , cospi [ 6 0 ] , buffer0 [ 1 5 ] , buffer0 [ 8 ] , ref buffer1 , 8 , 1 5 , cosBit , in rounding ) ;
Butterfly ( cospi [ 3 6 ] , cospi [ 2 8 ] , buffer0 [ 1 4 ] , buffer0 [ 9 ] , ref buffer1 , 9 , 1 4 , cosBit , in rounding ) ;
Butterfly ( cospi [ 2 0 ] , cospi [ 4 4 ] , buffer0 [ 1 3 ] , buffer0 [ 1 0 ] , ref buffer1 , 1 0 , 1 3 , cosBit , in rounding ) ;
Butterfly ( cospi [ 5 2 ] , cospi [ 1 2 ] , buffer0 [ 1 2 ] , buffer0 [ 1 1 ] , ref buffer1 , 1 1 , 1 2 , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer1 [ 1 6 ] , buffer0 [ 1 7 ] , out buffer1 [ 1 6 ] , out buffer1 [ 1 7 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer1 [ 1 9 ] , buffer0 [ 1 8 ] , out buffer1 [ 1 9 ] , out buffer1 [ 1 8 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer1 [ 2 0 ] , buffer0 [ 2 1 ] , out buffer1 [ 2 0 ] , out buffer1 [ 2 1 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer1 [ 2 3 ] , buffer0 [ 2 2 ] , out buffer1 [ 2 3 ] , out buffer1 [ 2 2 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer1 [ 2 4 ] , buffer0 [ 2 5 ] , out buffer1 [ 2 4 ] , out buffer1 [ 2 5 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer1 [ 2 7 ] , buffer0 [ 2 6 ] , out buffer1 [ 2 7 ] , out buffer1 [ 2 6 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer1 [ 2 8 ] , buffer0 [ 2 9 ] , out buffer1 [ 2 8 ] , out buffer1 [ 2 9 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer1 [ 3 1 ] , buffer0 [ 3 0 ] , out buffer1 [ 3 1 ] , out buffer1 [ 3 0 ] ) ;
Butterfly ( - cospi [ 4 ] , cospi [ 6 0 ] , buffer0 [ 3 3 ] , buffer0 [ 6 2 ] , ref buffer1 , 3 3 , 6 2 , cosBit , in rounding ) ;
Butterfly ( - cospi [ 6 0 ] , - cospi [ 4 ] , buffer0 [ 3 4 ] , buffer0 [ 6 1 ] , ref buffer1 , 3 4 , 6 1 , cosBit , in rounding ) ;
Butterfly ( - cospi [ 3 6 ] , cospi [ 2 8 ] , buffer0 [ 3 7 ] , buffer0 [ 5 8 ] , ref buffer1 , 3 7 , 5 8 , cosBit , in rounding ) ;
Butterfly ( - cospi [ 2 8 ] , - cospi [ 3 6 ] , buffer0 [ 3 8 ] , buffer0 [ 5 7 ] , ref buffer1 , 3 8 , 5 7 , cosBit , in rounding ) ;
Butterfly ( - cospi [ 2 0 ] , cospi [ 4 4 ] , buffer0 [ 4 1 ] , buffer0 [ 5 4 ] , ref buffer1 , 4 1 , 5 4 , cosBit , in rounding ) ;
Butterfly ( - cospi [ 4 4 ] , - cospi [ 2 0 ] , buffer0 [ 4 2 ] , buffer0 [ 5 3 ] , ref buffer1 , 4 2 , 5 3 , cosBit , in rounding ) ;
Butterfly ( - cospi [ 5 2 ] , cospi [ 1 2 ] , buffer0 [ 4 5 ] , buffer0 [ 5 0 ] , ref buffer1 , 4 5 , 5 0 , cosBit , in rounding ) ;
Butterfly ( - cospi [ 1 2 ] , - cospi [ 5 2 ] , buffer0 [ 4 6 ] , buffer0 [ 4 9 ] , ref buffer1 , 4 6 , 4 9 , cosBit , in rounding ) ;
// Stage 9 merges the remaining odd-frequency pairs before their terminal rotations. The table preserves the
// non-linear rotation order while keeping the constants in compile-time data.
for ( int i = 0 ; i < 8 ; i + + )
{
int low = 1 6 + i ;
int high = 3 1 - i ;
int odd = Dct64Stage9RotationOrder [ i ] ;
Butterfly ( cospi [ odd ] , cospi [ 6 4 - odd ] , buffer1 [ high ] , buffer1 [ low ] , ref buffer0 , low , high , cosBit , in rounding ) ;
}
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer0 [ 3 2 ] , buffer1 [ 3 3 ] , out buffer0 [ 3 2 ] , out buffer0 [ 3 3 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer0 [ 3 5 ] , buffer1 [ 3 4 ] , out buffer0 [ 3 5 ] , out buffer0 [ 3 4 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer0 [ 3 6 ] , buffer1 [ 3 7 ] , out buffer0 [ 3 6 ] , out buffer0 [ 3 7 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer0 [ 3 9 ] , buffer1 [ 3 8 ] , out buffer0 [ 3 9 ] , out buffer0 [ 3 8 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer0 [ 4 0 ] , buffer1 [ 4 1 ] , out buffer0 [ 4 0 ] , out buffer0 [ 4 1 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer0 [ 4 3 ] , buffer1 [ 4 2 ] , out buffer0 [ 4 3 ] , out buffer0 [ 4 2 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer0 [ 4 4 ] , buffer1 [ 4 5 ] , out buffer0 [ 4 4 ] , out buffer0 [ 4 5 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer0 [ 4 7 ] , buffer1 [ 4 6 ] , out buffer0 [ 4 7 ] , out buffer0 [ 4 6 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer0 [ 4 8 ] , buffer1 [ 4 9 ] , out buffer0 [ 4 8 ] , out buffer0 [ 4 9 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer0 [ 5 1 ] , buffer1 [ 5 0 ] , out buffer0 [ 5 1 ] , out buffer0 [ 5 0 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer0 [ 5 2 ] , buffer1 [ 5 3 ] , out buffer0 [ 5 2 ] , out buffer0 [ 5 3 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer0 [ 5 5 ] , buffer1 [ 5 4 ] , out buffer0 [ 5 5 ] , out buffer0 [ 5 4 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer0 [ 5 6 ] , buffer1 [ 5 7 ] , out buffer0 [ 5 6 ] , out buffer0 [ 5 7 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer0 [ 5 9 ] , buffer1 [ 5 8 ] , out buffer0 [ 5 9 ] , out buffer0 [ 5 8 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer0 [ 6 0 ] , buffer1 [ 6 1 ] , out buffer0 [ 6 0 ] , out buffer0 [ 6 1 ] ) ;
Av1ForwardTransformArithmetic < TValue > . AddSubtract ( buffer0 [ 6 3 ] , buffer1 [ 6 2 ] , out buffer0 [ 6 3 ] , out buffer0 [ 6 2 ] ) ;
// Stage 10 applies the pi/64 rotations to the penultimate odd-frequency level.
step [ 0 ] = output [ 0 ] ;
step [ 1 ] = output [ 1 ] ;
step [ 2 ] = output [ 2 ] ;
step [ 3 ] = output [ 3 ] ;
step [ 4 ] = output [ 4 ] ;
step [ 5 ] = output [ 5 ] ;
step [ 6 ] = output [ 6 ] ;
step [ 7 ] = output [ 7 ] ;
step [ 8 ] = output [ 8 ] ;
step [ 9 ] = output [ 9 ] ;
step [ 1 0 ] = output [ 1 0 ] ;
step [ 1 1 ] = output [ 1 1 ] ;
step [ 1 2 ] = output [ 1 2 ] ;
step [ 1 3 ] = output [ 1 3 ] ;
step [ 1 4 ] = output [ 1 4 ] ;
step [ 1 5 ] = output [ 1 5 ] ;
step [ 1 6 ] = output [ 1 6 ] ;
step [ 1 7 ] = output [ 1 7 ] ;
step [ 1 8 ] = output [ 1 8 ] ;
step [ 1 9 ] = output [ 1 9 ] ;
step [ 2 0 ] = output [ 2 0 ] ;
step [ 2 1 ] = output [ 2 1 ] ;
step [ 2 2 ] = output [ 2 2 ] ;
step [ 2 3 ] = output [ 2 3 ] ;
step [ 2 4 ] = output [ 2 4 ] ;
step [ 2 5 ] = output [ 2 5 ] ;
step [ 2 6 ] = output [ 2 6 ] ;
step [ 2 7 ] = output [ 2 7 ] ;
step [ 2 8 ] = output [ 2 8 ] ;
step [ 2 9 ] = output [ 2 9 ] ;
step [ 3 0 ] = output [ 3 0 ] ;
step [ 3 1 ] = output [ 3 1 ] ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( cospi [ 1 ] , cospi [ 6 3 ] , output [ 6 3 ] , output [ 3 2 ] , out step [ 3 2 ] , out step [ 6 3 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( cospi [ 3 3 ] , cospi [ 3 1 ] , output [ 6 2 ] , output [ 3 3 ] , out step [ 3 3 ] , out step [ 6 2 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( cospi [ 1 7 ] , cospi [ 4 7 ] , output [ 6 1 ] , output [ 3 4 ] , out step [ 3 4 ] , out step [ 6 1 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( cospi [ 4 9 ] , cospi [ 1 5 ] , output [ 6 0 ] , output [ 3 5 ] , out step [ 3 5 ] , out step [ 6 0 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( cospi [ 9 ] , cospi [ 5 5 ] , output [ 5 9 ] , output [ 3 6 ] , out step [ 3 6 ] , out step [ 5 9 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( cospi [ 4 1 ] , cospi [ 2 3 ] , output [ 5 8 ] , output [ 3 7 ] , out step [ 3 7 ] , out step [ 5 8 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( cospi [ 2 5 ] , cospi [ 3 9 ] , output [ 5 7 ] , output [ 3 8 ] , out step [ 3 8 ] , out step [ 5 7 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( cospi [ 5 7 ] , cospi [ 7 ] , output [ 5 6 ] , output [ 3 9 ] , out step [ 3 9 ] , out step [ 5 6 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( cospi [ 5 ] , cospi [ 5 9 ] , output [ 5 5 ] , output [ 4 0 ] , out step [ 4 0 ] , out step [ 5 5 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( cospi [ 3 7 ] , cospi [ 2 7 ] , output [ 5 4 ] , output [ 4 1 ] , out step [ 4 1 ] , out step [ 5 4 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( cospi [ 2 1 ] , cospi [ 4 3 ] , output [ 5 3 ] , output [ 4 2 ] , out step [ 4 2 ] , out step [ 5 3 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( cospi [ 5 3 ] , cospi [ 1 1 ] , output [ 5 2 ] , output [ 4 3 ] , out step [ 4 3 ] , out step [ 5 2 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( cospi [ 1 3 ] , cospi [ 5 1 ] , output [ 5 1 ] , output [ 4 4 ] , out step [ 4 4 ] , out step [ 5 1 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( cospi [ 4 5 ] , cospi [ 1 9 ] , output [ 5 0 ] , output [ 4 5 ] , out step [ 4 5 ] , out step [ 5 0 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( cospi [ 2 9 ] , cospi [ 3 5 ] , output [ 4 9 ] , output [ 4 6 ] , out step [ 4 6 ] , out step [ 4 9 ] , cosBit , in rounding ) ;
Av1ForwardTransformArithmetic < TValue > . Butterfly ( cospi [ 6 1 ] , cospi [ 3 ] , output [ 4 8 ] , output [ 4 7 ] , out step [ 4 7 ] , out step [ 4 8 ] , cosBit , in rounding ) ;
// Stage 11 applies the terminal pi/128 rotations and produces the staged coefficient values.
output [ 0 ] = step [ 0 ] ;
output [ 1 ] = step [ 3 2 ] ;
output [ 2 ] = step [ 1 6 ] ;
output [ 3 ] = step [ 4 8 ] ;
output [ 4 ] = step [ 8 ] ;
output [ 5 ] = step [ 4 0 ] ;
output [ 6 ] = step [ 2 4 ] ;
output [ 7 ] = step [ 5 6 ] ;
output [ 8 ] = step [ 4 ] ;
output [ 9 ] = step [ 3 6 ] ;
output [ 1 0 ] = step [ 2 0 ] ;
output [ 1 1 ] = step [ 5 2 ] ;
output [ 1 2 ] = step [ 1 2 ] ;
output [ 1 3 ] = step [ 4 4 ] ;
output [ 1 4 ] = step [ 2 8 ] ;
output [ 1 5 ] = step [ 6 0 ] ;
output [ 1 6 ] = step [ 2 ] ;
output [ 1 7 ] = step [ 3 4 ] ;
output [ 1 8 ] = step [ 1 8 ] ;
output [ 1 9 ] = step [ 5 0 ] ;
output [ 2 0 ] = step [ 1 0 ] ;
output [ 2 1 ] = step [ 4 2 ] ;
output [ 2 2 ] = step [ 2 6 ] ;
output [ 2 3 ] = step [ 5 8 ] ;
output [ 2 4 ] = step [ 6 ] ;
output [ 2 5 ] = step [ 3 8 ] ;
output [ 2 6 ] = step [ 2 2 ] ;
output [ 2 7 ] = step [ 5 4 ] ;
output [ 2 8 ] = step [ 1 4 ] ;
output [ 2 9 ] = step [ 4 6 ] ;
output [ 3 0 ] = step [ 3 0 ] ;
output [ 3 1 ] = step [ 6 2 ] ;
output [ 3 2 ] = step [ 1 ] ;
output [ 3 3 ] = step [ 3 3 ] ;
output [ 3 4 ] = step [ 1 7 ] ;
output [ 3 5 ] = step [ 4 9 ] ;
output [ 3 6 ] = step [ 9 ] ;
output [ 3 7 ] = step [ 4 1 ] ;
output [ 3 8 ] = step [ 2 5 ] ;
output [ 3 9 ] = step [ 5 7 ] ;
output [ 4 0 ] = step [ 5 ] ;
output [ 4 1 ] = step [ 3 7 ] ;
output [ 4 2 ] = step [ 2 1 ] ;
output [ 4 3 ] = step [ 5 3 ] ;
output [ 4 4 ] = step [ 1 3 ] ;
output [ 4 5 ] = step [ 4 5 ] ;
output [ 4 6 ] = step [ 2 9 ] ;
output [ 4 7 ] = step [ 6 1 ] ;
output [ 4 8 ] = step [ 3 ] ;
output [ 4 9 ] = step [ 3 5 ] ;
output [ 5 0 ] = step [ 1 9 ] ;
output [ 5 1 ] = step [ 5 1 ] ;
output [ 5 2 ] = step [ 1 1 ] ;
output [ 5 3 ] = step [ 4 3 ] ;
output [ 5 4 ] = step [ 2 7 ] ;
output [ 5 5 ] = step [ 5 9 ] ;
output [ 5 6 ] = step [ 7 ] ;
output [ 5 7 ] = step [ 3 9 ] ;
output [ 5 8 ] = step [ 2 3 ] ;
output [ 5 9 ] = step [ 5 5 ] ;
output [ 6 0 ] = step [ 1 5 ] ;
output [ 6 1 ] = step [ 4 7 ] ;
output [ 6 2 ] = step [ 3 1 ] ;
output [ 6 3 ] = step [ 6 3 ] ;
for ( int i = 0 ; i < 1 6 ; i + + )
{
int low = 3 2 + i ;
int high = 6 3 - i ;
int odd = Dct64Stage10RotationOrder [ i ] ;
Butterfly ( cospi [ odd ] , cospi [ 6 4 - odd ] , buffer0 [ high ] , buffer0 [ low ] , ref buffer1 , low , high , cosBit , in rounding ) ;
}
// Stage 11 applies the terminal permutation. The fused stages omit pass-through copies, so sources 4-7 and
// 16-31 remain in buffer0 at retirement,
// while every other source resides in buffer1. The mask maps that ownership through AV1 coefficient order.
ReadOnlySpan < byte > outputOrder = Dct64OutputOrder ;
for ( int i = 0 ; i < 6 4 ; i + + )
{
int sourceIndex = outputOrder [ i ] ;
TValue value = ( ( Dct64Buffer0OutputMask > > i ) & 1 ) ! = 0 ? buffer0 [ sourceIndex ] : buffer1 [ sourceIndex ] ;
Store ( ref values , outputStride , i , value ) ;
}
}
}