From 62a6a2342752ae1e8b644a1f86780b3731641dc8 Mon Sep 17 00:00:00 2001 From: Ynse Hoornenborg Date: Tue, 5 Nov 2024 22:10:42 +0100 Subject: [PATCH] Bug fixes to partition parsing --- .../Formats/Heif/Av1/Tiling/Av1FrameInfo.cs | 2 +- .../Tiling/Av1ParseAboveNeighbor4x4Context.cs | 4 ++-- .../Formats/Heif/Av1/Tiling/Av1TileReader.cs | 19 +++++++++++-------- .../Formats/Heif/Av1/Av1TilingTests.cs | 4 ++-- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1FrameInfo.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1FrameInfo.cs index 41011d93fd..0808d4844a 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1FrameInfo.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1FrameInfo.cs @@ -48,7 +48,7 @@ internal partial class Av1FrameInfo // Allocate the arrays. this.superblockInfos = new Av1SuperblockInfo[superblockCount]; this.modeInfos = new Av1BlockModeInfo[superblockCount * this.modeInfoCountPerSuperblock]; - this.modeInfoMap = new Av1FrameModeInfoMap(new Size(this.modeInfoCountPerSuperblock * this.superblockColumnCount, this.modeInfoCountPerSuperblock * this.superblockRowCount), superblockSizeLog2); + this.modeInfoMap = new Av1FrameModeInfoMap(new Size(this.modeInfoSizePerSuperblock * this.superblockColumnCount, this.modeInfoSizePerSuperblock * this.superblockRowCount), superblockSizeLog2); this.transformInfosY = new Av1TransformInfo[superblockCount * this.modeInfoCountPerSuperblock]; this.transformInfosUv = new Av1TransformInfo[2 * superblockCount * this.modeInfoCountPerSuperblock]; diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ParseAboveNeighbor4x4Context.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ParseAboveNeighbor4x4Context.cs index 9cae5c5254..0f6c4149cd 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ParseAboveNeighbor4x4Context.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ParseAboveNeighbor4x4Context.cs @@ -64,9 +64,9 @@ internal class Av1ParseAboveNeighbor4x4Context Array.Fill(this.aboveCompGroupIndex, 0, 0, width); } - public void UpdatePartition(Point modeInfoLocation, Av1TileInfo tileLoc, Av1BlockSize subSize, Av1BlockSize blockSize) + public void UpdatePartition(Point modeInfoLocation, Av1TileInfo tileInfo, Av1BlockSize subSize, Av1BlockSize blockSize) { - int startIndex = modeInfoLocation.X - tileLoc.ModeInfoColumnStart; + int startIndex = modeInfoLocation.X - tileInfo.ModeInfoColumnStart; int bw = blockSize.Get4x4WideCount(); int value = Av1PartitionContext.GetAboveContext(subSize); diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileReader.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileReader.cs index 48f45eceeb..0ce61bc0cc 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileReader.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileReader.cs @@ -187,8 +187,8 @@ internal class Av1TileReader : IAv1TileReader switch (partitionType) { case Av1PartitionType.Split: - Point loc1 = new(modeInfoLocation.X, modeInfoLocation.Y + halfBlock4x4Size); - Point loc2 = new(modeInfoLocation.X + halfBlock4x4Size, modeInfoLocation.Y); + Point loc1 = new(modeInfoLocation.X + halfBlock4x4Size, modeInfoLocation.Y); + Point loc2 = new(modeInfoLocation.X, modeInfoLocation.Y + halfBlock4x4Size); Point loc3 = new(modeInfoLocation.X + halfBlock4x4Size, modeInfoLocation.Y + halfBlock4x4Size); this.ParsePartition(ref reader, modeInfoLocation, subSize, superblockInfo, tileInfo); this.ParsePartition(ref reader, loc1, subSize, superblockInfo, tileInfo); @@ -248,7 +248,7 @@ internal class Av1TileReader : IAv1TileReader for (int i = 0; i < 4; i++) { int currentBlockRow = rowIndex + (i * quarterBlock4x4Size); - if (i > 0 && currentBlockRow > this.FrameHeader.ModeInfoRowCount) + if (i > 0 && currentBlockRow >= this.FrameHeader.ModeInfoRowCount) { break; } @@ -262,7 +262,7 @@ internal class Av1TileReader : IAv1TileReader for (int i = 0; i < 4; i++) { int currentBlockColumn = columnIndex + (i * quarterBlock4x4Size); - if (i > 0 && currentBlockColumn > this.FrameHeader.ModeInfoColumnCount) + if (i > 0 && currentBlockColumn >= this.FrameHeader.ModeInfoColumnCount) { break; } @@ -338,7 +338,7 @@ internal class Av1TileReader : IAv1TileReader this.ReadBlockTransformSize(ref reader, modeInfoLocation, partitionInfo, superblockInfo, tileInfo); if (partitionInfo.ModeInfo.Skip) { - this.ResetSkipContext(partitionInfo); + this.ResetSkipContext(partitionInfo, tileInfo); } this.Residual(ref reader, partitionInfo, superblockInfo, tileInfo, blockSize); @@ -347,7 +347,10 @@ internal class Av1TileReader : IAv1TileReader this.FrameInfo.UpdateModeInfo(blockModeInfo, superblockInfo); } - private void ResetSkipContext(Av1PartitionInfo partitionInfo) + /// + /// SVT: reset_skip_context + /// + private void ResetSkipContext(Av1PartitionInfo partitionInfo, Av1TileInfo tileInfo) { int planesCount = this.SequenceHeader.ColorConfig.PlaneCount; for (int i = 0; i < planesCount; i++) @@ -358,8 +361,8 @@ internal class Av1TileReader : IAv1TileReader DebugGuard.IsTrue(planeBlockSize != Av1BlockSize.Invalid, nameof(planeBlockSize)); int txsWide = planeBlockSize.GetWidth() >> 2; int txsHigh = planeBlockSize.GetHeight() >> 2; - int aboveOffset = (partitionInfo.ColumnIndex - this.FrameHeader.TilesInfo.TileColumnStartModeInfo[partitionInfo.ColumnIndex]) >> subX; - int leftOffset = (partitionInfo.RowIndex - this.FrameHeader.TilesInfo.TileRowStartModeInfo[partitionInfo.RowIndex]) >> subY; + int aboveOffset = (partitionInfo.ColumnIndex - tileInfo.ModeInfoColumnStart) >> subX; + int leftOffset = (partitionInfo.RowIndex - partitionInfo.SuperblockInfo.Position.Y) >> subY; this.aboveNeighborContext.ClearContext(i, aboveOffset, txsWide); this.leftNeighborContext.ClearContext(i, leftOffset, txsHigh); } diff --git a/tests/ImageSharp.Tests/Formats/Heif/Av1/Av1TilingTests.cs b/tests/ImageSharp.Tests/Formats/Heif/Av1/Av1TilingTests.cs index e1ad345605..3c5212b7ac 100644 --- a/tests/ImageSharp.Tests/Formats/Heif/Av1/Av1TilingTests.cs +++ b/tests/ImageSharp.Tests/Formats/Heif/Av1/Av1TilingTests.cs @@ -11,8 +11,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Heif.Av1; public class Av1TilingTests { [Theory] - /*[InlineData(TestImages.Heif.XnConvert, 0x010E, 0x03CC, 18)]*/ - [InlineData(TestImages.Heif.Orange4x4, 0x010E, 0x001d, 21)] + [InlineData(TestImages.Heif.XnConvert, 0x010E, 0x03CC, 18)] + // [InlineData(TestImages.Heif.Orange4x4, 0x010E, 0x001d, 21)] public void ReadFirstTile(string filename, int dataOffset, int dataSize, int tileOffset) { // Assign