From 303e479aae90ff8f4010c7f734dfe85c72ee3eb9 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 13 Nov 2016 14:06:39 +0100 Subject: [PATCH] auto-generated implementation for Block8x8.Transpose() --- .../Jpg/Components/Block8x8.Generated.cs | 23 +++ .../Jpg/Components/Block8x8.Generated.tt | 46 ++++++ .../Components/{Buffer8x8.cs => Block8x8.cs} | 41 +++--- .../Formats/Jpg/JpegDecoderCore.cs | 8 +- src/ImageSharp46/ImageSharp46.csproj | 16 ++- .../{Buffer8x8Tests.cs => Block8x8Tests.cs} | 136 ++++++++++++------ .../ImageSharp.Tests46.csproj | 2 +- 7 files changed, 202 insertions(+), 70 deletions(-) create mode 100644 src/ImageSharp46/Formats/Jpg/Components/Block8x8.Generated.cs create mode 100644 src/ImageSharp46/Formats/Jpg/Components/Block8x8.Generated.tt rename src/ImageSharp46/Formats/Jpg/Components/{Buffer8x8.cs => Block8x8.cs} (91%) rename tests/ImageSharp.Tests46/Formats/Jpg/{Buffer8x8Tests.cs => Block8x8Tests.cs} (68%) diff --git a/src/ImageSharp46/Formats/Jpg/Components/Block8x8.Generated.cs b/src/ImageSharp46/Formats/Jpg/Components/Block8x8.Generated.cs new file mode 100644 index 000000000..38ef256e3 --- /dev/null +++ b/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; + } + } +} diff --git a/src/ImageSharp46/Formats/Jpg/Components/Block8x8.Generated.tt b/src/ImageSharp46/Formats/Jpg/Components/Block8x8.Generated.tt new file mode 100644 index 000000000..3001c351e --- /dev/null +++ b/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()); + #> + } + } +} diff --git a/src/ImageSharp46/Formats/Jpg/Components/Buffer8x8.cs b/src/ImageSharp46/Formats/Jpg/Components/Block8x8.cs similarity index 91% rename from src/ImageSharp46/Formats/Jpg/Components/Buffer8x8.cs rename to src/ImageSharp46/Formats/Jpg/Components/Block8x8.cs index 546c712ac..0169dce22 100644 --- a/src/ImageSharp46/Formats/Jpg/Components/Buffer8x8.cs +++ b/src/ImageSharp46/Formats/Jpg/Components/Block8x8.cs @@ -1,11 +1,11 @@ using System; using System.Numerics; using System.Runtime.CompilerServices; +// ReSharper disable InconsistentNaming namespace ImageSharp.Formats { - // ReSharper disable once InconsistentNaming - public struct Buffer8x8 + public partial struct Block8x8 { public Vector4 V0L; public Vector4 V0R; @@ -103,7 +103,10 @@ namespace ImageSharp.Formats } - public unsafe void TranposeInto(ref Buffer8x8 destination) + /// + /// Used as a reference implementation for benchmarking + /// + internal unsafe void TransposeInto_PinningImpl(ref Block8x8 destination) { fixed (Vector4* sPtr = &V0L) { @@ -125,14 +128,10 @@ namespace ImageSharp.Formats } } - public void TransposeIntoSafe(ref Buffer8x8 d) - { - - } [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* dest = (float*) destPtr; @@ -147,7 +146,7 @@ namespace ImageSharp.Formats } } - private static readonly Vector4 _c = new Vector4(0.1250f); + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void MultiplyAllInplace(Vector4 s) @@ -159,18 +158,18 @@ namespace ImageSharp.Formats } // 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_RightPart(ref dest); - dest.TranposeInto(ref temp); + dest.TransposeInto(ref temp); temp.iDCT2D8x4_LeftPart(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); @@ -185,8 +184,10 @@ namespace ImageSharp.Formats 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); + 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; @@ -292,8 +293,8 @@ namespace ImageSharp.Formats */ } - - internal void iDCT2D8x4_RightPart(ref Buffer8x8 d) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + 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; @@ -401,13 +402,13 @@ namespace ImageSharp.Formats public static void SuchIDCT(ref Block block) { - Buffer8x8 source = new Buffer8x8(); + Block8x8 source = new Block8x8(); source.LoadFrom(block.Data); - Buffer8x8 dest = new Buffer8x8(); - Buffer8x8 temp = new Buffer8x8(); + Block8x8 dest = new Block8x8(); + Block8x8 temp = new Block8x8(); - source.TransformIDCTInto(ref dest, ref temp); + source.IDCTInto(ref dest, ref temp); dest.CopyTo(block.Data); } } diff --git a/src/ImageSharp46/Formats/Jpg/JpegDecoderCore.cs b/src/ImageSharp46/Formats/Jpg/JpegDecoderCore.cs index 8578a4033..25e0a0d1b 100644 --- a/src/ImageSharp46/Formats/Jpg/JpegDecoderCore.cs +++ b/src/ImageSharp46/Formats/Jpg/JpegDecoderCore.cs @@ -1814,7 +1814,7 @@ namespace ImageSharp.Formats //IDCT.Transform(ref b); //FloatIDCT.Transform(ref b); //ReferenceDCT.IDCT(ref b); - Buffer8x8.SuchIDCT(ref b); + Block8x8.SuchIDCT(ref b); byte[] dst; int offset; @@ -2014,7 +2014,7 @@ namespace ImageSharp.Formats break; } - zig = this.RefineNonZeroes(b, zig, zigEnd, val0, delta); + zig = this.RefineNonZeroes(ref b, zig, zigEnd, val0, delta); if (zig > zigEnd) { throw new ImageFormatException($"Too many coefficients {zig} > {zigEnd}"); @@ -2030,7 +2030,7 @@ namespace ImageSharp.Formats if (this.eobRun > 0) { this.eobRun--; - this.RefineNonZeroes(b, zig, zigEnd, -1, delta); + this.RefineNonZeroes(ref b, zig, zigEnd, -1, delta); } } @@ -2044,7 +2044,7 @@ namespace ImageSharp.Formats /// The non-zero entry /// The low transform offset /// The - 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++) { diff --git a/src/ImageSharp46/ImageSharp46.csproj b/src/ImageSharp46/ImageSharp46.csproj index d783ac7e5..2177f3683 100644 --- a/src/ImageSharp46/ImageSharp46.csproj +++ b/src/ImageSharp46/ImageSharp46.csproj @@ -227,7 +227,12 @@ - + + + True + True + Block8x8.Generated.tt + @@ -394,6 +399,15 @@ + + + TextTemplatingFileGenerator + Block8x8.Generated.cs + + + + +