diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1SymbolDecoder.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1SymbolDecoder.cs index dde2e72e48..09afb9b752 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1SymbolDecoder.cs +++ b/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 @@ 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]); } diff --git a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileDecoder.cs b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileDecoder.cs index 49f2cbd050..569f633b10 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileDecoder.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Tiling/Av1TileDecoder.cs @@ -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); @@ -1525,19 +1529,19 @@ private void PaletteModeInfo(ref Av1SymbolDecoder reader, Av1PartitionInfo parti /// 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; } diff --git a/tests/ImageSharp.Tests/Formats/Heif/Av1/Av1BitStreamTests.cs b/tests/ImageSharp.Tests/Formats/Heif/Av1/Av1BitStreamTests.cs index ce51300f24..ec9d1114da 100644 --- a/tests/ImageSharp.Tests/Formats/Heif/Av1/Av1BitStreamTests.cs +++ b/tests/ImageSharp.Tests/Formats/Heif/Av1/Av1BitStreamTests.cs @@ -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;