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
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

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

@ -61,9 +61,6 @@ internal class Av1FrameBuffer
this.superblockInfos[i] = new(this, point);
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++)
{
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.SuperblockInfo = superblockInfo;
this.IsChroma = isChroma;
this.PartitionType = partitionType;
this.Type = partitionType;
this.CdefStrength = [];
this.ReferenceFrame = [-1, -1];
}
public Av1BlockModeInfo ModeInfo { get; }
/// <summary>
/// Gets the <see cref="Av1SuperblockInfo"/> this partition resides inside.
/// </summary>
public Av1SuperblockInfo SuperblockInfo { 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 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; }
/// <summary>
/// Gets or sets the horizontal location of the block in units of 4x4 luma samples.
/// </summary>
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 Av1BlockModeInfo? AboveModeInfo { get; set; }
@ -59,9 +80,9 @@ internal class Av1PartitionInfo
Av1BlockSize blockSize = this.ModeInfo.BlockSize;
int bw4 = blockSize.Get4x4WideCount();
int bh4 = blockSize.Get4x4HighCount();
this.AvailableUp = this.RowIndex > tileInfo.ModeInfoRowStart;
this.AvailableAbove = this.RowIndex > tileInfo.ModeInfoRowStart;
this.AvailableLeft = this.ColumnIndex > tileInfo.ModeInfoColumnStart;
this.AvailableUpForChroma = this.AvailableUp;
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;

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

@ -346,7 +346,7 @@ internal class Av1TileDecoder : IAv1TileDecoder
{
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)
@ -355,7 +355,7 @@ internal class Av1TileDecoder : IAv1TileDecoder
}
}
if (partitionInfo.AvailableUp)
if (partitionInfo.AvailableAbove)
{
partitionInfo.AboveModeInfo = superblockInfo.GetModeInfo(new Point(rowIndex - 1, columnIndex));
}
@ -456,8 +456,8 @@ internal class Av1TileDecoder : IAv1TileDecoder
int coefficientIndex = this.coefficientIndex[plane];
int endOfBlock = 0;
Av1TransformInfo transformInfo = this.FrameBuffer.GetTransform(plane, transformInfoIndices[plane])!;
int blockColumn = transformInfo.TransformOffsetX;
int blockRow = transformInfo.TransformOffsetY;
int blockColumn = transformInfo.OffsetX;
int blockRow = transformInfo.OffsetY;
int startX = (partitionInfo.ColumnIndex >> subX) + blockColumn;
int startY = (partitionInfo.RowIndex >> subY) + blockRow;
@ -469,7 +469,7 @@ internal class Av1TileDecoder : IAv1TileDecoder
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)
@ -824,7 +824,7 @@ internal class Av1TileDecoder : IAv1TileDecoder
int above = (aboveWidth >= maxTransformSize.GetWidth()) ? 1 : 0;
int leftHeight = this.leftNeighborContext.LeftTransformHeight[partitionInfo.RowIndex - superblockInfo.Position.Y];
int left = (leftHeight >= maxTransformSize.GetHeight()) ? 1 : 0;
bool hasAbove = partitionInfo.AvailableUp;
bool hasAbove = partitionInfo.AvailableAbove;
bool hasLeft = partitionInfo.AvailableLeft;
if (hasAbove && hasLeft)
@ -902,12 +902,8 @@ internal class Av1TileDecoder : IAv1TileDecoder
{
for (int blockColumn = idx; blockColumn < unitWidth; blockColumn += stepColumn)
{
this.FrameBuffer.SetTransformY(transformInfoYIndex, new Av1TransformInfo
{
TransformSize = transformSize,
OffsetX = blockColumn,
OffsetY = blockRow
});
this.FrameBuffer.SetTransformY(transformInfoYIndex, new Av1TransformInfo(
transformSize, blockColumn, blockRow));
transformInfoYIndex++;
lumaTusCount++;
totalLumaTusCount++;
@ -931,12 +927,8 @@ internal class Av1TileDecoder : IAv1TileDecoder
{
for (int blockColumn = idx; blockColumn < unitWidth; blockColumn += stepColumn)
{
this.FrameBuffer.SetTransformUv(transformInfoUvIndex, new Av1TransformInfo
{
TransformSize = transformSizeUv,
OffsetX = blockColumn,
OffsetY = blockRow
});
this.FrameBuffer.SetTransformUv(transformInfoUvIndex, new Av1TransformInfo(
transformSizeUv, blockColumn, blockRow));
transformInfoUvIndex++;
chromaTusCount++;
totalChromaTusCount++;
@ -1176,12 +1168,12 @@ internal class Av1TileDecoder : IAv1TileDecoder
int prevL = -1;
int columnIndex = partitionInfo.ColumnIndex;
int rowIndex = partitionInfo.RowIndex;
if (partitionInfo.AvailableUp && partitionInfo.AvailableLeft)
if (partitionInfo.AvailableAbove && partitionInfo.AvailableLeft)
{
prevUL = this.GetSegmentId(partitionInfo, rowIndex - 1, columnIndex - 1);
}
if (partitionInfo.AvailableUp)
if (partitionInfo.AvailableAbove)
{
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;
/// <summary>
/// Information of a single Transform Block.
/// </summary>
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)
{
this.TransformSize = originalInfo.TransformSize;
this.Size = originalInfo.Size;
this.OffsetX = originalInfo.OffsetX;
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; }
/// <summary>
/// Gets or sets the Y offset of this block in ModeInfo units.
/// </summary>
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 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")]
public class Av1TilingTests
{
// [Theory]
[Theory]
[InlineData(TestImages.Heif.XnConvert, 0x010E, 0x03CC, 18, 0x03CC - 18)]
public void ReadFirstTile(string filename, int headerOffset, int headerSize, int tileOffset, int tileSize)
{

Loading…
Cancel
Save