diff --git a/src/ImageSharp/Formats/Heif/Av1/Entropy/Av1SymbolContextHelper.cs b/src/ImageSharp/Formats/Heif/Av1/Entropy/Av1SymbolContextHelper.cs index 6712036e76..07067974b7 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Entropy/Av1SymbolContextHelper.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Entropy/Av1SymbolContextHelper.cs @@ -108,29 +108,6 @@ internal static class Av1SymbolContextHelper return 3; } - /// - /// SVT: get_lower_levels_ctx_eob - /// - internal static int GetLowerLevelContextEndOfBlock(int blockWidthLog2, int height, int scanIndex) - { - if (scanIndex == 0) - { - return 0; - } - - if (scanIndex <= height << blockWidthLog2 >> 3) - { - return 1; - } - - if (scanIndex <= height << blockWidthLog2 >> 2) - { - return 2; - } - - return 3; - } - /// /// SVT: get_br_ctx_2d /// diff --git a/tests/ImageSharp.Tests/Formats/Heif/Av1/Av1SymbolContextTests.cs b/tests/ImageSharp.Tests/Formats/Heif/Av1/Av1SymbolContextTests.cs new file mode 100644 index 0000000000..01c88913e9 --- /dev/null +++ b/tests/ImageSharp.Tests/Formats/Heif/Av1/Av1SymbolContextTests.cs @@ -0,0 +1,71 @@ +// Copyright (c) Six Labors. +// Licensed under the Six Labors Split License. + +using SixLabors.ImageSharp.Formats.Heif.Av1; +using SixLabors.ImageSharp.Formats.Heif.Av1.Entropy; +using SixLabors.ImageSharp.Formats.Heif.Av1.Tiling; + +namespace SixLabors.ImageSharp.Tests.Formats.Heif.Av1; + +[Trait("Format", "Avif")] +public class Av1SymbolContextTests +{ + [Theory] + [MemberData(nameof(GetCombinations))] + public void TestAccuracy(int width, int height, int index) + { + // Arrange + Size size = new(width, height); + Av1LevelBuffer levels = new(Configuration.Default, size); + Point position = levels.GetPosition(index); + int blockWidthLog2 = Av1Math.Log2(width); + int expectedContext = GetExpectedLowerLevelContextEndOfBlock(blockWidthLog2, height, index); + + // Act + int actualContext = Av1SymbolContextHelper.GetLowerLevelContextEndOfBlock(levels, position); + + // Assert + Assert.Equal(expectedContext, actualContext); + } + + public static TheoryData GetCombinations() + { + TheoryData result = []; + for (int y = 1; y < 6; y++) + { + for (int x = 1; x < 6; x++) + { + int total = (1 << x) * (1 << y); + for (int i = 0; i < total; i++) + { + result.Add(1 << x, 1 << y, i); + } + } + } + + return result; + } + + /// + /// SVT: get_lower_levels_ctx_eob + /// + internal static int GetExpectedLowerLevelContextEndOfBlock(int blockWidthLog2, int height, int scanIndex) + { + if (scanIndex == 0) + { + return 0; + } + + if (scanIndex <= height << blockWidthLog2 >> 3) + { + return 1; + } + + if (scanIndex <= height << blockWidthLog2 >> 2) + { + return 2; + } + + return 3; + } +}