From c9677898cbc9198799f9aa673eec7e555a62f1b7 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 13 Nov 2016 19:00:27 +0100 Subject: [PATCH] refactor --- .../Formats/Jpg/Components/Block.cs | 6 + ...x8.Generated.cs => Block8x8F.Generated.cs} | 4 +- ...x8.Generated.tt => Block8x8F.Generated.tt} | 4 +- .../Components/{Block8x8.cs => Block8x8F.cs} | 80 +++++++--- .../Formats/Jpg/Components/Span.cs | 4 +- .../Formats/Jpg/JpegDecoderCore.cs | 85 ++++------- src/ImageSharp46/ImageSharp46.csproj | 11 +- .../ConsoleBenchmark/ConsoleBenchmark.csproj | 2 + tests/ConsoleBenchmark/Program.cs | 2 + .../Formats/Jpg/Block8x8Tests.cs | 140 ++++++++++++------ .../Formats/Jpg}/ReferenceDCT.cs | 24 +-- .../Formats/Jpg/UtilityTestClassBase.cs | 6 +- .../ImageSharp.Tests46.csproj | 5 + tests/ImageSharp.Tests46/packages.config | 1 + 14 files changed, 223 insertions(+), 151 deletions(-) rename src/ImageSharp46/Formats/Jpg/Components/{Block8x8.Generated.cs => Block8x8F.Generated.cs} (94%) rename src/ImageSharp46/Formats/Jpg/Components/{Block8x8.Generated.tt => Block8x8F.Generated.tt} (93%) rename src/ImageSharp46/Formats/Jpg/Components/{Block8x8.cs => Block8x8F.cs} (86%) rename {src/ImageSharp46/Formats/Jpg/Components => tests/ImageSharp.Tests46/Formats/Jpg}/ReferenceDCT.cs (94%) diff --git a/src/ImageSharp46/Formats/Jpg/Components/Block.cs b/src/ImageSharp46/Formats/Jpg/Components/Block.cs index d9b16a44e..111a1cac5 100644 --- a/src/ImageSharp46/Formats/Jpg/Components/Block.cs +++ b/src/ImageSharp46/Formats/Jpg/Components/Block.cs @@ -109,6 +109,12 @@ namespace ImageSharp.Formats } } + /// + /// Temporal class to make refactoring easier. + /// 1. Refactor Block -> BlockF + /// 2. Test + /// 3. Refactor BlockF -> Block8x8F + /// internal struct BlockF : IDisposable { private static readonly ArrayPool ArrayPool = ArrayPool.Create(BlockSize, 50); diff --git a/src/ImageSharp46/Formats/Jpg/Components/Block8x8.Generated.cs b/src/ImageSharp46/Formats/Jpg/Components/Block8x8F.Generated.cs similarity index 94% rename from src/ImageSharp46/Formats/Jpg/Components/Block8x8.Generated.cs rename to src/ImageSharp46/Formats/Jpg/Components/Block8x8F.Generated.cs index 38ef256e3..0e9abecce 100644 --- a/src/ImageSharp46/Formats/Jpg/Components/Block8x8.Generated.cs +++ b/src/ImageSharp46/Formats/Jpg/Components/Block8x8F.Generated.cs @@ -5,10 +5,10 @@ using System.Runtime.CompilerServices; namespace ImageSharp.Formats { - public partial struct Block8x8 + internal partial struct Block8x8F { [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void TransposeInto(ref Block8x8 d) + public void TransposeInto(ref Block8x8F 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; diff --git a/src/ImageSharp46/Formats/Jpg/Components/Block8x8.Generated.tt b/src/ImageSharp46/Formats/Jpg/Components/Block8x8F.Generated.tt similarity index 93% rename from src/ImageSharp46/Formats/Jpg/Components/Block8x8.Generated.tt rename to src/ImageSharp46/Formats/Jpg/Components/Block8x8F.Generated.tt index 3001c351e..9ead63b87 100644 --- a/src/ImageSharp46/Formats/Jpg/Components/Block8x8.Generated.tt +++ b/src/ImageSharp46/Formats/Jpg/Components/Block8x8F.Generated.tt @@ -11,10 +11,10 @@ using System.Runtime.CompilerServices; namespace ImageSharp.Formats { - public partial struct Block8x8 + internal partial struct Block8x8F { [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void TransposeInto(ref Block8x8 d) + public void TransposeInto(ref Block8x8F d) { <# char[] coordz = new[] {'X', 'Y', 'Z', 'W'}; diff --git a/src/ImageSharp46/Formats/Jpg/Components/Block8x8.cs b/src/ImageSharp46/Formats/Jpg/Components/Block8x8F.cs similarity index 86% rename from src/ImageSharp46/Formats/Jpg/Components/Block8x8.cs rename to src/ImageSharp46/Formats/Jpg/Components/Block8x8F.cs index b8cbf9816..bc18f9843 100644 --- a/src/ImageSharp46/Formats/Jpg/Components/Block8x8.cs +++ b/src/ImageSharp46/Formats/Jpg/Components/Block8x8F.cs @@ -7,7 +7,7 @@ using System.Runtime.InteropServices; namespace ImageSharp.Formats { - public partial struct Block8x8 + internal partial struct Block8x8F { public Vector4 V0L; public Vector4 V0R; @@ -66,13 +66,13 @@ namespace ImageSharp.Formats } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe void LoadFrom(Block8x8* blockPtr, Span source) + public static unsafe void LoadFrom(Block8x8F* blockPtr, Span source) { Marshal.Copy(source.Data, source.Offset, (IntPtr)blockPtr, ScalarCount); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe void CopyTo(Block8x8* blockPtr, Span dest) + public static unsafe void CopyTo(Block8x8F* blockPtr, Span dest) { Marshal.Copy((IntPtr)blockPtr, dest.Data, dest.Offset, ScalarCount); } @@ -125,7 +125,7 @@ namespace ImageSharp.Formats /// /// Reference implementation we can benchmark against /// - internal unsafe void TransposeInto_PinningImpl(ref Block8x8 destination) + internal unsafe void TransposeInto_PinningImpl(ref Block8x8F destination) { fixed (Vector4* sPtr = &V0L) { @@ -150,7 +150,7 @@ namespace ImageSharp.Formats [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe void TransposeInto(Block8x8* sourcePtr, Block8x8* destPtr) + public static unsafe void TransposeInto(Block8x8F* sourcePtr, Block8x8F* destPtr) { float* src = (float*)sourcePtr; float* dest = (float*) destPtr; @@ -175,7 +175,7 @@ namespace ImageSharp.Formats } // ReSharper disable once InconsistentNaming - public void IDCTInto(ref Block8x8 dest, ref Block8x8 temp) + public void IDCTInto(ref Block8x8F dest, ref Block8x8F temp) { TransposeInto(ref temp); temp.iDCT2D8x4_LeftPart(ref dest); @@ -192,8 +192,8 @@ namespace ImageSharp.Formats [MethodImpl(MethodImplOptions.AggressiveInlining)] public void IDCTInplace() { - Block8x8 result = new Block8x8(); - Block8x8 temp = new Block8x8(); + Block8x8F result = new Block8x8F(); + Block8x8F temp = new Block8x8F(); IDCTInto(ref result, ref temp); this = result; } @@ -213,7 +213,7 @@ namespace ImageSharp.Formats private static readonly Vector4 _0_125 = new Vector4(0.1250f); [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void iDCT2D8x4_LeftPart(ref Block8x8 d) + internal void iDCT2D8x4_LeftPart(ref Block8x8F d) { /* float a0,a1,a2,a3,b0,b1,b2,b3; float z0,z1,z2,z3,z4; float r[8]; int i; @@ -320,7 +320,7 @@ namespace ImageSharp.Formats } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void iDCT2D8x4_RightPart(ref Block8x8 d) + internal void iDCT2D8x4_RightPart(ref Block8x8F d) { /* float a0,a1,a2,a3,b0,b1,b2,b3; float z0,z1,z2,z3,z4; float r[8]; int i; @@ -428,11 +428,11 @@ namespace ImageSharp.Formats internal static void SuchIDCT(ref Block block) { - Block8x8 source = new Block8x8(); + Block8x8F source = new Block8x8F(); source.LoadFrom(block.Data); - Block8x8 dest = new Block8x8(); - Block8x8 temp = new Block8x8(); + Block8x8F dest = new Block8x8F(); + Block8x8F temp = new Block8x8F(); source.IDCTInto(ref dest, ref temp); dest.CopyTo(block.Data); @@ -440,11 +440,11 @@ namespace ImageSharp.Formats internal static void SuchIDCT(ref BlockF block) { - Block8x8 source = new Block8x8(); + Block8x8F source = new Block8x8F(); source.LoadFrom(block.Data); - Block8x8 dest = new Block8x8(); - Block8x8 temp = new Block8x8(); + Block8x8F dest = new Block8x8F(); + Block8x8F temp = new Block8x8F(); source.IDCTInto(ref dest, ref temp); dest.CopyTo(block.Data); @@ -455,7 +455,7 @@ namespace ImageSharp.Formats [MethodImpl(MethodImplOptions.AggressiveInlining)] get { - fixed (Block8x8* p = &this) + fixed (Block8x8F* p = &this) { float* fp = (float*) p; return fp[idx]; @@ -464,7 +464,7 @@ namespace ImageSharp.Formats [MethodImpl(MethodImplOptions.AggressiveInlining)] set { - fixed (Block8x8* p = &this) + fixed (Block8x8F* p = &this) { float* fp = (float*)p; fp[idx] = value; @@ -473,14 +473,14 @@ namespace ImageSharp.Formats } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static unsafe float GetScalarAt(Block8x8* blockPtr, int idx) + internal static unsafe float GetScalarAt(Block8x8F* blockPtr, int idx) { float* fp = (float*) blockPtr; return fp[idx]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static unsafe void SetScalarAt(Block8x8* blockPtr, int idx, float value) + internal static unsafe void SetScalarAt(Block8x8F* blockPtr, int idx, float value) { float* fp = (float*)blockPtr; fp[idx] = value; @@ -489,7 +489,7 @@ namespace ImageSharp.Formats [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void Clear() { - this = new Block8x8(); // LOL C# Plz! + this = new Block8x8F(); // LOL C# Plz! } internal void LoadFrom(ref BlockF legacyBlock) @@ -501,5 +501,43 @@ namespace ImageSharp.Formats { CopyTo(legacyBlock.Data); } + + internal unsafe void CopyColorsTo(Span buffer, int stride) + { + fixed (Block8x8F* p = &this) + { + 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; + + //dst[yStride + x + offset] = (byte)c; + } + } + } + + + } } } \ No newline at end of file diff --git a/src/ImageSharp46/Formats/Jpg/Components/Span.cs b/src/ImageSharp46/Formats/Jpg/Components/Span.cs index 8ef747125..2e19c18ca 100644 --- a/src/ImageSharp46/Formats/Jpg/Components/Span.cs +++ b/src/ImageSharp46/Formats/Jpg/Components/Span.cs @@ -4,7 +4,7 @@ using System.Runtime.CompilerServices; namespace ImageSharp.Formats { - public struct Span + internal struct Span { public T[] Data; public int Offset; @@ -57,7 +57,7 @@ namespace ImageSharp.Formats } } - public static class SpanExtensions + internal static class SpanExtensions { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void SaveTo(this Span data, ref Vector4 v) diff --git a/src/ImageSharp46/Formats/Jpg/JpegDecoderCore.cs b/src/ImageSharp46/Formats/Jpg/JpegDecoderCore.cs index 85e998450..3542fddcd 100644 --- a/src/ImageSharp46/Formats/Jpg/JpegDecoderCore.cs +++ b/src/ImageSharp46/Formats/Jpg/JpegDecoderCore.cs @@ -85,7 +85,7 @@ namespace ImageSharp.Formats /// /// Saved state between progressive-mode scans. /// - private readonly Block8x8[][] progCoeffs; + private readonly Block8x8F[][] progCoeffs; /// /// The huffman trees @@ -97,7 +97,7 @@ namespace ImageSharp.Formats /// /// Quantization tables, in zigzag order. /// - private readonly Block8x8[] quantizationTables; + private readonly Block8x8F[] quantizationTables; /// /// A temporary buffer for holding pixels @@ -204,10 +204,10 @@ namespace ImageSharp.Formats //this.huffmanTrees = new Huffman[MaxTc + 1, MaxTh + 1]; this.huffmanTrees = new Huffman[(MaxTc + 1) * (MaxTh + 1)]; - this.quantizationTables = new Block8x8[MaxTq + 1]; + this.quantizationTables = new Block8x8F[MaxTq + 1]; this.temp = new byte[2 * BlockF.BlockSize]; this.componentArray = new Component[MaxComponents]; - this.progCoeffs = new Block8x8[MaxComponents][]; + this.progCoeffs = new Block8x8F[MaxComponents][]; this.bits = new Bits(); this.bytes = new Bytes(); @@ -1571,7 +1571,7 @@ namespace ImageSharp.Formats { var size = mxx * myy * this.componentArray[compIndex].HorizontalFactor * this.componentArray[compIndex].VerticalFactor; - this.progCoeffs[compIndex] = new Block8x8[size]; + this.progCoeffs[compIndex] = new Block8x8F[size]; } } } @@ -1589,9 +1589,9 @@ namespace ImageSharp.Formats // blocks: the third block in the first row has (bx, by) = (2, 0). int bx, by, blockCount = 0; - Block8x8 b = new Block8x8(); - Block8x8 temp1 = new Block8x8(); - Block8x8 temp2 = new Block8x8(); + Block8x8F b = new Block8x8F(); + Block8x8F temp1 = new Block8x8F(); + Block8x8F temp2 = new Block8x8F(); for (int my = 0; my < myy; my++) { @@ -1648,13 +1648,13 @@ namespace ImageSharp.Formats var qtIndex = this.componentArray[compIndex].Selector; // TODO: Find a way to clean up this mess - fixed (Block8x8* qtp = &this.quantizationTables[qtIndex]) + fixed (Block8x8F* qtp = &this.quantizationTables[qtIndex]) { if (this.isProgressive) // Load the previous partially decoded coefficients, if applicable. { blockIndex = ((@by * mxx) * hi) + bx; - fixed (Block8x8* bp = &this.progCoeffs[compIndex][blockIndex]) + fixed (Block8x8F* bp = &this.progCoeffs[compIndex][blockIndex]) { ProcessBlockImpl(ah, bp, @@ -1722,13 +1722,13 @@ namespace ImageSharp.Formats private void ProcessBlockImpl( int ah, - Block8x8* b, - Block8x8* temp1, - Block8x8* temp2, + Block8x8F* b, + Block8x8F* temp1, + Block8x8F* temp2, Scan[] scan, int i, int zigStart, int zigEnd, int al, int[] dc, int compIndex, int @by, int mxx, int hi, int bx, - Block8x8* qt) + Block8x8F* qt) { if (ah != 0) { @@ -1752,7 +1752,7 @@ namespace ImageSharp.Formats dc[compIndex] += deltaDC; //b[0] = dc[compIndex] << al; - Block8x8.SetScalarAt(b, 0, dc[compIndex] << al); + Block8x8F.SetScalarAt(b, 0, dc[compIndex] << al); } if (zig <= zigEnd && this.eobRun > 0) @@ -1779,7 +1779,7 @@ namespace ImageSharp.Formats int ac = this.ReceiveExtend(val1); //b[Unzig[zig]] = ac << al; - Block8x8.SetScalarAt(b, Unzig[zig], ac << al); + Block8x8F.SetScalarAt(b, Unzig[zig], ac << al); } else { @@ -1828,15 +1828,15 @@ namespace ImageSharp.Formats //b[Unzig[zig]] *= qt[zig]; int unzigIdx = Unzig[zig]; - float value = Block8x8.GetScalarAt(b, unzigIdx); - value *= Block8x8.GetScalarAt(qt, zig); - Block8x8.SetScalarAt(b, unzigIdx, value); + float value = Block8x8F.GetScalarAt(b, unzigIdx); + value *= Block8x8F.GetScalarAt(qt, zig); + Block8x8F.SetScalarAt(b, unzigIdx, value); } //IDCT.Transform(ref b); //FloatIDCT.Transform(ref b); //ReferenceDCT.IDCT(ref b); - //Block8x8.SuchIDCT(ref b); + //Block8x8F.SuchIDCT(ref b); //b->IDCTInplace(); b->IDCTInto(ref *temp1, ref *temp2); @@ -1885,35 +1885,10 @@ namespace ImageSharp.Formats } // Level shift by +128, clip to [0, 255], and write to dst. - 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]; - //float c = Block8x8.GetScalarAt(b, y8 + x); - float c = Block8x8.GetScalarAt(temp1, y8 + x); - if (c < -128) - { - c = 0; - } - else if (c > 127) - { - c = 255; - } - else - { - c += 128; - } - - dst[yStride + x + offset] = (byte)c; - } - } + temp1->CopyColorsTo(new Span(dst, offset), stride); } - + private void ProcessScanImpl(int i, ref Scan currentScan, Scan[] scan, ref int totalHv) { // Component selector. @@ -1977,7 +1952,7 @@ namespace ImageSharp.Formats /// The zig-zag start index /// The zig-zag end index /// The low transform offset - private void Refine(Block8x8* b, ref Huffman h, int zigStart, int zigEnd, int delta) + private void Refine(Block8x8F* b, ref Huffman h, int zigStart, int zigEnd, int delta) { // Refining a DC component is trivial. if (zigStart == 0) @@ -1990,12 +1965,12 @@ namespace ImageSharp.Formats bool bit = this.DecodeBit(); if (bit) { - int stuff = (int) Block8x8.GetScalarAt(b, 0); + int stuff = (int) Block8x8F.GetScalarAt(b, 0); //int stuff = (int)b[0]; stuff |= delta; //b[0] = stuff; - Block8x8.SetScalarAt(b, 0, stuff); + Block8x8F.SetScalarAt(b, 0, stuff); } return; @@ -2057,7 +2032,7 @@ namespace ImageSharp.Formats if (z != 0) { //b[Unzig[zig]] = z; - Block8x8.SetScalarAt(b, Unzig[zig], z); + Block8x8F.SetScalarAt(b, Unzig[zig], z); } } } @@ -2079,12 +2054,12 @@ namespace ImageSharp.Formats /// The non-zero entry /// The low transform offset /// The - private int RefineNonZeroes(Block8x8* b, int zig, int zigEnd, int nz, int delta) + private int RefineNonZeroes(Block8x8F* b, int zig, int zigEnd, int nz, int delta) { for (; zig <= zigEnd; zig++) { int u = Unzig[zig]; - float bu = Block8x8.GetScalarAt(b, u); + float bu = Block8x8F.GetScalarAt(b, u); // TODO: Are the equality comparsions OK with floating point values? Isn't an epsilon value necessary? if (bu == 0) @@ -2107,12 +2082,12 @@ namespace ImageSharp.Formats if (bu >= 0) { //b[u] += delta; - Block8x8.SetScalarAt(b, u, bu + delta); + Block8x8F.SetScalarAt(b, u, bu + delta); } else { //b[u] -= delta; - Block8x8.SetScalarAt(b, u, bu - delta); + Block8x8F.SetScalarAt(b, u, bu - delta); } } diff --git a/src/ImageSharp46/ImageSharp46.csproj b/src/ImageSharp46/ImageSharp46.csproj index 2177f3683..303b12c72 100644 --- a/src/ImageSharp46/ImageSharp46.csproj +++ b/src/ImageSharp46/ImageSharp46.csproj @@ -227,11 +227,11 @@ - - + + True True - Block8x8.Generated.tt + Block8x8F.Generated.tt @@ -240,7 +240,6 @@ - @@ -400,9 +399,9 @@ - + TextTemplatingFileGenerator - Block8x8.Generated.cs + Block8x8F.Generated.cs diff --git a/tests/ConsoleBenchmark/ConsoleBenchmark.csproj b/tests/ConsoleBenchmark/ConsoleBenchmark.csproj index da38098fc..242b76146 100644 --- a/tests/ConsoleBenchmark/ConsoleBenchmark.csproj +++ b/tests/ConsoleBenchmark/ConsoleBenchmark.csproj @@ -32,6 +32,8 @@ TRACE prompt 4 + false + true diff --git a/tests/ConsoleBenchmark/Program.cs b/tests/ConsoleBenchmark/Program.cs index 52a53e316..56595310f 100644 --- a/tests/ConsoleBenchmark/Program.cs +++ b/tests/ConsoleBenchmark/Program.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Numerics; using System.Text; using System.Threading.Tasks; using ImageSharp.Tests; @@ -26,6 +27,7 @@ namespace ConsoleBenchmark static void Main(string[] args) { + Console.WriteLine("HW ACC: "+ Vector.IsHardwareAccelerated); DecodeJpegBenchmark benchmark = new DecodeJpegBenchmark(new Output()); benchmark.JpegCore(100); //JpegSandbox test = new JpegSandbox(null); diff --git a/tests/ImageSharp.Tests46/Formats/Jpg/Block8x8Tests.cs b/tests/ImageSharp.Tests46/Formats/Jpg/Block8x8Tests.cs index 289e390d1..24824774d 100644 --- a/tests/ImageSharp.Tests46/Formats/Jpg/Block8x8Tests.cs +++ b/tests/ImageSharp.Tests46/Formats/Jpg/Block8x8Tests.cs @@ -32,14 +32,14 @@ namespace ImageSharp.Tests.Formats.Jpg float sum = 0; Measure(Times, () => { - Block8x8 block = new Block8x8(); + Block8x8F block = new Block8x8F(); - for (int i = 0; i < Block8x8.ScalarCount; i++) + for (int i = 0; i < Block8x8F.ScalarCount; i++) { block[i] = i; } sum = 0; - for (int i = 0; i < Block8x8.ScalarCount; i++) + for (int i = 0; i < Block8x8F.ScalarCount; i++) { sum += block[i]; } @@ -53,16 +53,16 @@ namespace ImageSharp.Tests.Formats.Jpg float sum = 0; Measure(Times, () => { - Block8x8 block = new Block8x8(); + Block8x8F block = new Block8x8F(); - for (int i = 0; i < Block8x8.ScalarCount; i++) + for (int i = 0; i < Block8x8F.ScalarCount; i++) { - Block8x8.SetScalarAt(&block, i, i); + Block8x8F.SetScalarAt(&block, i, i); } sum = 0; - for (int i = 0; i < Block8x8.ScalarCount; i++) + for (int i = 0; i < Block8x8F.ScalarCount; i++) { - sum += Block8x8.GetScalarAt(&block, i); + sum += Block8x8F.GetScalarAt(&block, i); } }); Assert.Equal(sum, 64f * 63f * 0.5f); @@ -76,14 +76,14 @@ namespace ImageSharp.Tests.Formats.Jpg Measure(Times, () => { - //Block8x8 block = new Block8x8(); + //Block8x8F block = new Block8x8F(); float[] block = new float[64]; - for (int i = 0; i < Block8x8.ScalarCount; i++) + for (int i = 0; i < Block8x8F.ScalarCount; i++) { block[i] = i; } sum = 0; - for (int i = 0; i < Block8x8.ScalarCount; i++) + for (int i = 0; i < Block8x8F.ScalarCount; i++) { sum += block[i]; } @@ -94,16 +94,16 @@ namespace ImageSharp.Tests.Formats.Jpg [Fact] public void Load_Store_FloatArray() { - float[] data = new float[Block8x8.ScalarCount]; - float[] mirror = new float[Block8x8.ScalarCount]; + float[] data = new float[Block8x8F.ScalarCount]; + float[] mirror = new float[Block8x8F.ScalarCount]; - for (int i = 0; i < Block8x8.ScalarCount; i++) + for (int i = 0; i < Block8x8F.ScalarCount; i++) { data[i] = i; } Measure(Times, () => { - Block8x8 b = new Block8x8(); + Block8x8F b = new Block8x8F(); b.LoadFrom(data); b.CopyTo(mirror); }); @@ -115,18 +115,18 @@ namespace ImageSharp.Tests.Formats.Jpg [Fact] public unsafe void Load_Store_FloatArray_Ptr() { - float[] data = new float[Block8x8.ScalarCount]; - float[] mirror = new float[Block8x8.ScalarCount]; + float[] data = new float[Block8x8F.ScalarCount]; + float[] mirror = new float[Block8x8F.ScalarCount]; - for (int i = 0; i < Block8x8.ScalarCount; i++) + for (int i = 0; i < Block8x8F.ScalarCount; i++) { data[i] = i; } Measure(Times, () => { - Block8x8 b = new Block8x8(); - Block8x8.LoadFrom(&b, data); - Block8x8.CopyTo(&b, mirror); + Block8x8F b = new Block8x8F(); + Block8x8F.LoadFrom(&b, data); + Block8x8F.CopyTo(&b, mirror); }); Assert.Equal(data, mirror); @@ -136,16 +136,16 @@ namespace ImageSharp.Tests.Formats.Jpg [Fact] public void Load_Store_IntArray() { - int[] data = new int[Block8x8.ScalarCount]; - int[] mirror = new int[Block8x8.ScalarCount]; + int[] data = new int[Block8x8F.ScalarCount]; + int[] mirror = new int[Block8x8F.ScalarCount]; - for (int i = 0; i < Block8x8.ScalarCount; i++) + for (int i = 0; i < Block8x8F.ScalarCount; i++) { data[i] = i; } Measure(Times, () => { - Block8x8 v = new Block8x8(); + Block8x8F v = new Block8x8F(); v.LoadFrom(data); v.CopyTo(mirror); }); @@ -160,7 +160,7 @@ namespace ImageSharp.Tests.Formats.Jpg float[] expected = Create8x8FloatData(); ReferenceDCT.Transpose8x8(expected); - Block8x8 buffer = new Block8x8(); + Block8x8F buffer = new Block8x8F(); buffer.LoadFrom(Create8x8FloatData()); buffer.TransposeInplace(); @@ -177,10 +177,10 @@ namespace ImageSharp.Tests.Formats.Jpg float[] expected = Create8x8FloatData(); ReferenceDCT.Transpose8x8(expected); - Block8x8 source = new Block8x8(); + Block8x8F source = new Block8x8F(); source.LoadFrom(Create8x8FloatData()); - Block8x8 dest = new Block8x8(); + Block8x8F dest = new Block8x8F(); source.TransposeInto_PinningImpl(ref dest); float[] actual = new float[64]; @@ -195,10 +195,10 @@ namespace ImageSharp.Tests.Formats.Jpg float[] expected = Create8x8FloatData(); ReferenceDCT.Transpose8x8(expected); - Block8x8 source = new Block8x8(); + Block8x8F source = new Block8x8F(); source.LoadFrom(Create8x8FloatData()); - Block8x8 dest = new Block8x8(); + Block8x8F dest = new Block8x8F(); source.TransposeInto(ref dest); float[] actual = new float[64]; @@ -239,15 +239,15 @@ namespace ImageSharp.Tests.Formats.Jpg float[] expected = Create8x8FloatData(); ReferenceDCT.Transpose8x8(expected); - Block8x8 source = new Block8x8(); + Block8x8F source = new Block8x8F(); source.LoadFrom(Create8x8FloatData()); - Block8x8 dest = new Block8x8(); + Block8x8F dest = new Block8x8F(); - Block8x8* sPtr = &source; - Block8x8* dPtr = &dest; + Block8x8F* sPtr = &source; + Block8x8F* dPtr = &dest; - Block8x8.TransposeInto(sPtr, dPtr); + Block8x8F.TransposeInto(sPtr, dPtr); float[] actual = new float[64]; dest.CopyTo(actual); @@ -257,7 +257,7 @@ namespace ImageSharp.Tests.Formats.Jpg private class BufferHolder { - public Block8x8 Buffer; + public Block8x8F Buffer; } [Fact] @@ -306,16 +306,16 @@ namespace ImageSharp.Tests.Formats.Jpg source.Buffer.LoadFrom(Create8x8FloatData()); BufferHolder dest = new BufferHolder(); - fixed (Block8x8* sPtr = &source.Buffer) + fixed (Block8x8F* sPtr = &source.Buffer) { - fixed (Block8x8* dPtr = &dest.Buffer) + fixed (Block8x8F* dPtr = &dest.Buffer) { Output.WriteLine($"TransposeInto_WithPointers_Benchmark X {Times} ..."); Stopwatch sw = Stopwatch.StartNew(); for (int i = 0; i < Times; i++) { - Block8x8.TransposeInto(sPtr, dPtr); + Block8x8F.TransposeInto(sPtr, dPtr); } sw.Stop(); @@ -334,10 +334,10 @@ namespace ImageSharp.Tests.Formats.Jpg ReferenceDCT.iDCT2D8x4_32f(sourceArray, expectedDestArray); - Block8x8 source = new Block8x8(); + Block8x8F source = new Block8x8F(); source.LoadFrom(sourceArray); - Block8x8 dest = new Block8x8(); + Block8x8F dest = new Block8x8F(); source.iDCT2D8x4_LeftPart(ref dest); @@ -359,10 +359,10 @@ namespace ImageSharp.Tests.Formats.Jpg ReferenceDCT.iDCT2D8x4_32f(sourceArray.Slice(4), expectedDestArray.Slice(4)); - Block8x8 source = new Block8x8(); + Block8x8F source = new Block8x8F(); source.LoadFrom(sourceArray); - Block8x8 dest = new Block8x8(); + Block8x8F dest = new Block8x8F(); source.iDCT2D8x4_RightPart(ref dest); @@ -377,7 +377,7 @@ namespace ImageSharp.Tests.Formats.Jpg } [Fact] - public void IDCT() + public void IDCTInto() { float[] sourceArray = Create8x8FloatData(); float[] expectedDestArray = new float[64]; @@ -385,11 +385,11 @@ namespace ImageSharp.Tests.Formats.Jpg ReferenceDCT.iDCT8x8_llm_sse(sourceArray, expectedDestArray, tempArray); - Block8x8 source = new Block8x8(); + Block8x8F source = new Block8x8F(); source.LoadFrom(sourceArray); - Block8x8 dest = new Block8x8(); - Block8x8 tempBuffer = new Block8x8(); + Block8x8F dest = new Block8x8F(); + Block8x8F tempBuffer = new Block8x8F(); source.IDCTInto(ref dest, ref tempBuffer); @@ -401,6 +401,50 @@ namespace ImageSharp.Tests.Formats.Jpg Print8x8Data(actualDestArray); Assert.Equal(expectedDestArray, actualDestArray); } - + + private unsafe void CopyColorsTo_ReferenceImpl(ref Block8x8F block, Span 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; + } + } + } + + + } + + [Fact] + public void CopyColorsTo() + { + var data = Create8x8FloatData(); + Block8x8F block = new Block8x8F(); + block.LoadFrom(data); + + } } } \ No newline at end of file diff --git a/src/ImageSharp46/Formats/Jpg/Components/ReferenceDCT.cs b/tests/ImageSharp.Tests46/Formats/Jpg/ReferenceDCT.cs similarity index 94% rename from src/ImageSharp46/Formats/Jpg/Components/ReferenceDCT.cs rename to tests/ImageSharp.Tests46/Formats/Jpg/ReferenceDCT.cs index 595a3e54a..01a5ef7e9 100644 --- a/src/ImageSharp46/Formats/Jpg/Components/ReferenceDCT.cs +++ b/tests/ImageSharp.Tests46/Formats/Jpg/ReferenceDCT.cs @@ -17,7 +17,7 @@ namespace ImageSharp.Formats [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Matrix4x4 Load(Span src, int x, int y) + internal static Matrix4x4 Load(Span src, int x, int y) { int b0 = y*8 + x; y++; @@ -36,7 +36,7 @@ namespace ImageSharp.Formats } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Store(Matrix4x4 s, Span d, int x, int y) + internal static void Store(Matrix4x4 s, Span d, int x, int y) { int b0 = y*8 + x; y++; @@ -64,7 +64,7 @@ namespace ImageSharp.Formats d[b3 + 3] = s.M44; } - public static void Transpose8x8_SSE_Slow(Span data) + internal static void Transpose8x8_SSE_Slow(Span data) { Matrix4x4 a11 = Load(data, 0, 0); Matrix4x4 a12 = Load(data, 4, 0); @@ -82,7 +82,7 @@ namespace ImageSharp.Formats Store(a22, data, 4, 4); } - public static void Transpose8x8_SSE_Slow(Span src, Span dest) + internal static void Transpose8x8_SSE_Slow(Span src, Span dest) { Matrix4x4 a11 = Load(src, 0, 0); Matrix4x4 a12 = Load(src, 4, 0); @@ -100,7 +100,7 @@ namespace ImageSharp.Formats Store(a22, dest, 4, 4); } - public static void Transpose8x8(Span data) + internal static void Transpose8x8(Span data) { for (int i = 1; i < 8; i++) { @@ -114,7 +114,7 @@ namespace ImageSharp.Formats } } - public static void Transpose8x8(Span src, Span dest) + internal static void Transpose8x8(Span src, Span dest) { for (int i = 0; i < 8; i++) { @@ -141,7 +141,7 @@ namespace ImageSharp.Formats //Store(a22, dest, 4, 4); } - public static void iDCT1Dllm_32f(Span y, Span x) + internal static void iDCT1Dllm_32f(Span y, Span x) { float a0, a1, a2, a3, b0, b1, b2, b3; float z0, z1, z2, z3, z4; @@ -191,7 +191,7 @@ namespace ImageSharp.Formats x[4] = a3 - b3; } - public static void iDCT2D_llm(Span s, Span d, Span temp) + internal static void iDCT2D_llm(Span s, Span d, Span temp) { int j; @@ -241,7 +241,7 @@ namespace ImageSharp.Formats temp.ReturnToPool(); } - public static void iDCT8x8GT(Span s, Span d) + internal static void iDCT8x8GT(Span s, Span d) { idct81d_sse_GT(s, d); @@ -285,7 +285,7 @@ namespace ImageSharp.Formats } - public static void idct81d_sse_GT(Span src, Span dst) + internal static void idct81d_sse_GT(Span src, Span dst) { Vector4 c1414 = new Vector4(1.4142135623731f); Vector4 c0250 = new Vector4(0.25f); @@ -363,7 +363,7 @@ namespace ImageSharp.Formats private static readonly Vector4 _1_847759 = new Vector4(-1.847759f); private static readonly Vector4 _0_765367 = new Vector4(0.765367f); - public static void iDCT2D8x4_32f(Span y, Span x) + internal static void iDCT2D8x4_32f(Span y, Span x) { /* float a0,a1,a2,a3,b0,b1,b2,b3; float z0,z1,z2,z3,z4; float r[8]; int i; @@ -476,7 +476,7 @@ namespace ImageSharp.Formats */ } - public static void iDCT8x8_llm_sse(Span s, Span d, Span temp) + internal static void iDCT8x8_llm_sse(Span s, Span d, Span temp) { Transpose8x8(s, temp); iDCT2D8x4_32f(temp, d); diff --git a/tests/ImageSharp.Tests46/Formats/Jpg/UtilityTestClassBase.cs b/tests/ImageSharp.Tests46/Formats/Jpg/UtilityTestClassBase.cs index 1e205655d..a8dd2d7fa 100644 --- a/tests/ImageSharp.Tests46/Formats/Jpg/UtilityTestClassBase.cs +++ b/tests/ImageSharp.Tests46/Formats/Jpg/UtilityTestClassBase.cs @@ -44,9 +44,9 @@ namespace ImageSharp.Tests.Formats.Jpg return result; } - protected void Print8x8Data(Span data) => Print8x8Data(data.Data); + internal void Print8x8Data(Span data) => Print8x8Data(data.Data); - protected void Print8x8Data(T[] data) + internal void Print8x8Data(T[] data) { StringBuilder bld = new StringBuilder(); for (int i = 0; i < 8; i++) @@ -61,7 +61,7 @@ namespace ImageSharp.Tests.Formats.Jpg Output.WriteLine(bld.ToString()); } - protected void PrintLinearData(Span data, int count = -1) + internal void PrintLinearData(Span data, int count = -1) { if (count < 0) count = data.TotalCount; diff --git a/tests/ImageSharp.Tests46/ImageSharp.Tests46.csproj b/tests/ImageSharp.Tests46/ImageSharp.Tests46.csproj index 10fe942b6..ad042f7e0 100644 --- a/tests/ImageSharp.Tests46/ImageSharp.Tests46.csproj +++ b/tests/ImageSharp.Tests46/ImageSharp.Tests46.csproj @@ -37,6 +37,10 @@ + + ..\..\packages\System.Buffers.4.0.0\lib\netstandard1.1\System.Buffers.dll + True + @@ -77,6 +81,7 @@ + diff --git a/tests/ImageSharp.Tests46/packages.config b/tests/ImageSharp.Tests46/packages.config index e96e29cd6..96d135e20 100644 --- a/tests/ImageSharp.Tests46/packages.config +++ b/tests/ImageSharp.Tests46/packages.config @@ -1,5 +1,6 @@  +