Browse Source

DCT.cs -> FastFloatingPointDCT.cs

pull/322/head
Anton Firszov 9 years ago
parent
commit
905931fbe7
  1. 2
      src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/JpegBlockProcessor.cs
  2. 4
      src/ImageSharp/Formats/Jpeg/GolangPort/Components/FastFloatingPointDCT.cs
  3. 2
      src/ImageSharp/Formats/Jpeg/GolangPort/JpegEncoderCore.cs
  4. 12
      tests/ImageSharp.Tests/Formats/Jpg/DCTTests.cs
  5. 81
      tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.FastFloatingPointDCT.cs
  6. 24
      tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.StandardIntegerDCT.cs
  7. 4
      tests/ImageSharp.Tests/Formats/Jpg/Utils/JpegUtilityTestFixture.cs

2
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);

4
src/ImageSharp/Formats/Jpeg/GolangPort/Components/DCT.cs → 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
{
/// <summary>
/// Contains forward and inverse DCT implementations
/// Contains inaccurate, but fast forward and inverse DCT implementations.
/// </summary>
internal static class DCT
internal static class FastFloatingPointDCT
{
#pragma warning disable SA1310 // FieldNamesMustNotContainUnderscore
private static readonly float C_1_175876 = 1.175876f;

2
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;

12
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);

81
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<float> 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<float> 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);
}

24
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]

4
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);

Loading…
Cancel
Save