📷 A modern, cross-platform, 2D Graphics library for .NET
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

270 lines
8.1 KiB

// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Buffers.Binary;
using SixLabors.ImageSharp.Formats.Heif.Av1;
namespace SixLabors.ImageSharp.Tests.Formats.Heif.Av1;
[Trait("Format", "Avif")]
public class Av1BitStreamTests
{
[Theory]
[InlineData(42, new bool[] { false, false, true, false, true, false, true, false })]
[InlineData(52, new bool[] { false, false, true, true, false, true, false, false })]
public void ReadAsBoolean(byte value, bool[] bits)
{
int bitCount = bits.Length;
byte[] buffer = new byte[8];
buffer[0] = value;
Av1BitStreamReader reader = new(buffer);
bool[] actual = new bool[bitCount];
for (int i = 0; i < bitCount; i++)
{
actual[i] = reader.ReadBoolean();
}
Assert.Equal(bits, actual);
}
[Theory]
[InlineData(6, 4)]
[InlineData(42, 8)]
[InlineData(52, 8)]
[InlineData(4050, 16)]
public void ReadAsLiteral(uint expected, int bitCount)
{
byte[] buffer = new byte[8];
BinaryPrimitives.WriteUInt32BigEndian(buffer, expected << (32 - bitCount));
Av1BitStreamReader reader = new(buffer);
uint actual = reader.ReadLiteral(bitCount);
Assert.Equal(expected, actual);
}
[Theory]
[InlineData(new bool[] { false, false, true, false, true, false, true, false })]
[InlineData(new bool[] { false, true, false, true })]
public void WriteAsBoolean(bool[] booleans)
{
using MemoryStream stream = new(8);
Av1BitStreamWriter writer = new(stream);
for (int i = 0; i < booleans.Length; i++)
{
writer.WriteBoolean(booleans[i]);
}
writer.Flush();
// Read the written value back.
Av1BitStreamReader reader = new(stream.GetBuffer());
bool[] actual = new bool[booleans.Length];
for (int i = 0; i < booleans.Length; i++)
{
actual[i] = reader.ReadBoolean();
}
Assert.Equal(booleans, actual);
}
[Theory]
[InlineData(6, 4)]
[InlineData(42, 8)]
[InlineData(52, 8)]
[InlineData(4050, 16)]
public void WriteAsLiteral(uint value, int bitCount)
{
using MemoryStream stream = new(8);
Av1BitStreamWriter writer = new(stream);
writer.WriteLiteral(value, bitCount);
writer.Flush();
// Read the written value back.
Av1BitStreamReader reader = new(stream.GetBuffer());
uint actual = reader.ReadLiteral(bitCount);
Assert.Equal(value, actual);
}
[Theory]
[InlineData(3)]
[InlineData(4)]
[InlineData(5)]
[InlineData(6)]
[InlineData(7)]
[InlineData(8)]
[InlineData(16)]
public void ReadLiteralRainbowArray(int bitCount)
{
uint[] values = Enumerable.Range(0, (1 << bitCount) - 1).Select(i => (uint)i).ToArray();
using MemoryStream stream = new(280);
Av1BitStreamWriter writer = new(stream);
for (int i = 0; i < values.Length; i++)
{
writer.WriteLiteral(values[i], bitCount);
}
writer.Flush();
// Read the written value back.
Av1BitStreamReader reader = new(stream.GetBuffer());
uint[] actuals = new uint[values.Length];
for (int i = 0; i < values.Length; i++)
{
uint actual = reader.ReadLiteral(bitCount);
actuals[i] = actual;
}
Assert.Equal(values, actuals);
}
[Theory]
[InlineData(4, 6, 4, 9, 14)]
[InlineData(8, 42, 8, 189, 63)]
[InlineData(8, 52, 18, 255, 241)]
[InlineData(16, 4050, 16003, 503, 814)]
public void ReadWriteAsLiteralArray(int bitCount, uint val1, uint val2, uint val3, uint val4)
{
uint[] values = [val1, val2, val3, val4];
using MemoryStream stream = new(80);
Av1BitStreamWriter writer = new(stream);
for (int i = 0; i < values.Length; i++)
{
writer.WriteLiteral(values[i], bitCount);
}
writer.Flush();
// Read the written value back.
Av1BitStreamReader reader = new(stream.GetBuffer());
for (int i = 0; i < values.Length; i++)
{
uint actual = reader.ReadLiteral(bitCount);
Assert.NotEqual(0U, actual);
Assert.Equal(values[i], actual);
}
}
[Theory]
[InlineData(4, 0, 1, 2, 3)]
[InlineData(5, 0, 1, 2, 3)]
[InlineData(8, 0, 1, 2, 3)]
[InlineData(8, 4, 5, 6, 7)]
[InlineData(16, 15, 0, 5, 8)]
public void ReadWriteAsNonSymmetricArray(uint numberOfSymbols, uint val1, uint val2, uint val3, uint val4)
{
uint[] values = [val1, val2, val3, val4];
using MemoryStream stream = new(80);
Av1BitStreamWriter writer = new(stream);
for (int i = 0; i < values.Length; i++)
{
writer.WriteNonSymmetric(values[i], numberOfSymbols);
}
writer.Flush();
// Read the written value back.
Av1BitStreamReader reader = new(stream.GetBuffer());
uint[] actuals = new uint[4];
for (int i = 0; i < values.Length; i++)
{
ulong actual = reader.ReadNonSymmetric(numberOfSymbols);
actuals[i] = (uint)actual;
// Assert.NotEqual(0UL, actual);
}
Assert.Equal(values, actuals);
}
[Theory]
[InlineData(3)]
[InlineData(4)]
[InlineData(5)]
[InlineData(7)]
[InlineData(8)]
public void ReadSignedRainbowArray(int bitCount)
{
int maxValue = (1 << (bitCount - 1)) - 1;
int[] values = Enumerable.Range(-maxValue, maxValue).ToArray();
using MemoryStream stream = new(280);
Av1BitStreamWriter writer = new(stream);
for (int i = 0; i < values.Length; i++)
{
writer.WriteSignedFromUnsigned(values[i], bitCount);
}
writer.Flush();
// Read the written value back.
Av1BitStreamReader reader = new(stream.GetBuffer());
int[] actuals = new int[values.Length];
for (int i = 0; i < values.Length; i++)
{
int actual = reader.ReadSignedFromUnsigned(bitCount);
actuals[i] = actual;
}
Assert.Equal(values, actuals);
}
[Theory]
[InlineData(5, 6, 4, -7, -2)]
[InlineData(7, 26, -8, -19, -26)]
[InlineData(8, 52, 127, -127, -21)]
[InlineData(16, -4050, -16003, -503, 8414)]
public void ReadWriteSignedArray(int bitCount, int val1, int val2, int val3, int val4)
{
int[] values = [val1, val2, val3, val4];
using MemoryStream stream = new(80);
Av1BitStreamWriter writer = new(stream);
for (int i = 0; i < values.Length; i++)
{
writer.WriteSignedFromUnsigned(values[i], bitCount);
}
writer.Flush();
// Read the written value back.
Av1BitStreamReader reader = new(stream.GetBuffer());
int[] actuals = new int[4];
for (int i = 0; i < values.Length; i++)
{
int actual = reader.ReadSignedFromUnsigned(bitCount);
actuals[i] = actual;
// Assert.NotEqual(0, actual);
}
Assert.Equal(values, actuals);
}
[Theory]
[InlineData(4, 6, 7, 9, 14)]
[InlineData(8, 42, 8, 189, 63)]
[InlineData(8, 52, 18, 255, 241)]
[InlineData(16, 4050, 16003, 503, 8414)]
public void ReadWriteLittleEndianBytes128Array(uint val0, uint val1, uint val2, uint val3, uint val4)
{
uint[] values = [val0, val1, val2, val3, val4];
using MemoryStream stream = new(80);
Av1BitStreamWriter writer = new(stream);
for (int i = 0; i < values.Length; i++)
{
writer.WriteLittleEndianBytes128(values[i]);
}
writer.Flush();
// Read the written value back.
Av1BitStreamReader reader = new(stream.GetBuffer());
uint[] actuals = new uint[5];
for (int i = 0; i < values.Length; i++)
{
ulong actual = reader.ReadLittleEndianBytes128(out int length);
actuals[i] = (uint)actual;
Assert.NotEqual(0UL, actual);
}
Assert.Equal(values, actuals);
}
}