diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ParseAboveNeighbor4x4Context.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ParseAboveNeighbor4x4Context.cs index 1810bf6fc4..574735528d 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ParseAboveNeighbor4x4Context.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ParseAboveNeighbor4x4Context.cs @@ -81,13 +81,10 @@ internal class Av1ParseAboveNeighbor4x4Context int n4w = blockSize.Get4x4WideCount(); if (skip) { - transformWidth = n4w * (1 << Av1Constants.ModeInfoSizeLog2); + transformWidth = n4w << Av1Constants.ModeInfoSizeLog2; } - for (int i = 0; i < n4w; i++) - { - this.aboveTransformWidth[startIndex + i] = transformWidth; - } + Array.Fill(this.aboveTransformWidth, transformWidth, startIndex, n4w); } internal void ClearContext(int plane, int offset, int length) diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ParseLeftNeighbor4x4Context.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ParseLeftNeighbor4x4Context.cs index 8743ee329e..f505774746 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ParseLeftNeighbor4x4Context.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ParseLeftNeighbor4x4Context.cs @@ -80,13 +80,11 @@ internal class Av1ParseLeftNeighbor4x4Context int n4h = blockSize.Get4x4HighCount(); if (skip) { - transformHeight = n4h * (1 << Av1Constants.ModeInfoSizeLog2); + transformHeight = n4h << Av1Constants.ModeInfoSizeLog2; } - for (int i = 0; i < n4h; i++) - { - this.leftTransformHeight[startIndex + i] = transformHeight; - } + DebugGuard.MustBeLessThanOrEqualTo(startIndex + n4h, this.leftTransformHeight.Length, nameof(startIndex)); + Array.Fill(this.leftTransformHeight, transformHeight, startIndex, n4h); } internal void ClearContext(int plane, int offset, int length) diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1PartitionInfo.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1PartitionInfo.cs index 1a73c5eefc..99994f2d94 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1PartitionInfo.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1PartitionInfo.cs @@ -84,10 +84,11 @@ internal class Av1PartitionInfo this.AvailableLeft = this.ColumnIndex > tileInfo.ModeInfoColumnStart; this.AvailableAboveForChroma = this.AvailableAbove; this.AvailableLeftForChroma = this.AvailableLeft; - this.modeBlockToLeftEdge = -(this.ColumnIndex << Av1Constants.ModeInfoSizeLog2) << 3; - this.modeBlockToRightEdge = ((frameInfo.ModeInfoColumnCount - bw4 - this.ColumnIndex) << Av1Constants.ModeInfoSizeLog2) << 3; - this.modeBlockToTopEdge = -(this.RowIndex << Av1Constants.ModeInfoSizeLog2) << 3; - this.modeBlockToBottomEdge = ((frameInfo.ModeInfoRowCount - bh4 - this.RowIndex) << Av1Constants.ModeInfoSizeLog2) << 3; + int shift = Av1Constants.ModeInfoSizeLog2 + 3; + this.modeBlockToLeftEdge = -this.ColumnIndex << shift; + this.modeBlockToRightEdge = (frameInfo.ModeInfoColumnCount - bw4 - this.ColumnIndex) << shift; + this.modeBlockToTopEdge = -this.RowIndex << shift; + this.modeBlockToBottomEdge = (frameInfo.ModeInfoRowCount - bh4 - this.RowIndex) << shift; } public int GetMaxBlockWide(Av1BlockSize blockSize, bool subX) diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileDecoder.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileDecoder.cs index eeffbac337..285e5d13d9 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileDecoder.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileDecoder.cs @@ -1285,17 +1285,16 @@ internal class Av1TileDecoder : IAv1TileDecoder int block4x4Height = blockSize.Get4x4HighCount(); // 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, allowSelect); + Av1TransformSize transformSize = this.ReadTransformSize(ref reader, partitionInfo, superblockInfo, tileInfo, true); this.aboveNeighborContext.UpdateTransformation(modeInfoLocation, tileInfo, 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 transformInfoUvIndex = partitionInfo.ModeInfo.FirstTransformLocation[(int)Av1PlaneType.Uv]; + int transformInfoYIndex = superblockInfo.TransformInfoIndexY + partitionInfo.ModeInfo.FirstTransformLocation[(int)Av1PlaneType.Y]; + int transformInfoUvIndex = superblockInfo.TransformInfoIndexUv + partitionInfo.ModeInfo.FirstTransformLocation[(int)Av1PlaneType.Uv]; Av1TransformInfo lumaTransformInfo = this.FrameBuffer.GetTransformY(transformInfoYIndex); Av1TransformInfo chromaTransformInfo = this.FrameBuffer.GetTransformUv(transformInfoUvIndex); int totalLumaTusCount = 0; @@ -1324,8 +1323,8 @@ internal class Av1TileDecoder : IAv1TileDecoder int stepColumn = transformSize.Get4x4WideCount(); int stepRow = transformSize.Get4x4HighCount(); - int unitHeight = Av1Math.Round2(Math.Min(height + idy, maxBlockHigh), 0); - int unitWidth = Av1Math.Round2(Math.Min(width + idx, maxBlockWide), 0); + int unitHeight = Av1Math.RoundPowerOf2(Math.Min(height + idy, maxBlockHigh), 0); + int unitWidth = Av1Math.RoundPowerOf2(Math.Min(width + idx, maxBlockWide), 0); for (int blockRow = idy; blockRow < unitHeight; blockRow += stepRow) { for (int blockColumn = idx; blockColumn < unitWidth; blockColumn += stepColumn) @@ -1349,8 +1348,8 @@ internal class Av1TileDecoder : IAv1TileDecoder stepColumn = transformSizeUv.Get4x4WideCount(); stepRow = transformSizeUv.Get4x4HighCount(); - unitHeight = Av1Math.Round2(Math.Min(height + idx, maxBlockHigh), subY ? 1 : 0); - unitWidth = Av1Math.Round2(Math.Min(width + idx, maxBlockWide), subX ? 1 : 0); + unitHeight = Av1Math.RoundPowerOf2(Math.Min(height + idx, maxBlockHigh), subY ? 1 : 0); + unitWidth = Av1Math.RoundPowerOf2(Math.Min(width + idx, maxBlockWide), subX ? 1 : 0); for (int blockRow = idy; blockRow < unitHeight; blockRow += stepRow) { for (int blockColumn = idx; blockColumn < unitWidth; blockColumn += stepColumn) @@ -1382,7 +1381,7 @@ internal class Av1TileDecoder : IAv1TileDecoder partitionInfo.ModeInfo.TusCount[(int)Av1PlaneType.Uv] = totalChromaTusCount; this.firstTransformOffset[(int)Av1PlaneType.Y] += totalLumaTusCount; - this.firstTransformOffset[(int)Av1PlaneType.Uv] += totalChromaTusCount; + this.firstTransformOffset[(int)Av1PlaneType.Uv] += totalChromaTusCount << 1; } ///