Browse Source

Add some code comments

pull/2633/head
Ynse Hoornenborg 2 years ago
parent
commit
4e53f7cf81
  1. 6
      src/ImageSharp/Formats/Heif/Av1/Readme.md
  2. 3
      src/ImageSharp/Formats/Heif/Av1/Tiling/Av1FrameBuffer.cs
  3. 33
      src/ImageSharp/Formats/Heif/Av1/Tiling/Av1PartitionInfo.cs
  4. 32
      src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileDecoder.cs
  5. 50
      src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TransformInfo.cs
  6. 2
      tests/ImageSharp.Tests/Formats/Heif/Av1/Av1TilingTests.cs

6
src/ImageSharp/Formats/Heif/Av1/Readme.md

@ -41,7 +41,11 @@ Paritions can contain other partitions and blocks.
## Block ## Block
A block is the smallest are of the image which has the same transformation parameters. A block contains ore or more ModeInfos.
## Transform Block
A Transform Block is the smallest area of the image, which has the same transformation parameters. A block contains ore or more ModeInfos.
## ModeInfo ## ModeInfo

3
src/ImageSharp/Formats/Heif/Av1/Tiling/Av1FrameBuffer.cs

@ -61,9 +61,6 @@ internal class Av1FrameBuffer
this.superblockInfos[i] = new(this, point); this.superblockInfos[i] = new(this, point);
for (int u = 0; u < this.modeInfoSizePerSuperblock; u++) for (int u = 0; u < this.modeInfoSizePerSuperblock; u++)
{ {
this.transformInfosY[j] = new Av1TransformInfo();
this.transformInfosY[j << 1] = new Av1TransformInfo();
this.transformInfosY[(j << 1) + 1] = new Av1TransformInfo();
for (int v = 0; v < this.modeInfoSizePerSuperblock; v++) for (int v = 0; v < this.modeInfoSizePerSuperblock; v++)
{ {
this.modeInfos[k] = new Av1BlockModeInfo(numPlanes, Av1BlockSize.Block4x4, new Point(u, v)); this.modeInfos[k] = new Av1BlockModeInfo(numPlanes, Av1BlockSize.Block4x4, new Point(u, v));

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

@ -17,29 +17,50 @@ internal class Av1PartitionInfo
this.ModeInfo = modeInfo; this.ModeInfo = modeInfo;
this.SuperblockInfo = superblockInfo; this.SuperblockInfo = superblockInfo;
this.IsChroma = isChroma; this.IsChroma = isChroma;
this.PartitionType = partitionType; this.Type = partitionType;
this.CdefStrength = []; this.CdefStrength = [];
this.ReferenceFrame = [-1, -1]; this.ReferenceFrame = [-1, -1];
} }
public Av1BlockModeInfo ModeInfo { get; } public Av1BlockModeInfo ModeInfo { get; }
/// <summary>
/// Gets the <see cref="Av1SuperblockInfo"/> this partition resides inside.
/// </summary>
public Av1SuperblockInfo SuperblockInfo { get; } public Av1SuperblockInfo SuperblockInfo { get; }
public bool IsChroma { get; } public bool IsChroma { get; }
public Av1PartitionType PartitionType { get; } public Av1PartitionType Type { get; }
public bool AvailableUp { get; set; } /// <summary>
/// Gets or sets a value indicating whether the information from the block above can be used on the luma plane.
/// </summary>
public bool AvailableAbove { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the information from the block left can be used on the luma plane.
/// </summary>
public bool AvailableLeft { get; set; } public bool AvailableLeft { get; set; }
public bool AvailableUpForChroma { get; set; } /// <summary>
/// Gets or sets a value indicating whether the information from the block above can be used on the chroma plane.
/// </summary>
public bool AvailableAboveForChroma { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the information from the block left can be used on the chroma plane.
/// </summary>
public bool AvailableLeftForChroma { get; set; } public bool AvailableLeftForChroma { get; set; }
/// <summary>
/// Gets or sets the horizontal location of the block in units of 4x4 luma samples.
/// </summary>
public int ColumnIndex { get; set; } public int ColumnIndex { get; set; }
/// <summary>
/// Gets or sets the vertical location of the block in units of 4x4 luma samples.
/// </summary>
public int RowIndex { get; set; } public int RowIndex { get; set; }
public Av1BlockModeInfo? AboveModeInfo { get; set; } public Av1BlockModeInfo? AboveModeInfo { get; set; }
@ -59,9 +80,9 @@ internal class Av1PartitionInfo
Av1BlockSize blockSize = this.ModeInfo.BlockSize; Av1BlockSize blockSize = this.ModeInfo.BlockSize;
int bw4 = blockSize.Get4x4WideCount(); int bw4 = blockSize.Get4x4WideCount();
int bh4 = blockSize.Get4x4HighCount(); int bh4 = blockSize.Get4x4HighCount();
this.AvailableUp = this.RowIndex > tileInfo.ModeInfoRowStart; this.AvailableAbove = this.RowIndex > tileInfo.ModeInfoRowStart;
this.AvailableLeft = this.ColumnIndex > tileInfo.ModeInfoColumnStart; this.AvailableLeft = this.ColumnIndex > tileInfo.ModeInfoColumnStart;
this.AvailableUpForChroma = this.AvailableUp; this.AvailableAboveForChroma = this.AvailableAbove;
this.AvailableLeftForChroma = this.AvailableLeft; this.AvailableLeftForChroma = this.AvailableLeft;
this.modeBlockToLeftEdge = -(this.ColumnIndex << Av1Constants.ModeInfoSizeLog2) << 3; this.modeBlockToLeftEdge = -(this.ColumnIndex << Av1Constants.ModeInfoSizeLog2) << 3;
this.modeBlockToRightEdge = ((frameInfo.ModeInfoColumnCount - bw4 - this.ColumnIndex) << Av1Constants.ModeInfoSizeLog2) << 3; this.modeBlockToRightEdge = ((frameInfo.ModeInfoColumnCount - bw4 - this.ColumnIndex) << Av1Constants.ModeInfoSizeLog2) << 3;

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

@ -346,7 +346,7 @@ internal class Av1TileDecoder : IAv1TileDecoder
{ {
if (this.SequenceHeader.ColorConfig.SubSamplingY && block4x4Height == 1) if (this.SequenceHeader.ColorConfig.SubSamplingY && block4x4Height == 1)
{ {
partitionInfo.AvailableUpForChroma = this.IsInside(rowIndex - 2, columnIndex); partitionInfo.AvailableAboveForChroma = this.IsInside(rowIndex - 2, columnIndex);
} }
if (this.SequenceHeader.ColorConfig.SubSamplingX && block4x4Width == 1) if (this.SequenceHeader.ColorConfig.SubSamplingX && block4x4Width == 1)
@ -355,7 +355,7 @@ internal class Av1TileDecoder : IAv1TileDecoder
} }
} }
if (partitionInfo.AvailableUp) if (partitionInfo.AvailableAbove)
{ {
partitionInfo.AboveModeInfo = superblockInfo.GetModeInfo(new Point(rowIndex - 1, columnIndex)); partitionInfo.AboveModeInfo = superblockInfo.GetModeInfo(new Point(rowIndex - 1, columnIndex));
} }
@ -456,8 +456,8 @@ internal class Av1TileDecoder : IAv1TileDecoder
int coefficientIndex = this.coefficientIndex[plane]; int coefficientIndex = this.coefficientIndex[plane];
int endOfBlock = 0; int endOfBlock = 0;
Av1TransformInfo transformInfo = this.FrameBuffer.GetTransform(plane, transformInfoIndices[plane])!; Av1TransformInfo transformInfo = this.FrameBuffer.GetTransform(plane, transformInfoIndices[plane])!;
int blockColumn = transformInfo.TransformOffsetX; int blockColumn = transformInfo.OffsetX;
int blockRow = transformInfo.TransformOffsetY; int blockRow = transformInfo.OffsetY;
int startX = (partitionInfo.ColumnIndex >> subX) + blockColumn; int startX = (partitionInfo.ColumnIndex >> subX) + blockColumn;
int startY = (partitionInfo.RowIndex >> subY) + blockRow; int startY = (partitionInfo.RowIndex >> subY) + blockRow;
@ -469,7 +469,7 @@ internal class Av1TileDecoder : IAv1TileDecoder
if (!partitionInfo.ModeInfo.Skip) if (!partitionInfo.ModeInfo.Skip)
{ {
endOfBlock = this.TransformBlock(ref reader, partitionInfo, coefficientIndex, transformInfo, plane, blockColumn, blockRow, startX, startY, transformInfo.TransformSize, subX != 0, subY != 0); endOfBlock = this.TransformBlock(ref reader, partitionInfo, coefficientIndex, transformInfo, plane, blockColumn, blockRow, startX, startY, transformInfo.Size, subX != 0, subY != 0);
} }
if (endOfBlock != 0) if (endOfBlock != 0)
@ -824,7 +824,7 @@ internal class Av1TileDecoder : IAv1TileDecoder
int above = (aboveWidth >= maxTransformSize.GetWidth()) ? 1 : 0; int above = (aboveWidth >= maxTransformSize.GetWidth()) ? 1 : 0;
int leftHeight = this.leftNeighborContext.LeftTransformHeight[partitionInfo.RowIndex - superblockInfo.Position.Y]; int leftHeight = this.leftNeighborContext.LeftTransformHeight[partitionInfo.RowIndex - superblockInfo.Position.Y];
int left = (leftHeight >= maxTransformSize.GetHeight()) ? 1 : 0; int left = (leftHeight >= maxTransformSize.GetHeight()) ? 1 : 0;
bool hasAbove = partitionInfo.AvailableUp; bool hasAbove = partitionInfo.AvailableAbove;
bool hasLeft = partitionInfo.AvailableLeft; bool hasLeft = partitionInfo.AvailableLeft;
if (hasAbove && hasLeft) if (hasAbove && hasLeft)
@ -902,12 +902,8 @@ internal class Av1TileDecoder : IAv1TileDecoder
{ {
for (int blockColumn = idx; blockColumn < unitWidth; blockColumn += stepColumn) for (int blockColumn = idx; blockColumn < unitWidth; blockColumn += stepColumn)
{ {
this.FrameBuffer.SetTransformY(transformInfoYIndex, new Av1TransformInfo this.FrameBuffer.SetTransformY(transformInfoYIndex, new Av1TransformInfo(
{ transformSize, blockColumn, blockRow));
TransformSize = transformSize,
OffsetX = blockColumn,
OffsetY = blockRow
});
transformInfoYIndex++; transformInfoYIndex++;
lumaTusCount++; lumaTusCount++;
totalLumaTusCount++; totalLumaTusCount++;
@ -931,12 +927,8 @@ internal class Av1TileDecoder : IAv1TileDecoder
{ {
for (int blockColumn = idx; blockColumn < unitWidth; blockColumn += stepColumn) for (int blockColumn = idx; blockColumn < unitWidth; blockColumn += stepColumn)
{ {
this.FrameBuffer.SetTransformUv(transformInfoUvIndex, new Av1TransformInfo this.FrameBuffer.SetTransformUv(transformInfoUvIndex, new Av1TransformInfo(
{ transformSizeUv, blockColumn, blockRow));
TransformSize = transformSizeUv,
OffsetX = blockColumn,
OffsetY = blockRow
});
transformInfoUvIndex++; transformInfoUvIndex++;
chromaTusCount++; chromaTusCount++;
totalChromaTusCount++; totalChromaTusCount++;
@ -1176,12 +1168,12 @@ internal class Av1TileDecoder : IAv1TileDecoder
int prevL = -1; int prevL = -1;
int columnIndex = partitionInfo.ColumnIndex; int columnIndex = partitionInfo.ColumnIndex;
int rowIndex = partitionInfo.RowIndex; int rowIndex = partitionInfo.RowIndex;
if (partitionInfo.AvailableUp && partitionInfo.AvailableLeft) if (partitionInfo.AvailableAbove && partitionInfo.AvailableLeft)
{ {
prevUL = this.GetSegmentId(partitionInfo, rowIndex - 1, columnIndex - 1); prevUL = this.GetSegmentId(partitionInfo, rowIndex - 1, columnIndex - 1);
} }
if (partitionInfo.AvailableUp) if (partitionInfo.AvailableAbove)
{ {
prevU = this.GetSegmentId(partitionInfo, rowIndex - 1, columnIndex); prevU = this.GetSegmentId(partitionInfo, rowIndex - 1, columnIndex);
} }

50
src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TransformInfo.cs

@ -5,28 +5,64 @@ using SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
namespace SixLabors.ImageSharp.Formats.Heif.Av1.Symbol; namespace SixLabors.ImageSharp.Formats.Heif.Av1.Symbol;
/// <summary>
/// Information of a single Transform Block.
/// </summary>
internal class Av1TransformInfo internal class Av1TransformInfo
{ {
public Av1TransformInfo() /// <summary>
/// Initializes a new instance of the <see cref="Av1TransformInfo"/> class.
/// </summary>
public Av1TransformInfo(Av1TransformSize size, int offsetX, int offsetY)
{ {
this.Size = size;
this.OffsetX = offsetX;
this.OffsetY = offsetY;
} }
/// <summary>
/// Initializes a new instance of the <see cref="Av1TransformInfo"/> class.
/// </summary>
/// <param name="originalInfo">The <see cref="Av1TransformInfo"/> to copy the information from.</param>
public Av1TransformInfo(Av1TransformInfo originalInfo) public Av1TransformInfo(Av1TransformInfo originalInfo)
{ {
this.TransformSize = originalInfo.TransformSize; this.Size = originalInfo.Size;
this.OffsetX = originalInfo.OffsetX; this.OffsetX = originalInfo.OffsetX;
this.OffsetY = originalInfo.OffsetY; this.OffsetY = originalInfo.OffsetY;
} }
public Av1TransformSize TransformSize { get; internal set; } /// <summary>
/// Gets or sets the transform size to be used for this Transform Block.
/// </summary>
public Av1TransformSize Size { get; internal set; }
/// <summary>
/// Gets or sets the transform type to be used for this Transform Block.
/// </summary>
public Av1TransformType Type { get; internal set; }
/// <summary>
/// Gets or sets the X offset of this block in ModeInfo units.
/// </summary>
public int OffsetX { get; internal set; } public int OffsetX { get; internal set; }
/// <summary>
/// Gets or sets the Y offset of this block in ModeInfo units.
/// </summary>
public int OffsetY { get; internal set; } public int OffsetY { get; internal set; }
/// <summary>
/// Gets or sets a value indicating whether the Code block flag is set.
/// <list type="table">
/// <item>
/// <term>false</term>
/// <description>No residual for the block</description>
/// </item>
/// <item>
/// <term>true</term>
/// <description>Residual exists for the block</description>
/// </item>
/// </list>
/// </summary>
public bool CodeBlockFlag { get; internal set; } public bool CodeBlockFlag { get; internal set; }
public int TransformOffsetX { get; internal set; }
public int TransformOffsetY { get; internal set; }
} }

2
tests/ImageSharp.Tests/Formats/Heif/Av1/Av1TilingTests.cs

@ -10,7 +10,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Heif.Av1;
[Trait("Format", "Avif")] [Trait("Format", "Avif")]
public class Av1TilingTests public class Av1TilingTests
{ {
// [Theory] [Theory]
[InlineData(TestImages.Heif.XnConvert, 0x010E, 0x03CC, 18, 0x03CC - 18)] [InlineData(TestImages.Heif.XnConvert, 0x010E, 0x03CC, 18, 0x03CC - 18)]
public void ReadFirstTile(string filename, int headerOffset, int headerSize, int tileOffset, int tileSize) public void ReadFirstTile(string filename, int headerOffset, int headerSize, int tileOffset, int tileSize)
{ {

Loading…
Cancel
Save