Browse Source

Creator of IAv1TileReader

pull/2633/head
Ynse Hoornenborg 2 years ago
parent
commit
b4f3fe3a19
  1. 2
      src/ImageSharp/Formats/Heif/Av1/Av1Decoder.cs
  2. 7
      src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuReader.cs
  3. 2
      src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ParseLeftNeighbor4x4Context.cs
  4. 24
      tests/ImageSharp.Tests/Formats/Heif/Av1/Av1TilingTests.cs
  5. 14
      tests/ImageSharp.Tests/Formats/Heif/Av1/ObuFrameHeaderTests.cs

2
src/ImageSharp/Formats/Heif/Av1/Av1Decoder.cs

@ -31,7 +31,7 @@ internal class Av1Decoder : IAv1TileReader
public void Decode(Span<byte> buffer) public void Decode(Span<byte> buffer)
{ {
Av1BitStreamReader reader = new(buffer); Av1BitStreamReader reader = new(buffer);
this.obuReader.ReadAll(ref reader, buffer.Length, this, false); this.obuReader.ReadAll(ref reader, buffer.Length, () => this, false);
Guard.NotNull(this.tileReader, nameof(this.tileReader)); Guard.NotNull(this.tileReader, nameof(this.tileReader));
Guard.NotNull(this.SequenceHeader, nameof(this.SequenceHeader)); Guard.NotNull(this.SequenceHeader, nameof(this.SequenceHeader));
Guard.NotNull(this.FrameHeader, nameof(this.FrameHeader)); Guard.NotNull(this.FrameHeader, nameof(this.FrameHeader));

7
src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuReader.cs

@ -39,6 +39,8 @@ internal class ObuReader
private static readonly int[] SegmentationFeatureMax = [255, MaxLoopFilter, MaxLoopFilter, MaxLoopFilter, MaxLoopFilter, 7, 0, 0]; private static readonly int[] SegmentationFeatureMax = [255, MaxLoopFilter, MaxLoopFilter, MaxLoopFilter, MaxLoopFilter, 7, 0, 0];
private IAv1TileReader? decoder;
public ObuSequenceHeader? SequenceHeader { get; set; } public ObuSequenceHeader? SequenceHeader { get; set; }
public ObuFrameHeader? FrameHeader { get; set; } public ObuFrameHeader? FrameHeader { get; set; }
@ -46,7 +48,7 @@ internal class ObuReader
/// <summary> /// <summary>
/// Decode all OBU's in a frame. /// Decode all OBU's in a frame.
/// </summary> /// </summary>
public void ReadAll(ref Av1BitStreamReader reader, int dataSize, IAv1TileReader decoder, bool isAnnexB = false) public void ReadAll(ref Av1BitStreamReader reader, int dataSize, Func<IAv1TileReader> creator, bool isAnnexB = false)
{ {
bool seenFrameHeader = false; bool seenFrameHeader = false;
bool frameDecodingFinished = false; bool frameDecodingFinished = false;
@ -121,7 +123,8 @@ internal class ObuReader
throw new InvalidImageContentException("Corrupt frame"); throw new InvalidImageContentException("Corrupt frame");
} }
this.ReadTileGroup(ref reader, decoder, header, out frameDecodingFinished); this.decoder ??= creator();
this.ReadTileGroup(ref reader, this.decoder, header, out frameDecodingFinished);
if (frameDecodingFinished) if (frameDecodingFinished)
{ {
seenFrameHeader = false; seenFrameHeader = false;

2
src/ImageSharp/Formats/Heif/Av1/Tiling/Av1ParseLeftNeighbor4x4Context.cs

@ -69,7 +69,7 @@ internal class Av1ParseLeftNeighbor4x4Context
int startIndex = (modeInfoLocation.Y - superblockInfo.ModeInfoPosition.Y) & Av1PartitionContext.Mask; int startIndex = (modeInfoLocation.Y - superblockInfo.ModeInfoPosition.Y) & Av1PartitionContext.Mask;
int bh = blockSize.Get4x4HighCount(); int bh = blockSize.Get4x4HighCount();
int value = Av1PartitionContext.GetLeftContext(subSize); int value = Av1PartitionContext.GetLeftContext(subSize);
DebugGuard.MustBeLessThanOrEqualTo(startIndex, this.LeftTransformHeight.Length - bh, nameof(startIndex)); DebugGuard.MustBeLessThanOrEqualTo(startIndex, this.LeftPartitionHeight.Length - bh, nameof(startIndex));
Array.Fill(this.LeftPartitionHeight, value, startIndex, bh); Array.Fill(this.LeftPartitionHeight, value, startIndex, bh);
} }

24
tests/ImageSharp.Tests/Formats/Heif/Av1/Av1TilingTests.cs

@ -23,7 +23,7 @@ public class Av1TilingTests
Av1BitStreamReader bitStreamReader = new(headerSpan); Av1BitStreamReader bitStreamReader = new(headerSpan);
IAv1TileReader stub = new Av1TileDecoderStub(); IAv1TileReader stub = new Av1TileDecoderStub();
ObuReader obuReader = new(); ObuReader obuReader = new();
obuReader.ReadAll(ref bitStreamReader, dataSize, stub); obuReader.ReadAll(ref bitStreamReader, dataSize, () => stub);
Av1FrameBuffer frameBuffer = new(Configuration.Default, obuReader.SequenceHeader, Av1ColorFormat.Yuv444, false); Av1FrameBuffer frameBuffer = new(Configuration.Default, obuReader.SequenceHeader, Av1ColorFormat.Yuv444, false);
Av1FrameInfo frameInfo = new(obuReader.SequenceHeader); Av1FrameInfo frameInfo = new(obuReader.SequenceHeader);
Av1FrameDecoderStub frameDecoder = new(); Av1FrameDecoderStub frameDecoder = new();
@ -36,4 +36,26 @@ public class Av1TilingTests
Assert.Equal(dataSize * 8, bitStreamReader.BitPosition); Assert.Equal(dataSize * 8, bitStreamReader.BitPosition);
Assert.Equal(superblockCount, frameDecoder.SuperblockCount); Assert.Equal(superblockCount, frameDecoder.SuperblockCount);
} }
[Theory]
// [InlineData(TestImages.Heif.XnConvert, 0x010E, 0x03CC, 18, 16)]
[InlineData(TestImages.Heif.Orange4x4, 0x010E, 0x001d, 21, 1)]
public void DecodeFirstTile(string filename, int dataOffset, int dataSize, int tileOffset, int superblockCount)
{
// Assign
string filePath = Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, filename);
byte[] content = File.ReadAllBytes(filePath);
Span<byte> headerSpan = content.AsSpan(dataOffset, dataSize);
Span<byte> tileSpan = content.AsSpan(tileOffset, dataSize - tileOffset);
Av1BitStreamReader bitStreamReader = new(headerSpan);
ObuReader obuReader = new();
Av1FrameDecoderStub frameDecoder = new();
// Act
obuReader.ReadAll(ref bitStreamReader, dataSize, () => new Av1TileReader(Configuration.Default, obuReader.SequenceHeader, obuReader.FrameHeader, frameDecoder));
// Assert
Assert.Equal(dataSize * 8, bitStreamReader.BitPosition);
Assert.Equal(superblockCount, frameDecoder.SuperblockCount);
}
} }

14
tests/ImageSharp.Tests/Formats/Heif/Av1/ObuFrameHeaderTests.cs

@ -39,7 +39,7 @@ public class ObuFrameHeaderTests
ObuReader obuReader = new(); ObuReader obuReader = new();
// Act // Act
obuReader.ReadAll(ref reader, blockSize, decoder); obuReader.ReadAll(ref reader, blockSize, () => decoder);
// Assert // Assert
Assert.NotNull(obuReader.SequenceHeader); Assert.NotNull(obuReader.SequenceHeader);
@ -63,7 +63,7 @@ public class ObuFrameHeaderTests
ObuReader obuReader = new(); ObuReader obuReader = new();
// Act 1 // Act 1
obuReader.ReadAll(ref reader, blockSize, tileStub); obuReader.ReadAll(ref reader, blockSize, () => tileStub);
// Assign 2 // Assign 2
MemoryStream encoded = new(); MemoryStream encoded = new();
@ -91,7 +91,7 @@ public class ObuFrameHeaderTests
ObuReader obuReader1 = new(); ObuReader obuReader1 = new();
// Act 1 // Act 1
obuReader1.ReadAll(ref reader, blockSize, tileStub); obuReader1.ReadAll(ref reader, blockSize, () => tileStub);
// Assign 2 // Assign 2
MemoryStream encoded = new(); MemoryStream encoded = new();
@ -107,7 +107,7 @@ public class ObuFrameHeaderTests
ObuReader obuReader2 = new(); ObuReader obuReader2 = new();
// Act 2 // Act 2
obuReader2.ReadAll(ref reader2, encodedBuffer.Length, tileDecoder2); obuReader2.ReadAll(ref reader2, encodedBuffer.Length, () => tileDecoder2);
// Assert // Assert
Assert.Equal(ObuPrettyPrint.PrettyPrintProperties(obuReader1.SequenceHeader.ColorConfig), ObuPrettyPrint.PrettyPrintProperties(obuReader2.SequenceHeader.ColorConfig)); Assert.Equal(ObuPrettyPrint.PrettyPrintProperties(obuReader1.SequenceHeader.ColorConfig), ObuPrettyPrint.PrettyPrintProperties(obuReader2.SequenceHeader.ColorConfig));
@ -125,7 +125,7 @@ public class ObuFrameHeaderTests
IAv1TileReader tileDecoder = new Av1TileDecoderStub(); IAv1TileReader tileDecoder = new Av1TileDecoderStub();
// Act // Act
obuReader.ReadAll(ref reader, DefaultTemporalDelimiterBitStream.Length, tileDecoder); obuReader.ReadAll(ref reader, DefaultTemporalDelimiterBitStream.Length, () => tileDecoder);
// Assert // Assert
Assert.Null(obuReader.SequenceHeader); Assert.Null(obuReader.SequenceHeader);
@ -142,7 +142,7 @@ public class ObuFrameHeaderTests
IAv1TileReader tileDecoder = new Av1TileDecoderStub(); IAv1TileReader tileDecoder = new Av1TileDecoderStub();
// Act // Act
obuReader.ReadAll(ref reader, bitStream.Length, tileDecoder); obuReader.ReadAll(ref reader, bitStream.Length, () => tileDecoder);
// Assert // Assert
Assert.Null(obuReader.SequenceHeader); Assert.Null(obuReader.SequenceHeader);
@ -160,7 +160,7 @@ public class ObuFrameHeaderTests
ObuSequenceHeader expected = GetDefaultSequenceHeader(); ObuSequenceHeader expected = GetDefaultSequenceHeader();
// Act // Act
obuReader.ReadAll(ref reader, bitStream.Length, tileDecoder); obuReader.ReadAll(ref reader, bitStream.Length, () => tileDecoder);
// Assert // Assert
Assert.NotNull(obuReader.SequenceHeader); Assert.NotNull(obuReader.SequenceHeader);

Loading…
Cancel
Save