From fad143d5f8ff7d9ed2e4fda48924cf0be5fe71f3 Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Mon, 3 Apr 2023 19:39:32 +0200 Subject: [PATCH 01/13] Switch back to Sse2 version of residual costs, since avx version is not the same as scalar version --- .../Formats/Webp/Lossy/Vp8Residual.cs | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs index 177041506..68bf09f94 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs @@ -156,7 +156,7 @@ internal class Vp8Residual return LossyUtils.Vp8BitCost(0, (byte)p0); } - if (Avx2.IsSupported) + if (Sse2.IsSupported) { Span scratch = stackalloc byte[32]; Span ctxs = scratch.Slice(0, 16); @@ -165,19 +165,23 @@ internal class Vp8Residual // Precompute clamped levels and contexts, packed to 8b. ref short outputRef = ref MemoryMarshal.GetReference(this.Coeffs); - Vector256 c0 = Unsafe.As>(ref outputRef).AsInt16(); - Vector256 d0 = Avx2.Subtract(Vector256.Zero, c0); - Vector256 e0 = Avx2.Max(c0, d0); // abs(v), 16b - Vector256 f = Avx2.PackSignedSaturate(e0, e0); - Vector256 g = Avx2.Min(f.AsByte(), Vector256.Create((byte)2)); - Vector256 h = Avx2.Min(f.AsByte(), Vector256.Create((byte)67)); // clampLevel in [0..67] + Vector128 c0 = Unsafe.As>(ref outputRef).AsInt16(); + Vector128 c1 = Unsafe.As>(ref Unsafe.Add(ref outputRef, 8)).AsInt16(); + Vector128 d0 = Sse2.Subtract(Vector128.Zero, c0); + Vector128 d1 = Sse2.Subtract(Vector128.Zero, c1); + Vector128 e0 = Sse2.Max(c0, d0); // abs(v), 16b + Vector128 e1 = Sse2.Max(c1, d1); + Vector128 f = Sse2.PackSignedSaturate(e0, e1); + Vector128 g = Sse2.Min(f.AsByte(), Vector128.Create((byte)2)); // context = 0, 1, 2 + Vector128 h = Sse2.Min(f.AsByte(), Vector128.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>(ref ctxsRef) = g.GetLower(); - Unsafe.As>(ref levelsRef) = h.GetLower(); - Unsafe.As>(ref absLevelsRef) = e0.AsUInt16(); + Unsafe.As>(ref ctxsRef) = g; + Unsafe.As>(ref levelsRef) = h; + Unsafe.As>(ref absLevelsRef) = e0.AsUInt16(); + Unsafe.As>(ref Unsafe.Add(ref absLevelsRef, 8)) = e1.AsUInt16(); int level; int flevel; From 0d6e50f29fb5388f87d6be67f489c072ef4204a6 Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Fri, 7 Apr 2023 19:21:23 +0200 Subject: [PATCH 02/13] Add Vp8Residual Serialization test --- .../Formats/WebP/Vp8ResidualTests.cs | 107 +++++++++++++++++- 1 file changed, 101 insertions(+), 6 deletions(-) diff --git a/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs b/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs index 1f9136e9a..e9f0f31d7 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs @@ -1,6 +1,8 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. +using System.Text.Json; +using SixLabors.ImageSharp.Formats.Webp; using SixLabors.ImageSharp.Formats.Webp.Lossy; using SixLabors.ImageSharp.Tests.TestUtilities; @@ -9,10 +11,106 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp; [Trait("Format", "Webp")] public class Vp8ResidualTests { + [Fact] + public void Serialization_Works() + { + // arrange + Vp8Residual expected = new(); + Vp8EncProba encProb = new(); + Random rand = new(439); + CreateRandomProbas(encProb, rand); + CreateCosts(encProb, rand); + expected.Init(1, 0, encProb); + for (int i = 0; i < expected.Coeffs.Length; i++) + { + expected.Coeffs[i] = (byte)rand.Next(255); + } + + // act + string jsonString = JsonSerializer.Serialize(expected); + Vp8Residual actual = JsonSerializer.Deserialize(jsonString); + + // assert + Assert.Equal(expected.CoeffType, actual.CoeffType); + Assert.Equal(expected.Coeffs, actual.Coeffs); + Assert.Equal(expected.Costs.Length, actual.Costs.Length); + Assert.Equal(expected.First, actual.First); + Assert.Equal(expected.Last, actual.Last); + Assert.Equal(expected.Stats.Length, actual.Stats.Length); + for (int i = 0; i < expected.Stats.Length; i++) + { + Vp8StatsArray[] expectedStats = expected.Stats[i].Stats; + Vp8StatsArray[] actualStats = actual.Stats[i].Stats; + Assert.Equal(expectedStats.Length, actualStats.Length); + for (int j = 0; j < expectedStats.Length; j++) + { + Assert.Equal(expectedStats[j].Stats, actualStats[j].Stats); + } + } + + Assert.Equal(expected.Prob.Length, actual.Prob.Length); + for (int i = 0; i < expected.Prob.Length; i++) + { + Vp8ProbaArray[] expectedProbabilities = expected.Prob[i].Probabilities; + Vp8ProbaArray[] actualProbabilities = actual.Prob[i].Probabilities; + Assert.Equal(expectedProbabilities.Length, actualProbabilities.Length); + for (int j = 0; j < expectedProbabilities.Length; j++) + { + Assert.Equal(expectedProbabilities[j].Probabilities, actualProbabilities[j].Probabilities); + } + } + + for (int i = 0; i < expected.Costs.Length; i++) + { + Vp8CostArray[] expectedCosts = expected.Costs[i].Costs; + Vp8CostArray[] actualCosts = actual.Costs[i].Costs; + Assert.Equal(expectedCosts.Length, actualCosts.Length); + for (int j = 0; j < expectedCosts.Length; j++) + { + Assert.Equal(expectedCosts[j].Costs, actualCosts[j].Costs); + } + } + } + + private static void CreateRandomProbas(Vp8EncProba probas, Random rand) + { + for (int t = 0; t < WebpConstants.NumTypes; ++t) + { + for (int b = 0; b < WebpConstants.NumBands; ++b) + { + for (int c = 0; c < WebpConstants.NumCtx; ++c) + { + for (int p = 0; p < WebpConstants.NumProbas; ++p) + { + probas.Coeffs[t][b].Probabilities[c].Probabilities[p] = (byte)rand.Next(255); + } + } + } + } + } + + private static void CreateCosts(Vp8EncProba probas, Random rand) + { + for (int i = 0; i < probas.RemappedCosts.Length; i++) + { + for (int j = 0; j < probas.RemappedCosts[i].Length; j++) + { + for (int k = 0; k < probas.RemappedCosts[i][j].Costs.Length; k++) + { + ushort[] costs = probas.RemappedCosts[i][j].Costs[k].Costs; + for (int m = 0; m < costs.Length; m++) + { + costs[m] = (byte)rand.Next(255); + } + } + } + } + } + private static void RunSetCoeffsTest() { // arrange - var residual = new Vp8Residual(); + Vp8Residual residual = new(); short[] coeffs = { 110, 0, -2, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0 }; // act @@ -23,11 +121,8 @@ public class Vp8ResidualTests } [Fact] - public void RunSetCoeffsTest_Works() => RunSetCoeffsTest(); - - [Fact] - public void RunSetCoeffsTest_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunSetCoeffsTest, HwIntrinsics.AllowAll); + public void SetCoeffsTest_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunSetCoeffsTest, HwIntrinsics.AllowAll); [Fact] - public void RunSetCoeffsTest_WithoutHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunSetCoeffsTest, HwIntrinsics.DisableHWIntrinsic); + public void SetCoeffsTest_WithoutSSE2_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunSetCoeffsTest, HwIntrinsics.DisableSSE2); } From c8d580cbe050244a464ce97de6acb6cd4ef858d2 Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Fri, 7 Apr 2023 19:29:07 +0200 Subject: [PATCH 03/13] Add JsonConstructors --- .../Formats/Webp/Lossy/Vp8BandProbas.cs | 9 +++ .../Formats/Webp/Lossy/Vp8CostArray.cs | 9 +++ src/ImageSharp/Formats/Webp/Lossy/Vp8Costs.cs | 9 +++ .../Formats/Webp/Lossy/Vp8ProbaArray.cs | 9 +++ .../Formats/Webp/Lossy/Vp8Residual.cs | 66 +++++++++++++++++++ src/ImageSharp/Formats/Webp/Lossy/Vp8Stats.cs | 9 +++ .../Formats/Webp/Lossy/Vp8StatsArray.cs | 9 +++ 7 files changed, 120 insertions(+) diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8BandProbas.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8BandProbas.cs index 90506efb8..86304d4bd 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8BandProbas.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8BandProbas.cs @@ -1,6 +1,8 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. +using System.Text.Json.Serialization; + namespace SixLabors.ImageSharp.Formats.Webp.Lossy; /// @@ -20,6 +22,13 @@ internal class Vp8BandProbas } } + /// + /// Initializes a new instance of the class. + /// Only used for unit tests. + /// + [JsonConstructor] + public Vp8BandProbas(Vp8ProbaArray[] probabilities) => this.Probabilities = probabilities; + /// /// Gets the Probabilities. /// diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8CostArray.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8CostArray.cs index 2c8d723d7..8268e1c02 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8CostArray.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8CostArray.cs @@ -1,6 +1,8 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. +using System.Text.Json.Serialization; + namespace SixLabors.ImageSharp.Formats.Webp.Lossy; internal class Vp8CostArray @@ -10,5 +12,12 @@ internal class Vp8CostArray /// public Vp8CostArray() => this.Costs = new ushort[67 + 1]; + /// + /// Initializes a new instance of the class. + /// Only used for unit tests. + /// + [JsonConstructor] + public Vp8CostArray(ushort[] costs) => this.Costs = costs; + public ushort[] Costs { get; } } diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8Costs.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8Costs.cs index eee22159e..2441436fb 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8Costs.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8Costs.cs @@ -1,6 +1,8 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. +using System.Text.Json.Serialization; + namespace SixLabors.ImageSharp.Formats.Webp.Lossy; internal class Vp8Costs @@ -17,6 +19,13 @@ internal class Vp8Costs } } + /// + /// Initializes a new instance of the class. + /// Only used for unit tests. + /// + [JsonConstructor] + public Vp8Costs(Vp8CostArray[] costs) => this.Costs = costs; + /// /// Gets the Costs. /// diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8ProbaArray.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8ProbaArray.cs index 337527542..a19f9742f 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8ProbaArray.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8ProbaArray.cs @@ -1,6 +1,8 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. +using System.Text.Json.Serialization; + namespace SixLabors.ImageSharp.Formats.Webp.Lossy; /// @@ -13,6 +15,13 @@ internal class Vp8ProbaArray /// public Vp8ProbaArray() => this.Probabilities = new byte[WebpConstants.NumProbas]; + /// + /// Initializes a new instance of the class. + /// Only used for unit tests. + /// + [JsonConstructor] + public Vp8ProbaArray(byte[] probabilities) => this.Probabilities = probabilities; + /// /// Gets the probabilities. /// diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs index 68bf09f94..c00d7dbdd 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs @@ -7,6 +7,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; +using System.Text.Json.Serialization; namespace SixLabors.ImageSharp.Formats.Webp.Lossy; @@ -15,6 +16,22 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy; /// internal class Vp8Residual { + public Vp8Residual() + { + } + + [JsonConstructor] + public Vp8Residual(int first, int last, int coeffType, short[] coeffs, Vp8BandProbas[] prob, Vp8Stats[] stats, Vp8Costs[] costs) + { + this.First = first; + this.Last = last; + this.CoeffType = coeffType; + this.Coeffs = coeffs; + this.Prob = prob; + this.Stats = stats; + this.Costs = costs; + } + public int First { get; set; } public int Last { get; set; } @@ -156,6 +173,55 @@ internal class Vp8Residual return LossyUtils.Vp8BitCost(0, (byte)p0); } + if (false) + { + Span scratch = stackalloc byte[32]; + Span ctxs = scratch.Slice(0, 16); + Span levels = scratch.Slice(16); + Span absLevels = stackalloc ushort[16]; + + // Precompute clamped levels and contexts, packed to 8b. + ref short outputRef = ref MemoryMarshal.GetReference(this.Coeffs); + Vector256 c0 = Unsafe.As>(ref outputRef).AsInt16(); + Vector256 d0 = Avx2.Subtract(Vector256.Zero, c0); + Vector256 e0 = Avx2.Max(c0, d0); // abs(v), 16b + Vector256 f = Avx2.PackSignedSaturate(e0, e0); + Vector256 g = Avx2.Min(f.AsByte(), Vector256.Create((byte)2)); + Vector256 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>(ref ctxsRef) = g.GetLower(); + Unsafe.As>(ref levelsRef) = h.GetLower(); + Unsafe.As>(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 scratch = stackalloc byte[32]; diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8Stats.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8Stats.cs index dda921a7c..b6c05f2d4 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8Stats.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8Stats.cs @@ -1,6 +1,8 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. +using System.Text.Json.Serialization; + namespace SixLabors.ImageSharp.Formats.Webp.Lossy; internal class Vp8Stats @@ -17,5 +19,12 @@ internal class Vp8Stats } } + /// + /// Initializes a new instance of the class. + /// Only used for unit tests. + /// + [JsonConstructor] + public Vp8Stats(Vp8StatsArray[] stats) => this.Stats = stats; + public Vp8StatsArray[] Stats { get; } } diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8StatsArray.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8StatsArray.cs index 2fbba6996..864248dd8 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8StatsArray.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8StatsArray.cs @@ -1,6 +1,8 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. +using System.Text.Json.Serialization; + namespace SixLabors.ImageSharp.Formats.Webp.Lossy; internal class Vp8StatsArray @@ -10,5 +12,12 @@ internal class Vp8StatsArray /// public Vp8StatsArray() => this.Stats = new uint[WebpConstants.NumProbas]; + /// + /// Initializes a new instance of the class. + /// Only used for unit tests. + /// + [JsonConstructor] + public Vp8StatsArray(uint[] stats) => this.Stats = stats; + public uint[] Stats { get; } } From 79bc8ebef68fe106ae8f67791b5dbc33e60ddfbc Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Fri, 7 Apr 2023 19:40:06 +0200 Subject: [PATCH 04/13] Add test for calculating residual costs --- .../Formats/Webp/Lossy/Vp8Residual.cs | 49 ------------------- .../Formats/WebP/Vp8ResidualTests.cs | 16 ++++++ .../ImageSharp.Tests/ImageSharp.Tests.csproj | 3 ++ .../TestDataWebp/Vp8Residual.json | 1 + 4 files changed, 20 insertions(+), 49 deletions(-) create mode 100644 tests/ImageSharp.Tests/TestDataWebp/Vp8Residual.json diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs index c00d7dbdd..6e0937d86 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs @@ -173,55 +173,6 @@ internal class Vp8Residual return LossyUtils.Vp8BitCost(0, (byte)p0); } - if (false) - { - Span scratch = stackalloc byte[32]; - Span ctxs = scratch.Slice(0, 16); - Span levels = scratch.Slice(16); - Span absLevels = stackalloc ushort[16]; - - // Precompute clamped levels and contexts, packed to 8b. - ref short outputRef = ref MemoryMarshal.GetReference(this.Coeffs); - Vector256 c0 = Unsafe.As>(ref outputRef).AsInt16(); - Vector256 d0 = Avx2.Subtract(Vector256.Zero, c0); - Vector256 e0 = Avx2.Max(c0, d0); // abs(v), 16b - Vector256 f = Avx2.PackSignedSaturate(e0, e0); - Vector256 g = Avx2.Min(f.AsByte(), Vector256.Create((byte)2)); - Vector256 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>(ref ctxsRef) = g.GetLower(); - Unsafe.As>(ref levelsRef) = h.GetLower(); - Unsafe.As>(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 scratch = stackalloc byte[32]; diff --git a/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs b/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs index e9f0f31d7..2ced8e8ca 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs +++ b/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(jsonString); + + // act + int actual = residual.GetResidualCost(ctx0); + + // assert + Assert.Equal(expected, actual); + } + [Fact] public void Serialization_Works() { diff --git a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj index a6197b600..270a02c0c 100644 --- a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj +++ b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj @@ -56,6 +56,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest diff --git a/tests/ImageSharp.Tests/TestDataWebp/Vp8Residual.json b/tests/ImageSharp.Tests/TestDataWebp/Vp8Residual.json new file mode 100644 index 000000000..41a524b89 --- /dev/null +++ b/tests/ImageSharp.Tests/TestDataWebp/Vp8Residual.json @@ -0,0 +1 @@ +{"First":1,"Last":15,"CoeffType":0,"Coeffs":[0,-3,-5,1,1,0,0,1,2,0,-1,-1,0,-1,-1,2],"Prob":[{"Probabilities":[{"Probabilities":"gICAgICAgICAgIA="},{"Probabilities":"gICAgICAgICAgIA="},{"Probabilities":"gICAgICAgICAgIA="}]},{"Probabilities":[{"Probabilities":"/Yj+/+TbgICAgIA="},{"Probabilities":"vYHy/+PV/9uAgIA="},{"Probabilities":"an7j/NbR//+AgIA="}]},{"Probabilities":[{"Probabilities":"AWL4/+zi//+AgIA="},{"Probabilities":"tYXu/t3q/5qAgIA="},{"Probabilities":"TobK98a0/9uAgIA="}]},{"Probabilities":[{"Probabilities":"Abn5//P/gICAgIA="},{"Probabilities":"uJb3/+zggICAgIA="},{"Probabilities":"TW7Y/+zmgICAgIA="}]},{"Probabilities":[{"Probabilities":"AWX7//H/gICAgIA="},{"Probabilities":"qovx/OzR//+AgIA="},{"Probabilities":"JXTE8+T///+AgIA="}]},{"Probabilities":[{"Probabilities":"Acz+//X/gICAgIA="},{"Probabilities":"z6D6/+6AgICAgIA="},{"Probabilities":"Zmfn/9OrgICAgIA="}]},{"Probabilities":[{"Probabilities":"AZj8//D/gICAgIA="},{"Probabilities":"sYfz/+rhgICAgIA="},{"Probabilities":"UIHT/8LggICAgIA="}]},{"Probabilities":[{"Probabilities":"AQH/gICAgICAgIA="},{"Probabilities":"9gH/gICAgICAgIA="},{"Probabilities":"/4CAgICAgICAgIA="}]}],"Stats":[{"Stats":[{"Stats":[0,0,0,0,0,0,0,0,0,0,0]},{"Stats":[0,0,0,0,0,0,0,0,0,0,0]},{"Stats":[0,0,0,0,0,0,0,0,0,0,0]}]},{"Stats":[{"Stats":[3145728,0,0,0,0,0,0,0,0,0,0]},{"Stats":[0,0,0,0,0,0,0,0,0,0,0]},{"Stats":[0,0,0,0,0,0,0,0,0,0,0]}]},{"Stats":[{"Stats":[0,0,0,0,0,0,0,0,0,0,0]},{"Stats":[0,0,0,0,0,0,0,0,0,0,0]},{"Stats":[0,0,0,0,0,0,0,0,0,0,0]}]},{"Stats":[{"Stats":[0,0,0,0,0,0,0,0,0,0,0]},{"Stats":[0,0,0,0,0,0,0,0,0,0,0]},{"Stats":[0,0,0,0,0,0,0,0,0,0,0]}]},{"Stats":[{"Stats":[0,0,0,0,0,0,0,0,0,0,0]},{"Stats":[0,0,0,0,0,0,0,0,0,0,0]},{"Stats":[0,0,0,0,0,0,0,0,0,0,0]}]},{"Stats":[{"Stats":[0,0,0,0,0,0,0,0,0,0,0]},{"Stats":[0,0,0,0,0,0,0,0,0,0,0]},{"Stats":[0,0,0,0,0,0,0,0,0,0,0]}]},{"Stats":[{"Stats":[0,0,0,0,0,0,0,0,0,0,0]},{"Stats":[0,0,0,0,0,0,0,0,0,0,0]},{"Stats":[0,0,0,0,0,0,0,0,0,0,0]}]},{"Stats":[{"Stats":[0,0,0,0,0,0,0,0,0,0,0]},{"Stats":[0,0,0,0,0,0,0,0,0,0,0]},{"Stats":[0,0,0,0,0,0,0,0,0,0,0]}]}],"Costs":[{"Costs":[{"Costs":[256,512,1024,1280,1280,1280,1280,1280,1280,1280,1280,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536,1536]},{"Costs":[512,768,1280,1536,1536,1536,1536,1536,1536,1536,1536,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792]},{"Costs":[512,768,1280,1536,1536,1536,1536,1536,1536,1536,1536,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792,1792]}]},{"Costs":[{"Costs":[234,287,2122,2957,3618,4379,4379,4379,4379,4379,4379,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635,4635]},{"Costs":[756,784,1887,2721,3318,3692,3692,4353,4353,4353,4353,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934,5934]},{"Costs":[463,503,1342,2023,2578,2810,2810,4599,4599,4599,4599,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108,5108]}]},{"Costs":[{"Costs":[355,194,1496,2462,3209,3259,3259,5048,5048,5048,5048,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557,5557]},{"Costs":[700,761,1783,2503,3379,3707,3707,3861,3861,3861,3861,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820,5820]},{"Costs":[378,504,1102,1692,2013,2333,2333,2994,2994,2994,2994,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575,4575]}]},{"Costs":[{"Costs":[121,489,1867,2959,4748,4147,4147,4147,4147,4147,4147,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403,4403]},{"Costs":[671,818,2118,3088,3805,4387,4387,4387,4387,4387,4387,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643,4643]},{"Costs":[447,410,1071,2031,2844,3340,3340,3340,3340,3340,3340,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596,3596]}]},{"Costs":[{"Costs":[192,343,1900,2902,4691,4176,4176,4176,4176,4176,4176,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432]},{"Costs":[675,739,1866,2791,3528,4132,4132,4132,4132,4132,4132,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388]},{"Costs":[398,477,1157,1633,2350,3355,3355,3355,3355,3355,3355,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611]}]},{"Costs":[{"Costs":[342,197,1751,2791,4580,4028,4028,4028,4028,4028,4028,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284,4284]},{"Costs":[632,723,1799,2794,3349,3302,3302,5091,5091,5091,5091,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600,5600]},{"Costs":[354,387,893,1672,3461,1944,1944,3733,3733,3733,3733,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242,4242]}]},{"Costs":[{"Costs":[86,596,2405,3568,5357,4688,4688,4688,4688,4688,4688,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944,4944]},{"Costs":[790,991,2421,3640,3640,4693,4693,4693,4693,4693,4693,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949,4949]},{"Costs":[527,423,1330,2054,2314,3558,3558,3558,3558,3558,3558,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814,3814]}]},{"Costs":[{"Costs":[192,343,1900,2902,4691,4176,4176,4176,4176,4176,4176,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432]},{"Costs":[675,739,1866,2791,3528,4132,4132,4132,4132,4132,4132,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388]},{"Costs":[398,477,1157,1633,2350,3355,3355,3355,3355,3355,3355,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611]}]},{"Costs":[{"Costs":[192,343,1900,2902,4691,4176,4176,4176,4176,4176,4176,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432]},{"Costs":[675,739,1866,2791,3528,4132,4132,4132,4132,4132,4132,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388]},{"Costs":[398,477,1157,1633,2350,3355,3355,3355,3355,3355,3355,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611]}]},{"Costs":[{"Costs":[192,343,1900,2902,4691,4176,4176,4176,4176,4176,4176,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432]},{"Costs":[675,739,1866,2791,3528,4132,4132,4132,4132,4132,4132,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388]},{"Costs":[398,477,1157,1633,2350,3355,3355,3355,3355,3355,3355,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611]}]},{"Costs":[{"Costs":[192,343,1900,2902,4691,4176,4176,4176,4176,4176,4176,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432]},{"Costs":[675,739,1866,2791,3528,4132,4132,4132,4132,4132,4132,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388]},{"Costs":[398,477,1157,1633,2350,3355,3355,3355,3355,3355,3355,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611]}]},{"Costs":[{"Costs":[192,343,1900,2902,4691,4176,4176,4176,4176,4176,4176,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432]},{"Costs":[675,739,1866,2791,3528,4132,4132,4132,4132,4132,4132,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388]},{"Costs":[398,477,1157,1633,2350,3355,3355,3355,3355,3355,3355,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611]}]},{"Costs":[{"Costs":[192,343,1900,2902,4691,4176,4176,4176,4176,4176,4176,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432]},{"Costs":[675,739,1866,2791,3528,4132,4132,4132,4132,4132,4132,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388]},{"Costs":[398,477,1157,1633,2350,3355,3355,3355,3355,3355,3355,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611]}]},{"Costs":[{"Costs":[192,343,1900,2902,4691,4176,4176,4176,4176,4176,4176,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432]},{"Costs":[675,739,1866,2791,3528,4132,4132,4132,4132,4132,4132,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388]},{"Costs":[398,477,1157,1633,2350,3355,3355,3355,3355,3355,3355,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611]}]},{"Costs":[{"Costs":[192,343,1900,2902,4691,4176,4176,4176,4176,4176,4176,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432,4432]},{"Costs":[675,739,1866,2791,3528,4132,4132,4132,4132,4132,4132,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388,4388]},{"Costs":[398,477,1157,1633,2350,3355,3355,3355,3355,3355,3355,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611,3611]}]},{"Costs":[{"Costs":[1792,7,2308,2564,2564,2564,2564,2564,2564,2564,2564,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820,2820]},{"Costs":[3008,1223,3524,3780,3780,3780,3780,3780,3780,3780,3780,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036,4036]},{"Costs":[2048,2304,2816,3072,3072,3072,3072,3072,3072,3072,3072,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328,3328]}]}]} \ No newline at end of file From 4432937bd83a767a3129c82b728350ce10650a2a Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Fri, 7 Apr 2023 19:52:46 +0200 Subject: [PATCH 05/13] Skip serialization tests when SSE2 is not available --- .../Formats/WebP/Vp8ResidualTests.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs b/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs index 2ced8e8ca..f7a8482d9 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs @@ -1,6 +1,7 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. +using System.Runtime.Intrinsics.X86; using System.Text.Json; using SixLabors.ImageSharp.Formats.Webp; using SixLabors.ImageSharp.Formats.Webp.Lossy; @@ -14,6 +15,12 @@ public class Vp8ResidualTests [Fact] public void GetResidualCost_Works() { + if (!Sse2.IsSupported) + { + // JsonSerializer without SSE2 does not seem to work, skip test then. + return; + } + // arrange int ctx0 = 0; int expected = 20911; @@ -30,6 +37,12 @@ public class Vp8ResidualTests [Fact] public void Serialization_Works() { + if (!Sse2.IsSupported) + { + // JsonSerializer without SSE2 does not seem to work, skip test then. + return; + } + // arrange Vp8Residual expected = new(); Vp8EncProba encProb = new(); From ba7b1df56289c84da4c9dedb1caf8477fa684119 Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Fri, 7 Apr 2023 20:14:05 +0200 Subject: [PATCH 06/13] Fix path to test data --- tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs b/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs index f7a8482d9..cadf92973 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs @@ -24,7 +24,7 @@ public class Vp8ResidualTests // arrange int ctx0 = 0; int expected = 20911; - string jsonString = File.ReadAllText(@"TestDataWebp\Vp8Residual.json"); + string jsonString = File.ReadAllText(Path.Combine("TestDataWebp", "Vp8Residual.json")); Vp8Residual residual = JsonSerializer.Deserialize(jsonString); // act From 79448ec9590c93f1d1e7d4823ed39992f4204869 Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Sun, 9 Apr 2023 14:04:11 +0200 Subject: [PATCH 07/13] Revert adding JsonConstructor attributes --- .../Formats/Webp/Lossy/Vp8BandProbas.cs | 9 --------- .../Formats/Webp/Lossy/Vp8CostArray.cs | 9 --------- src/ImageSharp/Formats/Webp/Lossy/Vp8Costs.cs | 9 --------- .../Formats/Webp/Lossy/Vp8ProbaArray.cs | 9 --------- .../Formats/Webp/Lossy/Vp8Residual.cs | 17 ----------------- src/ImageSharp/Formats/Webp/Lossy/Vp8Stats.cs | 9 --------- .../Formats/Webp/Lossy/Vp8StatsArray.cs | 9 --------- 7 files changed, 71 deletions(-) diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8BandProbas.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8BandProbas.cs index 86304d4bd..90506efb8 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8BandProbas.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8BandProbas.cs @@ -1,8 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -using System.Text.Json.Serialization; - namespace SixLabors.ImageSharp.Formats.Webp.Lossy; /// @@ -22,13 +20,6 @@ internal class Vp8BandProbas } } - /// - /// Initializes a new instance of the class. - /// Only used for unit tests. - /// - [JsonConstructor] - public Vp8BandProbas(Vp8ProbaArray[] probabilities) => this.Probabilities = probabilities; - /// /// Gets the Probabilities. /// diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8CostArray.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8CostArray.cs index 8268e1c02..2c8d723d7 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8CostArray.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8CostArray.cs @@ -1,8 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -using System.Text.Json.Serialization; - namespace SixLabors.ImageSharp.Formats.Webp.Lossy; internal class Vp8CostArray @@ -12,12 +10,5 @@ internal class Vp8CostArray /// public Vp8CostArray() => this.Costs = new ushort[67 + 1]; - /// - /// Initializes a new instance of the class. - /// Only used for unit tests. - /// - [JsonConstructor] - public Vp8CostArray(ushort[] costs) => this.Costs = costs; - public ushort[] Costs { get; } } diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8Costs.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8Costs.cs index 2441436fb..eee22159e 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8Costs.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8Costs.cs @@ -1,8 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -using System.Text.Json.Serialization; - namespace SixLabors.ImageSharp.Formats.Webp.Lossy; internal class Vp8Costs @@ -19,13 +17,6 @@ internal class Vp8Costs } } - /// - /// Initializes a new instance of the class. - /// Only used for unit tests. - /// - [JsonConstructor] - public Vp8Costs(Vp8CostArray[] costs) => this.Costs = costs; - /// /// Gets the Costs. /// diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8ProbaArray.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8ProbaArray.cs index a19f9742f..337527542 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8ProbaArray.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8ProbaArray.cs @@ -1,8 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -using System.Text.Json.Serialization; - namespace SixLabors.ImageSharp.Formats.Webp.Lossy; /// @@ -15,13 +13,6 @@ internal class Vp8ProbaArray /// public Vp8ProbaArray() => this.Probabilities = new byte[WebpConstants.NumProbas]; - /// - /// Initializes a new instance of the class. - /// Only used for unit tests. - /// - [JsonConstructor] - public Vp8ProbaArray(byte[] probabilities) => this.Probabilities = probabilities; - /// /// Gets the probabilities. /// diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs index 6e0937d86..68bf09f94 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs @@ -7,7 +7,6 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -using System.Text.Json.Serialization; namespace SixLabors.ImageSharp.Formats.Webp.Lossy; @@ -16,22 +15,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy; /// internal class Vp8Residual { - public Vp8Residual() - { - } - - [JsonConstructor] - public Vp8Residual(int first, int last, int coeffType, short[] coeffs, Vp8BandProbas[] prob, Vp8Stats[] stats, Vp8Costs[] costs) - { - this.First = first; - this.Last = last; - this.CoeffType = coeffType; - this.Coeffs = coeffs; - this.Prob = prob; - this.Stats = stats; - this.Costs = costs; - } - public int First { get; set; } public int Last { get; set; } diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8Stats.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8Stats.cs index b6c05f2d4..dda921a7c 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8Stats.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8Stats.cs @@ -1,8 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -using System.Text.Json.Serialization; - namespace SixLabors.ImageSharp.Formats.Webp.Lossy; internal class Vp8Stats @@ -19,12 +17,5 @@ internal class Vp8Stats } } - /// - /// Initializes a new instance of the class. - /// Only used for unit tests. - /// - [JsonConstructor] - public Vp8Stats(Vp8StatsArray[] stats) => this.Stats = stats; - public Vp8StatsArray[] Stats { get; } } diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8StatsArray.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8StatsArray.cs index 864248dd8..2fbba6996 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8StatsArray.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8StatsArray.cs @@ -1,8 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -using System.Text.Json.Serialization; - namespace SixLabors.ImageSharp.Formats.Webp.Lossy; internal class Vp8StatsArray @@ -12,12 +10,5 @@ internal class Vp8StatsArray /// public Vp8StatsArray() => this.Stats = new uint[WebpConstants.NumProbas]; - /// - /// Initializes a new instance of the class. - /// Only used for unit tests. - /// - [JsonConstructor] - public Vp8StatsArray(uint[] stats) => this.Stats = stats; - public uint[] Stats { get; } } From 4dcf8569a72dc9f1e6e61fafd0d0a4c245006585 Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Sun, 9 Apr 2023 14:06:21 +0200 Subject: [PATCH 08/13] Add Vp8CostArray Serialization test, add stub for Vp8CostArray JsonConverter --- .../Vp8CostArrayJsonConverter.cs | 15 ++++++ .../Formats/WebP/Vp8ResidualTests.cs | 51 ++++++++++++++----- 2 files changed, 54 insertions(+), 12 deletions(-) create mode 100644 tests/ImageSharp.Tests/Formats/WebP/Serialization/Vp8CostArrayJsonConverter.cs diff --git a/tests/ImageSharp.Tests/Formats/WebP/Serialization/Vp8CostArrayJsonConverter.cs b/tests/ImageSharp.Tests/Formats/WebP/Serialization/Vp8CostArrayJsonConverter.cs new file mode 100644 index 000000000..b3cfd0340 --- /dev/null +++ b/tests/ImageSharp.Tests/Formats/WebP/Serialization/Vp8CostArrayJsonConverter.cs @@ -0,0 +1,15 @@ +// Copyright (c) Six Labors. +// Licensed under the Six Labors Split License. + +using System.Text.Json; +using System.Text.Json.Serialization; +using SixLabors.ImageSharp.Formats.Webp.Lossy; + +namespace SixLabors.ImageSharp.Tests.Formats.WebP.Serialization; + +internal class Vp8CostArrayJsonConverter : JsonConverter +{ + public override Vp8CostArray Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => throw new NotImplementedException(); + + public override void Write(Utf8JsonWriter writer, Vp8CostArray value, JsonSerializerOptions options) => throw new NotImplementedException(); +} diff --git a/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs b/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs index cadf92973..457f3576f 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs @@ -5,7 +5,9 @@ using System.Runtime.Intrinsics.X86; using System.Text.Json; using SixLabors.ImageSharp.Formats.Webp; using SixLabors.ImageSharp.Formats.Webp.Lossy; +using SixLabors.ImageSharp.Tests.Formats.WebP.Serialization; using SixLabors.ImageSharp.Tests.TestUtilities; +using JsonSerializer = System.Text.Json.JsonSerializer; namespace SixLabors.ImageSharp.Tests.Formats.Webp; @@ -13,29 +15,30 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp; public class Vp8ResidualTests { [Fact] - public void GetResidualCost_Works() + public void Vp8CostArray_Serialization_Works() { - if (!Sse2.IsSupported) + // arrange + Vp8CostArray expected = new(); + for (ushort i = 0; i < expected.Costs.Length; i++) { - // JsonSerializer without SSE2 does not seem to work, skip test then. - return; + expected.Costs[i] = i; } - // arrange - int ctx0 = 0; - int expected = 20911; - string jsonString = File.ReadAllText(Path.Combine("TestDataWebp", "Vp8Residual.json")); - Vp8Residual residual = JsonSerializer.Deserialize(jsonString); + JsonSerializerOptions options = new() + { + Converters = { new Vp8CostArrayJsonConverter() } + }; // act - int actual = residual.GetResidualCost(ctx0); + string jsonString = JsonSerializer.Serialize(expected); + Vp8CostArray actual = JsonSerializer.Deserialize(jsonString, options); // assert - Assert.Equal(expected, actual); + Assert.Equal(expected.Costs, actual.Costs); } [Fact] - public void Serialization_Works() + public void Vp8Residual_Serialization_Works() { if (!Sse2.IsSupported) { @@ -101,6 +104,30 @@ public class Vp8ResidualTests } } + [Fact] + public void GetResidualCost_Works() + { + if (!Sse2.IsSupported) + { + // JsonSerializer without SSE2 does not seem to work, skip test then. + return; + } + + // arrange + int ctx0 = 0; + int expected = 20911; + string jsonString = File.ReadAllText(Path.Combine("TestDataWebp", "Vp8Residual.json")); + Vp8Residual residual = JsonSerializer.Deserialize(jsonString); + + // act + int actual = residual.GetResidualCost(ctx0); + + // assert + Assert.Equal(expected, actual); + } + + + private static void CreateRandomProbas(Vp8EncProba probas, Random rand) { for (int t = 0; t < WebpConstants.NumTypes; ++t) From ed71d7e1dd04ad4c5b062bcb3f59c5204a7f5fa4 Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Wed, 12 Apr 2023 19:36:19 +0200 Subject: [PATCH 09/13] Add additional constructors for json serialization and add JsonConstructor attributes --- .../Formats/Webp/Lossy/Vp8BandProbas.cs | 9 +++++++ .../Formats/Webp/Lossy/Vp8CostArray.cs | 9 +++++++ src/ImageSharp/Formats/Webp/Lossy/Vp8Costs.cs | 9 +++++++ .../Formats/Webp/Lossy/Vp8ProbaArray.cs | 9 +++++++ .../Formats/Webp/Lossy/Vp8Residual.cs | 17 +++++++++++++ src/ImageSharp/Formats/Webp/Lossy/Vp8Stats.cs | 9 +++++++ .../Formats/Webp/Lossy/Vp8StatsArray.cs | 9 +++++++ .../Vp8CostArrayJsonConverter.cs | 15 ----------- .../Formats/WebP/Vp8ResidualTests.cs | 25 ------------------- 9 files changed, 71 insertions(+), 40 deletions(-) delete mode 100644 tests/ImageSharp.Tests/Formats/WebP/Serialization/Vp8CostArrayJsonConverter.cs diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8BandProbas.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8BandProbas.cs index 90506efb8..86304d4bd 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8BandProbas.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8BandProbas.cs @@ -1,6 +1,8 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. +using System.Text.Json.Serialization; + namespace SixLabors.ImageSharp.Formats.Webp.Lossy; /// @@ -20,6 +22,13 @@ internal class Vp8BandProbas } } + /// + /// Initializes a new instance of the class. + /// Only used for unit tests. + /// + [JsonConstructor] + public Vp8BandProbas(Vp8ProbaArray[] probabilities) => this.Probabilities = probabilities; + /// /// Gets the Probabilities. /// diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8CostArray.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8CostArray.cs index 2c8d723d7..8268e1c02 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8CostArray.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8CostArray.cs @@ -1,6 +1,8 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. +using System.Text.Json.Serialization; + namespace SixLabors.ImageSharp.Formats.Webp.Lossy; internal class Vp8CostArray @@ -10,5 +12,12 @@ internal class Vp8CostArray /// public Vp8CostArray() => this.Costs = new ushort[67 + 1]; + /// + /// Initializes a new instance of the class. + /// Only used for unit tests. + /// + [JsonConstructor] + public Vp8CostArray(ushort[] costs) => this.Costs = costs; + public ushort[] Costs { get; } } diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8Costs.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8Costs.cs index eee22159e..2441436fb 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8Costs.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8Costs.cs @@ -1,6 +1,8 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. +using System.Text.Json.Serialization; + namespace SixLabors.ImageSharp.Formats.Webp.Lossy; internal class Vp8Costs @@ -17,6 +19,13 @@ internal class Vp8Costs } } + /// + /// Initializes a new instance of the class. + /// Only used for unit tests. + /// + [JsonConstructor] + public Vp8Costs(Vp8CostArray[] costs) => this.Costs = costs; + /// /// Gets the Costs. /// diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8ProbaArray.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8ProbaArray.cs index 337527542..a19f9742f 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8ProbaArray.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8ProbaArray.cs @@ -1,6 +1,8 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. +using System.Text.Json.Serialization; + namespace SixLabors.ImageSharp.Formats.Webp.Lossy; /// @@ -13,6 +15,13 @@ internal class Vp8ProbaArray /// public Vp8ProbaArray() => this.Probabilities = new byte[WebpConstants.NumProbas]; + /// + /// Initializes a new instance of the class. + /// Only used for unit tests. + /// + [JsonConstructor] + public Vp8ProbaArray(byte[] probabilities) => this.Probabilities = probabilities; + /// /// Gets the probabilities. /// diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs index 68bf09f94..6e0937d86 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs @@ -7,6 +7,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; +using System.Text.Json.Serialization; namespace SixLabors.ImageSharp.Formats.Webp.Lossy; @@ -15,6 +16,22 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy; /// internal class Vp8Residual { + public Vp8Residual() + { + } + + [JsonConstructor] + public Vp8Residual(int first, int last, int coeffType, short[] coeffs, Vp8BandProbas[] prob, Vp8Stats[] stats, Vp8Costs[] costs) + { + this.First = first; + this.Last = last; + this.CoeffType = coeffType; + this.Coeffs = coeffs; + this.Prob = prob; + this.Stats = stats; + this.Costs = costs; + } + public int First { get; set; } public int Last { get; set; } diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8Stats.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8Stats.cs index dda921a7c..b6c05f2d4 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8Stats.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8Stats.cs @@ -1,6 +1,8 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. +using System.Text.Json.Serialization; + namespace SixLabors.ImageSharp.Formats.Webp.Lossy; internal class Vp8Stats @@ -17,5 +19,12 @@ internal class Vp8Stats } } + /// + /// Initializes a new instance of the class. + /// Only used for unit tests. + /// + [JsonConstructor] + public Vp8Stats(Vp8StatsArray[] stats) => this.Stats = stats; + public Vp8StatsArray[] Stats { get; } } diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8StatsArray.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8StatsArray.cs index 2fbba6996..864248dd8 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8StatsArray.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8StatsArray.cs @@ -1,6 +1,8 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. +using System.Text.Json.Serialization; + namespace SixLabors.ImageSharp.Formats.Webp.Lossy; internal class Vp8StatsArray @@ -10,5 +12,12 @@ internal class Vp8StatsArray /// public Vp8StatsArray() => this.Stats = new uint[WebpConstants.NumProbas]; + /// + /// Initializes a new instance of the class. + /// Only used for unit tests. + /// + [JsonConstructor] + public Vp8StatsArray(uint[] stats) => this.Stats = stats; + public uint[] Stats { get; } } diff --git a/tests/ImageSharp.Tests/Formats/WebP/Serialization/Vp8CostArrayJsonConverter.cs b/tests/ImageSharp.Tests/Formats/WebP/Serialization/Vp8CostArrayJsonConverter.cs deleted file mode 100644 index b3cfd0340..000000000 --- a/tests/ImageSharp.Tests/Formats/WebP/Serialization/Vp8CostArrayJsonConverter.cs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Six Labors Split License. - -using System.Text.Json; -using System.Text.Json.Serialization; -using SixLabors.ImageSharp.Formats.Webp.Lossy; - -namespace SixLabors.ImageSharp.Tests.Formats.WebP.Serialization; - -internal class Vp8CostArrayJsonConverter : JsonConverter -{ - public override Vp8CostArray Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => throw new NotImplementedException(); - - public override void Write(Utf8JsonWriter writer, Vp8CostArray value, JsonSerializerOptions options) => throw new NotImplementedException(); -} diff --git a/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs b/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs index 457f3576f..20a161371 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs @@ -2,10 +2,8 @@ // Licensed under the Six Labors Split License. using System.Runtime.Intrinsics.X86; -using System.Text.Json; using SixLabors.ImageSharp.Formats.Webp; using SixLabors.ImageSharp.Formats.Webp.Lossy; -using SixLabors.ImageSharp.Tests.Formats.WebP.Serialization; using SixLabors.ImageSharp.Tests.TestUtilities; using JsonSerializer = System.Text.Json.JsonSerializer; @@ -14,29 +12,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp; [Trait("Format", "Webp")] public class Vp8ResidualTests { - [Fact] - public void Vp8CostArray_Serialization_Works() - { - // arrange - Vp8CostArray expected = new(); - for (ushort i = 0; i < expected.Costs.Length; i++) - { - expected.Costs[i] = i; - } - - JsonSerializerOptions options = new() - { - Converters = { new Vp8CostArrayJsonConverter() } - }; - - // act - string jsonString = JsonSerializer.Serialize(expected); - Vp8CostArray actual = JsonSerializer.Deserialize(jsonString, options); - - // assert - Assert.Equal(expected.Costs, actual.Costs); - } - [Fact] public void Vp8Residual_Serialization_Works() { From 39f8c776debeabba977055c2ac1007c437eeba01 Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Fri, 14 Apr 2023 19:50:09 +0200 Subject: [PATCH 10/13] Using Binary serialization for Vp8Residual --- .../Formats/Webp/Lossy/Vp8BandProbas.cs | 8 +---- .../Formats/Webp/Lossy/Vp8CostArray.cs | 10 +----- src/ImageSharp/Formats/Webp/Lossy/Vp8Costs.cs | 10 +----- .../Formats/Webp/Lossy/Vp8ProbaArray.cs | 10 +----- .../Formats/Webp/Lossy/Vp8Residual.cs | 13 +------ src/ImageSharp/Formats/Webp/Lossy/Vp8Stats.cs | 10 +----- .../Formats/Webp/Lossy/Vp8StatsArray.cs | 10 +----- .../Formats/WebP/Vp8ResidualTests.cs | 32 +++++++----------- .../ImageSharp.Tests/ImageSharp.Tests.csproj | 2 +- .../TestDataWebp/Vp8Residual.bin | Bin 0 -> 15043 bytes 10 files changed, 20 insertions(+), 85 deletions(-) create mode 100644 tests/ImageSharp.Tests/TestDataWebp/Vp8Residual.bin diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8BandProbas.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8BandProbas.cs index 86304d4bd..5db842ba3 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8BandProbas.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8BandProbas.cs @@ -8,6 +8,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy; /// /// All the probabilities associated to one band. /// +[Serializable] internal class Vp8BandProbas { /// @@ -22,13 +23,6 @@ internal class Vp8BandProbas } } - /// - /// Initializes a new instance of the class. - /// Only used for unit tests. - /// - [JsonConstructor] - public Vp8BandProbas(Vp8ProbaArray[] probabilities) => this.Probabilities = probabilities; - /// /// Gets the Probabilities. /// diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8CostArray.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8CostArray.cs index 8268e1c02..ba1b49881 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8CostArray.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8CostArray.cs @@ -1,10 +1,9 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -using System.Text.Json.Serialization; - namespace SixLabors.ImageSharp.Formats.Webp.Lossy; +[Serializable] internal class Vp8CostArray { /// @@ -12,12 +11,5 @@ internal class Vp8CostArray /// public Vp8CostArray() => this.Costs = new ushort[67 + 1]; - /// - /// Initializes a new instance of the class. - /// Only used for unit tests. - /// - [JsonConstructor] - public Vp8CostArray(ushort[] costs) => this.Costs = costs; - public ushort[] Costs { get; } } diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8Costs.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8Costs.cs index 2441436fb..676874820 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8Costs.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8Costs.cs @@ -1,10 +1,9 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -using System.Text.Json.Serialization; - namespace SixLabors.ImageSharp.Formats.Webp.Lossy; +[Serializable] internal class Vp8Costs { /// @@ -19,13 +18,6 @@ internal class Vp8Costs } } - /// - /// Initializes a new instance of the class. - /// Only used for unit tests. - /// - [JsonConstructor] - public Vp8Costs(Vp8CostArray[] costs) => this.Costs = costs; - /// /// Gets the Costs. /// diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8ProbaArray.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8ProbaArray.cs index a19f9742f..ddc1c9d61 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8ProbaArray.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8ProbaArray.cs @@ -1,13 +1,12 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -using System.Text.Json.Serialization; - namespace SixLabors.ImageSharp.Formats.Webp.Lossy; /// /// Probabilities associated to one of the contexts. /// +[Serializable] internal class Vp8ProbaArray { /// @@ -15,13 +14,6 @@ internal class Vp8ProbaArray /// public Vp8ProbaArray() => this.Probabilities = new byte[WebpConstants.NumProbas]; - /// - /// Initializes a new instance of the class. - /// Only used for unit tests. - /// - [JsonConstructor] - public Vp8ProbaArray(byte[] probabilities) => this.Probabilities = probabilities; - /// /// Gets the probabilities. /// diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs index 6e0937d86..58fba10a7 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs @@ -14,24 +14,13 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy; /// /// On-the-fly info about the current set of residuals. /// +[Serializable] internal class Vp8Residual { public Vp8Residual() { } - [JsonConstructor] - public Vp8Residual(int first, int last, int coeffType, short[] coeffs, Vp8BandProbas[] prob, Vp8Stats[] stats, Vp8Costs[] costs) - { - this.First = first; - this.Last = last; - this.CoeffType = coeffType; - this.Coeffs = coeffs; - this.Prob = prob; - this.Stats = stats; - this.Costs = costs; - } - public int First { get; set; } public int Last { get; set; } diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8Stats.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8Stats.cs index b6c05f2d4..23d63f322 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8Stats.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8Stats.cs @@ -1,10 +1,9 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -using System.Text.Json.Serialization; - namespace SixLabors.ImageSharp.Formats.Webp.Lossy; +[Serializable] internal class Vp8Stats { /// @@ -19,12 +18,5 @@ internal class Vp8Stats } } - /// - /// Initializes a new instance of the class. - /// Only used for unit tests. - /// - [JsonConstructor] - public Vp8Stats(Vp8StatsArray[] stats) => this.Stats = stats; - public Vp8StatsArray[] Stats { get; } } diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8StatsArray.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8StatsArray.cs index 864248dd8..2ab0702eb 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8StatsArray.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8StatsArray.cs @@ -1,10 +1,9 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -using System.Text.Json.Serialization; - namespace SixLabors.ImageSharp.Formats.Webp.Lossy; +[Serializable] internal class Vp8StatsArray { /// @@ -12,12 +11,5 @@ internal class Vp8StatsArray /// public Vp8StatsArray() => this.Stats = new uint[WebpConstants.NumProbas]; - /// - /// Initializes a new instance of the class. - /// Only used for unit tests. - /// - [JsonConstructor] - public Vp8StatsArray(uint[] stats) => this.Stats = stats; - public uint[] Stats { get; } } diff --git a/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs b/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs index 20a161371..2371a179e 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs @@ -1,11 +1,10 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -using System.Runtime.Intrinsics.X86; +using System.Runtime.Serialization.Formatters.Binary; using SixLabors.ImageSharp.Formats.Webp; using SixLabors.ImageSharp.Formats.Webp.Lossy; using SixLabors.ImageSharp.Tests.TestUtilities; -using JsonSerializer = System.Text.Json.JsonSerializer; namespace SixLabors.ImageSharp.Tests.Formats.Webp; @@ -15,12 +14,6 @@ public class Vp8ResidualTests [Fact] public void Vp8Residual_Serialization_Works() { - if (!Sse2.IsSupported) - { - // JsonSerializer without SSE2 does not seem to work, skip test then. - return; - } - // arrange Vp8Residual expected = new(); Vp8EncProba encProb = new(); @@ -34,8 +27,12 @@ public class Vp8ResidualTests } // act - string jsonString = JsonSerializer.Serialize(expected); - Vp8Residual actual = JsonSerializer.Deserialize(jsonString); + BinaryFormatter formatter = new(); + using MemoryStream ms = new(); + formatter.Serialize(ms, expected); + ms.Position = 0; + object obj = formatter.Deserialize(ms); + Vp8Residual actual = (Vp8Residual)obj; // assert Assert.Equal(expected.CoeffType, actual.CoeffType); @@ -82,17 +79,14 @@ public class Vp8ResidualTests [Fact] public void GetResidualCost_Works() { - if (!Sse2.IsSupported) - { - // JsonSerializer without SSE2 does not seem to work, skip test then. - return; - } - // arrange int ctx0 = 0; int expected = 20911; - string jsonString = File.ReadAllText(Path.Combine("TestDataWebp", "Vp8Residual.json")); - Vp8Residual residual = JsonSerializer.Deserialize(jsonString); + byte[] data = File.ReadAllBytes(Path.Combine("TestDataWebp", "Vp8Residual.bin")); + BinaryFormatter formatter = new(); + using Stream stream = new MemoryStream(data); + object obj = formatter.Deserialize(stream); + Vp8Residual residual = (Vp8Residual)obj; // act int actual = residual.GetResidualCost(ctx0); @@ -101,8 +95,6 @@ public class Vp8ResidualTests Assert.Equal(expected, actual); } - - private static void CreateRandomProbas(Vp8EncProba probas, Random rand) { for (int t = 0; t < WebpConstants.NumTypes; ++t) diff --git a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj index 270a02c0c..d17cffc4f 100644 --- a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj +++ b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj @@ -56,7 +56,7 @@ PreserveNewest - + PreserveNewest diff --git a/tests/ImageSharp.Tests/TestDataWebp/Vp8Residual.bin b/tests/ImageSharp.Tests/TestDataWebp/Vp8Residual.bin new file mode 100644 index 0000000000000000000000000000000000000000..d96a3c093a7e4e97708b276341d17cbad0047afc GIT binary patch literal 15043 zcmd6t3wRXO6~}irySbS>cJeUTiYQgAeb5jd3bcVLSXvQnDhO?@#SJVNi3!c4B_aqa zFTocIB0j*kf^S7pqauyst3^u{TT4Zup(3J)5|qb!e`mPOegVHa`R3bi_I&wge`n{O zdw0&gGiPQtWQ9VZq<-3- zl$Mm1^eidu-gR(8ReeKkVnB7Gp}sa=)xB$ZLq%2Pn9~xCBWfljst1hi-@jiX5${{k zv(K1#MbF+*dg*g(Za4vJTgrSo{*+2^qTdwFOp!}H!uhVM3` zM-t=cKVEhQ5<#L!rWOZZzW&ph*q7X+r;9sbtPri4K(2=M_ty^jG)w=FoZ#WBwCx6h z+9cg3h;1X;NDh*V}*#$@;QiL3a6eFFqDE5W)#kLVI zeaQ}&z7E$-?QbF9Mvg!_BS#`#kfV^Jk*>&hkYkWzk#5Lw$al3w*-stY&E)VXnfCFD z%Bsrx%EUnvJ>q2^%N#zrwl?0_HnZ&Gbte{Slze^o7ZiQW%lq6_th znDIhChM4+7KY>^SLS+z(L1+NPst_6ou{?x+3U$>Ybdr8!v0#KwhFCd5gCLfW&|rwQ zBywJ27pFLBEW`77j1EsFK-OWfgv9D$srMRDZtCGJQXhNQg#I-06Y`(;;AmkWitQN%~(wDdi zLXJbmYf&6*eTjP>AuEydwI~kTzQmnC$SULlEs7I>FLA30S%XZ}qBxcK688^;tVQay zC{9Yg#H}Y}1M){Ls;`!|xP3Zul9K8BCn8Ql8nr0SPkw~Gkcg9!i?k?Cbbf@LLd2=a z#aa|+Oh3X-(_!rC$R%17r(Qq8UP{EvkQrJO=Wsv5&LrY2WVRMXG2lnoIYhi1nX5%n zRrnEh9ucoVuGFF^Py7gb6%nsSuF;}S(&9(h`8te!EpnX}MZx4p*abvfh+MBl4btLA z*hNIV0a>g?QNsBV_C_M!gxst}Q49JJ_7);8L6&M!6qSC2y;X;?Z$oa^qNq;&2zv(+ z??mp>5~WP_a#`6{g&u&YTZJBks5^xof+#?R9)_qyg&u*ZB!wP@C@F;=gQzWqRzTE-LXSff zi9%06REt6@A*wy0Cn3r{p{F3~KcS}~>NlY#h(b>28HkEb=vnWa!q94n`c1a{GejXL)C?sIy#P^>$!9M@;|;BWD6QnP zmmq2^p_d_wEumK+iY1{}p(;bKL6lGO*aAECcOHHOwg6h!jb>ktKv&>IkyjnLm9 zN*tke5G9Jx-yv!hp*JCl7NNKFnJ7tmruUqUw;+5_EWXfJfLp?%OThW0~C z3?-qZhB$Lrw;Hmb+YE)F+YMzvcNmI5cN*f(zIB(OOij++nsW4Ccv{=bx#v*Mdk^JY zW}N$G?@w-iM`Ae3jq{o5pC&iGnZ)hfXPoCx-L&_uHpmClt^Oe>YA9G_qWSrKMUnF-DQE&OMajsn0n%uV0bv|O8r&qt7+}7ec zA2m)Zu_w9XK=a3pbJ^S-d$%1J=L+LIuD*HaW_=%>jvhBo>$UyK&krwE5&Pa9|X^mWPA8(n9Uaaxw! zR=b^NjB{6t^I7Bk-*$S-=MFd>{r?-koK<>LW{bC0&v&TR>b6#;`t3J+Ih@eEkFdEz ztzPI*D^8@|N5~1+dn-=N-dnxgp;nyez4!HMhgwlMc<+k>!+R?V5$~F{G$U#ZePErYuF9EL*gHSP3VNs6ocGL#mV|p{49UvR-4HvrAjJxgO|v;% zN=w$Bvld%DA|IZ1vZ~a`oZ*G#`6*UVo@R44n-Sd}-V`3H zwq(DQ*DXKA3c97)9BymKKDyG{V9kicGfV8wc_|j_oMv;lwIU-LX}u6ypSdM_b3v1n zV);#JHiz3gGNMW0bz!BpW*6tRG!YQDCyhE$Con zjoaYC${M%gWki9=8jk~ll{Fqo1S@Mi7713?cr+8Ntnqj#SXtu{Rj{(gW3pgnjYoCC z${LRggOxQNSq3X>JT?th)_8OqtgP|)I9OTZ5q7Y$#$)tgWsOJq!O9vxCkR&7_(_9| zD5O*0g8kXD6@wgc literal 0 HcmV?d00001 From 461224485d948009c593add446c0d427a45ffa1a Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Sat, 15 Apr 2023 21:01:37 +0200 Subject: [PATCH 11/13] Use BinaryWriter/BinaryReader to serialize Vp8Residual --- .../Formats/WebP/Vp8ResidualTests.cs | 129 ++++++++++++++++-- .../TestDataWebp/Vp8Residual.bin | Bin 15043 -> 7892 bytes 2 files changed, 117 insertions(+), 12 deletions(-) diff --git a/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs b/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs index 2371a179e..4982929c2 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/Vp8ResidualTests.cs @@ -1,7 +1,7 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -using System.Runtime.Serialization.Formatters.Binary; +using System.Text; using SixLabors.ImageSharp.Formats.Webp; using SixLabors.ImageSharp.Formats.Webp.Lossy; using SixLabors.ImageSharp.Tests.TestUtilities; @@ -11,6 +11,117 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp; [Trait("Format", "Webp")] public class Vp8ResidualTests { + private static void WriteVp8Residual(string filename, Vp8Residual residual) + { + using FileStream stream = File.Open(filename, FileMode.Create); + using BinaryWriter writer = new(stream, Encoding.UTF8, false); + + writer.Write(residual.First); + writer.Write(residual.Last); + writer.Write(residual.CoeffType); + + for (int i = 0; i < residual.Coeffs.Length; i++) + { + writer.Write(residual.Coeffs[i]); + } + + for (int i = 0; i < residual.Prob.Length; i++) + { + for (int j = 0; j < residual.Prob[i].Probabilities.Length; j++) + { + writer.Write(residual.Prob[i].Probabilities[j].Probabilities); + } + } + + for (int i = 0; i < residual.Costs.Length; i++) + { + Vp8Costs costs = residual.Costs[i]; + Vp8CostArray[] costsArray = costs.Costs; + for (int j = 0; j < costsArray.Length; j++) + { + for (int k = 0; k < costsArray[j].Costs.Length; k++) + { + writer.Write(costsArray[j].Costs[k]); + } + } + } + + for (int i = 0; i < residual.Stats.Length; i++) + { + for (int j = 0; j < residual.Stats[i].Stats.Length; j++) + { + for (int k = 0; k < residual.Stats[i].Stats[j].Stats.Length; k++) + { + writer.Write(residual.Stats[i].Stats[j].Stats[k]); + } + } + } + + writer.Flush(); + } + + private static Vp8Residual ReadVp8Residual(string fileName) + { + using FileStream stream = File.Open(fileName, FileMode.Open); + using BinaryReader reader = new(stream, Encoding.UTF8, false); + + Vp8Residual residual = new() + { + First = reader.ReadInt32(), + Last = reader.ReadInt32(), + CoeffType = reader.ReadInt32() + }; + + for (int i = 0; i < residual.Coeffs.Length; i++) + { + residual.Coeffs[i] = reader.ReadInt16(); + } + + Vp8BandProbas[] bandProbas = new Vp8BandProbas[8]; + for (int i = 0; i < bandProbas.Length; i++) + { + bandProbas[i] = new Vp8BandProbas(); + for (int j = 0; j < bandProbas[i].Probabilities.Length; j++) + { + for (int k = 0; k < 11; k++) + { + bandProbas[i].Probabilities[j].Probabilities[k] = reader.ReadByte(); + } + } + } + + residual.Prob = bandProbas; + + residual.Costs = new Vp8Costs[16]; + for (int i = 0; i < residual.Costs.Length; i++) + { + residual.Costs[i] = new Vp8Costs(); + Vp8CostArray[] costsArray = residual.Costs[i].Costs; + for (int j = 0; j < costsArray.Length; j++) + { + for (int k = 0; k < costsArray[j].Costs.Length; k++) + { + costsArray[j].Costs[k] = reader.ReadUInt16(); + } + } + } + + residual.Stats = new Vp8Stats[8]; + for (int i = 0; i < residual.Stats.Length; i++) + { + residual.Stats[i] = new Vp8Stats(); + for (int j = 0; j < residual.Stats[i].Stats.Length; j++) + { + for (int k = 0; k < residual.Stats[i].Stats[j].Stats.Length; k++) + { + residual.Stats[i].Stats[j].Stats[k] = reader.ReadUInt32(); + } + } + } + + return residual; + } + [Fact] public void Vp8Residual_Serialization_Works() { @@ -27,12 +138,10 @@ public class Vp8ResidualTests } // act - BinaryFormatter formatter = new(); - using MemoryStream ms = new(); - formatter.Serialize(ms, expected); - ms.Position = 0; - object obj = formatter.Deserialize(ms); - Vp8Residual actual = (Vp8Residual)obj; + string fileName = "Vp8SerializationTest.bin"; + WriteVp8Residual(fileName, expected); + Vp8Residual actual = ReadVp8Residual(fileName); + File.Delete(fileName); // assert Assert.Equal(expected.CoeffType, actual.CoeffType); @@ -82,11 +191,7 @@ public class Vp8ResidualTests // arrange int ctx0 = 0; int expected = 20911; - byte[] data = File.ReadAllBytes(Path.Combine("TestDataWebp", "Vp8Residual.bin")); - BinaryFormatter formatter = new(); - using Stream stream = new MemoryStream(data); - object obj = formatter.Deserialize(stream); - Vp8Residual residual = (Vp8Residual)obj; + Vp8Residual residual = ReadVp8Residual(Path.Combine("TestDataWebp", "Vp8Residual.bin")); // act int actual = residual.GetResidualCost(ctx0); diff --git a/tests/ImageSharp.Tests/TestDataWebp/Vp8Residual.bin b/tests/ImageSharp.Tests/TestDataWebp/Vp8Residual.bin index d96a3c093a7e4e97708b276341d17cbad0047afc..1fbb39277626b5f71603c8170ab24aee76bd1262 100644 GIT binary patch delta 661 zcmX?Hdd0S$k%57MABZ8~@BiQb85uxg3_y|zNd5-`2+73IKnVQp`1k+GZLq4nji3HM zzWN`;$*Oz&=i0^p|A9=#q#ys^JOVSfw!Zs!_f`G>SwLaGwo~7aZ2>E0-1+nWXOPl{ zh8@$s|9|rU%=FE>@&C;;Fq1L$_y3O&1*^J0{&@p2SheKH=O;j?0+leH`S<@TM8Ww5 zzy7}i>uN|#fBygSYKRFl{`~&{QLxdh{qz4<55d9#jhFu)dH_+u2$2SIz9E=!v4)1p zIr1HoCn!L$l48f?EkNw1)G_%65N9cOO#TDJeJUN36;wMWZvx^=dL5H57cJeUTiYQgAeb5jd3bcVLSXvQnDhO?@#SJVNi3!c4B_aqa zFTocIB0j*kf^S7pqauyst3^u{TT4Zup(3J)5|qb!e`mPOegVHa`R3bi_I&wge`n{O zdw0&gGiPQtWQ9VZq<-3- zl$Mm1^eidu-gR(8ReeKkVnB7Gp}sa=)xB$ZLq%2Pn9~xCBWfljst1hi-@jiX5${{k zv(K1#MbF+*dg*g(Za4vJTgrSo{*+2^qTdwFOp!}H!uhVM3` zM-t=cKVEhQ5<#L!rWOZZzW&ph*q7X+r;9sbtPri4K(2=M_ty^jG)w=FoZ#WBwCx6h z+9cg3h;1X;NDh*V}*#$@;QiL3a6eFFqDE5W)#kLVI zeaQ}&z7E$-?QbF9Mvg!_BS#`#kfV^Jk*>&hkYkWzk#5Lw$al3w*-stY&E)VXnfCFD z%Bsrx%EUnvJ>q2^%N#zrwl?0_HnZ&Gbte{Slze^o7ZiQW%lq6_th znDIhChM4+7KY>^SLS+z(L1+NPst_6ou{?x+3U$>Ybdr8!v0#KwhFCd5gCLfW&|rwQ zBywJ27pFLBEW`77j1EsFK-OWfgv9D$srMRDZtCGJQXhNQg#I-06Y`(;;AmkWitQN%~(wDdi zLXJbmYf&6*eTjP>AuEydwI~kTzQmnC$SULlEs7I>FLA30S%XZ}qBxcK688^;tVQay zC{9Yg#H}Y}1M){Ls;`!|xP3Zul9K8BCn8Ql8nr0SPkw~Gkcg9!i?k?Cbbf@LLd2=a z#aa|+Oh3X-(_!rC$R%17r(Qq8UP{EvkQrJO=Wsv5&LrY2WVRMXG2lnoIYhi1nX5%n zRrnEh9ucoVuGFF^Py7gb6%nsSuF;}S(&9(h`8te!EpnX}MZx4p*abvfh+MBl4btLA z*hNIV0a>g?QNsBV_C_M!gxst}Q49JJ_7);8L6&M!6qSC2y;X;?Z$oa^qNq;&2zv(+ z??mp>5~WP_a#`6{g&u&YTZJBks5^xof+#?R9)_qyg&u*ZB!wP@C@F;=gQzWqRzTE-LXSff zi9%06REt6@A*wy0Cn3r{p{F3~KcS}~>NlY#h(b>28HkEb=vnWa!q94n`c1a{GejXL)C?sIy#P^>$!9M@;|;BWD6QnP zmmq2^p_d_wEumK+iY1{}p(;bKL6lGO*aAECcOHHOwg6h!jb>ktKv&>IkyjnLm9 zN*tke5G9Jx-yv!hp*JCl7NNKFnJ7tmruUqUw;+5_EWXfJfLp?%OThW0~C z3?-qZhB$Lrw;Hmb+YE)F+YMzvcNmI5cN*f(zIB(OOij++nsW4Ccv{=bx#v*Mdk^JY zW}N$G?@w-iM`Ae3jq{o5pC&iGnZ)hfXPoCx-L&_uHpmClt^Oe>YA9G_qWSrKMUnF-DQE&OMajsn0n%uV0bv|O8r&qt7+}7ec zA2m)Zu_w9XK=a3pbJ^S-d$%1J=L+LIuD*HaW_=%>jvhBo>$UyK&krwE5&Pa9|X^mWPA8(n9Uaaxw! zR=b^NjB{6t^I7Bk-*$S-=MFd>{r?-koK<>LW{bC0&v&TR>b6#;`t3J+Ih@eEkFdEz ztzPI*D^8@|N5~1+dn-=N-dnxgp;nyez4!HMhgwlMc<+k>!+R?V5$~F{G$U#ZePErYuF9EL*gHSP3VNs6ocGL#mV|p{49UvR-4HvrAjJxgO|v;% zN=w$Bvld%DA|IZ1vZ~a`oZ*G#`6*UVo@R44n-Sd}-V`3H zwq(DQ*DXKA3c97)9BymKKDyG{V9kicGfV8wc_|j_oMv;lwIU-LX}u6ypSdM_b3v1n zV);#JHiz3gGNMW0bz!BpW*6tRG!YQDCyhE$Con zjoaYC${M%gWki9=8jk~ll{Fqo1S@Mi7713?cr+8Ntnqj#SXtu{Rj{(gW3pgnjYoCC z${LRggOxQNSq3X>JT?th)_8OqtgP|)I9OTZ5q7Y$#$)tgWsOJq!O9vxCkR&7_(_9| zD5O*0g8kXD6@wgc From c49cb7df5ddda913118fa59176602bc79695007f Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Sat, 15 Apr 2023 21:03:06 +0200 Subject: [PATCH 12/13] Remove [Serializable] attributes --- src/ImageSharp/Formats/Webp/Lossy/Vp8CostArray.cs | 1 - src/ImageSharp/Formats/Webp/Lossy/Vp8Costs.cs | 1 - src/ImageSharp/Formats/Webp/Lossy/Vp8ProbaArray.cs | 1 - src/ImageSharp/Formats/Webp/Lossy/Vp8Stats.cs | 1 - src/ImageSharp/Formats/Webp/Lossy/Vp8StatsArray.cs | 1 - 5 files changed, 5 deletions(-) diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8CostArray.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8CostArray.cs index ba1b49881..2c8d723d7 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8CostArray.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8CostArray.cs @@ -3,7 +3,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy; -[Serializable] internal class Vp8CostArray { /// diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8Costs.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8Costs.cs index 676874820..eee22159e 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8Costs.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8Costs.cs @@ -3,7 +3,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy; -[Serializable] internal class Vp8Costs { /// diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8ProbaArray.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8ProbaArray.cs index ddc1c9d61..337527542 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8ProbaArray.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8ProbaArray.cs @@ -6,7 +6,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy; /// /// Probabilities associated to one of the contexts. /// -[Serializable] internal class Vp8ProbaArray { /// diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8Stats.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8Stats.cs index 23d63f322..dda921a7c 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8Stats.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8Stats.cs @@ -3,7 +3,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy; -[Serializable] internal class Vp8Stats { /// diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8StatsArray.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8StatsArray.cs index 2ab0702eb..2fbba6996 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8StatsArray.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8StatsArray.cs @@ -3,7 +3,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy; -[Serializable] internal class Vp8StatsArray { /// From 81d47f4d50ed5652e79e7b21d6f807c625d3f182 Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Sat, 15 Apr 2023 21:07:47 +0200 Subject: [PATCH 13/13] Remove some missed Serializable attributes --- src/ImageSharp/Formats/Webp/Lossy/Vp8BandProbas.cs | 3 --- src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs | 6 ------ 2 files changed, 9 deletions(-) diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8BandProbas.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8BandProbas.cs index 5db842ba3..90506efb8 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8BandProbas.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8BandProbas.cs @@ -1,14 +1,11 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -using System.Text.Json.Serialization; - namespace SixLabors.ImageSharp.Formats.Webp.Lossy; /// /// All the probabilities associated to one band. /// -[Serializable] internal class Vp8BandProbas { /// diff --git a/src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs b/src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs index 58fba10a7..68bf09f94 100644 --- a/src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs +++ b/src/ImageSharp/Formats/Webp/Lossy/Vp8Residual.cs @@ -7,20 +7,14 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; -using System.Text.Json.Serialization; namespace SixLabors.ImageSharp.Formats.Webp.Lossy; /// /// On-the-fly info about the current set of residuals. /// -[Serializable] internal class Vp8Residual { - public Vp8Residual() - { - } - public int First { get; set; } public int Last { get; set; }