Browse Source

Various tiling bug fixes

pull/2633/head
Ynse Hoornenborg 2 years ago
parent
commit
be134e89d2
  1. 7
      src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ParseAboveNeighbor4x4Context.cs
  2. 8
      src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ParseLeftNeighbor4x4Context.cs
  3. 9
      src/ImageSharp/Formats/Heif/Av1/Tiling/Av1PartitionInfo.cs
  4. 21
      src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileDecoder.cs

7
src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ParseAboveNeighbor4x4Context.cs

@ -81,13 +81,10 @@ internal class Av1ParseAboveNeighbor4x4Context
int n4w = blockSize.Get4x4WideCount(); int n4w = blockSize.Get4x4WideCount();
if (skip) if (skip)
{ {
transformWidth = n4w * (1 << Av1Constants.ModeInfoSizeLog2); transformWidth = n4w << Av1Constants.ModeInfoSizeLog2;
} }
for (int i = 0; i < n4w; i++) Array.Fill(this.aboveTransformWidth, transformWidth, startIndex, n4w);
{
this.aboveTransformWidth[startIndex + i] = transformWidth;
}
} }
internal void ClearContext(int plane, int offset, int length) internal void ClearContext(int plane, int offset, int length)

8
src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ParseLeftNeighbor4x4Context.cs

@ -80,13 +80,11 @@ internal class Av1ParseLeftNeighbor4x4Context
int n4h = blockSize.Get4x4HighCount(); int n4h = blockSize.Get4x4HighCount();
if (skip) if (skip)
{ {
transformHeight = n4h * (1 << Av1Constants.ModeInfoSizeLog2); transformHeight = n4h << Av1Constants.ModeInfoSizeLog2;
} }
for (int i = 0; i < n4h; i++) DebugGuard.MustBeLessThanOrEqualTo(startIndex + n4h, this.leftTransformHeight.Length, nameof(startIndex));
{ Array.Fill(this.leftTransformHeight, transformHeight, startIndex, n4h);
this.leftTransformHeight[startIndex + i] = transformHeight;
}
} }
internal void ClearContext(int plane, int offset, int length) internal void ClearContext(int plane, int offset, int length)

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

@ -84,10 +84,11 @@ internal class Av1PartitionInfo
this.AvailableLeft = this.ColumnIndex > tileInfo.ModeInfoColumnStart; this.AvailableLeft = this.ColumnIndex > tileInfo.ModeInfoColumnStart;
this.AvailableAboveForChroma = this.AvailableAbove; this.AvailableAboveForChroma = this.AvailableAbove;
this.AvailableLeftForChroma = this.AvailableLeft; this.AvailableLeftForChroma = this.AvailableLeft;
this.modeBlockToLeftEdge = -(this.ColumnIndex << Av1Constants.ModeInfoSizeLog2) << 3; int shift = Av1Constants.ModeInfoSizeLog2 + 3;
this.modeBlockToRightEdge = ((frameInfo.ModeInfoColumnCount - bw4 - this.ColumnIndex) << Av1Constants.ModeInfoSizeLog2) << 3; this.modeBlockToLeftEdge = -this.ColumnIndex << shift;
this.modeBlockToTopEdge = -(this.RowIndex << Av1Constants.ModeInfoSizeLog2) << 3; this.modeBlockToRightEdge = (frameInfo.ModeInfoColumnCount - bw4 - this.ColumnIndex) << shift;
this.modeBlockToBottomEdge = ((frameInfo.ModeInfoRowCount - bh4 - this.RowIndex) << Av1Constants.ModeInfoSizeLog2) << 3; this.modeBlockToTopEdge = -this.RowIndex << shift;
this.modeBlockToBottomEdge = (frameInfo.ModeInfoRowCount - bh4 - this.RowIndex) << shift;
} }
public int GetMaxBlockWide(Av1BlockSize blockSize, bool subX) public int GetMaxBlockWide(Av1BlockSize blockSize, bool subX)

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

@ -1285,17 +1285,16 @@ internal class Av1TileDecoder : IAv1TileDecoder
int block4x4Height = blockSize.Get4x4HighCount(); int block4x4Height = blockSize.Get4x4HighCount();
// First condition in spec is for INTER frames, implemented only the INTRA condition. // First condition in spec is for INTER frames, implemented only the INTRA condition.
bool allowSelect = !partitionInfo.ModeInfo.Skip || true; Av1TransformSize transformSize = this.ReadTransformSize(ref reader, partitionInfo, superblockInfo, tileInfo, true);
Av1TransformSize transformSize = this.ReadTransformSize(ref reader, partitionInfo, superblockInfo, tileInfo, allowSelect);
this.aboveNeighborContext.UpdateTransformation(modeInfoLocation, tileInfo, transformSize, blockSize, false); this.aboveNeighborContext.UpdateTransformation(modeInfoLocation, tileInfo, transformSize, blockSize, false);
this.leftNeighborContext.UpdateTransformation(modeInfoLocation, superblockInfo, transformSize, blockSize, false); this.leftNeighborContext.UpdateTransformation(modeInfoLocation, superblockInfo, transformSize, blockSize, false);
this.UpdateTransformInfo(partitionInfo, blockSize, transformSize); this.UpdateTransformInfo(partitionInfo, superblockInfo, blockSize, transformSize);
} }
private unsafe void UpdateTransformInfo(Av1PartitionInfo partitionInfo, Av1BlockSize blockSize, Av1TransformSize transformSize) private unsafe void UpdateTransformInfo(Av1PartitionInfo partitionInfo, Av1SuperblockInfo superblockInfo, Av1BlockSize blockSize, Av1TransformSize transformSize)
{ {
int transformInfoYIndex = partitionInfo.ModeInfo.FirstTransformLocation[(int)Av1PlaneType.Y]; int transformInfoYIndex = superblockInfo.TransformInfoIndexY + partitionInfo.ModeInfo.FirstTransformLocation[(int)Av1PlaneType.Y];
int transformInfoUvIndex = partitionInfo.ModeInfo.FirstTransformLocation[(int)Av1PlaneType.Uv]; int transformInfoUvIndex = superblockInfo.TransformInfoIndexUv + partitionInfo.ModeInfo.FirstTransformLocation[(int)Av1PlaneType.Uv];
Av1TransformInfo lumaTransformInfo = this.FrameBuffer.GetTransformY(transformInfoYIndex); Av1TransformInfo lumaTransformInfo = this.FrameBuffer.GetTransformY(transformInfoYIndex);
Av1TransformInfo chromaTransformInfo = this.FrameBuffer.GetTransformUv(transformInfoUvIndex); Av1TransformInfo chromaTransformInfo = this.FrameBuffer.GetTransformUv(transformInfoUvIndex);
int totalLumaTusCount = 0; int totalLumaTusCount = 0;
@ -1324,8 +1323,8 @@ internal class Av1TileDecoder : IAv1TileDecoder
int stepColumn = transformSize.Get4x4WideCount(); int stepColumn = transformSize.Get4x4WideCount();
int stepRow = transformSize.Get4x4HighCount(); int stepRow = transformSize.Get4x4HighCount();
int unitHeight = Av1Math.Round2(Math.Min(height + idy, maxBlockHigh), 0); int unitHeight = Av1Math.RoundPowerOf2(Math.Min(height + idy, maxBlockHigh), 0);
int unitWidth = Av1Math.Round2(Math.Min(width + idx, maxBlockWide), 0); int unitWidth = Av1Math.RoundPowerOf2(Math.Min(width + idx, maxBlockWide), 0);
for (int blockRow = idy; blockRow < unitHeight; blockRow += stepRow) for (int blockRow = idy; blockRow < unitHeight; blockRow += stepRow)
{ {
for (int blockColumn = idx; blockColumn < unitWidth; blockColumn += stepColumn) for (int blockColumn = idx; blockColumn < unitWidth; blockColumn += stepColumn)
@ -1349,8 +1348,8 @@ internal class Av1TileDecoder : IAv1TileDecoder
stepColumn = transformSizeUv.Get4x4WideCount(); stepColumn = transformSizeUv.Get4x4WideCount();
stepRow = transformSizeUv.Get4x4HighCount(); stepRow = transformSizeUv.Get4x4HighCount();
unitHeight = Av1Math.Round2(Math.Min(height + idx, maxBlockHigh), subY ? 1 : 0); unitHeight = Av1Math.RoundPowerOf2(Math.Min(height + idx, maxBlockHigh), subY ? 1 : 0);
unitWidth = Av1Math.Round2(Math.Min(width + idx, maxBlockWide), subX ? 1 : 0); unitWidth = Av1Math.RoundPowerOf2(Math.Min(width + idx, maxBlockWide), subX ? 1 : 0);
for (int blockRow = idy; blockRow < unitHeight; blockRow += stepRow) for (int blockRow = idy; blockRow < unitHeight; blockRow += stepRow)
{ {
for (int blockColumn = idx; blockColumn < unitWidth; blockColumn += stepColumn) for (int blockColumn = idx; blockColumn < unitWidth; blockColumn += stepColumn)
@ -1382,7 +1381,7 @@ internal class Av1TileDecoder : IAv1TileDecoder
partitionInfo.ModeInfo.TusCount[(int)Av1PlaneType.Uv] = totalChromaTusCount; partitionInfo.ModeInfo.TusCount[(int)Av1PlaneType.Uv] = totalChromaTusCount;
this.firstTransformOffset[(int)Av1PlaneType.Y] += totalLumaTusCount; this.firstTransformOffset[(int)Av1PlaneType.Y] += totalLumaTusCount;
this.firstTransformOffset[(int)Av1PlaneType.Uv] += totalChromaTusCount; this.firstTransformOffset[(int)Av1PlaneType.Uv] += totalChromaTusCount << 1;
} }
/// <summary> /// <summary>

Loading…
Cancel
Save