Browse Source

removed non master-branch-like junk

pull/34/head
Anton Firszov 9 years ago
parent
commit
7facf26009
  1. 402
      tests/ImageSharp.Tests46/Formats/Jpg/Block8x8FTests.cs
  2. 54
      tests/ImageSharp.Tests46/Formats/Jpg/DctTests.cs
  3. 364
      tests/ImageSharp.Tests46/Formats/Jpg/ReferenceImplementations.cs
  4. 95
      tests/ImageSharp.Tests46/Formats/Jpg/UtilityTestClassBase.cs
  5. 21
      tests/JpegBenchmark/JpegBenchmark.xproj
  6. 91
      tests/JpegBenchmark/Program.cs
  7. 19
      tests/JpegBenchmark/Properties/AssemblyInfo.cs
  8. 22
      tests/JpegBenchmark/project.json

402
tests/ImageSharp.Tests46/Formats/Jpg/Block8x8FTests.cs

@ -1,402 +0,0 @@
// Uncomment this to turn unit tests into benchmarks:
//#define BENCHMARKING
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using ImageSharp.Formats;
using Xunit;
using Xunit.Abstractions;
// ReSharper disable InconsistentNaming
namespace ImageSharp.Tests.Formats.Jpg
{
public class Block8x8FTests : UtilityTestClassBase
{
#if BENCHMARKING
public const int Times = 1000000;
#else
public const int Times = 1;
#endif
public Block8x8FTests(ITestOutputHelper output) : base(output)
{
}
[Fact]
public void Indexer()
{
float sum = 0;
Measure(Times, () =>
{
Block8x8F block = new Block8x8F();
for (int i = 0; i < Block8x8F.ScalarCount; i++)
{
block[i] = i;
}
sum = 0;
for (int i = 0; i < Block8x8F.ScalarCount; i++)
{
sum += block[i];
}
});
Assert.Equal(sum, 64f*63f*0.5f);
}
[Fact]
public unsafe void Indexer_GetScalarAt_SetScalarAt()
{
float sum = 0;
Measure(Times, () =>
{
Block8x8F block = new Block8x8F();
for (int i = 0; i < Block8x8F.ScalarCount; i++)
{
Block8x8F.SetScalarAt(&block, i, i);
}
sum = 0;
for (int i = 0; i < Block8x8F.ScalarCount; i++)
{
sum += Block8x8F.GetScalarAt(&block, i);
}
});
Assert.Equal(sum, 64f*63f*0.5f);
}
[Fact]
public void Indexer_ReferenceBenchmarkWithArray()
{
float sum = 0;
Measure(Times, () =>
{
//Block8x8F block = new Block8x8F();
float[] block = new float[64];
for (int i = 0; i < Block8x8F.ScalarCount; i++)
{
block[i] = i;
}
sum = 0;
for (int i = 0; i < Block8x8F.ScalarCount; i++)
{
sum += block[i];
}
});
Assert.Equal(sum, 64f*63f*0.5f);
}
[Fact]
public void Load_Store_FloatArray()
{
float[] data = new float[Block8x8F.ScalarCount];
float[] mirror = new float[Block8x8F.ScalarCount];
for (int i = 0; i < Block8x8F.ScalarCount; i++)
{
data[i] = i;
}
Measure(Times, () =>
{
Block8x8F b = new Block8x8F();
b.LoadFrom(data);
b.CopyTo(mirror);
});
Assert.Equal(data, mirror);
//PrintLinearData((MutableSpan<float>)mirror);
}
[Fact]
public unsafe void Load_Store_FloatArray_Ptr()
{
float[] data = new float[Block8x8F.ScalarCount];
float[] mirror = new float[Block8x8F.ScalarCount];
for (int i = 0; i < Block8x8F.ScalarCount; i++)
{
data[i] = i;
}
Measure(Times, () =>
{
Block8x8F b = new Block8x8F();
Block8x8F.LoadFrom(&b, data);
Block8x8F.CopyTo(&b, mirror);
});
Assert.Equal(data, mirror);
//PrintLinearData((MutableSpan<float>)mirror);
}
[Fact]
public void Load_Store_IntArray()
{
int[] data = new int[Block8x8F.ScalarCount];
int[] mirror = new int[Block8x8F.ScalarCount];
for (int i = 0; i < Block8x8F.ScalarCount; i++)
{
data[i] = i;
}
Measure(Times, () =>
{
Block8x8F v = new Block8x8F();
v.LoadFrom(data);
v.CopyTo(mirror);
});
Assert.Equal(data, mirror);
//PrintLinearData((MutableSpan<int>)mirror);
}
[Fact]
public void TransposeInplace()
{
float[] expected = Create8x8FloatData();
ReferenceImplementations.Transpose8x8(expected);
Block8x8F buffer = new Block8x8F();
buffer.LoadFrom(Create8x8FloatData());
buffer.TransposeInplace();
float[] actual = new float[64];
buffer.CopyTo(actual);
Assert.Equal(expected, actual);
}
[Fact]
public void TransposeInto()
{
float[] expected = Create8x8FloatData();
ReferenceImplementations.Transpose8x8(expected);
Block8x8F source = new Block8x8F();
source.LoadFrom(Create8x8FloatData());
Block8x8F dest = new Block8x8F();
source.TransposeInto(ref dest);
float[] actual = new float[64];
dest.CopyTo(actual);
Assert.Equal(expected, actual);
}
private class BufferHolder
{
public Block8x8F Buffer;
}
[Fact]
public void TranposeInto_Benchmark()
{
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");
}
[Fact]
public void iDCT2D8x4_LeftPart()
{
float[] sourceArray = Create8x8FloatData();
float[] expectedDestArray = new float[64];
ReferenceImplementations.iDCT2D8x4_32f(sourceArray, expectedDestArray);
Block8x8F source = new Block8x8F();
source.LoadFrom(sourceArray);
Block8x8F dest = new Block8x8F();
source.iDCT2D8x4_LeftPart(ref dest);
float[] actualDestArray = new float[64];
dest.CopyTo(actualDestArray);
Print8x8Data(expectedDestArray);
Output.WriteLine("**************");
Print8x8Data(actualDestArray);
Assert.Equal(expectedDestArray, actualDestArray);
}
[Fact]
public void iDCT2D8x4_RightPart()
{
MutableSpan<float> sourceArray = Create8x8FloatData();
MutableSpan<float> expectedDestArray = new float[64];
ReferenceImplementations.iDCT2D8x4_32f(sourceArray.Slice(4), expectedDestArray.Slice(4));
Block8x8F source = new Block8x8F();
source.LoadFrom(sourceArray);
Block8x8F dest = new Block8x8F();
source.iDCT2D8x4_RightPart(ref dest);
float[] actualDestArray = new float[64];
dest.CopyTo(actualDestArray);
Print8x8Data(expectedDestArray);
Output.WriteLine("**************");
Print8x8Data(actualDestArray);
Assert.Equal(expectedDestArray.Data, actualDestArray);
}
private struct ApproximateFloatComparer : IEqualityComparer<float>
{
private const float Eps = 0.0001f;
public bool Equals(float x, float y)
{
float d = x - y;
return d > -Eps && d < Eps;
}
public int GetHashCode(float obj)
{
throw new InvalidOperationException();
}
}
[Fact]
public void IDCTInto()
{
float[] sourceArray = Create8x8FloatData();
float[] expectedDestArray = new float[64];
float[] tempArray = new float[64];
ReferenceImplementations.iDCT2D_llm(sourceArray, expectedDestArray, tempArray);
//ReferenceImplementations.iDCT8x8_llm_sse(sourceArray, expectedDestArray, tempArray);
Block8x8F source = new Block8x8F();
source.LoadFrom(sourceArray);
Block8x8F dest = new Block8x8F();
Block8x8F tempBuffer = new Block8x8F();
source.IDCTInto(ref dest, ref tempBuffer);
float[] actualDestArray = new float[64];
dest.CopyTo(actualDestArray);
Print8x8Data(expectedDestArray);
Output.WriteLine("**************");
Print8x8Data(actualDestArray);
Assert.Equal(expectedDestArray, actualDestArray, new ApproximateFloatComparer());
Assert.Equal(expectedDestArray, actualDestArray, new ApproximateFloatComparer());
}
[Fact]
public unsafe void CopyColorsTo()
{
var data = Create8x8FloatData();
Block8x8F block = new Block8x8F();
block.LoadFrom(data);
block.MultiplyAllInplace(new Vector4(5, 5, 5, 5));
int stride = 256;
int height = 42;
int offset = height*10 + 20;
byte[] colorsExpected = new byte[stride*height];
byte[] colorsActual = new byte[stride*height];
Block8x8F temp = new Block8x8F();
ReferenceImplementations.CopyColorsTo(ref block, new MutableSpan<byte>(colorsExpected, offset), stride);
block.CopyColorsTo(new MutableSpan<byte>(colorsActual, offset), stride, &temp);
//Output.WriteLine("******* EXPECTED: *********");
//PrintLinearData(colorsExpected);
//Output.WriteLine("******** ACTUAL: **********");
Assert.Equal(colorsExpected, colorsActual);
}
[Fact]
public void CropInto()
{
Block8x8F block = new Block8x8F();
block.LoadFrom(Create8x8FloatData());
Block8x8F dest = new Block8x8F();
block.CropInto(10, 20, ref dest);
float[] array = new float[64];
dest.CopyTo(array);
PrintLinearData(array);
foreach (float val in array)
{
Assert.InRange(val, 10, 20);
}
}
private static float[] Create8x8ColorCropTestData()
{
float[] result = new float[64];
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
result[i * 8 + j] = -300 + i * 100 + j * 10;
}
}
return result;
}
[Fact]
public void ColorifyInto()
{
Block8x8F block = new Block8x8F();
var input = Create8x8ColorCropTestData();
block.LoadFrom(input);
Output.WriteLine("Input:");
PrintLinearData(input);
Block8x8F dest = new Block8x8F();
block.ColorifyInto(ref dest);
float[] array = new float[64];
dest.CopyTo(array);
Output.WriteLine("Result:");
PrintLinearData(array);
foreach (float val in array)
{
Assert.InRange(val, 0, 255);
}
}
}
}

54
tests/ImageSharp.Tests46/Formats/Jpg/DctTests.cs

@ -1,54 +0,0 @@
using System.Numerics;
using ImageSharp.Formats;
using Xunit;
using Xunit.Abstractions;
namespace ImageSharp.Tests.Formats.Jpg
{
public class DctTests : UtilityTestClassBase
{
public DctTests(ITestOutputHelper output)
: base(output)
{
}
[Fact]
public void Mennyi()
{
Output.WriteLine(Vector.IsHardwareAccelerated.ToString());
Output.WriteLine(Vector<float>.Count.ToString());
}
[Fact]
public void CheckTestData()
{
var data = Create8x8FloatData();
Print8x8Data(data);
}
[Fact]
public void Transpose8x8()
{
var data = Create8x8FloatData();
MutableSpan<float> result = new MutableSpan<float>(64);
ReferenceImplementations.Transpose8x8(data, result);
Print8x8Data(result.Data);
}
[Fact]
public void Transpose8x8_Inplace()
{
var data = Create8x8FloatData();
ReferenceImplementations.Transpose8x8(data);
Print8x8Data(data);
}
}
}

364
tests/ImageSharp.Tests46/Formats/Jpg/ReferenceImplementations.cs

@ -1,364 +0,0 @@
using System;
using System.Buffers;
using System.Numerics;
using System.Runtime.CompilerServices;
using ImageSharp.Formats;
// ReSharper disable InconsistentNaming
namespace ImageSharp.Tests.Formats.Jpg
{
/// <summary>
/// This class contains simplified (unefficient) reference implementations to produce verification data for unit tests
/// DCT code Ported from https://github.com/norishigefukushima/dct_simd
/// </summary>
internal static class ReferenceImplementations
{
internal static void Transpose8x8(MutableSpan<float> data)
{
for (int i = 1; i < 8; i++)
{
int i8 = i*8;
for (int j = 0; j < i; j++)
{
float tmp = data[i8 + j];
data[i8 + j] = data[j*8 + i];
data[j*8 + i] = tmp;
}
}
}
internal static void Transpose8x8(MutableSpan<float> src, MutableSpan<float> dest)
{
for (int i = 0; i < 8; i++)
{
int i8 = i*8;
for (int j = 0; j < 8; j++)
{
dest[j*8 + i] = src[i8 + j];
}
}
}
internal static void iDCT1Dllm_32f(MutableSpan<float> y, MutableSpan<float> x)
{
float a0, a1, a2, a3, b0, b1, b2, b3;
float z0, z1, z2, z3, z4;
float r0 = 1.414214f;
float r1 = 1.387040f;
float r2 = 1.306563f;
float r3 = 1.175876f;
float r4 = 1.000000f;
float r5 = 0.785695f;
float r6 = 0.541196f;
float r7 = 0.275899f;
z0 = y[1] + y[7];
z1 = y[3] + y[5];
z2 = y[3] + y[7];
z3 = y[1] + y[5];
z4 = (z0 + z1)*r3;
z0 = z0*(-r3 + r7);
z1 = z1*(-r3 - r1);
z2 = z2*(-r3 - r5) + z4;
z3 = z3*(-r3 + r5) + z4;
b3 = y[7]*(-r1 + r3 + r5 - r7) + z0 + z2;
b2 = y[5]*(r1 + r3 - r5 + r7) + z1 + z3;
b1 = y[3]*(r1 + r3 + r5 - r7) + z1 + z2;
b0 = y[1]*(r1 + r3 - r5 - r7) + z0 + z3;
z4 = (y[2] + y[6])*r6;
z0 = y[0] + y[4];
z1 = y[0] - y[4];
z2 = z4 - y[6]*(r2 + r6);
z3 = z4 + y[2]*(r2 - r6);
a0 = z0 + z3;
a3 = z0 - z3;
a1 = z1 + z2;
a2 = z1 - z2;
x[0] = a0 + b0;
x[7] = a0 - b0;
x[1] = a1 + b1;
x[6] = a1 - b1;
x[2] = a2 + b2;
x[5] = a2 - b2;
x[3] = a3 + b3;
x[4] = a3 - b3;
}
internal static void iDCT2D_llm(MutableSpan<float> s, MutableSpan<float> d, MutableSpan<float> temp)
{
int j;
for (j = 0; j < 8; j++)
{
iDCT1Dllm_32f(s.Slice(j*8), temp.Slice(j*8));
}
Transpose8x8(temp, d);
for (j = 0; j < 8; j++)
{
iDCT1Dllm_32f(d.Slice(j*8), temp.Slice(j*8));
}
Transpose8x8(temp, d);
for (j = 0; j < 64; j++)
{
d[j] *= 0.125f;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector4 _mm_load_ps(MutableSpan<float> src, int offset)
{
src = src.Slice(offset);
return new Vector4(src[0], src[1], src[2], src[3]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector4 _mm_load_ps(MutableSpan<float> src)
{
return new Vector4(src[0], src[1], src[2], src[3]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void _mm_store_ps(MutableSpan<float> dest, int offset, Vector4 src)
{
dest = dest.Slice(offset);
dest[0] = src.X;
dest[1] = src.Y;
dest[2] = src.Z;
dest[3] = src.W;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void _mm_store_ps(MutableSpan<float> dest, Vector4 src)
{
dest[0] = src.X;
dest[1] = src.Y;
dest[2] = src.Z;
dest[3] = src.W;
}
private static readonly Vector4 _1_175876 = new Vector4(1.175876f);
private static readonly Vector4 _1_961571 = new Vector4(-1.961571f);
private static readonly Vector4 _0_390181 = new Vector4(-0.390181f);
private static readonly Vector4 _0_899976 = new Vector4(-0.899976f);
private static readonly Vector4 _2_562915 = new Vector4(-2.562915f);
private static readonly Vector4 _0_298631 = new Vector4(0.298631f);
private static readonly Vector4 _2_053120 = new Vector4(2.053120f);
private static readonly Vector4 _3_072711 = new Vector4(3.072711f);
private static readonly Vector4 _1_501321 = new Vector4(1.501321f);
private static readonly Vector4 _0_541196 = new Vector4(0.541196f);
private static readonly Vector4 _1_847759 = new Vector4(-1.847759f);
private static readonly Vector4 _0_765367 = new Vector4(0.765367f);
internal static void iDCT2D8x4_32f(MutableSpan<float> y, MutableSpan<float> x)
{
/*
float a0,a1,a2,a3,b0,b1,b2,b3; float z0,z1,z2,z3,z4; float r[8]; int i;
for(i = 0;i < 8;i++){ r[i] = (float)(cos((double)i / 16.0 * M_PI) * M_SQRT2); }
*/
/*
0: 1.414214
1: 1.387040
2: 1.306563
3:
4: 1.000000
5: 0.785695
6:
7: 0.275899
*/
Vector4 my1 = _mm_load_ps(y, 8);
Vector4 my7 = _mm_load_ps(y, 56);
Vector4 mz0 = my1 + my7;
Vector4 my3 = _mm_load_ps(y, 24);
Vector4 mz2 = my3 + my7;
Vector4 my5 = _mm_load_ps(y, 40);
Vector4 mz1 = my3 + my5;
Vector4 mz3 = my1 + my5;
Vector4 mz4 = ((mz0 + mz1)* _1_175876);
//z0 = y[1] + y[7]; z1 = y[3] + y[5]; z2 = y[3] + y[7]; z3 = y[1] + y[5];
//z4 = (z0 + z1) * r[3];
mz2 = mz2* _1_961571 + mz4;
mz3 = mz3* _0_390181 + mz4;
mz0 = mz0* _0_899976;
mz1 = mz1* _2_562915;
/*
-0.899976
-2.562915
-1.961571
-0.390181
z0 = z0 * (-r[3] + r[7]);
z1 = z1 * (-r[3] - r[1]);
z2 = z2 * (-r[3] - r[5]) + z4;
z3 = z3 * (-r[3] + r[5]) + z4;*/
Vector4 mb3 = my7* _0_298631 + mz0 + mz2;
Vector4 mb2 = my5* _2_053120 + mz1 + mz3;
Vector4 mb1 = my3* _3_072711 + mz1 + mz2;
Vector4 mb0 = my1* _1_501321 + mz0 + mz3;
/*
0.298631
2.053120
3.072711
1.501321
b3 = y[7] * (-r[1] + r[3] + r[5] - r[7]) + z0 + z2;
b2 = y[5] * ( r[1] + r[3] - r[5] + r[7]) + z1 + z3;
b1 = y[3] * ( r[1] + r[3] + r[5] - r[7]) + z1 + z2;
b0 = y[1] * ( r[1] + r[3] - r[5] - r[7]) + z0 + z3;
*/
Vector4 my2 = _mm_load_ps(y, 16);
Vector4 my6 = _mm_load_ps(y, 48);
mz4 = (my2 + my6)* _0_541196;
Vector4 my0 = _mm_load_ps(y, 0);
Vector4 my4 = _mm_load_ps(y, 32);
mz0 = my0 + my4;
mz1 = my0 - my4;
mz2 = mz4 + my6* _1_847759;
mz3 = mz4 + my2* _0_765367;
my0 = mz0 + mz3;
my3 = mz0 - mz3;
my1 = mz1 + mz2;
my2 = mz1 - mz2;
/*
1.847759
0.765367
z4 = (y[2] + y[6]) * r[6];
z0 = y[0] + y[4]; z1 = y[0] - y[4];
z2 = z4 - y[6] * (r[2] + r[6]);
z3 = z4 + y[2] * (r[2] - r[6]);
a0 = z0 + z3; a3 = z0 - z3;
a1 = z1 + z2; a2 = z1 - z2;
*/
_mm_store_ps(x, 0, my0 + mb0);
_mm_store_ps(x, 56, my0 - mb0);
_mm_store_ps(x, 8, my1 + mb1);
_mm_store_ps(x, 48, my1 - mb1);
_mm_store_ps(x, 16, my2 + mb2);
_mm_store_ps(x, 40, my2 - mb2);
_mm_store_ps(x, 24, my3 + mb3);
_mm_store_ps(x, 32, my3 - mb3);
/*
x[0] = a0 + b0; x[7] = a0 - b0;
x[1] = a1 + b1; x[6] = a1 - b1;
x[2] = a2 + b2; x[5] = a2 - b2;
x[3] = a3 + b3; x[4] = a3 - b3;
for(i = 0;i < 8;i++){ x[i] *= 0.353554f; }
*/
}
internal static void iDCT8x8_llm_sse(MutableSpan<float> s, MutableSpan<float> d, MutableSpan<float> temp)
{
Transpose8x8(s, temp);
iDCT2D8x4_32f(temp, d);
iDCT2D8x4_32f(temp.Slice(4), d.Slice(4));
Transpose8x8(d, temp);
iDCT2D8x4_32f(temp, d);
iDCT2D8x4_32f(temp.Slice(4), d.Slice(4));
Vector4 c = new Vector4(0.1250f);
_mm_store_ps(d, (_mm_load_ps(d)*c));d.AddOffset(4);//0
_mm_store_ps(d, (_mm_load_ps(d)*c));d.AddOffset(4);//1
_mm_store_ps(d, (_mm_load_ps(d)*c));d.AddOffset(4);//2
_mm_store_ps(d, (_mm_load_ps(d)*c));d.AddOffset(4);//3
_mm_store_ps(d, (_mm_load_ps(d)*c));d.AddOffset(4);//4
_mm_store_ps(d, (_mm_load_ps(d)*c));d.AddOffset(4);//5
_mm_store_ps(d, (_mm_load_ps(d)*c));d.AddOffset(4);//6
_mm_store_ps(d, (_mm_load_ps(d)*c));d.AddOffset(4);//7
_mm_store_ps(d, (_mm_load_ps(d)*c));d.AddOffset(4);//8
_mm_store_ps(d, (_mm_load_ps(d)*c));d.AddOffset(4);//9
_mm_store_ps(d, (_mm_load_ps(d)*c));d.AddOffset(4);//10
_mm_store_ps(d, (_mm_load_ps(d)*c));d.AddOffset(4);//11
_mm_store_ps(d, (_mm_load_ps(d)*c));d.AddOffset(4);//12
_mm_store_ps(d, (_mm_load_ps(d)*c));d.AddOffset(4);//13
_mm_store_ps(d, (_mm_load_ps(d)*c));d.AddOffset(4);//14
_mm_store_ps(d, (_mm_load_ps(d)*c));d.AddOffset(4);//15
}
internal static unsafe void CopyColorsTo(ref Block8x8F block, MutableSpan<byte> buffer, int stride)
{
fixed (Block8x8F* p = &block)
{
float* b = (float*)p;
for (int y = 0; y < 8; y++)
{
int y8 = y * 8;
int yStride = y * stride;
for (int x = 0; x < 8; x++)
{
float c = b[y8 + x];
if (c < -128)
{
c = 0;
}
else if (c > 127)
{
c = 255;
}
else
{
c += 128;
}
buffer[yStride + x] = (byte)c;
}
}
}
}
}
}

95
tests/ImageSharp.Tests46/Formats/Jpg/UtilityTestClassBase.cs

@ -1,95 +0,0 @@
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Text;
using ImageSharp.Formats;
using Xunit.Abstractions;
namespace ImageSharp.Tests.Formats.Jpg
{
public class UtilityTestClassBase
{
public UtilityTestClassBase(ITestOutputHelper output)
{
Output = output;
}
protected ITestOutputHelper Output { get; }
// ReSharper disable once InconsistentNaming
public static float[] Create8x8FloatData()
{
float[] result = new float[64];
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
result[i * 8 + j] = i * 10 + j;
}
}
return result;
}
// ReSharper disable once InconsistentNaming
public static int[] Create8x8IntData()
{
int[] result = new int[64];
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
result[i * 8 + j] = i * 10 + j;
}
}
return result;
}
internal void Print8x8Data<T>(MutableSpan<T> data) => Print8x8Data(data.Data);
internal void Print8x8Data<T>(T[] data)
{
StringBuilder bld = new StringBuilder();
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
bld.Append($"{data[i * 8 + j],3} ");
}
bld.AppendLine();
}
Output.WriteLine(bld.ToString());
}
internal void PrintLinearData<T>(T[] data) => PrintLinearData(new MutableSpan<T>(data), data.Length);
internal void PrintLinearData<T>(MutableSpan<T> data, int count = -1)
{
if (count < 0) count = data.TotalCount;
StringBuilder bld = new StringBuilder();
for (int i = 0; i < count; i++)
{
bld.Append($"{data[i],3} ");
}
Output.WriteLine(bld.ToString());
}
protected void Measure(int times, Action action, [CallerMemberName] string operationName = null)
{
Output.WriteLine($"{operationName} X {times} ...");
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < times; i++)
{
action();
}
sw.Stop();
Output.WriteLine($"{operationName} finished in {sw.ElapsedMilliseconds} ms");
}
}
}

21
tests/JpegBenchmark/JpegBenchmark.xproj

@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>7c69f09a-3286-45a1-bed2-b9c628150fa9</ProjectGuid>
<RootNamespace>JpegBenchmark</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

91
tests/JpegBenchmark/Program.cs

@ -1,91 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Reflection;
using System.Threading.Tasks;
using ImageSharp;
namespace JpegBenchmark
{
public class Program
{
private const string TestImageDir = @"../ImageSharp.Tests/TestImages/Formats/Jpg";
private static byte[][] ReadAllFiles()
{
var files = Directory.EnumerateFiles(TestImageDir).ToArray();
return files.Select(File.ReadAllBytes).ToArray();
}
public static void Main(string[] args)
{
var allData = ReadAllFiles();
bool methodSystemDrawing = args.Length > 0 && args[0].ToLower().Contains("system");
int times;
if (args.Length < 2 || !int.TryParse(args[1], out times))
{
times = 20;
}
Console.WriteLine($"Vector.IsHardwareAccelerated == {Vector.IsHardwareAccelerated}");
Console.WriteLine($"Method: {(methodSystemDrawing?"System.Drawing":"ImageSharp")}");
Console.WriteLine($"Decoding {allData.Length} jpegs X {times} times ...");
double estimatedTotalBlockCount = 0;
Stopwatch sw = Stopwatch.StartNew();
Func<byte[], double> method = methodSystemDrawing ? (Func<byte[], double>) DecodeMonoSystemDrawing : DecodeImageSharp;
estimatedTotalBlockCount = DecodeAll(allData, times, method);
sw.Stop();
Console.WriteLine($"Completed in {sw.ElapsedMilliseconds} ms");
Console.WriteLine($"Estimated block count: {estimatedTotalBlockCount}");
Console.ReadLine();
}
private static double DecodeImageSharp(byte[] data)
{
var stream = new MemoryStream(data);
Image img = new Image(stream);
return img.Width * img.Height / 64.0;
}
private static double DecodeMonoSystemDrawing(byte[] data)
{
var stream = new MemoryStream(data);
var img = new System.Drawing.Bitmap(stream);
return img.Width * img.Height / 64.0;
}
private static double DecodeAll(byte[][] allData, int times, Func<byte[], double> decoderFunc)
{
double estimatedTotalBlockCount = 0;
for (int i = 0; i < times; i++)
{
estimatedTotalBlockCount = 0;
foreach (byte[] data in allData)
{
estimatedTotalBlockCount += decoderFunc(data);
}
}
return estimatedTotalBlockCount;
}
}
}

19
tests/JpegBenchmark/Properties/AssemblyInfo.cs

@ -1,19 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Sapa")]
[assembly: AssemblyProduct("JpegBenchmark")]
[assembly: AssemblyTrademark("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("7c69f09a-3286-45a1-bed2-b9c628150fa9")]

22
tests/JpegBenchmark/project.json

@ -1,22 +0,0 @@
{
"version": "1.0.0-*",
"buildOptions": {
"emitEntryPoint": true,
"optimize": true
},
"dependencies": {
"CoreCompat.System.Drawing": "1.0.0-beta006",
"ImageSharp": "1.0.0-*",
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.1"
}
},
"frameworks": {
"netcoreapp1.0": {
"imports": "dnxcore50"
}
}
}
Loading…
Cancel
Save