Skip to content

Commit

Permalink
Refactor forward transformers
Browse files Browse the repository at this point in the history
  • Loading branch information
ynse01 committed Oct 5, 2024
1 parent 97052eb commit 242dded
Show file tree
Hide file tree
Showing 26 changed files with 453 additions and 315 deletions.
40 changes: 20 additions & 20 deletions src/ImageSharp/Formats/Heif/Av1/Transform/Av1ForwardTransformer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,22 @@ internal class Av1ForwardTransformer
private const int NewSqrt = 5793;
private const int NewSqrtBitCount = 12;

private static readonly IAv1ForwardTransformer?[] Transformers =
private static readonly IAv1Forward1dTransformer?[] Transformers =
[
new Av1Dct4ForwardTransformer(),
new Av1Dct8ForwardTransformer(),
new Av1Dct16ForwardTransformer(),
new Av1Dct32ForwardTransformer(),
new Av1Dct64ForwardTransformer(),
new Av1Adst4ForwardTransformer(),
new Av1Adst8ForwardTransformer(),
new Av1Adst16ForwardTransformer(),
new Av1Adst32ForwardTransformer(),
new Av1Identity4ForwardTransformer(),
new Av1Identity8ForwardTransformer(),
new Av1Identity16ForwardTransformer(),
new Av1Identity32ForwardTransformer(),
new Av1Identity64ForwardTransformer(),
new Av1Dct4Forward1dTransformer(),
new Av1Dct8Forward1dTransformer(),
new Av1Dct16Forward1dTransformer(),
new Av1Dct32Forward1dTransformer(),
new Av1Dct64Forward1dTransformer(),
new Av1Adst4Forward1dTransformer(),
new Av1Adst8Forward1dTransformer(),
new Av1Adst16Forward1dTransformer(),
new Av1Adst32Forward1dTransformer(),
new Av1Identity4Forward1dTransformer(),
new Av1Identity8Forward1dTransformer(),
new Av1Identity16Forward1dTransformer(),
new Av1Identity32Forward1dTransformer(),
new Av1Identity64Forward1dTransformer(),
null
];

Expand All @@ -37,8 +37,8 @@ internal static void Transform2d(Span<short> input, Span<int> coefficients, uint
{
Av1Transform2dFlipConfiguration config = new(transformType, transformSize);
ref int buffer = ref TemporaryCoefficientsBuffer[0];
IAv1ForwardTransformer? columnTransformer = GetTransformer(config.TransformFunctionTypeColumn);
IAv1ForwardTransformer? rowTransformer = GetTransformer(config.TransformFunctionTypeRow);
IAv1Forward1dTransformer? columnTransformer = GetTransformer(config.TransformFunctionTypeColumn);
IAv1Forward1dTransformer? rowTransformer = GetTransformer(config.TransformFunctionTypeRow);
if (columnTransformer != null && rowTransformer != null)
{
Transform2dCore(columnTransformer, rowTransformer, ref input[0], stride, ref coefficients[0], config, ref buffer, bitDepth);
Expand Down Expand Up @@ -97,15 +97,15 @@ private static void Transform8x8Avx2(Span<short> input, Span<int> coefficients,
}
}

private static IAv1ForwardTransformer? GetTransformer(Av1TransformFunctionType transformerType)
private static IAv1Forward1dTransformer? GetTransformer(Av1TransformFunctionType transformerType)
=> Transformers[(int)transformerType];

/// <summary>
/// SVT: av1_tranform_two_d_core_c
/// </summary>
private static void Transform2dCore<TColumn, TRow>(TColumn transformFunctionColumn, TRow transformFunctionRow, ref short input, uint inputStride, ref int output, Av1Transform2dFlipConfiguration config, ref int buf, int bitDepth)
where TColumn : IAv1ForwardTransformer
where TRow : IAv1ForwardTransformer
where TColumn : IAv1Forward1dTransformer
where TRow : IAv1Forward1dTransformer
{
int c, r;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.

using System.Runtime.Intrinsics;

namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward;

internal class Av1Identity16ForwardTransformer : IAv1ForwardTransformer
internal class Av1Adst16Forward1dTransformer : IAv1Forward1dTransformer
{
public void Transform(ref int input, ref int output, int cosBit, Span<byte> stageRange)
=> throw new NotImplementedException();

public void TransformAvx2(ref Vector256<int> input, ref Vector256<int> output, int cosBit, int columnNumber)
=> throw new NotImplementedException();
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.

using System.Runtime.Intrinsics;

namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward;

internal class Av1Identity32ForwardTransformer : IAv1ForwardTransformer
internal class Av1Adst32Forward1dTransformer : IAv1Forward1dTransformer
{
public void Transform(ref int input, ref int output, int cosBit, Span<byte> stageRange)
=> throw new NotImplementedException();

public void TransformAvx2(ref Vector256<int> input, ref Vector256<int> output, int cosBit, int columnNumber)
=> throw new NotImplementedException();
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.

using System.Runtime.Intrinsics;

namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward;

internal class Av1Identity4ForwardTransformer : IAv1ForwardTransformer
internal class Av1Adst4Forward1dTransformer : IAv1Forward1dTransformer
{
public void Transform(ref int input, ref int output, int cosBit, Span<byte> stageRange)
=> throw new NotImplementedException();

public void TransformAvx2(ref Vector256<int> input, ref Vector256<int> output, int cosBit, int columnNumber)
=> throw new NotImplementedException();
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.

using System.Runtime.Intrinsics;

namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward;

internal class Av1Identity8ForwardTransformer : IAv1ForwardTransformer
internal class Av1Adst8Forward1dTransformer : IAv1Forward1dTransformer
{
public void Transform(ref int input, ref int output, int cosBit, Span<byte> stageRange)
=> throw new NotImplementedException();

public void TransformAvx2(ref Vector256<int> input, ref Vector256<int> output, int cosBit, int columnNumber)
=> throw new NotImplementedException();
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.

using System.Runtime.Intrinsics;

namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward;

internal class Av1Dct8ForwardTransformer : IAv1ForwardTransformer
internal class Av1Dct16Forward1dTransformer : IAv1Forward1dTransformer
{
public void Transform(ref int input, ref int output, int cosBit, Span<byte> stageRange)
=> throw new NotImplementedException();

public void TransformAvx2(ref Vector256<int> input, ref Vector256<int> output, int cosBit, int columnNumber)
=> throw new NotImplementedException();
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.

using System.Runtime.Intrinsics;

namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward;

internal class Av1Adst8ForwardTransformer : IAv1ForwardTransformer
internal class Av1Dct32Forward1dTransformer : IAv1Forward1dTransformer
{
public void Transform(ref int input, ref int output, int cosBit, Span<byte> stageRange)
=> throw new NotImplementedException();

public void TransformAvx2(ref Vector256<int> input, ref Vector256<int> output, int cosBit, int columnNumber)
=> throw new NotImplementedException();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.

using System.Runtime.CompilerServices;

namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform.Forward;

internal class Av1Dct4Forward1dTransformer : IAv1Forward1dTransformer
{
public void Transform(ref int input, ref int output, int cosBit, Span<byte> stageRange)
=> TransformScalar(ref input, ref output, cosBit);

private static void TransformScalar(ref int input, ref int output, int cosBit)
{
Span<int> cospi = Av1SinusConstants.CosinusPi(cosBit);
ref int bf0 = ref output;
ref int bf1 = ref output;
Span<int> stepSpan = new int[4];
ref int step0 = ref stepSpan[0];
ref int step1 = ref Unsafe.Add(ref step0, 1);
ref int step2 = ref Unsafe.Add(ref step0, 2);
ref int step3 = ref Unsafe.Add(ref step0, 3);
ref int output1 = ref Unsafe.Add(ref output, 1);
ref int output2 = ref Unsafe.Add(ref output, 2);
ref int output3 = ref Unsafe.Add(ref output, 3);

// stage 0;

// stage 1;
output = input + Unsafe.Add(ref input, 3);
output1 = Unsafe.Add(ref input, 1) + Unsafe.Add(ref input, 2);
output2 = -Unsafe.Add(ref input, 2) + Unsafe.Add(ref input, 1);
output3 = -Unsafe.Add(ref input, 3) + Unsafe.Add(ref input, 0);

// stage 2
step0 = HalfBtf(cospi[32], output, cospi[32], output1, cosBit);
step1 = HalfBtf(-cospi[32], output1, cospi[32], output, cosBit);
step2 = HalfBtf(cospi[48], output2, cospi[16], output3, cosBit);
step3 = HalfBtf(cospi[48], output3, -cospi[16], output2, cosBit);

// stage 3
output = step0;
output1 = step2;
output2 = step1;
output3 = step3;
}

private static int HalfBtf(int w0, int in0, int w1, int in1, int bit)
{
long result64 = (long)(w0 * in0) + (w1 * in1);
long intermediate = result64 + (1L << (bit - 1));

// NOTE(david.barker): The value 'result_64' may not necessarily fit
// into 32 bits. However, the result of this function is nominally
// ROUND_POWER_OF_TWO_64(result_64, bit)
// and that is required to fit into stage_range[stage] many bits
// (checked by range_check_buf()).
//
// Here we've unpacked that rounding operation, and it can be shown
// that the value of 'intermediate' here *does* fit into 32 bits
// for any conformant bitstream.
// The upshot is that, if you do all this calculation using
// wrapping 32-bit arithmetic instead of (non-wrapping) 64-bit arithmetic,
// then you'll still get the correct result.
return (int)(intermediate >> bit);
}
}
Loading

0 comments on commit 242dded

Please sign in to comment.