Browse Source

Additional scan order unit test

pull/2633/head
Ynse Hoornenborg 1 year ago
parent
commit
a362c0b586
  1. 8
      src/ImageSharp/Formats/Heif/Av1/Transform/Av1ScanOrderConstants.cs
  2. 39
      tests/ImageSharp.Tests/Formats/Heif/Av1/Av1CoefficientsEntropyTests.cs
  3. 39
      tests/ImageSharp.Tests/Formats/Heif/Av1/Av1ScanOrderTests.cs

8
src/ImageSharp/Formats/Heif/Av1/Transform/Av1ScanOrderConstants.cs

@ -359,7 +359,6 @@ internal static class Av1ScanOrderConstants
private static readonly short[] DefaultInverseScan8x8 = [];
private static readonly short[] DefaultInverseScan16x16 = [];
private static readonly short[] DefaultInverseScan32x32 = [];
private static readonly short[] DefaultInverseScan64x64 = [];
private static readonly short[] DefaultInverseScan4x8 = [];
private static readonly short[] DefaultInverseScan8x4 = [];
private static readonly short[] DefaultInverseScan8x16 = [];
@ -375,7 +374,6 @@ internal static class Av1ScanOrderConstants
private static readonly short[] MatrixColumnInverseScan8x8 = [];
private static readonly short[] MatrixColumnInverseScan16x16 = [];
private static readonly short[] MatrixColumnInverseScan32x32 = [];
private static readonly short[] MatrixColumnInverseScan64x64 = [];
private static readonly short[] MatrixColumnInverseScan4x8 = [];
private static readonly short[] MatrixColumnInverseScan8x4 = [];
private static readonly short[] MatrixColumnInverseScan8x16 = [];
@ -391,7 +389,6 @@ internal static class Av1ScanOrderConstants
private static readonly short[] MatrixRowInverseScan8x8 = [];
private static readonly short[] MatrixRowInverseScan16x16 = [];
private static readonly short[] MatrixRowInverseScan32x32 = [];
private static readonly short[] MatrixRowInverseScan64x64 = [];
private static readonly short[] MatrixRowInverseScan4x8 = [];
private static readonly short[] MatrixRowInverseScan8x4 = [];
private static readonly short[] MatrixRowInverseScan8x16 = [];
@ -403,12 +400,11 @@ internal static class Av1ScanOrderConstants
private static readonly short[] MatrixRowInverseScan8x32 = [];
private static readonly short[] MatrixRowInverseScan32x8 = [];
// Neighborss are not used (yet) for AVIF coding, leave these arrays empty for now.
// Neighbors are not used (yet) for AVIF coding, leave these arrays empty for now.
private static readonly short[] DefaultScan4x4Neighbors = [];
private static readonly short[] DefaultScan8x8Neighbors = [];
private static readonly short[] DefaultScan16x16Neighbors = [];
private static readonly short[] DefaultScan32x32Neighbors = [];
private static readonly short[] DefaultScan64x64Neighbors = [];
private static readonly short[] DefaultScan4x8Neighbors = [];
private static readonly short[] DefaultScan8x4Neighbors = [];
private static readonly short[] DefaultScan8x16Neighbors = [];
@ -424,7 +420,6 @@ internal static class Av1ScanOrderConstants
private static readonly short[] MatrixColumnScan8x8Neighbors = [];
private static readonly short[] MatrixColumnScan16x16Neighbors = [];
private static readonly short[] MatrixColumnScan32x32Neighbors = [];
private static readonly short[] MatrixColumnScan64x64Neighbors = [];
private static readonly short[] MatrixColumnScan4x8Neighbors = [];
private static readonly short[] MatrixColumnScan8x4Neighbors = [];
private static readonly short[] MatrixColumnScan8x16Neighbors = [];
@ -440,7 +435,6 @@ internal static class Av1ScanOrderConstants
private static readonly short[] MatrixRowScan8x8Neighbors = [];
private static readonly short[] MatrixRowScan16x16Neighbors = [];
private static readonly short[] MatrixRowScan32x32Neighbors = [];
private static readonly short[] MatrixRowScan64x64Neighbors = [];
private static readonly short[] MatrixRowScan4x8Neighbors = [];
private static readonly short[] MatrixRowScan8x4Neighbors = [];
private static readonly short[] MatrixRowScan8x16Neighbors = [];

39
tests/ImageSharp.Tests/Formats/Heif/Av1/Av1CoefficientsEntropyTests.cs

@ -101,14 +101,14 @@ public class Av1CoefficientsEntropyTests
}
[Theory]
[MemberData(nameof(GetBlockSize4x4Data))]
public void RoundTripFullCoefficientsYSize4x4(int bSize, int txSize, int txType)
[MemberData(nameof(GetTransformTypes))]
public void RoundTripFullCoefficientsYSize4x4(int txType)
{
// Assign
const ushort endOfBlock = 16;
const Av1ComponentType componentType = Av1ComponentType.Luminance;
Av1BlockSize blockSize = (Av1BlockSize)bSize;
Av1TransformSize transformSize = (Av1TransformSize)txSize;
Av1BlockSize blockSize = Av1BlockSize.Block4x4;
Av1TransformSize transformSize = blockSize.GetMaximumTransformSize();
Av1TransformType transformType = (Av1TransformType)txType;
Av1PredictionMode intraDirection = Av1PredictionMode.DC;
Av1FilterIntraMode filterIntraMode = Av1FilterIntraMode.DC;
@ -116,14 +116,29 @@ public class Av1CoefficientsEntropyTests
}
[Theory]
[MemberData(nameof(GetBlockSize4x4Data))]
public void RoundTripFullCoefficientsUvSize4x4(int bSize, int txSize, int txType)
[MemberData(nameof(GetTransformTypes))]
public void RoundTripFullCoefficientsYSize8x8(int txType)
{
// Assign
const ushort endOfBlock = 16;
const Av1ComponentType componentType = Av1ComponentType.Luminance;
Av1BlockSize blockSize = Av1BlockSize.Block8x8;
Av1TransformSize transformSize = blockSize.GetMaximumTransformSize();
Av1TransformType transformType = (Av1TransformType)txType;
Av1PredictionMode intraDirection = Av1PredictionMode.DC;
Av1FilterIntraMode filterIntraMode = Av1FilterIntraMode.DC;
RoundTripCoefficientsCore(endOfBlock, componentType, blockSize, transformSize, transformType, intraDirection, filterIntraMode);
}
[Theory]
[MemberData(nameof(GetTransformTypes))]
public void RoundTripFullCoefficientsUvSize4x4(int txType)
{
// Assign
const ushort endOfBlock = 16;
const Av1ComponentType componentType = Av1ComponentType.Chroma;
Av1BlockSize blockSize = (Av1BlockSize)bSize;
Av1TransformSize transformSize = (Av1TransformSize)txSize;
Av1BlockSize blockSize = Av1BlockSize.Block4x4;
Av1TransformSize transformSize = blockSize.GetMaxUvTransformSize(true, true);
Av1TransformType transformType = (Av1TransformType)txType;
Av1PredictionMode intraDirection = Av1PredictionMode.DC;
Av1FilterIntraMode filterIntraMode = Av1FilterIntraMode.DC;
@ -155,14 +170,12 @@ public class Av1CoefficientsEntropyTests
Assert.Equal(coefficientsBuffer[..endOfBlock], actuals[1..(endOfBlock + 1)]);
}
public static TheoryData<int, int, int> GetBlockSize4x4Data()
public static TheoryData<int> GetTransformTypes()
{
TheoryData<int, int, int> result = [];
Av1BlockSize blockSize = Av1BlockSize.Block4x4;
Av1TransformSize transformSize = blockSize.GetMaximumTransformSize();
TheoryData<int> result = [];
for (Av1TransformType transformType = Av1TransformType.DctDct; transformType < Av1TransformType.VerticalDct; transformType++)
{
result.Add((int)blockSize, (int)transformSize, (int)transformType);
result.Add((int)transformType);
}
return result;

39
tests/ImageSharp.Tests/Formats/Heif/Av1/Av1ScanOrderTests.cs

@ -65,6 +65,45 @@ public class Av1ScanOrderTests
Assert.Equal(width * height, scanOrder.Scan.Length);
}
[Theory]
[MemberData(nameof(GetCombinations))]
internal void AllIndicesAreInDiagonalOrder(int s, int t)
{
// Assign
Av1TransformSize transformSize = (Av1TransformSize)s;
Av1TransformType transformType = (Av1TransformType)t;
int width = Math.Min(transformSize.GetWidth(), 32);
int height = Math.Min(transformSize.GetHeight(), 32);
// Act
Av1ScanOrder scanOrder = Av1ScanOrderConstants.GetScanOrder(transformSize, transformType);
// Assert
HashSet<int> visited = [];
ReadOnlySpan<short> scan = scanOrder.Scan;
// In reverse order, the indiced used in
// <see cref="Av1SymbolContextHelper.GetBaseRangeContext2d()" /> must already be known.
for (int i = scanOrder.Scan.Length - 1; i >= 0; i--)
{
visited.Add(scan[i]);
if (scan.Length > i + 1)
{
Assert.Contains(scan[i + 1], visited);
}
if (scan.Length > i + width)
{
Assert.Contains(scan[i + width], visited);
}
if (scan.Length > i + width + 1)
{
Assert.Contains(scan[i + width + 1], visited);
}
}
}
public static TheoryData<int, int> GetCombinations()
{
TheoryData<int, int> combinations = [];

Loading…
Cancel
Save