Skip to content

Commit

Permalink
Misc tile parsing fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
ynse01 committed Jul 21, 2024
1 parent 22b7c72 commit 4323205
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 33 deletions.
9 changes: 5 additions & 4 deletions src/ImageSharp/Formats/Heif/Av1/Tiling/Av1SymbolDecoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -244,17 +245,17 @@ public int ReadChromFromLumaSign()
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]);
}

Expand Down
52 changes: 28 additions & 24 deletions src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileDecoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -154,25 +154,29 @@ private void ParsePartition(ref Av1SymbolDecoder reader, Point modeInfoLocation,
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);
Expand Down Expand Up @@ -1525,19 +1529,19 @@ private void PaletteModeInfo(ref Av1SymbolDecoder reader, Av1PartitionInfo parti
/// </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;
}

Expand Down
11 changes: 6 additions & 5 deletions tests/ImageSharp.Tests/Formats/Heif/Av1/Av1BitStreamTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,12 @@ public void ReadLiteral32BitsWithMsbSet()
{
// 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;
Expand Down

0 comments on commit 4323205

Please sign in to comment.