diff --git a/src/ImageSharp/Formats/Heif/Av1/Av1BlockSize.cs b/src/ImageSharp/Formats/Heif/Av1/Av1BlockSize.cs
index c38f620c4..62c4ff59e 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Av1BlockSize.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Av1BlockSize.cs
@@ -72,7 +72,7 @@ internal enum Av1BlockSize : byte
/// A block of samples, 64 samples wide and 16 samples high.
Block64x16 = 21,
- SizesAll = 22,
+ AllSizes = 22,
SizeS = Block4x16,
Invalid = 255,
Largest = SizeS - 1,
diff --git a/src/ImageSharp/Formats/Heif/Av1/Av1BlockSizeExtensions.cs b/src/ImageSharp/Formats/Heif/Av1/Av1BlockSizeExtensions.cs
index 3c5ce9e59..6029d4fdd 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Av1BlockSizeExtensions.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Av1BlockSizeExtensions.cs
@@ -1,7 +1,6 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
-using SixLabors.ImageSharp.Formats.Heif.Av1.Quantization;
using SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
namespace SixLabors.ImageSharp.Formats.Heif.Av1;
@@ -104,7 +103,7 @@ internal static class Av1BlockSizeExtensions
{
Av1BlockSize planeBlockSize = blockSize.GetSubsampled(subX, subY);
Av1TransformSize uvTransformSize = Av1TransformSize.Invalid;
- if (planeBlockSize < Av1BlockSize.SizesAll)
+ if (planeBlockSize < Av1BlockSize.AllSizes)
{
uvTransformSize = planeBlockSize.GetMaximumTransformSize();
}
diff --git a/src/ImageSharp/Formats/Heif/Av1/Transform/Av1TransformTypeExtensions.cs b/src/ImageSharp/Formats/Heif/Av1/Transform/Av1TransformTypeExtensions.cs
index 48c14ba2a..c03b3b440 100644
--- a/src/ImageSharp/Formats/Heif/Av1/Transform/Av1TransformTypeExtensions.cs
+++ b/src/ImageSharp/Formats/Heif/Av1/Transform/Av1TransformTypeExtensions.cs
@@ -1,8 +1,6 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
-using System;
-
namespace SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
internal static class Av1TransformTypeExtensions
diff --git a/tests/ImageSharp.Tests/Formats/Heif/Av1/Av1BlockSizeTests.cs b/tests/ImageSharp.Tests/Formats/Heif/Av1/Av1BlockSizeTests.cs
new file mode 100644
index 000000000..79b32e92a
--- /dev/null
+++ b/tests/ImageSharp.Tests/Formats/Heif/Av1/Av1BlockSizeTests.cs
@@ -0,0 +1,119 @@
+// 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 Av1BlockSizeTests
+{
+ [Theory]
+ [MemberData(nameof(GetAllSizes))]
+ internal void GetWidthReturnsCorrectWidth(int s)
+ {
+ // Assign
+ Av1BlockSize blockSize = (Av1BlockSize)s;
+ int expectedWidth = blockSize switch
+ {
+ Av1BlockSize.Block4x4 or Av1BlockSize.Block4x8 or Av1BlockSize.Block4x16 => 4,
+ Av1BlockSize.Block8x4 or Av1BlockSize.Block8x8 or Av1BlockSize.Block8x16 or Av1BlockSize.Block8x32 => 8,
+ Av1BlockSize.Block16x4 or Av1BlockSize.Block16x8 or Av1BlockSize.Block16x16 or Av1BlockSize.Block16x32 or Av1BlockSize.Block16x64 => 16,
+ Av1BlockSize.Block32x8 or Av1BlockSize.Block32x16 or Av1BlockSize.Block32x32 or Av1BlockSize.Block32x64 => 32,
+ Av1BlockSize.Block64x16 or Av1BlockSize.Block64x32 or Av1BlockSize.Block64x64 or Av1BlockSize.Block64x128 => 64,
+ Av1BlockSize.Block128x64 or Av1BlockSize.Block128x128 => 128,
+ _ => -1
+ };
+
+ // Act
+ int actualWidth = blockSize.GetWidth();
+
+ // Assert
+ Assert.Equal(expectedWidth, actualWidth);
+ }
+
+ [Theory]
+ [MemberData(nameof(GetAllSizes))]
+ internal void GetHeightReturnsCorrectHeight(int s)
+ {
+ // Assign
+ Av1BlockSize blockSize = (Av1BlockSize)s;
+ int expectedHeight = blockSize switch
+ {
+ Av1BlockSize.Block4x4 or Av1BlockSize.Block8x4 or Av1BlockSize.Block16x4 => 4,
+ Av1BlockSize.Block4x8 or Av1BlockSize.Block8x8 or Av1BlockSize.Block16x8 or Av1BlockSize.Block32x8 => 8,
+ Av1BlockSize.Block4x16 or Av1BlockSize.Block8x16 or Av1BlockSize.Block16x16 or Av1BlockSize.Block32x16 or Av1BlockSize.Block64x16 => 16,
+ Av1BlockSize.Block8x32 or Av1BlockSize.Block16x32 or Av1BlockSize.Block32x32 or Av1BlockSize.Block64x32 => 32,
+ Av1BlockSize.Block16x64 or Av1BlockSize.Block32x64 or Av1BlockSize.Block64x64 or Av1BlockSize.Block128x64 => 64,
+ Av1BlockSize.Block64x128 or Av1BlockSize.Block128x128 => 128,
+ _ => -1
+ };
+
+ // Act
+ int actualHeight = blockSize.GetHeight();
+
+ // Assert
+ Assert.Equal(expectedHeight, actualHeight);
+ }
+
+ [Theory]
+ [MemberData(nameof(GetAllSizes))]
+ internal void GetSubSampledReturnsCorrectSize(int s)
+ {
+ if (s is 0 or 1 or 2 or 16 or 17)
+ {
+ // Exceptional values, skip for this generic test.
+ return;
+ }
+
+ // Assign
+ Av1BlockSize blockSize = (Av1BlockSize)s;
+ int originalWidth = blockSize.GetWidth();
+ int originalHeight = blockSize.GetHeight();
+
+ // Act
+ Av1BlockSize actualNoNo = blockSize.GetSubsampled(false, false);
+ Av1BlockSize actualYesNo = blockSize.GetSubsampled(true, false);
+ Av1BlockSize actualNoYes = blockSize.GetSubsampled(false, true);
+ Av1BlockSize actualYesYes = blockSize.GetSubsampled(true, true);
+
+ // Assert
+ Assert.Equal(originalWidth, actualNoNo.GetWidth());
+ Assert.Equal(originalHeight, actualNoNo.GetHeight());
+
+ if (actualYesNo != Av1BlockSize.Invalid)
+ {
+ Assert.Equal(originalWidth, actualYesNo.GetWidth() * 2);
+ Assert.Equal(originalHeight, actualYesNo.GetHeight());
+ }
+
+ if (actualNoYes != Av1BlockSize.Invalid)
+ {
+ Assert.Equal(originalWidth, actualNoYes.GetWidth());
+ Assert.Equal(originalHeight, actualNoYes.GetHeight() * 2);
+ }
+
+ Assert.Equal(originalWidth, actualYesYes.GetWidth() * 2);
+ Assert.Equal(originalHeight, actualYesYes.GetHeight() * 2);
+ }
+
+ public static TheoryData GetAllSizes()
+ {
+ TheoryData combinations = [];
+ for (int s = 0; s < (int)Av1BlockSize.AllSizes; s++)
+ {
+ combinations.Add(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;
+ }
+}
diff --git a/tests/ImageSharp.Tests/Formats/Heif/Av1/Av1TransformSizeTests.cs b/tests/ImageSharp.Tests/Formats/Heif/Av1/Av1TransformSizeTests.cs
new file mode 100644
index 000000000..d0740edc3
--- /dev/null
+++ b/tests/ImageSharp.Tests/Formats/Heif/Av1/Av1TransformSizeTests.cs
@@ -0,0 +1,152 @@
+// 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 Av1TransformSizeTests
+{
+ [Theory]
+ [MemberData(nameof(GetAllSizes))]
+ internal void GetWidthReturnsCorrectWidth(int s)
+ {
+ // Assign
+ Av1TransformSize transformSize = (Av1TransformSize)s;
+ int expectedWidth = transformSize switch
+ {
+ Av1TransformSize.Size4x4 or Av1TransformSize.Size4x8 or Av1TransformSize.Size4x16 => 4,
+ Av1TransformSize.Size8x4 or Av1TransformSize.Size8x8 or Av1TransformSize.Size8x16 or Av1TransformSize.Size8x32 => 8,
+ Av1TransformSize.Size16x4 or Av1TransformSize.Size16x8 or Av1TransformSize.Size16x16 or Av1TransformSize.Size16x32 or Av1TransformSize.Size16x64 => 16,
+ Av1TransformSize.Size32x8 or Av1TransformSize.Size32x16 or Av1TransformSize.Size32x32 or Av1TransformSize.Size32x64 => 32,
+ Av1TransformSize.Size64x16 or Av1TransformSize.Size64x32 or Av1TransformSize.Size64x64 => 64,
+ _ => -1
+ };
+
+ // Act
+ int actualWidth = transformSize.GetWidth();
+
+ // Assert
+ Assert.Equal(expectedWidth, actualWidth);
+ }
+
+ [Theory]
+ [MemberData(nameof(GetAllSizes))]
+ internal void GetHeightReturnsCorrectHeight(int s)
+ {
+ // Assign
+ Av1TransformSize transformSize = (Av1TransformSize)s;
+ int expectedHeight = transformSize switch
+ {
+ Av1TransformSize.Size4x4 or Av1TransformSize.Size8x4 or Av1TransformSize.Size16x4 => 4,
+ Av1TransformSize.Size4x8 or Av1TransformSize.Size8x8 or Av1TransformSize.Size16x8 or Av1TransformSize.Size32x8 => 8,
+ Av1TransformSize.Size4x16 or Av1TransformSize.Size8x16 or Av1TransformSize.Size16x16 or Av1TransformSize.Size32x16 or Av1TransformSize.Size64x16 => 16,
+ Av1TransformSize.Size8x32 or Av1TransformSize.Size16x32 or Av1TransformSize.Size32x32 or Av1TransformSize.Size64x32 => 32,
+ Av1TransformSize.Size16x64 or Av1TransformSize.Size32x64 or Av1TransformSize.Size64x64 => 64,
+ _ => -1
+ };
+
+ // Act
+ int actualHeight = transformSize.GetHeight();
+
+ // Assert
+ Assert.Equal(expectedHeight, actualHeight);
+ }
+
+ [Theory]
+ [MemberData(nameof(GetAllSizes))]
+ internal void GetSubSizeReturnsCorrectRatio(int s)
+ {
+ // Assign
+ Av1TransformSize transformSize = (Av1TransformSize)s;
+ int ratio = GetRatio(transformSize);
+ int expectedRatio = (ratio == 4) ? 2 : 1;
+
+ // Act
+ Av1TransformSize actual = transformSize.GetSubSize();
+ int actualRatio = GetRatio(actual);
+
+ // Assert
+ Assert.Equal(expectedRatio, actualRatio);
+ }
+
+ [Theory]
+ [MemberData(nameof(GetAllSizes))]
+ internal void GetSquareSizeReturnsCorrectRatio(int s)
+ {
+ // Assign
+ Av1TransformSize transformSize = (Av1TransformSize)s;
+ int ratio = GetRatio(transformSize);
+ int expectedRatio = 1;
+ int expectedSize = Math.Min(transformSize.GetWidth(), transformSize.GetHeight());
+
+ // Act
+ Av1TransformSize actual = transformSize.GetSquareSize();
+ int actualRatio = GetRatio(actual);
+
+ // Assert
+ Assert.Equal(expectedRatio, actualRatio);
+ Assert.Equal(expectedSize, actual.GetWidth());
+ Assert.Equal(expectedSize, actual.GetHeight());
+ }
+
+ [Theory]
+ [MemberData(nameof(GetAllSizes))]
+ internal void GetSquareUpSizeReturnsCorrectRatio(int s)
+ {
+ // Assign
+ Av1TransformSize transformSize = (Av1TransformSize)s;
+ int ratio = GetRatio(transformSize);
+ int expectedRatio = 1;
+ int expectedSize = Math.Max(transformSize.GetWidth(), transformSize.GetHeight());
+
+ // Act
+ Av1TransformSize actual = transformSize.GetSquareUpSize();
+ int actualRatio = GetRatio(actual);
+
+ // Assert
+ Assert.Equal(expectedRatio, actualRatio);
+ Assert.Equal(expectedSize, actual.GetWidth());
+ Assert.Equal(expectedSize, actual.GetHeight());
+ }
+
+ [Theory]
+ [MemberData(nameof(GetAllSizes))]
+ internal void ToBlockSizeReturnsSameWidthAndHeight(int s)
+ {
+ // Assign
+ Av1TransformSize transformSize = (Av1TransformSize)s;
+ int transformWidth = transformSize.GetWidth();
+ int transformHeight = transformSize.GetHeight();
+
+ // Act
+ Av1BlockSize blockSize = transformSize.ToBlockSize();
+ int blockWidth = blockSize.GetWidth();
+ int blockHeight = blockSize.GetHeight();
+
+ // Assert
+ Assert.Equal(transformWidth, blockWidth);
+ Assert.Equal(transformHeight, blockHeight);
+ }
+
+ public static TheoryData GetAllSizes()
+ {
+ TheoryData combinations = [];
+ for (int s = 0; s < (int)Av1TransformSize.AllSizes; s++)
+ {
+ combinations.Add(s);
+ }
+
+ return combinations;
+ }
+
+ private static int GetRatio(Av1TransformSize transformSize)
+ {
+ int width = transformSize.GetWidth();
+ int height = transformSize.GetHeight();
+ int ratio = width > height ? width / height : height / width;
+ return ratio;
+ }
+}