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)
{
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.SequenceHeader, nameof(this.SequenceHeader));
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 IAv1TileReader? decoder;
public ObuSequenceHeader? SequenceHeader { get; set; }
public ObuFrameHeader? FrameHeader { get; set; }
@ -46,7 +48,7 @@ internal class ObuReader
/// <summary>
/// Decode all OBU's in a frame.
/// </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 frameDecodingFinished = false;
@ -121,7 +123,8 @@ internal class ObuReader
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)
{
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 bh = blockSize.Get4x4HighCount();
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);
}

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

@ -23,7 +23,7 @@ public class Av1TilingTests
Av1BitStreamReader bitStreamReader = new(headerSpan);
IAv1TileReader stub = new Av1TileDecoderStub();
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);
Av1FrameInfo frameInfo = new(obuReader.SequenceHeader);
Av1FrameDecoderStub frameDecoder = new();
@ -36,4 +36,26 @@ public class Av1TilingTests
Assert.Equal(dataSize * 8, bitStreamReader.BitPosition);
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();
// Act
obuReader.ReadAll(ref reader, blockSize, decoder);
obuReader.ReadAll(ref reader, blockSize, () => decoder);
// Assert
Assert.NotNull(obuReader.SequenceHeader);
@ -63,7 +63,7 @@ public class ObuFrameHeaderTests
ObuReader obuReader = new();
// Act 1
obuReader.ReadAll(ref reader, blockSize, tileStub);
obuReader.ReadAll(ref reader, blockSize, () => tileStub);
// Assign 2
MemoryStream encoded = new();
@ -91,7 +91,7 @@ public class ObuFrameHeaderTests
ObuReader obuReader1 = new();
// Act 1
obuReader1.ReadAll(ref reader, blockSize, tileStub);
obuReader1.ReadAll(ref reader, blockSize, () => tileStub);
// Assign 2
MemoryStream encoded = new();
@ -107,7 +107,7 @@ public class ObuFrameHeaderTests
ObuReader obuReader2 = new();
// Act 2
obuReader2.ReadAll(ref reader2, encodedBuffer.Length, tileDecoder2);
obuReader2.ReadAll(ref reader2, encodedBuffer.Length, () => tileDecoder2);
// Assert
Assert.Equal(ObuPrettyPrint.PrettyPrintProperties(obuReader1.SequenceHeader.ColorConfig), ObuPrettyPrint.PrettyPrintProperties(obuReader2.SequenceHeader.ColorConfig));
@ -125,7 +125,7 @@ public class ObuFrameHeaderTests
IAv1TileReader tileDecoder = new Av1TileDecoderStub();
// Act
obuReader.ReadAll(ref reader, DefaultTemporalDelimiterBitStream.Length, tileDecoder);
obuReader.ReadAll(ref reader, DefaultTemporalDelimiterBitStream.Length, () => tileDecoder);
// Assert
Assert.Null(obuReader.SequenceHeader);
@ -142,7 +142,7 @@ public class ObuFrameHeaderTests
IAv1TileReader tileDecoder = new Av1TileDecoderStub();
// Act
obuReader.ReadAll(ref reader, bitStream.Length, tileDecoder);
obuReader.ReadAll(ref reader, bitStream.Length, () => tileDecoder);
// Assert
Assert.Null(obuReader.SequenceHeader);
@ -160,7 +160,7 @@ public class ObuFrameHeaderTests
ObuSequenceHeader expected = GetDefaultSequenceHeader();
// Act
obuReader.ReadAll(ref reader, bitStream.Length, tileDecoder);
obuReader.ReadAll(ref reader, bitStream.Length, () => tileDecoder);
// Assert
Assert.NotNull(obuReader.SequenceHeader);

Loading…
Cancel
Save