Browse Source

Misc tile parsing fixes

pull/2633/head
Ynse Hoornenborg 2 years ago
parent
commit
43232056c2
  1. 9
      src/ImageSharp/Formats/Heif/Av1/Tiling/Av1SymbolDecoder.cs
  2. 52
      src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileDecoder.cs
  3. 11
      tests/ImageSharp.Tests/Formats/Heif/Av1/Av1BitStreamTests.cs

9
src/ImageSharp/Formats/Heif/Av1/Tiling/Av1SymbolDecoder.cs

@ -9,6 +9,7 @@ namespace SixLabors.ImageSharp.Formats.Heif.Av1.Symbol;
internal ref struct Av1SymbolDecoder
{
private static readonly int[] IntraModeContext = [0, 1, 2, 3, 4, 4, 4, 4, 3, 0, 1, 2, 0];
private static readonly int[] AlphaVContexts = [-1, 0, 3, -1, 1, 4, -1, 2, 5];
private readonly Av1Distribution tileIntraBlockCopy = Av1DefaultDistributions.IntraBlockCopy;
private readonly Av1Distribution[] tilePartitionTypes = Av1DefaultDistributions.PartitionTypes;
@ -244,17 +245,17 @@ internal ref struct Av1SymbolDecoder
return r.ReadSymbol(this.chromeForLumaSign);
}
public int ReadChromaFromLumaAlphaU(int jointSign)
public int ReadChromaFromLumaAlphaU(int jointSignPlus1)
{
ref Av1SymbolReader r = ref this.reader;
int context = jointSign + 1 - 3;
int context = jointSignPlus1 - 3;
return r.ReadSymbol(this.chromeForLumaAlpha[context]);
}
public int ReadChromaFromLumaAlphaV(int jointSign)
public int ReadChromaFromLumaAlphaV(int jointSignPlus1)
{
ref Av1SymbolReader r = ref this.reader;
int context = (((jointSign + 1) % 3) * 3) + ((jointSign + 1) / 3) - 3;
int context = AlphaVContexts[jointSignPlus1];
return r.ReadSymbol(this.chromeForLumaAlpha[context]);
}

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

@ -154,25 +154,29 @@ internal class Av1TileDecoder : IAv1TileDecoder
int quarterBlock4x4Size = halfBlock4x4Size >> 1;
bool hasRows = (modeInfoLocation.Y + halfBlock4x4Size) < this.FrameInfo.ModeInfoRowCount;
bool hasColumns = (modeInfoLocation.X + halfBlock4x4Size) < this.FrameInfo.ModeInfoColumnCount;
int ctx = this.GetPartitionPlaneContext(modeInfoLocation, blockSize, tileInfo, superblockInfo);
Av1PartitionType partitionType = Av1PartitionType.Split;
if (blockSize < Av1BlockSize.Block8x8)
{
partitionType = Av1PartitionType.None;
}
else if (hasRows && hasColumns)
{
partitionType = reader.ReadPartitionType(ctx);
}
else if (hasColumns)
{
bool splitOrVertical = reader.ReadSplitOrVertical(blockSize, ctx);
partitionType = splitOrVertical ? Av1PartitionType.Split : Av1PartitionType.Horizontal;
}
else if (hasRows)
Av1PartitionType partitionType = Av1PartitionType.None;
if (blockSize >= Av1BlockSize.Block8x8)
{
bool splitOrHorizontal = reader.ReadSplitOrHorizontal(blockSize, ctx);
partitionType = splitOrHorizontal ? Av1PartitionType.Split : Av1PartitionType.Vertical;
int ctx = this.GetPartitionPlaneContext(modeInfoLocation, blockSize, tileInfo, superblockInfo);
partitionType = Av1PartitionType.Split;
if (blockSize < Av1BlockSize.Block8x8)
{
partitionType = Av1PartitionType.None;
}
else if (hasRows && hasColumns)
{
partitionType = reader.ReadPartitionType(ctx);
}
else if (hasColumns)
{
bool splitOrVertical = reader.ReadSplitOrVertical(blockSize, ctx);
partitionType = splitOrVertical ? Av1PartitionType.Split : Av1PartitionType.Horizontal;
}
else if (hasRows)
{
bool splitOrHorizontal = reader.ReadSplitOrHorizontal(blockSize, ctx);
partitionType = splitOrHorizontal ? Av1PartitionType.Split : Av1PartitionType.Vertical;
}
}
Av1BlockSize subSize = partitionType.GetBlockSubSize(blockSize);
@ -1525,19 +1529,19 @@ internal class Av1TileDecoder : IAv1TileDecoder
/// </summary>
private static void ReadChromaFromLumaAlphas(ref Av1SymbolDecoder reader, Av1BlockModeInfo modeInfo)
{
int jointSign = reader.ReadChromFromLumaSign();
int jointSignPlus1 = reader.ReadChromFromLumaSign() + 1;
int index = 0;
if (jointSign + 1 != 0)
if (jointSignPlus1 >= 3)
{
index = reader.ReadChromaFromLumaAlphaU(jointSign) << Av1Constants.ChromaFromLumaAlphabetSizeLog2;
index = reader.ReadChromaFromLumaAlphaU(jointSignPlus1) << Av1Constants.ChromaFromLumaAlphabetSizeLog2;
}
if ((jointSign + 1) % 3 != 0)
if (jointSignPlus1 % 3 != 0)
{
index += reader.ReadChromaFromLumaAlphaV(jointSign);
index += reader.ReadChromaFromLumaAlphaV(jointSignPlus1);
}
modeInfo.ChromaFromLumaAlphaSign = jointSign;
modeInfo.ChromaFromLumaAlphaSign = jointSignPlus1 - 1;
modeInfo.ChromaFromLumaAlphaIndex = index;
}

11
tests/ImageSharp.Tests/Formats/Heif/Av1/Av1BitStreamTests.cs

@ -46,11 +46,12 @@ public class Av1BitStreamTests
{
// arrange
// Three 32-bit values with MSB set.
byte[] buffer = {
0xff, 0xff, 0xff, 0xff, // 4294967295
0x80, 0xff, 0xee, 0xdd, // 2164256477
0xa0, 0xaa, 0xbb, 0xcc // 2695543756
};
byte[] buffer =
[
0xff, 0xff, 0xff, 0xff, // 4294967295
0x80, 0xff, 0xee, 0xdd, // 2164256477
0xa0, 0xaa, 0xbb, 0xcc // 2695543756
];
uint expected0 = 4294967295;
uint expected1 = 2164256477;
uint expected2 = 2695543756;

Loading…
Cancel
Save