diff --git a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs index 1c3a6be19b..65e632cd2c 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs @@ -52,13 +52,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components public Vector4 V7R; #pragma warning restore SA1600 // ElementsMustBeDocumented -#if SUPPORTS_RUNTIME_INTRINSICS - private static readonly Vector NegativeOneAvx = new Vector(-1F); - private static readonly Vector OffsetAxv = new Vector(.5F); -#endif - private static readonly Vector4 NegativeOne = new Vector4(-1); - private static readonly Vector4 Offset = new Vector4(.5F); - /// /// Get/Set scalar elements at a given index /// @@ -566,11 +559,14 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components // Avx version is written inline to avoid JIT bugs on MacOS. if (Avx.IsSupported) { + var vneg = new Vector(-1F); + var vadd = new Vector(.5F); + // V0 Vector vs = Unsafe.As>(ref a.V0L); Vector voff - = Vector.Min(Vector.Max(NegativeOneAvx, vs), Vector.One) - * OffsetAxv; + = Vector.Min(Vector.Max(vneg, vs), Vector.One) + * vadd; Vector256 v = Avx.Divide( Unsafe.As, Vector256>(ref vs), @@ -581,7 +577,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components // V1 vs = Unsafe.As>(ref a.V1L); - voff = Vector.Min(Vector.Max(NegativeOneAvx, vs), Vector.One) * OffsetAxv; + voff = Vector.Min(Vector.Max(vneg, vs), Vector.One) * vadd; v = Avx.Divide( Unsafe.As, Vector256>(ref vs), @@ -592,7 +588,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components // V2 vs = Unsafe.As>(ref a.V2L); - voff = Vector.Min(Vector.Max(NegativeOneAvx, vs), Vector.One) * OffsetAxv; + voff = Vector.Min(Vector.Max(vneg, vs), Vector.One) * vadd; v = Avx.Divide( Unsafe.As, Vector256>(ref vs), @@ -603,7 +599,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components // V3 vs = Unsafe.As>(ref a.V3L); - voff = Vector.Min(Vector.Max(NegativeOneAvx, vs), Vector.One) * OffsetAxv; + voff = Vector.Min(Vector.Max(vneg, vs), Vector.One) * vadd; v = Avx.Divide( Unsafe.As, Vector256>(ref vs), @@ -614,7 +610,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components // V4 vs = Unsafe.As>(ref a.V4L); - voff = Vector.Min(Vector.Max(NegativeOneAvx, vs), Vector.One) * OffsetAxv; + voff = Vector.Min(Vector.Max(vneg, vs), Vector.One) * vadd; v = Avx.Divide( Unsafe.As, Vector256>(ref vs), @@ -625,7 +621,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components // V5 vs = Unsafe.As>(ref a.V5L); - voff = Vector.Min(Vector.Max(NegativeOneAvx, vs), Vector.One) * OffsetAxv; + voff = Vector.Min(Vector.Max(vneg, vs), Vector.One) * vadd; v = Avx.Divide( Unsafe.As, Vector256>(ref vs), @@ -636,7 +632,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components // V6 vs = Unsafe.As>(ref a.V6L); - voff = Vector.Min(Vector.Max(NegativeOneAvx, vs), Vector.One) * OffsetAxv; + voff = Vector.Min(Vector.Max(vneg, vs), Vector.One) * vadd; v = Avx.Divide( Unsafe.As, Vector256>(ref vs), @@ -647,7 +643,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components // V7 vs = Unsafe.As>(ref a.V7L); - voff = Vector.Min(Vector.Max(NegativeOneAvx, vs), Vector.One) * OffsetAxv; + voff = Vector.Min(Vector.Max(vneg, vs), Vector.One) * vadd; v = Avx.Divide( Unsafe.As, Vector256>(ref vs), @@ -678,14 +674,17 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components } } - [MethodImpl(InliningOptions.ShortMethod)] + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Vector4 DivideRound(Vector4 dividend, Vector4 divisor) { + var neg = new Vector4(-1); + var add = new Vector4(.5F); + // sign(dividend) = max(min(dividend, 1), -1) - Vector4 sign = Numerics.Clamp(dividend, NegativeOne, Vector4.One); + Vector4 sign = Numerics.Clamp(dividend, neg, Vector4.One); // AlmostRound(dividend/divisor) = dividend/divisor + 0.5*sign(dividend) - return (dividend / divisor) + (sign * Offset); + return (dividend / divisor) + (sign * add); } public void RoundInto(ref Block8x8 dest)