Browse Source

Unit test for Partition Type

pull/2633/head
Ynse Hoornenborg 2 years ago
parent
commit
08cbc5ad11
  1. 90
      src/ImageSharp/Formats/Heif/Av1/Av1PartitionType.cs
  2. 9
      src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileDecoder.cs
  3. 12
      tests/ImageSharp.Tests/Formats/Heif/Av1/Av1BlockSizeTests.cs
  4. 61
      tests/ImageSharp.Tests/Formats/Heif/Av1/Av1PartitionTypeTests.cs

90
src/ImageSharp/Formats/Heif/Av1/Av1PartitionType.cs

@ -10,51 +10,139 @@ internal enum Av1PartitionType
/// <summary>
/// Not partitioned any further.
/// </summary>
/// <remarks>
/// <code>
/// ***
/// * *
/// ***
/// </code>
/// </remarks>
None = 0,
/// <summary>
/// Horizontally split in 2 partitions.
/// </summary>
/// <remarks>
/// <code>
/// ***
/// * *
/// ***
/// * *
/// ***
/// </code>
/// </remarks>
Horizontal = 1,
/// <summary>
/// Vertically split in 2 partitions.
/// </summary>
/// <remarks>
/// <code>
/// *****
/// * * *
/// *****
/// </code>
/// </remarks>
Vertical = 2,
/// <summary>
/// 4 equally sized partitions.
/// </summary>
/// <remarks>
/// <code>
/// *****
/// * * *
/// *****
/// * * *
/// *****
/// </code>
/// </remarks>
Split = 3,
/// <summary>
/// Horizontal split and the top partition is split again.
/// </summary>
/// <remarks>
/// <code>
/// *****
/// * * *
/// *****
/// * *
/// *****
/// </code>
/// </remarks>
HorizontalA = 4,
/// <summary>
/// Horizontal split and the bottom partition is split again.
/// </summary>
/// <remarks>
/// <code>
/// *****
/// * *
/// *****
/// * * *
/// *****
/// </code>
/// </remarks>
HorizontalB = 5,
/// <summary>
/// Vertical split and the left partition is split again.
/// </summary>
/// <remarks>
/// <code>
/// *****
/// * * *
/// *** *
/// * * *
/// *****
/// </code>
/// </remarks>
VerticalA = 6,
/// <summary>
/// Vertical split and the right partitino is split again.
/// Vertical split and the right partition is split again.
/// </summary>
/// <remarks>
/// <code>
/// *****
/// * * *
/// * ***
/// * * *
/// *****
/// </code>
/// </remarks>
VerticalB = 7,
/// <summary>
/// 4:1 horizontal partition.
/// </summary>
/// <remarks>
/// <code>
/// ***
/// * *
/// ***
/// * *
/// ***
/// * *
/// ***
/// * *
/// ***
/// </code>
/// </remarks>
Horizontal4 = 8,
/// <summary>
/// 4:1 vertical partition.
/// </summary>
/// <remarks>
/// <code>
/// *********
/// * * * * *
/// *********
/// </code>
/// </remarks>
Vertical4 = 9,
/// <summary>

9
src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileDecoder.cs

@ -336,13 +336,14 @@ internal class Av1TileDecoder : IAv1TileDecoder
int planesCount = this.SequenceHeader.ColorConfig.PlaneCount;
for (int i = 0; i < planesCount; i++)
{
bool subX = i > 0 && this.SequenceHeader.ColorConfig.SubSamplingX;
bool subY = i > 0 && this.SequenceHeader.ColorConfig.SubSamplingY;
int subX = (i > 0 && this.SequenceHeader.ColorConfig.SubSamplingX) ? 1 : 0;
int subY = (i > 0 && this.SequenceHeader.ColorConfig.SubSamplingY) ? 1 : 0;
Av1BlockSize planeBlockSize = partitionInfo.ModeInfo.BlockSize.GetSubsampled(subX, subY);
DebugGuard.IsTrue(planeBlockSize != Av1BlockSize.Invalid, nameof(planeBlockSize));
int txsWide = planeBlockSize.GetWidth() >> 2;
int txsHigh = planeBlockSize.GetHeight() >> 2;
int aboveOffset = (partitionInfo.ColumnIndex - this.FrameInfo.TilesInfo.TileColumnStartModeInfo[partitionInfo.ColumnIndex]) >> (subX ? 1 : 0);
int leftOffset = (partitionInfo.RowIndex - this.FrameInfo.TilesInfo.TileRowStartModeInfo[partitionInfo.RowIndex]) >> (subY ? 1 : 0);
int aboveOffset = (partitionInfo.ColumnIndex - this.FrameInfo.TilesInfo.TileColumnStartModeInfo[partitionInfo.ColumnIndex]) >> subX;
int leftOffset = (partitionInfo.RowIndex - this.FrameInfo.TilesInfo.TileRowStartModeInfo[partitionInfo.RowIndex]) >> subY;
this.aboveNeighborContext.ClearContext(i, aboveOffset, txsWide);
this.leftNeighborContext.ClearContext(i, leftOffset, txsHigh);
}

12
tests/ImageSharp.Tests/Formats/Heif/Av1/Av1BlockSizeTests.cs

@ -71,6 +71,8 @@ public class Av1BlockSizeTests
Av1BlockSize blockSize = (Av1BlockSize)s;
int originalWidth = blockSize.GetWidth();
int originalHeight = blockSize.GetHeight();
int halfWidth = originalWidth / 2;
int halfHeight = originalHeight / 2;
// Act
Av1BlockSize actualNoNo = blockSize.GetSubsampled(false, false);
@ -84,18 +86,18 @@ public class Av1BlockSizeTests
if (actualYesNo != Av1BlockSize.Invalid)
{
Assert.Equal(originalWidth, actualYesNo.GetWidth() * 2);
Assert.Equal(halfWidth, actualYesNo.GetWidth());
Assert.Equal(originalHeight, actualYesNo.GetHeight());
}
if (actualNoYes != Av1BlockSize.Invalid)
{
Assert.Equal(originalWidth, actualNoYes.GetWidth());
Assert.Equal(originalHeight, actualNoYes.GetHeight() * 2);
Assert.Equal(halfHeight, actualNoYes.GetHeight());
}
Assert.Equal(originalWidth, actualYesYes.GetWidth() * 2);
Assert.Equal(originalHeight, actualYesYes.GetHeight() * 2);
Assert.Equal(halfWidth, actualYesYes.GetWidth());
Assert.Equal(halfHeight, actualYesYes.GetHeight());
}
public static TheoryData<int> GetAllSizes()
@ -113,7 +115,7 @@ public class Av1BlockSizeTests
{
int width = blockSize.GetWidth();
int height = blockSize.GetHeight();
int ratio = width > height ? width / height : height / width;
int ratio = width >= height ? width / height : -height / width;
return ratio;
}
}

61
tests/ImageSharp.Tests/Formats/Heif/Av1/Av1PartitionTypeTests.cs

@ -0,0 +1,61 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using SixLabors.ImageSharp.Formats.Heif.Av1;
using SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
namespace SixLabors.ImageSharp.Tests.Formats.Heif.Av1;
[Trait("Format", "Avif")]
public class Av1PartitionTypeTests
{
[Theory]
[MemberData(nameof(GetAllCombinations))]
internal void GetSubBlockSizeReturnsCorrectRatio(int t, int s)
{
// Assign
Av1PartitionType partitionType = (Av1PartitionType)t;
Av1BlockSize blockSize = (Av1BlockSize)s;
int expectedRatio = partitionType switch
{
Av1PartitionType.None or Av1PartitionType.Split => 1,
Av1PartitionType.HorizontalA or Av1PartitionType.HorizontalB or Av1PartitionType.Horizontal => 2,
Av1PartitionType.VerticalA or Av1PartitionType.VerticalB or Av1PartitionType.Vertical => -2,
Av1PartitionType.Horizontal4 => 4,
Av1PartitionType.Vertical4 => -4,
_ => -1
};
// Act
Av1BlockSize subBlockSize = partitionType.GetBlockSubSize(blockSize);
// Assert
if (subBlockSize != Av1BlockSize.Invalid)
{
int actualRatio = GetRatio(subBlockSize);
Assert.Equal(expectedRatio, actualRatio);
}
}
public static TheoryData<int, int> GetAllCombinations()
{
TheoryData<int, int> combinations = [];
for (int t = 0; t <= (int)Av1PartitionType.Vertical4; t++)
{
for (int s = 0; s < (int)Av1BlockSize.AllSizes; s++)
{
combinations.Add(t, s);
}
}
return combinations;
}
private static int GetRatio(Av1BlockSize blockSize)
{
int width = blockSize.GetWidth();
int height = blockSize.GetHeight();
int ratio = width >= height ? width / height : -height / width;
return ratio;
}
}
Loading…
Cancel
Save