diff --git a/src/ImageSharp/Formats/Heif/Av1/Av1BitStreamReader.cs b/src/ImageSharp/Formats/Heif/Av1/Av1BitStreamReader.cs index f4a1af2b7..8e034da35 100644 --- a/src/ImageSharp/Formats/Heif/Av1/Av1BitStreamReader.cs +++ b/src/ImageSharp/Formats/Heif/Av1/Av1BitStreamReader.cs @@ -70,8 +70,14 @@ internal ref struct Av1BitStreamReader { // See section 4.10.3 of the AV1-Specification int leadingZerosCount = 0; - while (leadingZerosCount < 32 && !this.ReadBoolean()) + while (leadingZerosCount < 32) { + uint bit = this.ReadLiteral(1); + if (bit == 1) + { + break; + } + leadingZerosCount++; } @@ -80,9 +86,14 @@ internal ref struct Av1BitStreamReader return uint.MaxValue; } - uint basis = (1U << leadingZerosCount) - 1U; - uint value = this.ReadLiteral(leadingZerosCount); - return basis + value; + if (leadingZerosCount != 0) + { + uint basis = (1U << leadingZerosCount) - 1U; + uint value = this.ReadLiteral(leadingZerosCount); + return basis + value; + } + + return 0; } public uint ReadNonSymmetric(uint n) diff --git a/tests/ImageSharp.Tests/Formats/Heif/Av1/Av1BitStreamTests.cs b/tests/ImageSharp.Tests/Formats/Heif/Av1/Av1BitStreamTests.cs index 0f91bd4c9..5cfe0acac 100644 --- a/tests/ImageSharp.Tests/Formats/Heif/Av1/Av1BitStreamTests.cs +++ b/tests/ImageSharp.Tests/Formats/Heif/Av1/Av1BitStreamTests.cs @@ -267,6 +267,23 @@ public class Av1BitStreamTests Assert.Equal(expected, actual); } + [Theory] + [InlineData(new byte[] { 0x80 }, 0)] // Zero bit value. + [InlineData(new byte[] { 0x60 }, 2)] // One bit value, 011. + [InlineData(new byte[] { 0x38 }, 6)] // Two bit value, 00111. + [InlineData(new byte[] { 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE }, uint.MaxValue - 1)] // 31 bit value. + public void ReadUnsignedVariableLength(byte[] buffer, uint expected) + { + // arrange + Av1BitStreamReader reader = new(buffer); + + // act + uint actual = reader.ReadUnsignedVariableLength(); + + // assert + Assert.Equal(expected, actual); + } + [Theory] [InlineData(5, 6, 4, -7, -2)] [InlineData(7, 26, -8, -19, -26)]