Browse Source

Fill some more data structures

pull/2633/head
Ynse Hoornenborg 2 years ago
parent
commit
682b05c5d0
  1. 15
      src/ImageSharp/Formats/Heif/Av1/Av1Constants.cs
  2. 33
      src/ImageSharp/Formats/Heif/Av1/Tiling/Av1BlockGeometry.cs
  3. 11
      src/ImageSharp/Formats/Heif/Av1/Tiling/Av1BlockStruct.cs
  4. 4
      src/ImageSharp/Formats/Heif/Av1/Tiling/Av1EntropyCodingContext.cs
  5. 17
      src/ImageSharp/Formats/Heif/Av1/Tiling/Av1MacroBlockD.cs
  6. 163
      src/ImageSharp/Formats/Heif/Av1/Tiling/Av1NeighborArrayUnit.cs
  7. 2
      src/ImageSharp/Formats/Heif/Av1/Tiling/Av1PictureParentControlSet.cs
  8. 13
      src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TransformUnit.cs

15
src/ImageSharp/Formats/Heif/Av1/Av1Constants.cs

@ -2,6 +2,7 @@
// Licensed under the Six Labors Split License.
using SixLabors.ImageSharp.Formats.Heif.Av1.OpenBitstreamUnit;
using SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
namespace SixLabors.ImageSharp.Formats.Heif.Av1;
@ -187,4 +188,18 @@ internal static class Av1Constants
// Number of transform sizes that use extended transforms.
public const int ExtendedTransformCount = 4;
public const int MaxVarTransform = 2;
/// <summary>
/// Maximum number of transform blocks per depth
/// </summary>
public const int MaxTransformBlockCount = 16;
/// <summary>
/// Number of items in the <see cref="Av1PlaneType"/> enumeration.
/// </summary>
public const int PlaneTypeCount = 2;
public const int MaxTransformUnitCount = 16;
}

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

@ -9,16 +9,47 @@ internal partial class Av1TileWriter
{
internal class Av1BlockGeometry
{
public Av1BlockGeometry()
{
this.TransformOrigin = new Point[Av1Constants.MaxVarTransform + 1][];
for (int i = 0; i < this.TransformOrigin.Length; i++)
{
this.TransformOrigin[i] = new Point[Av1Constants.MaxTransformBlockCount];
}
}
public Av1BlockSize BlockSize { get; internal set; }
public Av1BlockSize BlockSizeUv { get; internal set; }
/// <summary>
/// Gets or sets the Origin point from lop left of the superblock.
/// </summary>
public Point Origin { get; internal set; }
public bool HasUv { get; internal set; }
/// <summary>
/// Gets or sets the blocks width.
/// </summary>
public int BlockWidth { get; internal set; }
/// <summary>
/// Gets or sets the blocks height.
/// </summary>
public int BlockHeight { get; internal set; }
public required Av1TransformSize[] TransformSize { get; internal set; }
public int[] TransformBlockCount { get; } = new int[Av1Constants.MaxVarTransform + 1];
public Av1TransformSize[] TransformSize { get; } = new Av1TransformSize[Av1Constants.MaxVarTransform + 1];
public Av1TransformSize[] TransformSizeUv { get; } = new Av1TransformSize[Av1Constants.MaxVarTransform + 1];
public Point[][] TransformOrigin { get; private set; }
/// <summary>
/// Gets or sets the block index in md scan.
/// </summary>
public int BlockIndex { get; set; }
}
}

11
src/ImageSharp/Formats/Heif/Av1/Tiling/Av1BlockStruct.cs

@ -5,4 +5,15 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
internal class Av1BlockStruct
{
public Av1TransformUnit[] TransformBlocks { get; } = new Av1TransformUnit[Av1Constants.MaxTransformUnitCount];
public required Av1MacroBlockD av1xd { get; set; }
public int MdScanIndex { get; set; }
public int QIndex { get; set; }
public int SegmentId { get; set; }
public Av1FilterIntraMode FilterIntraMode { get; set; }
}

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

@ -10,5 +10,9 @@ internal partial class Av1TileWriter
public required Av1MacroBlockModeInfo MacroBlockModeInfo { get; internal set; }
public Point SuperblockOrigin { get; internal set; }
public int CodedAreaSuperblock { get; internal set; }
public int CodedAreaSuperblockUv { get; internal set; }
}
}

17
src/ImageSharp/Formats/Heif/Av1/Tiling/Av1MacroBlockD.cs

@ -3,20 +3,17 @@
namespace SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
internal partial class Av1TileWriter
internal class Av1MacroBlockD
{
internal class Av1MacroBlockD
{
public required Av1BlockModeInfo ModeInfo { get; internal set; }
public required Av1BlockModeInfo ModeInfo { get; internal set; }
public required Av1TileInfo Tile { get; internal set; }
public required Av1TileInfo Tile { get; internal set; }
public bool IsUpAvailable { get; }
public bool IsUpAvailable { get; }
public bool IsLeftAvailable { get; }
public bool IsLeftAvailable { get; }
public Av1MacroBlockModeInfo? AboveMacroBlock { get; internal set; }
public Av1MacroBlockModeInfo? AboveMacroBlock { get; internal set; }
public Av1MacroBlockModeInfo? LeftMacroBlock { get; internal set; }
}
public Av1MacroBlockModeInfo? LeftMacroBlock { get; internal set; }
}

163
src/ImageSharp/Formats/Heif/Av1/Tiling/Av1NeighborArrayUnit.cs

@ -1,11 +1,168 @@
// Copyright (c) Six Labors.
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Numerics;
using System.Runtime.CompilerServices;
namespace SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
internal partial class Av1TileWriter
internal class Av1NeighborArrayUnit<T>
where T : struct, IMinMaxValue<T>
{
internal class Av1NeighborArrayUnit
public static readonly T InvalidNeighborData = T.MaxValue;
[Flags]
public enum UnitMask
{
Left = 1,
Top = 2,
TopLeft = 4,
}
private readonly T[] left;
private readonly T[] top;
private readonly T[] topLeft;
public Av1NeighborArrayUnit(int leftSize, int topSize, int topLeftSize)
{
this.left = new T[leftSize];
this.top = new T[topSize];
this.topLeft = new T[topLeftSize];
}
public Span<T> Left => this.left;
public Span<T> Top => this.top;
public Span<T> TopLeft => this.topLeft;
public required int GranularityNormalLog2 { get; set; }
public required int GranularityTopLeftLog2 { get; set; }
public int UnitSize { get; private set; }
public int GetLeftIndex(Point loc) => loc.Y >> this.GranularityNormalLog2;
public int GetTopIndex(Point loc) => loc.X >> this.GranularityNormalLog2;
public int GetTopLeftIndex(Point loc)
=> this.left.Length + (loc.X >> this.GranularityTopLeftLog2) - (loc.Y >> this.GranularityTopLeftLog2);
public void UnitModeWrite(Span<T> value, Point origin, Size blockSize, UnitMask mask)
{
int idx, j;
int count;
int na_offset;
int na_unit_size;
na_unit_size = this.UnitSize;
if ((mask & UnitMask.Top) == UnitMask.Top)
{
// Top Neighbor Array
// ----------12345678---------------------
// ^ ^
// | |
// | |
// xxxxxxxx
// x x
// x x
// 12345678
//
// The top neighbor array is updated with the samples from the
// bottom row of the source block
//
// Index = org_x
na_offset = this.GetTopIndex(origin);
ref T dst_ptr = ref this.Top[na_offset * na_unit_size];
count = blockSize.Width >> this.GranularityNormalLog2;
for (idx = 0; idx < count; ++idx)
{
/* svt_memcpy less that 10 bytes*/
for (j = 0; j < na_unit_size; ++j)
{
dst_ptr = value[j];
dst_ptr = Unsafe.Add(ref dst_ptr, 1);
}
}
}
if ((mask & UnitMask.Left) == UnitMask.Left)
{
// Left Neighbor Array
//
// |
// |
// 1 xxxxxxx1
// 2 <---- x 2
// 3 <---- x 3
// 4 xxxxxxx4
// |
// |
//
// The left neighbor array is updated with the samples from the
// right column of the source block
//
// Index = org_y
na_offset = this.GetLeftIndex(origin);
ref T dst_ptr = ref this.Left[na_offset * na_unit_size];
count = blockSize.Height >> this.GranularityNormalLog2;
for (idx = 0; idx < count; ++idx)
{
/* svt_memcpy less that 10 bytes*/
for (j = 0; j < na_unit_size; ++j)
{
dst_ptr = value[j];
dst_ptr = Unsafe.Add(ref dst_ptr, 1);
}
}
}
if ((mask & UnitMask.TopLeft) == UnitMask.TopLeft)
{
// Top-left Neighbor Array
//
// 4-5--6--7------------
// 3 \ \
// 2 \ \
// 1 \ \
// |\ xxxxxx7
// | \ x 6
// | \ x 5
// | \1x2x3x4
// |
//
// The top-left neighbor array is updated with the reversed samples
// from the right column and bottom row of the source block
//
// Index = org_x - org_y
Point topLeft = origin;
topLeft.Offset(0, blockSize.Height - 1);
na_offset = this.GetTopLeftIndex(topLeft);
// Copy bottom-row + right-column
// *Note - start from the bottom-left corner
ref T dst_ptr = ref this.TopLeft[na_offset * na_unit_size];
count = ((blockSize.Width + blockSize.Height) >> this.GranularityTopLeftLog2) - 1;
for (idx = 0; idx < count; ++idx)
{
/* svt_memcpy less that 10 bytes*/
for (j = 0; j < na_unit_size; ++j)
{
dst_ptr = value[j];
dst_ptr = Unsafe.Add(ref dst_ptr, 1);
}
}
}
}
}

2
src/ImageSharp/Formats/Heif/Av1/Tiling/Av1PictureParentControlSet.cs

@ -16,5 +16,7 @@ internal partial class Av1TileWriter
public required int[] PreviousQIndex { get; internal set; }
public int PaletteLevel { get; internal set; }
public int AlignedWidth { get; internal set; }
public int AlignedHeight { get; internal set; }
}
}

13
src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TransformUnit.cs

@ -0,0 +1,13 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using SixLabors.ImageSharp.Formats.Heif.Av1.Transform;
namespace SixLabors.ImageSharp.Formats.Heif.Av1.Tiling;
internal class Av1TransformUnit
{
public ushort[] NzCoefficientCount { get; } = new ushort[3];
public Av1TransformType[] TransformType { get; } = new Av1TransformType[Av1Constants.PlaneTypeCount];
}
Loading…
Cancel
Save