Browse Source

Return span of TransformInfos from FrameInfo

pull/2633/head
Ynse Hoornenborg 1 year ago
parent
commit
be75282afe
  1. 14
      src/ImageSharp/Formats/Heif/Av1/Tiling/Av1FrameInfo.cs
  2. 4
      src/ImageSharp/Formats/Heif/Av1/Tiling/Av1SuperblockInfo.cs
  3. 18
      src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileReader.cs
  4. 23
      src/ImageSharp/Formats/Heif/Av1/Transform/Av1BlockDecoder.cs

14
src/ImageSharp/Formats/Heif/Av1/Tiling/Av1FrameInfo.cs

@ -113,28 +113,28 @@ internal partial class Av1FrameInfo
return this.modeInfos[index];
}
public ref Av1TransformInfo GetSuperblockTransform(int plane, Point index)
public Span<Av1TransformInfo> GetSuperblockTransform(int plane, Point index)
{
if (plane == 0)
{
return ref this.GetSuperblockTransformY(index);
return this.GetSuperblockTransformY(index);
}
return ref this.GetSuperblockTransformUv(index);
return this.GetSuperblockTransformUv(index);
}
public ref Av1TransformInfo GetSuperblockTransformY(Point index)
public Span<Av1TransformInfo> GetSuperblockTransformY(Point index)
{
Span<Av1TransformInfo> span = this.transformInfosY;
int offset = ((index.Y * this.superblockColumnCount) + index.X) * this.modeInfoCountPerSuperblock;
return ref span[offset];
return span.Slice(offset, this.modeInfoCountPerSuperblock);
}
public ref Av1TransformInfo GetSuperblockTransformUv(Point index)
public Span<Av1TransformInfo> GetSuperblockTransformUv(Point index)
{
Span<Av1TransformInfo> span = this.transformInfosUv;
int offset = (((index.Y * this.superblockColumnCount) + index.X) * this.modeInfoCountPerSuperblock) << 1;
return ref span[offset];
return span.Slice(offset, this.modeInfoCountPerSuperblock);
}
public Span<int> GetCoefficients(int plane) =>

4
src/ImageSharp/Formats/Heif/Av1/Tiling/Av1SuperblockInfo.cs

@ -43,9 +43,9 @@ internal class Av1SuperblockInfo
public int BlockCount { get; internal set; }
public ref Av1TransformInfo GetTransformInfoY() => ref this.frameInfo.GetSuperblockTransformY(this.Position);
public Span<Av1TransformInfo> GetTransformInfoY() => this.frameInfo.GetSuperblockTransformY(this.Position);
public ref Av1TransformInfo GetTransformInfoUv() => ref this.frameInfo.GetSuperblockTransformUv(this.Position);
public Span<Av1TransformInfo> GetTransformInfoUv() => this.frameInfo.GetSuperblockTransformUv(this.Position);
public Av1BlockModeInfo GetModeInfo(Point index) => this.frameInfo.GetModeInfo(this.Position, index);

18
src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileReader.cs

@ -413,13 +413,13 @@ internal class Av1TileReader : IAv1TileReader
continue;
}
ref Av1TransformInfo transformInfoRef = ref (plane == 0) ? ref superblockInfo.GetTransformInfoY() : ref superblockInfo.GetTransformInfoUv();
Span<Av1TransformInfo> transformInfoSpan = (plane == 0) ? superblockInfo.GetTransformInfoY() : superblockInfo.GetTransformInfoUv();
if (isLosslessBlock)
{
// TODO: Implement.
int unitHeight = Av1Math.RoundPowerOf2(Math.Min(modeUnitBlocksHigh + row, maxBlocksHigh), 0);
int unitWidth = Av1Math.RoundPowerOf2(Math.Min(modeUnitBlocksWide + column, maxBlocksWide), 0);
DebugGuard.IsTrue(Unsafe.Add(ref transformInfoRef, transformInfoIndices[plane]).Size == Av1TransformSize.Size4x4, "Lossless frame shall have transform units of size 4x4.");
DebugGuard.IsTrue(transformInfoSpan[transformInfoIndices[plane]].Size == Av1TransformSize.Size4x4, "Lossless frame shall have transform units of size 4x4.");
transformUnitCount = ((unitWidth - column) * (unitHeight - row)) >> (subX + subY);
}
else
@ -439,7 +439,7 @@ internal class Av1TileReader : IAv1TileReader
DebugGuard.IsFalse(transformUnitCount == 0, nameof(transformUnitCount), string.Empty);
for (int tu = 0; tu < transformUnitCount; tu++)
{
Av1TransformInfo transformInfo = Unsafe.Add(ref transformInfoRef, transformInfoIndices[plane]);
Av1TransformInfo transformInfo = transformInfoSpan[transformInfoIndices[plane]];
DebugGuard.MustBeLessThanOrEqualTo(transformInfo.OffsetX, maxBlocksWide, nameof(transformInfo));
DebugGuard.MustBeLessThanOrEqualTo(transformInfo.OffsetY, maxBlocksHigh, nameof(transformInfo));
@ -830,8 +830,8 @@ internal class Av1TileReader : IAv1TileReader
{
int transformInfoYIndex = partitionInfo.ModeInfo.FirstTransformLocation[(int)Av1PlaneType.Y];
int transformInfoUvIndex = partitionInfo.ModeInfo.FirstTransformLocation[(int)Av1PlaneType.Uv];
ref Av1TransformInfo lumaTransformInfo = ref superblockInfo.GetTransformInfoY();
ref Av1TransformInfo chromaTransformInfo = ref superblockInfo.GetTransformInfoUv();
Span<Av1TransformInfo> lumaTransformInfo = superblockInfo.GetTransformInfoY();
Span<Av1TransformInfo> chromaTransformInfo = superblockInfo.GetTransformInfoUv();
int totalLumaTransformUnitCount = 0;
int totalChromaTransformUnitCount = 0;
int forceSplitCount = 0;
@ -864,7 +864,7 @@ internal class Av1TileReader : IAv1TileReader
{
for (int blockColumn = idx; blockColumn < unitWidth; blockColumn += stepColumn)
{
Unsafe.Add(ref lumaTransformInfo, transformInfoYIndex) = new Av1TransformInfo(
lumaTransformInfo[transformInfoYIndex] = new Av1TransformInfo(
transformSize, blockColumn, blockRow);
transformInfoYIndex++;
lumaTransformUnitCount++;
@ -889,7 +889,7 @@ internal class Av1TileReader : IAv1TileReader
{
for (int blockColumn = idx; blockColumn < unitWidth; blockColumn += stepColumn)
{
Unsafe.Add(ref chromaTransformInfo, transformInfoUvIndex) = new Av1TransformInfo(
chromaTransformInfo[transformInfoUvIndex] = new Av1TransformInfo(
transformSizeUv, blockColumn, blockRow);
transformInfoUvIndex++;
chromaTransformUnitCount++;
@ -910,8 +910,8 @@ internal class Av1TileReader : IAv1TileReader
partitionInfo.ModeInfo.FirstTransformLocation[(int)Av1PlaneType.Uv],
nameof(totalChromaTransformUnitCount));
int originalIndex = transformInfoUvIndex - totalChromaTransformUnitCount;
ref Av1TransformInfo originalInfo = ref Unsafe.Add(ref chromaTransformInfo, originalIndex);
ref Av1TransformInfo infoV = ref Unsafe.Add(ref chromaTransformInfo, transformInfoUvIndex);
ref Av1TransformInfo originalInfo = ref chromaTransformInfo[originalIndex];
ref Av1TransformInfo infoV = ref chromaTransformInfo[transformInfoUvIndex];
for (int i = 0; i < totalChromaTransformUnitCount; i++)
{
infoV = originalInfo;

23
src/ImageSharp/Formats/Heif/Av1/Transform/Av1BlockDecoder.cs

@ -75,8 +75,8 @@ internal class Av1BlockDecoder
for (int plane = 0; plane < colorConfig.PlaneCount; plane++)
{
int subX = (plane > 0) ? colorConfig.SubSamplingX ? 1 : 0 : 0;
int subY = (plane > 0) ? colorConfig.SubSamplingY ? 1 : 0 : 0;
int subX = (plane > 0) && colorConfig.SubSamplingX ? 1 : 0;
int subY = (plane > 0) && colorConfig.SubSamplingY ? 1 : 0;
if (plane != 0 && !partitionInfo.IsChroma)
{
@ -90,11 +90,12 @@ internal class Av1BlockDecoder
0 => superblockInfo.TransformInfoIndexY + modeInfo.FirstTransformLocation[plane],
_ => throw new InvalidImageContentException("Maximum of 3 color planes")
};
ref Av1TransformInfo transformInfo = ref Unsafe.Add(ref this.frameInfo.GetSuperblockTransform(plane, superblockInfo.Position), transformInfoIndex);
Span<Av1TransformInfo> transformInfo = this.frameInfo.GetSuperblockTransform(plane, superblockInfo.Position)[transformInfoIndex..];
Guard.NotNull(transformInfo[0]);
if (isLosslessBlock)
{
Guard.IsTrue(transformInfo.Size == Av1TransformSize.Size4x4, nameof(transformInfo.Size), "Lossless may only have 4x4 blocks.");
Guard.IsTrue(transformInfo[0].Size == Av1TransformSize.Size4x4, nameof(transformInfo), "Lossless may only have 4x4 blocks.");
transformUnitCount = (maxBlocksWide * maxBlocksHigh) >> (subX + subY);
}
else
@ -120,10 +121,10 @@ internal class Av1BlockDecoder
Span<byte> transformBlockReconstructionBuffer;
int transformBlockOffset;
transformSize = transformInfo.Size;
transformSize = transformInfo[0].Size;
Span<int> coefficients = superblockInfo.GetCoefficients((Av1Plane)plane)[this.currentCoefficientIndex[plane]..];
transformBlockOffset = ((transformInfo.OffsetY * reconstructionStride) + transformInfo.OffsetX) << Av1Constants.ModeInfoSizeLog2;
transformBlockOffset = ((transformInfo[0].OffsetY * reconstructionStride) + transformInfo[0].OffsetX) << Av1Constants.ModeInfoSizeLog2;
transformBlockReconstructionBuffer = blockReconstructionBuffer.Slice(transformBlockOffset << (highBitDepth ? 1 : 0));
if (this.isLoopFilterEnabled)
@ -156,18 +157,18 @@ internal class Av1BlockDecoder
transformBlockReconstructionBuffer,
reconstructionStride,
this.frameBuffer.BitDepth,
transformInfo.OffsetX,
transformInfo.OffsetY);
transformInfo[0].OffsetX,
transformInfo[0].OffsetY);
}
int numberOfCoefficients = 0;
if (!modeInfo.Skip && transformInfo.CodeBlockFlag)
if (!modeInfo.Skip && transformInfo[0].CodeBlockFlag)
{
Span<int> quantizationCoefficients = this.CurrentInverseQuantizationCoefficients;
int inverseQuantizationSize = transformSize.GetWidth() * transformSize.GetHeight();
quantizationCoefficients[..inverseQuantizationSize].Clear();
transformType = transformInfo.Type;
transformType = transformInfo[0].Type;
// SVT: svt_aom_inverse_quantize
numberOfCoefficients = inverseQuantizer.InverseQuantize(
@ -216,7 +217,7 @@ internal class Av1BlockDecoder
}
// increment transform pointer
transformInfo = ref Unsafe.Add(ref transformInfo, 1);
transformInfo = transformInfo[1..];
}
}
}

Loading…
Cancel
Save