Browse Source

auto-generated implementation for Block8x8.Transpose()

af/merge-core
Anton Firszov 10 years ago
parent
commit
ed155aafe2
  1. 23
      src/ImageSharp46/Formats/Jpg/Components/Block8x8.Generated.cs
  2. 46
      src/ImageSharp46/Formats/Jpg/Components/Block8x8.Generated.tt
  3. 41
      src/ImageSharp46/Formats/Jpg/Components/Block8x8.cs
  4. 8
      src/ImageSharp46/Formats/Jpg/JpegDecoderCore.cs
  5. 16
      src/ImageSharp46/ImageSharp46.csproj
  6. 136
      tests/ImageSharp.Tests46/Formats/Jpg/Block8x8Tests.cs
  7. 2
      tests/ImageSharp.Tests46/ImageSharp.Tests46.csproj

23
src/ImageSharp46/Formats/Jpg/Components/Block8x8.Generated.cs

@ -0,0 +1,23 @@

using System;
using System.Numerics;
using System.Runtime.CompilerServices;
namespace ImageSharp.Formats
{
public partial struct Block8x8
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void TransposeInto(ref Block8x8 d)
{
d.V0L.X = V0L.X; d.V1L.X = V0L.Y; d.V2L.X = V0L.Z; d.V3L.X = V0L.W; d.V4L.X = V0R.X; d.V5L.X = V0R.Y; d.V6L.X = V0R.Z; d.V7L.X = V0R.W;
d.V0L.Y = V1L.X; d.V1L.Y = V1L.Y; d.V2L.Y = V1L.Z; d.V3L.Y = V1L.W; d.V4L.Y = V1R.X; d.V5L.Y = V1R.Y; d.V6L.Y = V1R.Z; d.V7L.Y = V1R.W;
d.V0L.Z = V2L.X; d.V1L.Z = V2L.Y; d.V2L.Z = V2L.Z; d.V3L.Z = V2L.W; d.V4L.Z = V2R.X; d.V5L.Z = V2R.Y; d.V6L.Z = V2R.Z; d.V7L.Z = V2R.W;
d.V0L.W = V3L.X; d.V1L.W = V3L.Y; d.V2L.W = V3L.Z; d.V3L.W = V3L.W; d.V4L.W = V3R.X; d.V5L.W = V3R.Y; d.V6L.W = V3R.Z; d.V7L.W = V3R.W;
d.V0R.X = V4L.X; d.V1R.X = V4L.Y; d.V2R.X = V4L.Z; d.V3R.X = V4L.W; d.V4R.X = V4R.X; d.V5R.X = V4R.Y; d.V6R.X = V4R.Z; d.V7R.X = V4R.W;
d.V0R.Y = V5L.X; d.V1R.Y = V5L.Y; d.V2R.Y = V5L.Z; d.V3R.Y = V5L.W; d.V4R.Y = V5R.X; d.V5R.Y = V5R.Y; d.V6R.Y = V5R.Z; d.V7R.Y = V5R.W;
d.V0R.Z = V6L.X; d.V1R.Z = V6L.Y; d.V2R.Z = V6L.Z; d.V3R.Z = V6L.W; d.V4R.Z = V6R.X; d.V5R.Z = V6R.Y; d.V6R.Z = V6R.Z; d.V7R.Z = V6R.W;
d.V0R.W = V7L.X; d.V1R.W = V7L.Y; d.V2R.W = V7L.Z; d.V3R.W = V7L.W; d.V4R.W = V7R.X; d.V5R.W = V7R.Y; d.V6R.W = V7R.Z; d.V7R.W = V7R.W;
}
}
}

46
src/ImageSharp46/Formats/Jpg/Components/Block8x8.Generated.tt

@ -0,0 +1,46 @@
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".cs" #>
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
namespace ImageSharp.Formats
{
public partial struct Block8x8
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void TransposeInto(ref Block8x8 d)
{
<#
char[] coordz = new[] {'X', 'Y', 'Z', 'W'};
//StringBuilder bld = new StringBuilder();
PushIndent(" ");
for (int i = 0; i < 8; i++)
{
char destCoord = coordz[i % 4];
char destSide = (i / 4) % 2 == 0 ? 'L' : 'R';
for (int j = 0; j < 8; j++)
{
char srcCoord = coordz[j % 4];
char srcSide = (j / 4) % 2 == 0 ? 'L' : 'R';
string expression = $"d.V{j}{destSide}.{destCoord} = V{i}{srcSide}.{srcCoord}; ";
//bld.Append(expression);
Write(expression);
}
//bld.AppendLine();
WriteLine("");
}
PopIndent();
//Write(bld.ToString());
#>
}
}
}

41
src/ImageSharp46/Formats/Jpg/Components/Buffer8x8.cs → src/ImageSharp46/Formats/Jpg/Components/Block8x8.cs

@ -1,11 +1,11 @@
using System; using System;
using System.Numerics; using System.Numerics;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
// ReSharper disable InconsistentNaming
namespace ImageSharp.Formats namespace ImageSharp.Formats
{ {
// ReSharper disable once InconsistentNaming public partial struct Block8x8
public struct Buffer8x8
{ {
public Vector4 V0L; public Vector4 V0L;
public Vector4 V0R; public Vector4 V0R;
@ -103,7 +103,10 @@ namespace ImageSharp.Formats
} }
public unsafe void TranposeInto(ref Buffer8x8 destination) /// <summary>
/// Used as a reference implementation for benchmarking
/// </summary>
internal unsafe void TransposeInto_PinningImpl(ref Block8x8 destination)
{ {
fixed (Vector4* sPtr = &V0L) fixed (Vector4* sPtr = &V0L)
{ {
@ -125,14 +128,10 @@ namespace ImageSharp.Formats
} }
} }
public void TransposeIntoSafe(ref Buffer8x8 d)
{
}
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe void PinnedTransposeInto(Buffer8x8* sourcePtr, Buffer8x8* destPtr) public static unsafe void TransposeInto(Block8x8* sourcePtr, Block8x8* destPtr)
{ {
float* src = (float*)sourcePtr; float* src = (float*)sourcePtr;
float* dest = (float*) destPtr; float* dest = (float*) destPtr;
@ -147,7 +146,7 @@ namespace ImageSharp.Formats
} }
} }
private static readonly Vector4 _c = new Vector4(0.1250f);
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void MultiplyAllInplace(Vector4 s) public void MultiplyAllInplace(Vector4 s)
@ -159,18 +158,18 @@ namespace ImageSharp.Formats
} }
// ReSharper disable once InconsistentNaming // ReSharper disable once InconsistentNaming
public void TransformIDCTInto(ref Buffer8x8 dest, ref Buffer8x8 temp) public void IDCTInto(ref Block8x8 dest, ref Block8x8 temp)
{ {
TranposeInto(ref temp); TransposeInto(ref temp);
temp.iDCT2D8x4_LeftPart(ref dest); temp.iDCT2D8x4_LeftPart(ref dest);
temp.iDCT2D8x4_RightPart(ref dest); temp.iDCT2D8x4_RightPart(ref dest);
dest.TranposeInto(ref temp); dest.TransposeInto(ref temp);
temp.iDCT2D8x4_LeftPart(ref dest); temp.iDCT2D8x4_LeftPart(ref dest);
temp.iDCT2D8x4_RightPart(ref dest); temp.iDCT2D8x4_RightPart(ref dest);
dest.MultiplyAllInplace(new Vector4(0.1250f)); dest.MultiplyAllInplace(_0_125);
} }
private static readonly Vector4 _1_175876 = new Vector4(1.175876f); private static readonly Vector4 _1_175876 = new Vector4(1.175876f);
@ -185,8 +184,10 @@ namespace ImageSharp.Formats
private static readonly Vector4 _0_541196 = new Vector4(0.541196f); private static readonly Vector4 _0_541196 = new Vector4(0.541196f);
private static readonly Vector4 _1_847759 = new Vector4(-1.847759f); private static readonly Vector4 _1_847759 = new Vector4(-1.847759f);
private static readonly Vector4 _0_765367 = new Vector4(0.765367f); private static readonly Vector4 _0_765367 = new Vector4(0.765367f);
private static readonly Vector4 _0_125 = new Vector4(0.1250f);
internal void iDCT2D8x4_LeftPart(ref Buffer8x8 d) [MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void iDCT2D8x4_LeftPart(ref Block8x8 d)
{ {
/* /*
float a0,a1,a2,a3,b0,b1,b2,b3; float z0,z1,z2,z3,z4; float r[8]; int i; float a0,a1,a2,a3,b0,b1,b2,b3; float z0,z1,z2,z3,z4; float r[8]; int i;
@ -292,8 +293,8 @@ namespace ImageSharp.Formats
*/ */
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void iDCT2D8x4_RightPart(ref Buffer8x8 d) internal void iDCT2D8x4_RightPart(ref Block8x8 d)
{ {
/* /*
float a0,a1,a2,a3,b0,b1,b2,b3; float z0,z1,z2,z3,z4; float r[8]; int i; float a0,a1,a2,a3,b0,b1,b2,b3; float z0,z1,z2,z3,z4; float r[8]; int i;
@ -401,13 +402,13 @@ namespace ImageSharp.Formats
public static void SuchIDCT(ref Block block) public static void SuchIDCT(ref Block block)
{ {
Buffer8x8 source = new Buffer8x8(); Block8x8 source = new Block8x8();
source.LoadFrom(block.Data); source.LoadFrom(block.Data);
Buffer8x8 dest = new Buffer8x8(); Block8x8 dest = new Block8x8();
Buffer8x8 temp = new Buffer8x8(); Block8x8 temp = new Block8x8();
source.TransformIDCTInto(ref dest, ref temp); source.IDCTInto(ref dest, ref temp);
dest.CopyTo(block.Data); dest.CopyTo(block.Data);
} }
} }

8
src/ImageSharp46/Formats/Jpg/JpegDecoderCore.cs

@ -1814,7 +1814,7 @@ namespace ImageSharp.Formats
//IDCT.Transform(ref b); //IDCT.Transform(ref b);
//FloatIDCT.Transform(ref b); //FloatIDCT.Transform(ref b);
//ReferenceDCT.IDCT(ref b); //ReferenceDCT.IDCT(ref b);
Buffer8x8.SuchIDCT(ref b); Block8x8.SuchIDCT(ref b);
byte[] dst; byte[] dst;
int offset; int offset;
@ -2014,7 +2014,7 @@ namespace ImageSharp.Formats
break; break;
} }
zig = this.RefineNonZeroes(b, zig, zigEnd, val0, delta); zig = this.RefineNonZeroes(ref b, zig, zigEnd, val0, delta);
if (zig > zigEnd) if (zig > zigEnd)
{ {
throw new ImageFormatException($"Too many coefficients {zig} > {zigEnd}"); throw new ImageFormatException($"Too many coefficients {zig} > {zigEnd}");
@ -2030,7 +2030,7 @@ namespace ImageSharp.Formats
if (this.eobRun > 0) if (this.eobRun > 0)
{ {
this.eobRun--; this.eobRun--;
this.RefineNonZeroes(b, zig, zigEnd, -1, delta); this.RefineNonZeroes(ref b, zig, zigEnd, -1, delta);
} }
} }
@ -2044,7 +2044,7 @@ namespace ImageSharp.Formats
/// <param name="nz">The non-zero entry</param> /// <param name="nz">The non-zero entry</param>
/// <param name="delta">The low transform offset</param> /// <param name="delta">The low transform offset</param>
/// <returns>The <see cref="int"/></returns> /// <returns>The <see cref="int"/></returns>
private int RefineNonZeroes(Block b, int zig, int zigEnd, int nz, int delta) private int RefineNonZeroes(ref Block b, int zig, int zigEnd, int nz, int delta)
{ {
for (; zig <= zigEnd; zig++) for (; zig <= zigEnd; zig++)
{ {

16
src/ImageSharp46/ImageSharp46.csproj

@ -227,7 +227,12 @@
<Compile Include="Formats\IImageFormat.cs" /> <Compile Include="Formats\IImageFormat.cs" />
<Compile Include="Formats\Jpg\Components\Bits.cs" /> <Compile Include="Formats\Jpg\Components\Bits.cs" />
<Compile Include="Formats\Jpg\Components\Block.cs" /> <Compile Include="Formats\Jpg\Components\Block.cs" />
<Compile Include="Formats\Jpg\Components\Buffer8x8.cs" /> <Compile Include="Formats\Jpg\Components\Block8x8.cs" />
<Compile Include="Formats\Jpg\Components\Block8x8.Generated.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Block8x8.Generated.tt</DependentUpon>
</Compile>
<Compile Include="Formats\Jpg\Components\Bytes.cs" /> <Compile Include="Formats\Jpg\Components\Bytes.cs" />
<Compile Include="Formats\Jpg\Components\Component.cs" /> <Compile Include="Formats\Jpg\Components\Component.cs" />
<Compile Include="Formats\Jpg\Components\FDCT.cs" /> <Compile Include="Formats\Jpg\Components\FDCT.cs" />
@ -394,6 +399,15 @@
<None Include="packages.config" /> <None Include="packages.config" />
<None Include="Profiles\Exif\README.md" /> <None Include="Profiles\Exif\README.md" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Content Include="Formats\Jpg\Components\Block8x8.Generated.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>Block8x8.Generated.cs</LastGenOutput>
</Content>
</ItemGroup>
<ItemGroup>
<Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.

136
tests/ImageSharp.Tests46/Formats/Jpg/Buffer8x8Tests.cs → tests/ImageSharp.Tests46/Formats/Jpg/Block8x8Tests.cs

@ -2,6 +2,7 @@
using System.Diagnostics; using System.Diagnostics;
using System.Numerics; using System.Numerics;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Text;
using ImageSharp.Formats; using ImageSharp.Formats;
using Xunit; using Xunit;
using Xunit.Abstractions; using Xunit.Abstractions;
@ -9,9 +10,9 @@ using Xunit.Abstractions;
namespace ImageSharp.Tests.Formats.Jpg namespace ImageSharp.Tests.Formats.Jpg
{ {
// ReSharper disable once InconsistentNaming // ReSharper disable once InconsistentNaming
public class Buffer8x8Tests : UtilityTestClassBase public class Block8x8Tests : UtilityTestClassBase
{ {
public Buffer8x8Tests(ITestOutputHelper output) : base(output) public Block8x8Tests(ITestOutputHelper output) : base(output)
{ {
} }
@ -22,16 +23,16 @@ namespace ImageSharp.Tests.Formats.Jpg
{ {
float[] data = new float[Buffer8x8.ScalarCount]; float[] data = new float[Block8x8.ScalarCount];
float[] mirror = new float[Buffer8x8.ScalarCount]; float[] mirror = new float[Block8x8.ScalarCount];
for (int i = 0; i < Buffer8x8.ScalarCount; i++) for (int i = 0; i < Block8x8.ScalarCount; i++)
{ {
data[i] = i; data[i] = i;
} }
Measure(times, () => Measure(times, () =>
{ {
Buffer8x8 v = new Buffer8x8(); Block8x8 v = new Block8x8();
v.LoadFrom(data); v.LoadFrom(data);
v.CopyTo(mirror); v.CopyTo(mirror);
}); });
@ -47,16 +48,16 @@ namespace ImageSharp.Tests.Formats.Jpg
{ {
int[] data = new int[Buffer8x8.ScalarCount]; int[] data = new int[Block8x8.ScalarCount];
int[] mirror = new int[Buffer8x8.ScalarCount]; int[] mirror = new int[Block8x8.ScalarCount];
for (int i = 0; i < Buffer8x8.ScalarCount; i++) for (int i = 0; i < Block8x8.ScalarCount; i++)
{ {
data[i] = i; data[i] = i;
} }
Measure(times, () => Measure(times, () =>
{ {
Buffer8x8 v = new Buffer8x8(); Block8x8 v = new Block8x8();
v.LoadFrom(data); v.LoadFrom(data);
v.CopyTo(mirror); v.CopyTo(mirror);
}); });
@ -71,7 +72,7 @@ namespace ImageSharp.Tests.Formats.Jpg
float[] expected = Create8x8FloatData(); float[] expected = Create8x8FloatData();
ReferenceDCT.Transpose8x8(expected); ReferenceDCT.Transpose8x8(expected);
Buffer8x8 buffer = new Buffer8x8(); Block8x8 buffer = new Block8x8();
buffer.LoadFrom(Create8x8FloatData()); buffer.LoadFrom(Create8x8FloatData());
buffer.TransposeInplace(); buffer.TransposeInplace();
@ -83,16 +84,16 @@ namespace ImageSharp.Tests.Formats.Jpg
} }
[Fact] [Fact]
public void TransposeInto() public void TranposeInto_PinningImpl()
{ {
float[] expected = Create8x8FloatData(); float[] expected = Create8x8FloatData();
ReferenceDCT.Transpose8x8(expected); ReferenceDCT.Transpose8x8(expected);
Buffer8x8 source = new Buffer8x8(); Block8x8 source = new Block8x8();
source.LoadFrom(Create8x8FloatData()); source.LoadFrom(Create8x8FloatData());
Buffer8x8 dest = new Buffer8x8(); Block8x8 dest = new Block8x8();
source.TranposeInto(ref dest); source.TransposeInto_PinningImpl(ref dest);
float[] actual = new float[64]; float[] actual = new float[64];
dest.CopyTo(actual); dest.CopyTo(actual);
@ -101,16 +102,16 @@ namespace ImageSharp.Tests.Formats.Jpg
} }
[Fact] [Fact]
public void TransposeIntoSafe() public void TransposeInto()
{ {
float[] expected = Create8x8FloatData(); float[] expected = Create8x8FloatData();
ReferenceDCT.Transpose8x8(expected); ReferenceDCT.Transpose8x8(expected);
Buffer8x8 source = new Buffer8x8(); Block8x8 source = new Block8x8();
source.LoadFrom(Create8x8FloatData()); source.LoadFrom(Create8x8FloatData());
Buffer8x8 dest = new Buffer8x8(); Block8x8 dest = new Block8x8();
source.TransposeIntoSafe(ref dest); source.TransposeInto(ref dest);
float[] actual = new float[64]; float[] actual = new float[64];
dest.CopyTo(actual); dest.CopyTo(actual);
@ -119,20 +120,46 @@ namespace ImageSharp.Tests.Formats.Jpg
} }
[Fact] [Fact]
public unsafe void PinnedTransposeInto() public void Buffer8x8_TransposeInto_GeneratorTest()
{
char[] coordz = new[] {'X', 'Y', 'Z', 'W'};
StringBuilder bld = new StringBuilder();
for (int i = 0; i < 8; i++)
{
char destCoord = coordz[i % 4];
char destSide = (i / 4) % 2 == 0 ? 'L' : 'R';
for (int j = 0; j < 8; j++)
{
char srcCoord = coordz[j % 4];
char srcSide = (j / 4) % 2 == 0 ? 'L' : 'R';
string expression = $"d.V{j}{destSide}.{destCoord} = V{i}{srcSide}.{srcCoord}; ";
bld.Append(expression);
}
bld.AppendLine();
}
Output.WriteLine(bld.ToString());
}
[Fact]
public unsafe void TransposeInto_WithPointers()
{ {
float[] expected = Create8x8FloatData(); float[] expected = Create8x8FloatData();
ReferenceDCT.Transpose8x8(expected); ReferenceDCT.Transpose8x8(expected);
Buffer8x8 source = new Buffer8x8(); Block8x8 source = new Block8x8();
source.LoadFrom(Create8x8FloatData()); source.LoadFrom(Create8x8FloatData());
Buffer8x8 dest = new Buffer8x8(); Block8x8 dest = new Block8x8();
Buffer8x8* sPtr = &source; Block8x8* sPtr = &source;
Buffer8x8* dPtr = &dest; Block8x8* dPtr = &dest;
Buffer8x8.PinnedTransposeInto(sPtr, dPtr); Block8x8.TransposeInto(sPtr, dPtr);
float[] actual = new float[64]; float[] actual = new float[64];
dest.CopyTo(actual); dest.CopyTo(actual);
@ -142,53 +169,74 @@ namespace ImageSharp.Tests.Formats.Jpg
private class BufferHolder private class BufferHolder
{ {
public Buffer8x8 Buffer; public Block8x8 Buffer;
}
[Theory]
[InlineData(1)]
[InlineData(10000000)]
public void TranposeInto_Benchmark(int times)
{
BufferHolder source = new BufferHolder();
source.Buffer.LoadFrom(Create8x8FloatData());
BufferHolder dest = new BufferHolder();
Output.WriteLine($"TranposeInto_PinningImpl_Benchmark X {times} ...");
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < times; i++)
{
source.Buffer.TransposeInto(ref dest.Buffer);
}
sw.Stop();
Output.WriteLine($"TranposeInto_PinningImpl_Benchmark finished in {sw.ElapsedMilliseconds} ms");
} }
[Theory] [Theory]
[InlineData(1)] [InlineData(1)]
[InlineData(10000000)] [InlineData(10000000)]
public void TransposeInto_Benchmark(int times) public void TranposeInto_PinningImpl_Benchmark(int times)
{ {
BufferHolder source = new BufferHolder(); BufferHolder source = new BufferHolder();
source.Buffer.LoadFrom(Create8x8FloatData()); source.Buffer.LoadFrom(Create8x8FloatData());
BufferHolder dest = new BufferHolder(); BufferHolder dest = new BufferHolder();
Output.WriteLine($"TransposeInto_Benchmark X {times} ..."); Output.WriteLine($"TranposeInto_PinningImpl_Benchmark X {times} ...");
Stopwatch sw = Stopwatch.StartNew(); Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < times; i++) for (int i = 0; i < times; i++)
{ {
source.Buffer.TranposeInto(ref dest.Buffer); source.Buffer.TransposeInto_PinningImpl(ref dest.Buffer);
} }
sw.Stop(); sw.Stop();
Output.WriteLine($"TransposeInto_Benchmark finished in {sw.ElapsedMilliseconds} ms"); Output.WriteLine($"TranposeInto_PinningImpl_Benchmark finished in {sw.ElapsedMilliseconds} ms");
} }
[Theory] [Theory]
[InlineData(1)] [InlineData(1)]
[InlineData(10000000)] [InlineData(10000000)]
public unsafe void PinnedTransposeInto_Benchmark(int times) public unsafe void TransposeInto_WithPointers_Benchmark(int times)
{ {
BufferHolder source = new BufferHolder(); BufferHolder source = new BufferHolder();
source.Buffer.LoadFrom(Create8x8FloatData()); source.Buffer.LoadFrom(Create8x8FloatData());
BufferHolder dest = new BufferHolder(); BufferHolder dest = new BufferHolder();
fixed (Buffer8x8* sPtr = &source.Buffer) fixed (Block8x8* sPtr = &source.Buffer)
{ {
fixed (Buffer8x8* dPtr = &dest.Buffer) fixed (Block8x8* dPtr = &dest.Buffer)
{ {
Output.WriteLine($"PinnedTransposeInto_Benchmark X {times} ..."); Output.WriteLine($"TransposeInto_WithPointers_Benchmark X {times} ...");
Stopwatch sw = Stopwatch.StartNew(); Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < times; i++) for (int i = 0; i < times; i++)
{ {
Buffer8x8.PinnedTransposeInto(sPtr, dPtr); Block8x8.TransposeInto(sPtr, dPtr);
} }
sw.Stop(); sw.Stop();
Output.WriteLine($"PinnedTransposeInto_Benchmark finished in {sw.ElapsedMilliseconds} ms"); Output.WriteLine($"TransposeInto_WithPointers_Benchmark finished in {sw.ElapsedMilliseconds} ms");
} }
} }
@ -203,10 +251,10 @@ namespace ImageSharp.Tests.Formats.Jpg
ReferenceDCT.iDCT2D8x4_32f(sourceArray, expectedDestArray); ReferenceDCT.iDCT2D8x4_32f(sourceArray, expectedDestArray);
Buffer8x8 source = new Buffer8x8(); Block8x8 source = new Block8x8();
source.LoadFrom(sourceArray); source.LoadFrom(sourceArray);
Buffer8x8 dest = new Buffer8x8(); Block8x8 dest = new Block8x8();
source.iDCT2D8x4_LeftPart(ref dest); source.iDCT2D8x4_LeftPart(ref dest);
@ -228,10 +276,10 @@ namespace ImageSharp.Tests.Formats.Jpg
ReferenceDCT.iDCT2D8x4_32f(sourceArray.Slice(4), expectedDestArray.Slice(4)); ReferenceDCT.iDCT2D8x4_32f(sourceArray.Slice(4), expectedDestArray.Slice(4));
Buffer8x8 source = new Buffer8x8(); Block8x8 source = new Block8x8();
source.LoadFrom(sourceArray); source.LoadFrom(sourceArray);
Buffer8x8 dest = new Buffer8x8(); Block8x8 dest = new Block8x8();
source.iDCT2D8x4_RightPart(ref dest); source.iDCT2D8x4_RightPart(ref dest);
@ -254,13 +302,13 @@ namespace ImageSharp.Tests.Formats.Jpg
ReferenceDCT.iDCT8x8_llm_sse(sourceArray, expectedDestArray, tempArray); ReferenceDCT.iDCT8x8_llm_sse(sourceArray, expectedDestArray, tempArray);
Buffer8x8 source = new Buffer8x8(); Block8x8 source = new Block8x8();
source.LoadFrom(sourceArray); source.LoadFrom(sourceArray);
Buffer8x8 dest = new Buffer8x8(); Block8x8 dest = new Block8x8();
Buffer8x8 tempBuffer = new Buffer8x8(); Block8x8 tempBuffer = new Block8x8();
source.TransformIDCTInto(ref dest, ref tempBuffer); source.IDCTInto(ref dest, ref tempBuffer);
float[] actualDestArray = new float[64]; float[] actualDestArray = new float[64];
dest.CopyTo(actualDestArray); dest.CopyTo(actualDestArray);

2
tests/ImageSharp.Tests46/ImageSharp.Tests46.csproj

@ -74,7 +74,7 @@
<Compile Include="FileTestBase.cs" /> <Compile Include="FileTestBase.cs" />
<Compile Include="Formats\Bmp\BitmapTests.cs" /> <Compile Include="Formats\Bmp\BitmapTests.cs" />
<Compile Include="Formats\GeneralFormatTests.cs" /> <Compile Include="Formats\GeneralFormatTests.cs" />
<Compile Include="Formats\Jpg\Buffer8x8Tests.cs" /> <Compile Include="Formats\Jpg\Block8x8Tests.cs" />
<Compile Include="Formats\Jpg\DctTests.cs" /> <Compile Include="Formats\Jpg\DctTests.cs" />
<Compile Include="Formats\Jpg\JpegTests.cs" /> <Compile Include="Formats\Jpg\JpegTests.cs" />
<Compile Include="Formats\Jpg\UtilityTestClassBase.cs" /> <Compile Include="Formats\Jpg\UtilityTestClassBase.cs" />

Loading…
Cancel
Save