From 905931fbe7299061894b995519df08aced6ffcce Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sat, 26 Aug 2017 20:00:43 +0200 Subject: [PATCH] DCT.cs -> FastFloatingPointDCT.cs --- .../Components/Decoder/JpegBlockProcessor.cs | 2 +- .../{DCT.cs => FastFloatingPointDCT.cs} | 4 +- .../Jpeg/GolangPort/JpegEncoderCore.cs | 2 +- .../ImageSharp.Tests/Formats/Jpg/DCTTests.cs | 12 +-- ...plementationsTests.FastFloatingPointDCT.cs | 81 +++++++++---------- ...ImplementationsTests.StandardIntegerDCT.cs | 24 ++---- .../Jpg/Utils/JpegUtilityTestFixture.cs | 4 +- 7 files changed, 55 insertions(+), 74 deletions(-) rename src/ImageSharp/Formats/Jpeg/GolangPort/Components/{DCT.cs => FastFloatingPointDCT.cs} (98%) diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/JpegBlockProcessor.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/JpegBlockProcessor.cs index 4182e18a97..d65680901c 100644 --- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/JpegBlockProcessor.cs +++ b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/JpegBlockProcessor.cs @@ -77,7 +77,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder Block8x8F.UnZigAndQuantize(b, this.pointers.QuantiazationTable, this.pointers.Unzig); - DCT.TransformIDCT(ref *b, ref *this.pointers.Temp1, ref *this.pointers.Temp2); + FastFloatingPointDCT.TransformIDCT(ref *b, ref *this.pointers.Temp1, ref *this.pointers.Temp2); OldJpegPixelArea destChannel = decoder.GetDestinationChannel(this.componentIndex); OldJpegPixelArea destArea = destChannel.GetOffsetedSubAreaForBlock(bx, by); diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/DCT.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/FastFloatingPointDCT.cs similarity index 98% rename from src/ImageSharp/Formats/Jpeg/GolangPort/Components/DCT.cs rename to src/ImageSharp/Formats/Jpeg/GolangPort/Components/FastFloatingPointDCT.cs index 8229fb65bb..eba88c1c27 100644 --- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/DCT.cs +++ b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/FastFloatingPointDCT.cs @@ -9,9 +9,9 @@ using Block8x8F = SixLabors.ImageSharp.Formats.Jpeg.Common.Block8x8F; namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components { /// - /// Contains forward and inverse DCT implementations + /// Contains inaccurate, but fast forward and inverse DCT implementations. /// - internal static class DCT + internal static class FastFloatingPointDCT { #pragma warning disable SA1310 // FieldNamesMustNotContainUnderscore private static readonly float C_1_175876 = 1.175876f; diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/JpegEncoderCore.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/JpegEncoderCore.cs index 9924e0b6e7..f4cbcb4e9f 100644 --- a/src/ImageSharp/Formats/Jpeg/GolangPort/JpegEncoderCore.cs +++ b/src/ImageSharp/Formats/Jpeg/GolangPort/JpegEncoderCore.cs @@ -562,7 +562,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort Block8x8F* quant, int* unzigPtr) { - DCT.TransformFDCT(ref *src, ref *tempDest1, ref *tempDest2); + FastFloatingPointDCT.TransformFDCT(ref *src, ref *tempDest1, ref *tempDest2); Block8x8F.UnzigDivRound(tempDest1, tempDest2, quant, unzigPtr); float* unziggedDestPtr = (float*)tempDest2; diff --git a/tests/ImageSharp.Tests/Formats/Jpg/DCTTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/DCTTests.cs index 8c9c4bbca3..40a3895ad7 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/DCTTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/DCTTests.cs @@ -33,7 +33,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg Block8x8F dest = new Block8x8F(); - DCT.IDCT8x4_LeftPart(ref source, ref dest); + FastFloatingPointDCT.IDCT8x4_LeftPart(ref source, ref dest); float[] actualDestArray = new float[64]; dest.CopyTo(actualDestArray); @@ -58,7 +58,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg Block8x8F dest = new Block8x8F(); - DCT.IDCT8x4_RightPart(ref source, ref dest); + FastFloatingPointDCT.IDCT8x4_RightPart(ref source, ref dest); float[] actualDestArray = new float[64]; dest.CopyTo(actualDestArray); @@ -89,7 +89,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg Block8x8F dest = new Block8x8F(); Block8x8F tempBuffer = new Block8x8F(); - DCT.TransformIDCT(ref source, ref dest, ref tempBuffer); + FastFloatingPointDCT.TransformIDCT(ref source, ref dest, ref tempBuffer); float[] actualDestArray = new float[64]; dest.CopyTo(actualDestArray); @@ -116,7 +116,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg float[] expectedDest = new float[64]; ReferenceImplementations.FastFloatingPointDCT.fDCT2D8x4_32f(src, expectedDest); - DCT.FDCT8x4_LeftPart(ref srcBlock, ref destBlock); + FastFloatingPointDCT.FDCT8x4_LeftPart(ref srcBlock, ref destBlock); float[] actualDest = new float[64]; destBlock.CopyTo(actualDest); @@ -138,7 +138,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg float[] expectedDest = new float[64]; ReferenceImplementations.FastFloatingPointDCT.fDCT2D8x4_32f(src.Slice(4), expectedDest.AsSpan().Slice(4)); - DCT.FDCT8x4_RightPart(ref srcBlock, ref destBlock); + FastFloatingPointDCT.FDCT8x4_RightPart(ref srcBlock, ref destBlock); float[] actualDest = new float[64]; destBlock.CopyTo(actualDest); @@ -162,7 +162,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg Block8x8F temp2 = new Block8x8F(); ReferenceImplementations.FastFloatingPointDCT.fDCT2D_llm(src, expectedDest, temp1, downscaleBy8: true); - DCT.TransformFDCT(ref srcBlock, ref destBlock, ref temp2, false); + FastFloatingPointDCT.TransformFDCT(ref srcBlock, ref destBlock, ref temp2, false); float[] actualDest = new float[64]; destBlock.CopyTo(actualDest); diff --git a/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.FastFloatingPointDCT.cs b/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.FastFloatingPointDCT.cs index 66d9e8d0c9..96c2f1c9d9 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.FastFloatingPointDCT.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.FastFloatingPointDCT.cs @@ -35,32 +35,35 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg this.CompareBlocks(data.ConvertAllToFloat(), src, 2f); } - [Theory(Skip = "Sandboxing only! (Incorrect reference implementation)")] - [InlineData(42)] - [InlineData(1)] - [InlineData(2)] - public void IDCT_IsEquivalentTo_StandardIntegerImplementation(int seed) - { - int[] intData = JpegUtilityTestFixture.Create8x8RandomIntData(-1000, 1000, seed); - Span floatSrc = intData.ConvertAllToFloat(); + //[Theory(Skip = "Sandboxing only! (Incorrect reference implementation)")] + //[InlineData(42)] + //[InlineData(1)] + //[InlineData(2)] + //public void IDCT_IsEquivalentTo_StandardIntegerImplementation(int seed) + //{ + // int[] intData = JpegUtilityTestFixture.Create8x8RandomIntData(-1000, 1000, seed); + // Span floatSrc = intData.ConvertAllToFloat(); - ReferenceImplementations.StandardIntegerDCT.TransformIDCTInplace(intData); + // ReferenceImplementations.StandardIntegerDCT.TransformIDCTInplace(intData); - float[] dest = new float[64]; - float[] temp = new float[64]; + // float[] dest = new float[64]; + // float[] temp = new float[64]; - ReferenceImplementations.FastFloatingPointDCT.iDCT2D_llm(floatSrc, dest, temp); + // ReferenceImplementations.FastFloatingPointDCT.iDCT2D_llm(floatSrc, dest, temp); - this.CompareBlocks(intData.ConvertAllToFloat(), dest, 1f); - } + // this.CompareBlocks(intData.ConvertAllToFloat(), dest, 1f); + //} [Theory] - [InlineData(42)] - [InlineData(1)] - [InlineData(2)] - public void IDCT_IsEquivalentTo_AccurateImplementation(int seed) + [InlineData(42, 1000)] + [InlineData(1, 1000)] + [InlineData(2, 1000)] + [InlineData(42, 200)] + [InlineData(1, 200)] + [InlineData(2, 200)] + public void IDCT_IsEquivalentTo_AccurateImplementation(int seed, int range) { - int[] intData = JpegUtilityTestFixture.Create8x8RandomIntData(-1000, 1000, seed); + int[] intData = JpegUtilityTestFixture.Create8x8RandomIntData(-range, range, seed); float[] floatSrc = intData.ConvertAllToFloat(); ReferenceImplementations.AccurateDCT.TransformIDCTInplace(intData); @@ -73,24 +76,24 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg this.CompareBlocks(intData.ConvertAllToFloat(), dest, 1f); } - [Theory] - [InlineData(42)] - [InlineData(1)] - [InlineData(2)] - public void FDCT_IsEquivalentTo_StandardIntegerImplementation(int seed) - { - int[] intData = JpegUtilityTestFixture.Create8x8RandomIntData(-1000, 1000, seed); - float[] floatSrc = intData.ConvertAllToFloat(); + //[Theory] + //[InlineData(42)] + //[InlineData(1)] + //[InlineData(2)] + //public void FDCT_IsEquivalentTo_StandardIntegerImplementation(int seed) + //{ + // int[] intData = JpegUtilityTestFixture.Create8x8RandomIntData(-1000, 1000, seed); + // float[] floatSrc = intData.ConvertAllToFloat(); - ReferenceImplementations.StandardIntegerDCT.Subtract128_TransformFDCT_Upscale8_Inplace(intData); + // ReferenceImplementations.StandardIntegerDCT.Subtract128_TransformFDCT_Upscale8_Inplace(intData); - float[] dest = new float[64]; - float[] temp = new float[64]; + // float[] dest = new float[64]; + // float[] temp = new float[64]; - ReferenceImplementations.FastFloatingPointDCT.fDCT2D_llm(floatSrc, dest, temp, subtract128FromSource: true); + // ReferenceImplementations.FastFloatingPointDCT.fDCT2D_llm(floatSrc, dest, temp, subtract128FromSource: true); - this.CompareBlocks(intData.ConvertAllToFloat(), dest, 2f); - } + // this.CompareBlocks(intData.ConvertAllToFloat(), dest, 2f); + //} [Theory] [InlineData(42)] @@ -108,18 +111,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg actual /= 8; this.CompareBlocks(expected, actual, 1f); - - //int[] intData = JpegUtilityTestFixture.Create8x8RandomIntData(-1000, 1000, seed); - //float[] floatSrc = intData.ConvertAllToFloat(); - - //ReferenceImplementations.AccurateDCT.TransformFDCTInplace(intData); - - //float[] dest = new float[64]; - //float[] temp = new float[64]; - - //ReferenceImplementations.FastFloatingPointDCT.fDCT2D_llm(floatSrc, dest, temp, offsetSourceByNeg128: false); - - //this.CompareBlocks(intData.ConvertAllToFloat(), dest, 1f); } diff --git a/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.StandardIntegerDCT.cs b/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.StandardIntegerDCT.cs index 1ea9609bb4..e9e0503ed8 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.StandardIntegerDCT.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.StandardIntegerDCT.cs @@ -18,13 +18,13 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg { } - [Theory(Skip = "Sandboxing only! (Incorrect reference implementation)")] - [InlineData(42)] - [InlineData(1)] - [InlineData(2)] - public void IDCT_IsEquivalentTo_AccurateImplementation(int seed) + [Theory] + [InlineData(42, 200)] + [InlineData(1, 200)] + [InlineData(2, 200)] + public void IDCT_IsEquivalentTo_AccurateImplementation(int seed, int range) { - int[] data = Create8x8RandomIntData(-1000, 1000, seed); + int[] data = Create8x8RandomIntData(-range, range, seed); Block8x8 source = default(Block8x8); source.LoadFrom(data); @@ -32,17 +32,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg Block8x8 expected = ReferenceImplementations.AccurateDCT.TransformIDCT(ref source); Block8x8 actual = ReferenceImplementations.StandardIntegerDCT.TransformIDCT(ref source); - Block8x8F sourceF = source.AsFloatBlock(); - Block8x8F wut0 = ReferenceImplementations.FastFloatingPointDCT.TransformIDCT(ref sourceF); - Block8x8 wut1 = wut0.RoundAsInt16Block(); - - long diff = Block8x8.TotalDifference(ref expected, ref actual); - this.Output.WriteLine(expected.ToString()); - this.Output.WriteLine(actual.ToString()); - this.Output.WriteLine(wut1.ToString()); - this.Output.WriteLine("DIFFERENCE: "+diff); - - Assert.True(diff < 4); + this.CompareBlocks(expected, actual, 1); } [Theory] diff --git a/tests/ImageSharp.Tests/Formats/Jpg/Utils/JpegUtilityTestFixture.cs b/tests/ImageSharp.Tests/Formats/Jpg/Utils/JpegUtilityTestFixture.cs index 057a84fde3..1ecfeacef9 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/Utils/JpegUtilityTestFixture.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/Utils/JpegUtilityTestFixture.cs @@ -137,8 +137,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg.Utils this.Output.WriteLine(msg); } - internal void CompareBlocks(Block8x8 a, Block8x8 b, float tolerance) => - this.CompareBlocks(a.AsFloatBlock(), b.AsFloatBlock(), tolerance); + internal void CompareBlocks(Block8x8 a, Block8x8 b, int tolerance) => + this.CompareBlocks(a.AsFloatBlock(), b.AsFloatBlock(), (float)tolerance + 1e-5f); internal void CompareBlocks(Block8x8F a, Block8x8F b, float tolerance) => this.CompareBlocks(a.ToArray(), b.ToArray(), tolerance);