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 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[] 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 tileIntraBlockCopy = Av1DefaultDistributions.IntraBlockCopy;
private readonly Av1Distribution[] tilePartitionTypes = Av1DefaultDistributions.PartitionTypes; private readonly Av1Distribution[] tilePartitionTypes = Av1DefaultDistributions.PartitionTypes;
@ -244,17 +245,17 @@ internal ref struct Av1SymbolDecoder
return r.ReadSymbol(this.chromeForLumaSign); return r.ReadSymbol(this.chromeForLumaSign);
} }
public int ReadChromaFromLumaAlphaU(int jointSign) public int ReadChromaFromLumaAlphaU(int jointSignPlus1)
{ {
ref Av1SymbolReader r = ref this.reader; ref Av1SymbolReader r = ref this.reader;
int context = jointSign + 1 - 3; int context = jointSignPlus1 - 3;
return r.ReadSymbol(this.chromeForLumaAlpha[context]); return r.ReadSymbol(this.chromeForLumaAlpha[context]);
} }
public int ReadChromaFromLumaAlphaV(int jointSign) public int ReadChromaFromLumaAlphaV(int jointSignPlus1)
{ {
ref Av1SymbolReader r = ref this.reader; 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]); 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; int quarterBlock4x4Size = halfBlock4x4Size >> 1;
bool hasRows = (modeInfoLocation.Y + halfBlock4x4Size) < this.FrameInfo.ModeInfoRowCount; bool hasRows = (modeInfoLocation.Y + halfBlock4x4Size) < this.FrameInfo.ModeInfoRowCount;
bool hasColumns = (modeInfoLocation.X + halfBlock4x4Size) < this.FrameInfo.ModeInfoColumnCount; bool hasColumns = (modeInfoLocation.X + halfBlock4x4Size) < this.FrameInfo.ModeInfoColumnCount;
int ctx = this.GetPartitionPlaneContext(modeInfoLocation, blockSize, tileInfo, superblockInfo); Av1PartitionType partitionType = Av1PartitionType.None;
Av1PartitionType partitionType = Av1PartitionType.Split; if (blockSize >= Av1BlockSize.Block8x8)
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); int ctx = this.GetPartitionPlaneContext(modeInfoLocation, blockSize, tileInfo, superblockInfo);
partitionType = splitOrHorizontal ? Av1PartitionType.Split : Av1PartitionType.Vertical; 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); Av1BlockSize subSize = partitionType.GetBlockSubSize(blockSize);
@ -1525,19 +1529,19 @@ internal class Av1TileDecoder : IAv1TileDecoder
/// </summary> /// </summary>
private static void ReadChromaFromLumaAlphas(ref Av1SymbolDecoder reader, Av1BlockModeInfo modeInfo) private static void ReadChromaFromLumaAlphas(ref Av1SymbolDecoder reader, Av1BlockModeInfo modeInfo)
{ {
int jointSign = reader.ReadChromFromLumaSign(); int jointSignPlus1 = reader.ReadChromFromLumaSign() + 1;
int index = 0; 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; modeInfo.ChromaFromLumaAlphaIndex = index;
} }

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

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

Loading…
Cancel
Save