From 63e574cdb2fcb14f71a9d271dbf344ba289cc7f3 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 17 Sep 2017 17:24:47 +0200 Subject: [PATCH] more cleanup + more tests --- .../Jpeg/Common/Block8x8F.Generated.cs | 3 +- .../Jpeg/Common/Block8x8F.Generated.tt | 1 + .../Formats/Jpeg/Common/Block8x8F.cs | 2 +- .../Common/Decoder/JpegBlockPostProcessor.cs | 2 +- .../Decoder/JpegColorConverter.FromYCbCr.cs | 68 ++----------------- .../Formats/Jpg/Block8x8FTests.cs | 28 +++++++- 6 files changed, 35 insertions(+), 69 deletions(-) diff --git a/src/ImageSharp/Formats/Jpeg/Common/Block8x8F.Generated.cs b/src/ImageSharp/Formats/Jpeg/Common/Block8x8F.Generated.cs index e8614205c..246df9d91 100644 --- a/src/ImageSharp/Formats/Jpeg/Common/Block8x8F.Generated.cs +++ b/src/ImageSharp/Formats/Jpeg/Common/Block8x8F.Generated.cs @@ -146,6 +146,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common ref Vector row7 = ref Unsafe.As>(ref this.V7L); row7 = NormalizeAndRound(row7, off, max); - } + + } } } diff --git a/src/ImageSharp/Formats/Jpeg/Common/Block8x8F.Generated.tt b/src/ImageSharp/Formats/Jpeg/Common/Block8x8F.Generated.tt index 9ab3ee12c..7b5b6823a 100644 --- a/src/ImageSharp/Formats/Jpeg/Common/Block8x8F.Generated.tt +++ b/src/ImageSharp/Formats/Jpeg/Common/Block8x8F.Generated.tt @@ -96,6 +96,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common <# } #> + } } } diff --git a/src/ImageSharp/Formats/Jpeg/Common/Block8x8F.cs b/src/ImageSharp/Formats/Jpeg/Common/Block8x8F.cs index ff9db6ab9..fcf618e84 100644 --- a/src/ImageSharp/Formats/Jpeg/Common/Block8x8F.cs +++ b/src/ImageSharp/Formats/Jpeg/Common/Block8x8F.cs @@ -241,7 +241,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common /// /// Destination [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe void CopyTo(Span dest) + public void CopyTo(Span dest) { ref byte d = ref Unsafe.As(ref dest.DangerousGetPinnableReference()); ref byte s = ref Unsafe.As(ref this); diff --git a/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegBlockPostProcessor.cs b/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegBlockPostProcessor.cs index d0f2b8817..a081c8415 100644 --- a/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegBlockPostProcessor.cs +++ b/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegBlockPostProcessor.cs @@ -11,7 +11,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder /// Encapsulates the implementation of processing "raw" -s into Jpeg image channels. /// [StructLayout(LayoutKind.Sequential)] - internal unsafe struct JpegBlockPostProcessor + internal struct JpegBlockPostProcessor { /// /// Source block diff --git a/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegColorConverter.FromYCbCr.cs b/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegColorConverter.FromYCbCr.cs index fef6d6438..b988695e1 100644 --- a/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegColorConverter.FromYCbCr.cs +++ b/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegColorConverter.FromYCbCr.cs @@ -1,6 +1,7 @@ using System; using System.Numerics; using System.Runtime.CompilerServices; +using SixLabors.ImageSharp.Common.Tuples; namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder { @@ -124,9 +125,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder if (Vector.Count == 4) { // TODO: Find a way to properly run & test this path on AVX2 PC-s! (Have I already mentioned that Vector is terrible?) - r.RoundAndDownscaleBasic(); - g.RoundAndDownscaleBasic(); - b.RoundAndDownscaleBasic(); + r.RoundAndDownscalePreAvx2(); + g.RoundAndDownscalePreAvx2(); + b.RoundAndDownscalePreAvx2(); } else if (SimdUtils.IsAvx2CompatibleArchitecture) { @@ -147,67 +148,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder } } - /// - /// Its faster to process multiple Vector4-s together - /// - private struct Vector4Pair - { - public Vector4 A; - - public Vector4 B; - - private static readonly Vector4 Scale = new Vector4(1 / 255f); - - private static readonly Vector4 Half = new Vector4(0.5f); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void RoundAndDownscaleBasic() - { - ref Vector a = ref Unsafe.As>(ref this.A); - a = a.FastRound(); - - ref Vector b = ref Unsafe.As>(ref this.B); - b = b.FastRound(); - - // Downscale by 1/255 - this.A *= Scale; - this.B *= Scale; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void RoundAndDownscaleAvx2() - { - ref Vector self = ref Unsafe.As>(ref this); - Vector v = self; - v = v.FastRound(); - - // Downscale by 1/255 - v *= new Vector(1 / 255f); - self = v; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void MultiplyInplace(float value) - { - this.A *= value; - this.B *= value; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AddInplace(Vector4 value) - { - this.A += value; - this.B += value; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void AddInplace(ref Vector4Pair other) - { - this.A += other.A; - this.B += other.B; - } - } - private struct Vector4Octet { #pragma warning disable SA1132 // Do not combine fields diff --git a/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs index 8d1e585db..94f8d2ead 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs @@ -32,6 +32,16 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg { } + private bool SkipOnNonAvx2Runner() + { + if (!SimdUtils.IsAvx2CompatibleArchitecture) + { + this.Output.WriteLine("AVX2 not supported, skipping!"); + return true; + } + return false; + } + [Fact] public void Indexer() { @@ -263,9 +273,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg [InlineData(2)] public void NormalizeColorsAndRoundAvx2(int seed) { - if (!SimdUtils.IsAvx2CompatibleArchitecture) + if (this.SkipOnNonAvx2Runner()) { - this.Output.WriteLine("AVX2 not supported, skipping!"); return; } @@ -283,6 +292,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg this.CompareBlocks(expected, actual, 0); } + [Theory] [InlineData(1)] [InlineData(2)] @@ -413,5 +423,19 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg this.CompareBlocks(expected, actual, 0); } + + [Fact] + public void MultiplyInplace_ByScalar() + { + Block8x8F original = CreateRandomFloatBlock(-500, 500); + + Block8x8F actual = original; + actual.MultiplyInplace(42f); + + for (int i = 0; i < 64; i++) + { + Assert.Equal(original[i]*42f, actual[i]); + } + } } } \ No newline at end of file