Browse Source

Add test for calculating residual costs

pull/2432/head
Brian Popow 3 years ago
parent
commit
79bc8ebef6
  1. 49
      src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs
  2. 16
      tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs
  3. 3
      tests/ImageSharp.Tests/ImageSharp.Tests.csproj
  4. 1
      tests/ImageSharp.Tests/TestDataWebp/Vp8Residual.json

49
src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs

@ -173,55 +173,6 @@ internal class Vp8Residual
return LossyUtils.Vp8BitCost(0, (byte)p0);
}
if (false)
{
Span<byte> scratch = stackalloc byte[32];
Span<byte> ctxs = scratch.Slice(0, 16);
Span<byte> levels = scratch.Slice(16);
Span<ushort> absLevels = stackalloc ushort[16];
// Precompute clamped levels and contexts, packed to 8b.
ref short outputRef = ref MemoryMarshal.GetReference<short>(this.Coeffs);
Vector256<short> c0 = Unsafe.As<short, Vector256<byte>>(ref outputRef).AsInt16();
Vector256<short> d0 = Avx2.Subtract(Vector256<short>.Zero, c0);
Vector256<short> e0 = Avx2.Max(c0, d0); // abs(v), 16b
Vector256<sbyte> f = Avx2.PackSignedSaturate(e0, e0);
Vector256<byte> g = Avx2.Min(f.AsByte(), Vector256.Create((byte)2));
Vector256<byte> h = Avx2.Min(f.AsByte(), Vector256.Create((byte)67)); // clampLevel in [0..67]
ref byte ctxsRef = ref MemoryMarshal.GetReference(ctxs);
ref byte levelsRef = ref MemoryMarshal.GetReference(levels);
ref ushort absLevelsRef = ref MemoryMarshal.GetReference(absLevels);
Unsafe.As<byte, Vector128<byte>>(ref ctxsRef) = g.GetLower();
Unsafe.As<byte, Vector128<byte>>(ref levelsRef) = h.GetLower();
Unsafe.As<ushort, Vector256<ushort>>(ref absLevelsRef) = e0.AsUInt16();
int level;
int flevel;
for (; n < this.Last; ++n)
{
int ctx = ctxs[n];
level = levels[n];
flevel = absLevels[n];
cost += WebpLookupTables.Vp8LevelFixedCosts[flevel] + t.Costs[level];
t = costs[n + 1].Costs[ctx];
}
// Last coefficient is always non-zero.
level = levels[n];
flevel = absLevels[n];
cost += WebpLookupTables.Vp8LevelFixedCosts[flevel] + t.Costs[level];
if (n < 15)
{
int b = WebpConstants.Vp8EncBands[n + 1];
int ctx = ctxs[n];
int lastP0 = this.Prob[b].Probabilities[ctx].Probabilities[0];
cost += LossyUtils.Vp8BitCost(0, (byte)lastP0);
}
return cost;
}
if (Sse2.IsSupported)
{
Span<byte> scratch = stackalloc byte[32];

16
tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs

@ -11,6 +11,22 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp;
[Trait("Format", "Webp")]
public class Vp8ResidualTests
{
[Fact]
public void GetResidualCost_Works()
{
// arrange
int ctx0 = 0;
int expected = 20911;
string jsonString = File.ReadAllText(@"TestDataWebp\Vp8Residual.json");
Vp8Residual residual = JsonSerializer.Deserialize<Vp8Residual>(jsonString);
// act
int actual = residual.GetResidualCost(ctx0);
// assert
Assert.Equal(expected, actual);
}
[Fact]
public void Serialization_Works()
{

3
tests/ImageSharp.Tests/ImageSharp.Tests.csproj

@ -56,6 +56,9 @@
<None Update="TestFonts\SixLaborsSampleAB.woff">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="TestDataWebp\Vp8Residual.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="xunit.runner.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>

1
tests/ImageSharp.Tests/TestDataWebp/Vp8Residual.json

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save