From aebe375e2ccfd01949e6528d0986bce4175fad55 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Fri, 2 May 2025 19:50:29 +1000 Subject: [PATCH] Reduce JPEG color conversion to two pipelines --- src/ImageSharp/Common/Helpers/SimdUtils.cs | 38 +-- .../JpegColorConverter.CmykArm64.cs | 95 -------- .../JpegColorConverter.CmykAvx.cs | 95 -------- .../JpegColorConverter.CmykScalar.cs | 2 +- .../JpegColorConverter.GrayScaleArm.cs | 68 ------ .../JpegColorConverter.GrayScaleAvx.cs | 68 ------ .../JpegColorConverter.GrayScaleScalar.cs | 2 +- .../JpegColorConverter.RgbArm.cs | 53 ----- .../JpegColorConverter.RgbAvx.cs | 52 ----- .../JpegColorConverter.RgbScalar.cs | 2 +- .../JpegColorConverter.YCbCrArm.cs | 122 ---------- .../JpegColorConverter.YCbCrAvx.cs | 121 ---------- .../JpegColorConverter.YCbCrScalar.cs | 2 +- .../JpegColorConverter.YCbCrVector.cs | 36 +-- .../JpegColorConverter.YccKArm64.cs | 133 ----------- .../JpegColorConverter.YccKAvx.cs | 132 ----------- .../JpegColorConverter.YccKScalar.cs | 2 +- .../ColorConverters/JpegColorConverterArm.cs | 35 --- .../JpegColorConverterArm64.cs | 35 --- .../ColorConverters/JpegColorConverterAvx.cs | 34 --- .../ColorConverters/JpegColorConverterBase.cs | 123 +++------- .../JpegColorConverterVector.cs | 2 +- .../Decoder/SpectralConverter{TPixel}.cs | 2 +- .../ColorConversion/CmykColorConversion.cs | 20 +- .../GrayscaleColorConversion.cs | 14 +- .../ColorConversion/RgbColorConversion.cs | 20 +- .../ColorConversion/YCbCrColorConversion.cs | 20 +- .../ColorConversion/YccKColorConverter.cs | 20 +- .../Formats/Jpg/JpegColorConverterTests.cs | 218 ++---------------- 29 files changed, 99 insertions(+), 1467 deletions(-) delete mode 100644 src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.CmykArm64.cs delete mode 100644 src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.CmykAvx.cs delete mode 100644 src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.GrayScaleArm.cs delete mode 100644 src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.GrayScaleAvx.cs delete mode 100644 src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.RgbArm.cs delete mode 100644 src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.RgbAvx.cs delete mode 100644 src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YCbCrArm.cs delete mode 100644 src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YCbCrAvx.cs delete mode 100644 src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YccKArm64.cs delete mode 100644 src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YccKAvx.cs delete mode 100644 src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterArm.cs delete mode 100644 src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterArm64.cs delete mode 100644 src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterAvx.cs diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.cs b/src/ImageSharp/Common/Helpers/SimdUtils.cs index 0279e57cc..273947272 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.cs @@ -1,10 +1,9 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System.Diagnostics; using System.Numerics; using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; @@ -36,30 +35,37 @@ internal static partial class SimdUtils /// /// Rounds all values in 'v' to the nearest integer following semantics. - /// Source: - /// - /// https://github.com/g-truc/glm/blob/master/glm/simd/common.h#L110 - /// /// /// The vector [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static Vector FastRound(this Vector v) { - if (Avx2.IsSupported) + if (Avx512F.IsSupported && Vector.Count == Vector512.Count) + { + ref Vector512 v512 = ref Unsafe.As, Vector512>(ref v); + + // imm8 = 0b1000: + // imm8[7:4] = 0b0000 -> preserve 0 fractional bits (round to whole numbers) + // imm8[3:0] = 0b1000 -> _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC (round to nearest even, suppress exceptions) + Vector512 vRound = Avx512F.RoundScale(v512, 0b0000_1000); + return Unsafe.As, Vector>(ref vRound); + } + + if (Avx2.IsSupported && Vector.Count == Vector256.Count) { ref Vector256 v256 = ref Unsafe.As, Vector256>(ref v); Vector256 vRound = Avx.RoundToNearestInteger(v256); return Unsafe.As, Vector>(ref vRound); } - else - { - var magic0 = new Vector(int.MinValue); // 0x80000000 - var sgn0 = Vector.AsVectorSingle(magic0); - var and0 = Vector.BitwiseAnd(sgn0, v); - var or0 = Vector.BitwiseOr(and0, new Vector(8388608.0f)); - var add0 = Vector.Add(v, or0); - return Vector.Subtract(add0, or0); - } + + // https://github.com/g-truc/glm/blob/master/glm/simd/common.h#L11 + Vector magic0 = new(int.MinValue); // 0x80000000 + Vector sgn0 = Vector.AsVectorSingle(magic0); + Vector and0 = Vector.BitwiseAnd(sgn0, v); + Vector or0 = Vector.BitwiseOr(and0, new Vector(8388608.0f)); + Vector add0 = Vector.Add(v, or0); + + return Vector.Subtract(add0, or0); } [Conditional("DEBUG")] diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.CmykArm64.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.CmykArm64.cs deleted file mode 100644 index 11122d3b8..000000000 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.CmykArm64.cs +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Six Labors Split License. - -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.Arm; - -namespace SixLabors.ImageSharp.Formats.Jpeg.Components; - -internal abstract partial class JpegColorConverterBase -{ - internal sealed class CmykArm64 : JpegColorConverterArm64 - { - public CmykArm64(int precision) - : base(JpegColorSpace.Cmyk, precision) - { - } - - /// - public override void ConvertToRgbInplace(in ComponentValues values) - { - ref Vector128 c0Base = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component0)); - ref Vector128 c1Base = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component1)); - ref Vector128 c2Base = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component2)); - ref Vector128 c3Base = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component3)); - - // Used for the color conversion - var scale = Vector128.Create(1 / (this.MaximumValue * this.MaximumValue)); - - nint n = (nint)(uint)values.Component0.Length / Vector128.Count; - for (nint i = 0; i < n; i++) - { - ref Vector128 c = ref Unsafe.Add(ref c0Base, i); - ref Vector128 m = ref Unsafe.Add(ref c1Base, i); - ref Vector128 y = ref Unsafe.Add(ref c2Base, i); - Vector128 k = Unsafe.Add(ref c3Base, i); - - k = AdvSimd.Multiply(k, scale); - c = AdvSimd.Multiply(c, k); - m = AdvSimd.Multiply(m, k); - y = AdvSimd.Multiply(y, k); - } - } - - /// - public override void ConvertFromRgb(in ComponentValues values, Span rLane, Span gLane, Span bLane) - => ConvertFromRgb(in values, this.MaximumValue, rLane, gLane, bLane); - - public static void ConvertFromRgb(in ComponentValues values, float maxValue, Span rLane, Span gLane, Span bLane) - { - ref Vector128 destC = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component0)); - ref Vector128 destM = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component1)); - ref Vector128 destY = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component2)); - ref Vector128 destK = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component3)); - - ref Vector128 srcR = - ref Unsafe.As>(ref MemoryMarshal.GetReference(rLane)); - ref Vector128 srcG = - ref Unsafe.As>(ref MemoryMarshal.GetReference(gLane)); - ref Vector128 srcB = - ref Unsafe.As>(ref MemoryMarshal.GetReference(bLane)); - - var scale = Vector128.Create(maxValue); - - nint n = (nint)(uint)values.Component0.Length / Vector128.Count; - for (nint i = 0; i < n; i++) - { - Vector128 ctmp = AdvSimd.Subtract(scale, Unsafe.Add(ref srcR, i)); - Vector128 mtmp = AdvSimd.Subtract(scale, Unsafe.Add(ref srcG, i)); - Vector128 ytmp = AdvSimd.Subtract(scale, Unsafe.Add(ref srcB, i)); - Vector128 ktmp = AdvSimd.Min(ctmp, AdvSimd.Min(mtmp, ytmp)); - - Vector128 kMask = AdvSimd.Not(AdvSimd.CompareEqual(ktmp, scale)); - - ctmp = AdvSimd.And(AdvSimd.Arm64.Divide(AdvSimd.Subtract(ctmp, ktmp), AdvSimd.Subtract(scale, ktmp)), kMask); - mtmp = AdvSimd.And(AdvSimd.Arm64.Divide(AdvSimd.Subtract(mtmp, ktmp), AdvSimd.Subtract(scale, ktmp)), kMask); - ytmp = AdvSimd.And(AdvSimd.Arm64.Divide(AdvSimd.Subtract(ytmp, ktmp), AdvSimd.Subtract(scale, ktmp)), kMask); - - Unsafe.Add(ref destC, i) = AdvSimd.Subtract(scale, AdvSimd.Multiply(ctmp, scale)); - Unsafe.Add(ref destM, i) = AdvSimd.Subtract(scale, AdvSimd.Multiply(mtmp, scale)); - Unsafe.Add(ref destY, i) = AdvSimd.Subtract(scale, AdvSimd.Multiply(ytmp, scale)); - Unsafe.Add(ref destK, i) = AdvSimd.Subtract(scale, ktmp); - } - } - } -} diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.CmykAvx.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.CmykAvx.cs deleted file mode 100644 index 76d188f45..000000000 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.CmykAvx.cs +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Six Labors Split License. - -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.X86; - -namespace SixLabors.ImageSharp.Formats.Jpeg.Components; - -internal abstract partial class JpegColorConverterBase -{ - internal sealed class CmykAvx : JpegColorConverterAvx - { - public CmykAvx(int precision) - : base(JpegColorSpace.Cmyk, precision) - { - } - - /// - public override void ConvertToRgbInplace(in ComponentValues values) - { - ref Vector256 c0Base = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component0)); - ref Vector256 c1Base = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component1)); - ref Vector256 c2Base = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component2)); - ref Vector256 c3Base = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component3)); - - // Used for the color conversion - var scale = Vector256.Create(1 / (this.MaximumValue * this.MaximumValue)); - - nuint n = values.Component0.Vector256Count(); - for (nuint i = 0; i < n; i++) - { - ref Vector256 c = ref Unsafe.Add(ref c0Base, i); - ref Vector256 m = ref Unsafe.Add(ref c1Base, i); - ref Vector256 y = ref Unsafe.Add(ref c2Base, i); - Vector256 k = Unsafe.Add(ref c3Base, i); - - k = Avx.Multiply(k, scale); - c = Avx.Multiply(c, k); - m = Avx.Multiply(m, k); - y = Avx.Multiply(y, k); - } - } - - /// - public override void ConvertFromRgb(in ComponentValues values, Span rLane, Span gLane, Span bLane) - => ConvertFromRgb(in values, this.MaximumValue, rLane, gLane, bLane); - - public static void ConvertFromRgb(in ComponentValues values, float maxValue, Span rLane, Span gLane, Span bLane) - { - ref Vector256 destC = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component0)); - ref Vector256 destM = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component1)); - ref Vector256 destY = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component2)); - ref Vector256 destK = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component3)); - - ref Vector256 srcR = - ref Unsafe.As>(ref MemoryMarshal.GetReference(rLane)); - ref Vector256 srcG = - ref Unsafe.As>(ref MemoryMarshal.GetReference(gLane)); - ref Vector256 srcB = - ref Unsafe.As>(ref MemoryMarshal.GetReference(bLane)); - - var scale = Vector256.Create(maxValue); - - nuint n = values.Component0.Vector256Count(); - for (nuint i = 0; i < n; i++) - { - Vector256 ctmp = Avx.Subtract(scale, Unsafe.Add(ref srcR, i)); - Vector256 mtmp = Avx.Subtract(scale, Unsafe.Add(ref srcG, i)); - Vector256 ytmp = Avx.Subtract(scale, Unsafe.Add(ref srcB, i)); - Vector256 ktmp = Avx.Min(ctmp, Avx.Min(mtmp, ytmp)); - - Vector256 kMask = Avx.CompareNotEqual(ktmp, scale); - - ctmp = Avx.And(Avx.Divide(Avx.Subtract(ctmp, ktmp), Avx.Subtract(scale, ktmp)), kMask); - mtmp = Avx.And(Avx.Divide(Avx.Subtract(mtmp, ktmp), Avx.Subtract(scale, ktmp)), kMask); - ytmp = Avx.And(Avx.Divide(Avx.Subtract(ytmp, ktmp), Avx.Subtract(scale, ktmp)), kMask); - - Unsafe.Add(ref destC, i) = Avx.Subtract(scale, Avx.Multiply(ctmp, scale)); - Unsafe.Add(ref destM, i) = Avx.Subtract(scale, Avx.Multiply(mtmp, scale)); - Unsafe.Add(ref destY, i) = Avx.Subtract(scale, Avx.Multiply(ytmp, scale)); - Unsafe.Add(ref destK, i) = Avx.Subtract(scale, ktmp); - } - } - } -} diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.CmykScalar.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.CmykScalar.cs index 6d0013b88..1b3be69fa 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.CmykScalar.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.CmykScalar.cs @@ -13,7 +13,7 @@ internal abstract partial class JpegColorConverterBase } /// - public override void ConvertToRgbInplace(in ComponentValues values) => + public override void ConvertToRgbInPlace(in ComponentValues values) => ConvertToRgbInplace(values, this.MaximumValue); /// diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.GrayScaleArm.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.GrayScaleArm.cs deleted file mode 100644 index 6bb8fd7aa..000000000 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.GrayScaleArm.cs +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Six Labors Split License. - -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.Arm; -using static SixLabors.ImageSharp.SimdUtils; - -namespace SixLabors.ImageSharp.Formats.Jpeg.Components; - -internal abstract partial class JpegColorConverterBase -{ - internal sealed class GrayscaleArm : JpegColorConverterArm - { - public GrayscaleArm(int precision) - : base(JpegColorSpace.Grayscale, precision) - { - } - - /// - public override void ConvertToRgbInplace(in ComponentValues values) - { - ref Vector128 c0Base = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component0)); - - // Used for the color conversion - var scale = Vector128.Create(1 / this.MaximumValue); - - nuint n = values.Component0.Vector128Count(); - for (nuint i = 0; i < n; i++) - { - ref Vector128 c0 = ref Unsafe.Add(ref c0Base, i); - c0 = AdvSimd.Multiply(c0, scale); - } - } - - /// - public override void ConvertFromRgb(in ComponentValues values, Span rLane, Span gLane, Span bLane) - { - ref Vector128 destLuminance = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component0)); - - ref Vector128 srcRed = - ref Unsafe.As>(ref MemoryMarshal.GetReference(rLane)); - ref Vector128 srcGreen = - ref Unsafe.As>(ref MemoryMarshal.GetReference(gLane)); - ref Vector128 srcBlue = - ref Unsafe.As>(ref MemoryMarshal.GetReference(bLane)); - - // Used for the color conversion - var f0299 = Vector128.Create(0.299f); - var f0587 = Vector128.Create(0.587f); - var f0114 = Vector128.Create(0.114f); - - nuint n = values.Component0.Vector128Count(); - for (nuint i = 0; i < n; i++) - { - ref Vector128 r = ref Unsafe.Add(ref srcRed, i); - ref Vector128 g = ref Unsafe.Add(ref srcGreen, i); - ref Vector128 b = ref Unsafe.Add(ref srcBlue, i); - - // luminocity = (0.299 * r) + (0.587 * g) + (0.114 * b) - Unsafe.Add(ref destLuminance, i) = HwIntrinsics.MultiplyAdd(HwIntrinsics.MultiplyAdd(AdvSimd.Multiply(f0114, b), f0587, g), f0299, r); - } - } - } -} diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.GrayScaleAvx.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.GrayScaleAvx.cs deleted file mode 100644 index a9e1c5d13..000000000 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.GrayScaleAvx.cs +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Six Labors Split License. - -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.X86; -using static SixLabors.ImageSharp.SimdUtils; - -namespace SixLabors.ImageSharp.Formats.Jpeg.Components; - -internal abstract partial class JpegColorConverterBase -{ - internal sealed class GrayscaleAvx : JpegColorConverterAvx - { - public GrayscaleAvx(int precision) - : base(JpegColorSpace.Grayscale, precision) - { - } - - /// - public override void ConvertToRgbInplace(in ComponentValues values) - { - ref Vector256 c0Base = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component0)); - - // Used for the color conversion - var scale = Vector256.Create(1 / this.MaximumValue); - - nuint n = values.Component0.Vector256Count(); - for (nuint i = 0; i < n; i++) - { - ref Vector256 c0 = ref Unsafe.Add(ref c0Base, i); - c0 = Avx.Multiply(c0, scale); - } - } - - /// - public override void ConvertFromRgb(in ComponentValues values, Span rLane, Span gLane, Span bLane) - { - ref Vector256 destLuminance = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component0)); - - ref Vector256 srcRed = - ref Unsafe.As>(ref MemoryMarshal.GetReference(rLane)); - ref Vector256 srcGreen = - ref Unsafe.As>(ref MemoryMarshal.GetReference(gLane)); - ref Vector256 srcBlue = - ref Unsafe.As>(ref MemoryMarshal.GetReference(bLane)); - - // Used for the color conversion - var f0299 = Vector256.Create(0.299f); - var f0587 = Vector256.Create(0.587f); - var f0114 = Vector256.Create(0.114f); - - nuint n = values.Component0.Vector256Count(); - for (nuint i = 0; i < n; i++) - { - ref Vector256 r = ref Unsafe.Add(ref srcRed, i); - ref Vector256 g = ref Unsafe.Add(ref srcGreen, i); - ref Vector256 b = ref Unsafe.Add(ref srcBlue, i); - - // luminocity = (0.299 * r) + (0.587 * g) + (0.114 * b) - Unsafe.Add(ref destLuminance, i) = HwIntrinsics.MultiplyAdd(HwIntrinsics.MultiplyAdd(Avx.Multiply(f0114, b), f0587, g), f0299, r); - } - } - } -} diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.GrayScaleScalar.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.GrayScaleScalar.cs index 4d3b5c60b..c01811182 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.GrayScaleScalar.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.GrayScaleScalar.cs @@ -16,7 +16,7 @@ internal abstract partial class JpegColorConverterBase } /// - public override void ConvertToRgbInplace(in ComponentValues values) + public override void ConvertToRgbInPlace(in ComponentValues values) => ConvertToRgbInplace(values.Component0, this.MaximumValue); /// diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.RgbArm.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.RgbArm.cs deleted file mode 100644 index 75eeb17dd..000000000 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.RgbArm.cs +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Six Labors Split License. - -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.Arm; -using System.Runtime.Intrinsics.X86; - -namespace SixLabors.ImageSharp.Formats.Jpeg.Components; - -internal abstract partial class JpegColorConverterBase -{ - internal sealed class RgbArm : JpegColorConverterArm - { - public RgbArm(int precision) - : base(JpegColorSpace.RGB, precision) - { - } - - /// - public override void ConvertToRgbInplace(in ComponentValues values) - { - ref Vector128 rBase = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component0)); - ref Vector128 gBase = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component1)); - ref Vector128 bBase = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component2)); - - // Used for the color conversion - var scale = Vector128.Create(1 / this.MaximumValue); - nuint n = values.Component0.Vector128Count(); - for (nuint i = 0; i < n; i++) - { - ref Vector128 r = ref Unsafe.Add(ref rBase, i); - ref Vector128 g = ref Unsafe.Add(ref gBase, i); - ref Vector128 b = ref Unsafe.Add(ref bBase, i); - r = AdvSimd.Multiply(r, scale); - g = AdvSimd.Multiply(g, scale); - b = AdvSimd.Multiply(b, scale); - } - } - - /// - public override void ConvertFromRgb(in ComponentValues values, Span rLane, Span gLane, Span bLane) - { - rLane.CopyTo(values.Component0); - gLane.CopyTo(values.Component1); - bLane.CopyTo(values.Component2); - } - } -} diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.RgbAvx.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.RgbAvx.cs deleted file mode 100644 index b56728fa7..000000000 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.RgbAvx.cs +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Six Labors Split License. - -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.X86; - -namespace SixLabors.ImageSharp.Formats.Jpeg.Components; - -internal abstract partial class JpegColorConverterBase -{ - internal sealed class RgbAvx : JpegColorConverterAvx - { - public RgbAvx(int precision) - : base(JpegColorSpace.RGB, precision) - { - } - - /// - public override void ConvertToRgbInplace(in ComponentValues values) - { - ref Vector256 rBase = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component0)); - ref Vector256 gBase = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component1)); - ref Vector256 bBase = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component2)); - - // Used for the color conversion - var scale = Vector256.Create(1 / this.MaximumValue); - nuint n = values.Component0.Vector256Count(); - for (nuint i = 0; i < n; i++) - { - ref Vector256 r = ref Unsafe.Add(ref rBase, i); - ref Vector256 g = ref Unsafe.Add(ref gBase, i); - ref Vector256 b = ref Unsafe.Add(ref bBase, i); - r = Avx.Multiply(r, scale); - g = Avx.Multiply(g, scale); - b = Avx.Multiply(b, scale); - } - } - - /// - public override void ConvertFromRgb(in ComponentValues values, Span rLane, Span gLane, Span bLane) - { - rLane.CopyTo(values.Component0); - gLane.CopyTo(values.Component1); - bLane.CopyTo(values.Component2); - } - } -} diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.RgbScalar.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.RgbScalar.cs index a43b7ef84..f62b2c7ff 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.RgbScalar.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.RgbScalar.cs @@ -13,7 +13,7 @@ internal abstract partial class JpegColorConverterBase } /// - public override void ConvertToRgbInplace(in ComponentValues values) + public override void ConvertToRgbInPlace(in ComponentValues values) => ConvertToRgbInplace(values, this.MaximumValue); /// diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YCbCrArm.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YCbCrArm.cs deleted file mode 100644 index 4f7cf1ed6..000000000 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YCbCrArm.cs +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Six Labors Split License. - -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.Arm; -using System.Runtime.Intrinsics.X86; -using static SixLabors.ImageSharp.SimdUtils; - -// ReSharper disable ImpureMethodCallOnReadonlyValueField -namespace SixLabors.ImageSharp.Formats.Jpeg.Components; - -internal abstract partial class JpegColorConverterBase -{ - internal sealed class YCbCrArm : JpegColorConverterArm - { - public YCbCrArm(int precision) - : base(JpegColorSpace.YCbCr, precision) - { - } - - /// - public override void ConvertToRgbInplace(in ComponentValues values) - { - ref Vector128 c0Base = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component0)); - ref Vector128 c1Base = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component1)); - ref Vector128 c2Base = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component2)); - - // Used for the color conversion - var chromaOffset = Vector128.Create(-this.HalfValue); - var scale = Vector128.Create(1 / this.MaximumValue); - var rCrMult = Vector128.Create(YCbCrScalar.RCrMult); - var gCbMult = Vector128.Create(-YCbCrScalar.GCbMult); - var gCrMult = Vector128.Create(-YCbCrScalar.GCrMult); - var bCbMult = Vector128.Create(YCbCrScalar.BCbMult); - - // Walking 8 elements at one step: - nuint n = (uint)values.Component0.Length / (uint)Vector128.Count; - for (nuint i = 0; i < n; i++) - { - // y = yVals[i]; - // cb = cbVals[i] - 128F; - // cr = crVals[i] - 128F; - ref Vector128 c0 = ref Unsafe.Add(ref c0Base, i); - ref Vector128 c1 = ref Unsafe.Add(ref c1Base, i); - ref Vector128 c2 = ref Unsafe.Add(ref c2Base, i); - - Vector128 y = c0; - Vector128 cb = AdvSimd.Add(c1, chromaOffset); - Vector128 cr = AdvSimd.Add(c2, chromaOffset); - - // r = y + (1.402F * cr); - // g = y - (0.344136F * cb) - (0.714136F * cr); - // b = y + (1.772F * cb); - Vector128 r = HwIntrinsics.MultiplyAdd(y, cr, rCrMult); - Vector128 g = HwIntrinsics.MultiplyAdd(HwIntrinsics.MultiplyAdd(y, cb, gCbMult), cr, gCrMult); - Vector128 b = HwIntrinsics.MultiplyAdd(y, cb, bCbMult); - - r = AdvSimd.Multiply(AdvSimd.RoundToNearest(r), scale); - g = AdvSimd.Multiply(AdvSimd.RoundToNearest(g), scale); - b = AdvSimd.Multiply(AdvSimd.RoundToNearest(b), scale); - - c0 = r; - c1 = g; - c2 = b; - } - } - - /// - public override void ConvertFromRgb(in ComponentValues values, Span rLane, Span gLane, Span bLane) - { - ref Vector128 destY = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component0)); - ref Vector128 destCb = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component1)); - ref Vector128 destCr = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component2)); - - ref Vector128 srcR = - ref Unsafe.As>(ref MemoryMarshal.GetReference(rLane)); - ref Vector128 srcG = - ref Unsafe.As>(ref MemoryMarshal.GetReference(gLane)); - ref Vector128 srcB = - ref Unsafe.As>(ref MemoryMarshal.GetReference(bLane)); - - // Used for the color conversion - var chromaOffset = Vector128.Create(this.HalfValue); - - var f0299 = Vector128.Create(0.299f); - var f0587 = Vector128.Create(0.587f); - var f0114 = Vector128.Create(0.114f); - var fn0168736 = Vector128.Create(-0.168736f); - var fn0331264 = Vector128.Create(-0.331264f); - var fn0418688 = Vector128.Create(-0.418688f); - var fn0081312F = Vector128.Create(-0.081312F); - var f05 = Vector128.Create(0.5f); - - nuint n = (uint)values.Component0.Length / (uint)Vector128.Count; - for (nuint i = 0; i < n; i++) - { - Vector128 r = Unsafe.Add(ref srcR, i); - Vector128 g = Unsafe.Add(ref srcG, i); - Vector128 b = Unsafe.Add(ref srcB, i); - - // y = 0 + (0.299 * r) + (0.587 * g) + (0.114 * b) - // cb = 128 - (0.168736 * r) - (0.331264 * g) + (0.5 * b) - // cr = 128 + (0.5 * r) - (0.418688 * g) - (0.081312 * b) - Vector128 y = HwIntrinsics.MultiplyAdd(HwIntrinsics.MultiplyAdd(AdvSimd.Multiply(f0114, b), f0587, g), f0299, r); - Vector128 cb = AdvSimd.Add(chromaOffset, HwIntrinsics.MultiplyAdd(HwIntrinsics.MultiplyAdd(AdvSimd.Multiply(f05, b), fn0331264, g), fn0168736, r)); - Vector128 cr = AdvSimd.Add(chromaOffset, HwIntrinsics.MultiplyAdd(HwIntrinsics.MultiplyAdd(AdvSimd.Multiply(fn0081312F, b), fn0418688, g), f05, r)); - - Unsafe.Add(ref destY, i) = y; - Unsafe.Add(ref destCb, i) = cb; - Unsafe.Add(ref destCr, i) = cr; - } - } - } -} diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YCbCrAvx.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YCbCrAvx.cs deleted file mode 100644 index c5fa786e2..000000000 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YCbCrAvx.cs +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Six Labors Split License. - -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.X86; -using static SixLabors.ImageSharp.SimdUtils; - -// ReSharper disable ImpureMethodCallOnReadonlyValueField -namespace SixLabors.ImageSharp.Formats.Jpeg.Components; - -internal abstract partial class JpegColorConverterBase -{ - internal sealed class YCbCrAvx : JpegColorConverterAvx - { - public YCbCrAvx(int precision) - : base(JpegColorSpace.YCbCr, precision) - { - } - - /// - public override void ConvertToRgbInplace(in ComponentValues values) - { - ref Vector256 c0Base = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component0)); - ref Vector256 c1Base = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component1)); - ref Vector256 c2Base = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component2)); - - // Used for the color conversion - var chromaOffset = Vector256.Create(-this.HalfValue); - var scale = Vector256.Create(1 / this.MaximumValue); - var rCrMult = Vector256.Create(YCbCrScalar.RCrMult); - var gCbMult = Vector256.Create(-YCbCrScalar.GCbMult); - var gCrMult = Vector256.Create(-YCbCrScalar.GCrMult); - var bCbMult = Vector256.Create(YCbCrScalar.BCbMult); - - // Walking 8 elements at one step: - nuint n = values.Component0.Vector256Count(); - for (nuint i = 0; i < n; i++) - { - // y = yVals[i]; - // cb = cbVals[i] - 128F; - // cr = crVals[i] - 128F; - ref Vector256 c0 = ref Unsafe.Add(ref c0Base, i); - ref Vector256 c1 = ref Unsafe.Add(ref c1Base, i); - ref Vector256 c2 = ref Unsafe.Add(ref c2Base, i); - - Vector256 y = c0; - Vector256 cb = Avx.Add(c1, chromaOffset); - Vector256 cr = Avx.Add(c2, chromaOffset); - - // r = y + (1.402F * cr); - // g = y - (0.344136F * cb) - (0.714136F * cr); - // b = y + (1.772F * cb); - Vector256 r = HwIntrinsics.MultiplyAdd(y, cr, rCrMult); - Vector256 g = HwIntrinsics.MultiplyAdd(HwIntrinsics.MultiplyAdd(y, cb, gCbMult), cr, gCrMult); - Vector256 b = HwIntrinsics.MultiplyAdd(y, cb, bCbMult); - - r = Avx.Multiply(Avx.RoundToNearestInteger(r), scale); - g = Avx.Multiply(Avx.RoundToNearestInteger(g), scale); - b = Avx.Multiply(Avx.RoundToNearestInteger(b), scale); - - c0 = r; - c1 = g; - c2 = b; - } - } - - /// - public override void ConvertFromRgb(in ComponentValues values, Span rLane, Span gLane, Span bLane) - { - ref Vector256 destY = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component0)); - ref Vector256 destCb = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component1)); - ref Vector256 destCr = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component2)); - - ref Vector256 srcR = - ref Unsafe.As>(ref MemoryMarshal.GetReference(rLane)); - ref Vector256 srcG = - ref Unsafe.As>(ref MemoryMarshal.GetReference(gLane)); - ref Vector256 srcB = - ref Unsafe.As>(ref MemoryMarshal.GetReference(bLane)); - - // Used for the color conversion - var chromaOffset = Vector256.Create(this.HalfValue); - - var f0299 = Vector256.Create(0.299f); - var f0587 = Vector256.Create(0.587f); - var f0114 = Vector256.Create(0.114f); - var fn0168736 = Vector256.Create(-0.168736f); - var fn0331264 = Vector256.Create(-0.331264f); - var fn0418688 = Vector256.Create(-0.418688f); - var fn0081312F = Vector256.Create(-0.081312F); - var f05 = Vector256.Create(0.5f); - - nuint n = values.Component0.Vector256Count(); - for (nuint i = 0; i < n; i++) - { - Vector256 r = Unsafe.Add(ref srcR, i); - Vector256 g = Unsafe.Add(ref srcG, i); - Vector256 b = Unsafe.Add(ref srcB, i); - - // y = 0 + (0.299 * r) + (0.587 * g) + (0.114 * b) - // cb = 128 - (0.168736 * r) - (0.331264 * g) + (0.5 * b) - // cr = 128 + (0.5 * r) - (0.418688 * g) - (0.081312 * b) - Vector256 y = HwIntrinsics.MultiplyAdd(HwIntrinsics.MultiplyAdd(Avx.Multiply(f0114, b), f0587, g), f0299, r); - Vector256 cb = Avx.Add(chromaOffset, HwIntrinsics.MultiplyAdd(HwIntrinsics.MultiplyAdd(Avx.Multiply(f05, b), fn0331264, g), fn0168736, r)); - Vector256 cr = Avx.Add(chromaOffset, HwIntrinsics.MultiplyAdd(HwIntrinsics.MultiplyAdd(Avx.Multiply(fn0081312F, b), fn0418688, g), f05, r)); - - Unsafe.Add(ref destY, i) = y; - Unsafe.Add(ref destCb, i) = cb; - Unsafe.Add(ref destCr, i) = cr; - } - } - } -} diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YCbCrScalar.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YCbCrScalar.cs index e3e5a452a..e7e29a87a 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YCbCrScalar.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YCbCrScalar.cs @@ -19,7 +19,7 @@ internal abstract partial class JpegColorConverterBase } /// - public override void ConvertToRgbInplace(in ComponentValues values) + public override void ConvertToRgbInPlace(in ComponentValues values) => ConvertToRgbInplace(values, this.MaximumValue, this.HalfValue); /// diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YCbCrVector.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YCbCrVector.cs index a5d0c889e..2591ae310 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YCbCrVector.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YCbCrVector.cs @@ -27,13 +27,13 @@ internal abstract partial class JpegColorConverterBase ref Vector c2Base = ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component2)); - var chromaOffset = new Vector(-this.HalfValue); + Vector chromaOffset = new(-this.HalfValue); - var scale = new Vector(1 / this.MaximumValue); - var rCrMult = new Vector(YCbCrScalar.RCrMult); - var gCbMult = new Vector(-YCbCrScalar.GCbMult); - var gCrMult = new Vector(-YCbCrScalar.GCrMult); - var bCbMult = new Vector(YCbCrScalar.BCbMult); + Vector scale = new(1 / this.MaximumValue); + Vector rCrMult = new(YCbCrScalar.RCrMult); + Vector gCbMult = new(-YCbCrScalar.GCbMult); + Vector gCrMult = new(-YCbCrScalar.GCrMult); + Vector bCbMult = new(YCbCrScalar.BCbMult); nuint n = values.Component0.VectorCount(); for (nuint i = 0; i < n; i++) @@ -89,19 +89,19 @@ internal abstract partial class JpegColorConverterBase ref Vector srcB = ref Unsafe.As>(ref MemoryMarshal.GetReference(bLane)); - var chromaOffset = new Vector(this.HalfValue); + Vector chromaOffset = new(this.HalfValue); - var rYMult = new Vector(0.299f); - var gYMult = new Vector(0.587f); - var bYMult = new Vector(0.114f); + Vector rYMult = new(0.299f); + Vector gYMult = new(0.587f); + Vector bYMult = new(0.114f); - var rCbMult = new Vector(0.168736f); - var gCbMult = new Vector(0.331264f); - var bCbMult = new Vector(0.5f); + Vector rCbMult = new(0.168736f); + Vector gCbMult = new(0.331264f); + Vector bCbMult = new(0.5f); - var rCrMult = new Vector(0.5f); - var gCrMult = new Vector(0.418688f); - var bCrMult = new Vector(0.081312f); + Vector rCrMult = new(0.5f); + Vector gCrMult = new(0.418688f); + Vector bCrMult = new(0.081312f); nuint n = values.Component0.VectorCount(); for (nuint i = 0; i < n; i++) @@ -120,7 +120,7 @@ internal abstract partial class JpegColorConverterBase } /// - protected override void ConvertFromRgbScalarRemainder(in ComponentValues values, Span r, Span g, Span b) - => YCbCrScalar.ConvertFromRgb(values, this.HalfValue, r, g, b); + protected override void ConvertFromRgbScalarRemainder(in ComponentValues values, Span rLane, Span gLane, Span bLane) + => YCbCrScalar.ConvertFromRgb(values, this.HalfValue, rLane, gLane, bLane); } } diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YccKArm64.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YccKArm64.cs deleted file mode 100644 index 285ba62cf..000000000 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YccKArm64.cs +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Six Labors Split License. - -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.Arm; -using System.Runtime.Intrinsics.X86; -using static SixLabors.ImageSharp.SimdUtils; - -namespace SixLabors.ImageSharp.Formats.Jpeg.Components; - -internal abstract partial class JpegColorConverterBase -{ - internal sealed class YccKArm64 : JpegColorConverterArm64 - { - public YccKArm64(int precision) - : base(JpegColorSpace.Ycck, precision) - { - } - - /// - public override void ConvertToRgbInplace(in ComponentValues values) - { - ref Vector128 c0Base = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component0)); - ref Vector128 c1Base = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component1)); - ref Vector128 c2Base = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component2)); - ref Vector128 kBase = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component3)); - - // Used for the color conversion - var chromaOffset = Vector128.Create(-this.HalfValue); - var scale = Vector128.Create(1 / (this.MaximumValue * this.MaximumValue)); - var max = Vector128.Create(this.MaximumValue); - var rCrMult = Vector128.Create(YCbCrScalar.RCrMult); - var gCbMult = Vector128.Create(-YCbCrScalar.GCbMult); - var gCrMult = Vector128.Create(-YCbCrScalar.GCrMult); - var bCbMult = Vector128.Create(YCbCrScalar.BCbMult); - - // Walking 8 elements at one step: - nuint n = (uint)values.Component0.Length / (uint)Vector128.Count; - for (nuint i = 0; i < n; i++) - { - // y = yVals[i]; - // cb = cbVals[i] - 128F; - // cr = crVals[i] - 128F; - // k = kVals[i] / 256F; - ref Vector128 c0 = ref Unsafe.Add(ref c0Base, i); - ref Vector128 c1 = ref Unsafe.Add(ref c1Base, i); - ref Vector128 c2 = ref Unsafe.Add(ref c2Base, i); - Vector128 y = c0; - Vector128 cb = AdvSimd.Add(c1, chromaOffset); - Vector128 cr = AdvSimd.Add(c2, chromaOffset); - Vector128 scaledK = AdvSimd.Multiply(Unsafe.Add(ref kBase, i), scale); - - // r = y + (1.402F * cr); - // g = y - (0.344136F * cb) - (0.714136F * cr); - // b = y + (1.772F * cb); - Vector128 r = HwIntrinsics.MultiplyAdd(y, cr, rCrMult); - Vector128 g = - HwIntrinsics.MultiplyAdd(HwIntrinsics.MultiplyAdd(y, cb, gCbMult), cr, gCrMult); - Vector128 b = HwIntrinsics.MultiplyAdd(y, cb, bCbMult); - - r = AdvSimd.Subtract(max, AdvSimd.RoundToNearest(r)); - g = AdvSimd.Subtract(max, AdvSimd.RoundToNearest(g)); - b = AdvSimd.Subtract(max, AdvSimd.RoundToNearest(b)); - - r = AdvSimd.Multiply(r, scaledK); - g = AdvSimd.Multiply(g, scaledK); - b = AdvSimd.Multiply(b, scaledK); - - c0 = r; - c1 = g; - c2 = b; - } - } - - /// - public override void ConvertFromRgb(in ComponentValues values, Span rLane, Span gLane, Span bLane) - { - // rgb -> cmyk - CmykArm64.ConvertFromRgb(in values, this.MaximumValue, rLane, gLane, bLane); - - // cmyk -> ycck - ref Vector128 destY = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component0)); - ref Vector128 destCb = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component1)); - ref Vector128 destCr = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component2)); - - ref Vector128 srcR = ref destY; - ref Vector128 srcG = ref destCb; - ref Vector128 srcB = ref destCr; - - // Used for the color conversion - var maxSampleValue = Vector128.Create(this.MaximumValue); - - var chromaOffset = Vector128.Create(this.HalfValue); - - var f0299 = Vector128.Create(0.299f); - var f0587 = Vector128.Create(0.587f); - var f0114 = Vector128.Create(0.114f); - var fn0168736 = Vector128.Create(-0.168736f); - var fn0331264 = Vector128.Create(-0.331264f); - var fn0418688 = Vector128.Create(-0.418688f); - var fn0081312F = Vector128.Create(-0.081312F); - var f05 = Vector128.Create(0.5f); - - nuint n = (uint)values.Component0.Length / (uint)Vector128.Count; - for (nuint i = 0; i < n; i++) - { - Vector128 r = AdvSimd.Subtract(maxSampleValue, Unsafe.Add(ref srcR, i)); - Vector128 g = AdvSimd.Subtract(maxSampleValue, Unsafe.Add(ref srcG, i)); - Vector128 b = AdvSimd.Subtract(maxSampleValue, Unsafe.Add(ref srcB, i)); - - // y = 0 + (0.299 * r) + (0.587 * g) + (0.114 * b) - // cb = 128 - (0.168736 * r) - (0.331264 * g) + (0.5 * b) - // cr = 128 + (0.5 * r) - (0.418688 * g) - (0.081312 * b) - Vector128 y = HwIntrinsics.MultiplyAdd(HwIntrinsics.MultiplyAdd(AdvSimd.Multiply(f0114, b), f0587, g), f0299, r); - Vector128 cb = AdvSimd.Add(chromaOffset, HwIntrinsics.MultiplyAdd(HwIntrinsics.MultiplyAdd(AdvSimd.Multiply(f05, b), fn0331264, g), fn0168736, r)); - Vector128 cr = AdvSimd.Add(chromaOffset, HwIntrinsics.MultiplyAdd(HwIntrinsics.MultiplyAdd(AdvSimd.Multiply(fn0081312F, b), fn0418688, g), f05, r)); - - Unsafe.Add(ref destY, i) = y; - Unsafe.Add(ref destCb, i) = cb; - Unsafe.Add(ref destCr, i) = cr; - } - } - } -} diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YccKAvx.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YccKAvx.cs deleted file mode 100644 index efe40ba08..000000000 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YccKAvx.cs +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Six Labors Split License. - -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.X86; -using static SixLabors.ImageSharp.SimdUtils; - -namespace SixLabors.ImageSharp.Formats.Jpeg.Components; - -internal abstract partial class JpegColorConverterBase -{ - internal sealed class YccKAvx : JpegColorConverterAvx - { - public YccKAvx(int precision) - : base(JpegColorSpace.Ycck, precision) - { - } - - /// - public override void ConvertToRgbInplace(in ComponentValues values) - { - ref Vector256 c0Base = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component0)); - ref Vector256 c1Base = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component1)); - ref Vector256 c2Base = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component2)); - ref Vector256 kBase = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component3)); - - // Used for the color conversion - var chromaOffset = Vector256.Create(-this.HalfValue); - var scale = Vector256.Create(1 / (this.MaximumValue * this.MaximumValue)); - var max = Vector256.Create(this.MaximumValue); - var rCrMult = Vector256.Create(YCbCrScalar.RCrMult); - var gCbMult = Vector256.Create(-YCbCrScalar.GCbMult); - var gCrMult = Vector256.Create(-YCbCrScalar.GCrMult); - var bCbMult = Vector256.Create(YCbCrScalar.BCbMult); - - // Walking 8 elements at one step: - nuint n = values.Component0.Vector256Count(); - for (nuint i = 0; i < n; i++) - { - // y = yVals[i]; - // cb = cbVals[i] - 128F; - // cr = crVals[i] - 128F; - // k = kVals[i] / 256F; - ref Vector256 c0 = ref Unsafe.Add(ref c0Base, i); - ref Vector256 c1 = ref Unsafe.Add(ref c1Base, i); - ref Vector256 c2 = ref Unsafe.Add(ref c2Base, i); - Vector256 y = c0; - Vector256 cb = Avx.Add(c1, chromaOffset); - Vector256 cr = Avx.Add(c2, chromaOffset); - Vector256 scaledK = Avx.Multiply(Unsafe.Add(ref kBase, i), scale); - - // r = y + (1.402F * cr); - // g = y - (0.344136F * cb) - (0.714136F * cr); - // b = y + (1.772F * cb); - Vector256 r = HwIntrinsics.MultiplyAdd(y, cr, rCrMult); - Vector256 g = - HwIntrinsics.MultiplyAdd(HwIntrinsics.MultiplyAdd(y, cb, gCbMult), cr, gCrMult); - Vector256 b = HwIntrinsics.MultiplyAdd(y, cb, bCbMult); - - r = Avx.Subtract(max, Avx.RoundToNearestInteger(r)); - g = Avx.Subtract(max, Avx.RoundToNearestInteger(g)); - b = Avx.Subtract(max, Avx.RoundToNearestInteger(b)); - - r = Avx.Multiply(r, scaledK); - g = Avx.Multiply(g, scaledK); - b = Avx.Multiply(b, scaledK); - - c0 = r; - c1 = g; - c2 = b; - } - } - - /// - public override void ConvertFromRgb(in ComponentValues values, Span rLane, Span gLane, Span bLane) - { - // rgb -> cmyk - CmykAvx.ConvertFromRgb(in values, this.MaximumValue, rLane, gLane, bLane); - - // cmyk -> ycck - ref Vector256 destY = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component0)); - ref Vector256 destCb = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component1)); - ref Vector256 destCr = - ref Unsafe.As>(ref MemoryMarshal.GetReference(values.Component2)); - - ref Vector256 srcR = ref destY; - ref Vector256 srcG = ref destCb; - ref Vector256 srcB = ref destCr; - - // Used for the color conversion - var maxSampleValue = Vector256.Create(this.MaximumValue); - - var chromaOffset = Vector256.Create(this.HalfValue); - - var f0299 = Vector256.Create(0.299f); - var f0587 = Vector256.Create(0.587f); - var f0114 = Vector256.Create(0.114f); - var fn0168736 = Vector256.Create(-0.168736f); - var fn0331264 = Vector256.Create(-0.331264f); - var fn0418688 = Vector256.Create(-0.418688f); - var fn0081312F = Vector256.Create(-0.081312F); - var f05 = Vector256.Create(0.5f); - - nuint n = values.Component0.Vector256Count(); - for (nuint i = 0; i < n; i++) - { - Vector256 r = Avx.Subtract(maxSampleValue, Unsafe.Add(ref srcR, i)); - Vector256 g = Avx.Subtract(maxSampleValue, Unsafe.Add(ref srcG, i)); - Vector256 b = Avx.Subtract(maxSampleValue, Unsafe.Add(ref srcB, i)); - - // y = 0 + (0.299 * r) + (0.587 * g) + (0.114 * b) - // cb = 128 - (0.168736 * r) - (0.331264 * g) + (0.5 * b) - // cr = 128 + (0.5 * r) - (0.418688 * g) - (0.081312 * b) - Vector256 y = HwIntrinsics.MultiplyAdd(HwIntrinsics.MultiplyAdd(Avx.Multiply(f0114, b), f0587, g), f0299, r); - Vector256 cb = Avx.Add(chromaOffset, HwIntrinsics.MultiplyAdd(HwIntrinsics.MultiplyAdd(Avx.Multiply(f05, b), fn0331264, g), fn0168736, r)); - Vector256 cr = Avx.Add(chromaOffset, HwIntrinsics.MultiplyAdd(HwIntrinsics.MultiplyAdd(Avx.Multiply(fn0081312F, b), fn0418688, g), f05, r)); - - Unsafe.Add(ref destY, i) = y; - Unsafe.Add(ref destCb, i) = cb; - Unsafe.Add(ref destCr, i) = cr; - } - } - } -} diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YccKScalar.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YccKScalar.cs index e47572b02..610c0a84e 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YccKScalar.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.YccKScalar.cs @@ -19,7 +19,7 @@ internal abstract partial class JpegColorConverterBase } /// - public override void ConvertToRgbInplace(in ComponentValues values) + public override void ConvertToRgbInPlace(in ComponentValues values) => ConvertToRgpInplace(values, this.MaximumValue, this.HalfValue); /// diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterArm.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterArm.cs deleted file mode 100644 index bfbbf200c..000000000 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterArm.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Six Labors Split License. -using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.Arm; -using System.Runtime.Intrinsics.X86; - -namespace SixLabors.ImageSharp.Formats.Jpeg.Components; - -internal abstract partial class JpegColorConverterBase -{ - /// - /// abstract base for implementations - /// based on instructions. - /// - /// - /// Converters of this family would expect input buffers lengths to be - /// divisible by 8 without a remainder. - /// This is guaranteed by real-life data as jpeg stores pixels via 8x8 blocks. - /// DO NOT pass test data of invalid size to these converters as they - /// potentially won't do a bound check and return a false positive result. - /// - internal abstract class JpegColorConverterArm : JpegColorConverterBase - { - protected JpegColorConverterArm(JpegColorSpace colorSpace, int precision) - : base(colorSpace, precision) - { - } - - public static bool IsSupported => AdvSimd.IsSupported; - - public sealed override bool IsAvailable => IsSupported; - - public sealed override int ElementsPerBatch => Vector128.Count; - } -} diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterArm64.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterArm64.cs deleted file mode 100644 index d6d4d6ef9..000000000 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterArm64.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Six Labors Split License. -using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.Arm; -using System.Runtime.Intrinsics.X86; - -namespace SixLabors.ImageSharp.Formats.Jpeg.Components; - -internal abstract partial class JpegColorConverterBase -{ - /// - /// abstract base for implementations - /// based on instructions. - /// - /// - /// Converters of this family would expect input buffers lengths to be - /// divisible by 8 without a remainder. - /// This is guaranteed by real-life data as jpeg stores pixels via 8x8 blocks. - /// DO NOT pass test data of invalid size to these converters as they - /// potentially won't do a bound check and return a false positive result. - /// - internal abstract class JpegColorConverterArm64 : JpegColorConverterBase - { - protected JpegColorConverterArm64(JpegColorSpace colorSpace, int precision) - : base(colorSpace, precision) - { - } - - public static bool IsSupported => AdvSimd.Arm64.IsSupported; - - public sealed override bool IsAvailable => IsSupported; - - public sealed override int ElementsPerBatch => Vector128.Count; - } -} diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterAvx.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterAvx.cs deleted file mode 100644 index a3e41bdc6..000000000 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterAvx.cs +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Six Labors Split License. -using System.Runtime.Intrinsics; -using System.Runtime.Intrinsics.X86; - -namespace SixLabors.ImageSharp.Formats.Jpeg.Components; - -internal abstract partial class JpegColorConverterBase -{ - /// - /// abstract base for implementations - /// based on instructions. - /// - /// - /// Converters of this family would expect input buffers lengths to be - /// divisible by 8 without a remainder. - /// This is guaranteed by real-life data as jpeg stores pixels via 8x8 blocks. - /// DO NOT pass test data of invalid size to these converters as they - /// potentially won't do a bound check and return a false positive result. - /// - internal abstract class JpegColorConverterAvx : JpegColorConverterBase - { - protected JpegColorConverterAvx(JpegColorSpace colorSpace, int precision) - : base(colorSpace, precision) - { - } - - public static bool IsSupported => Avx.IsSupported; - - public sealed override bool IsAvailable => IsSupported; - - public sealed override int ElementsPerBatch => Vector256.Count; - } -} diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterBase.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterBase.cs index 041f6b057..581919e72 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterBase.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterBase.cs @@ -71,25 +71,14 @@ internal abstract partial class JpegColorConverterBase /// The precision in bits. /// Invalid colorspace. public static JpegColorConverterBase GetConverter(JpegColorSpace colorSpace, int precision) - { - JpegColorConverterBase converter = Array.Find( - Converters, - c => c.ColorSpace == colorSpace - && c.Precision == precision); - - if (converter is null) - { - throw new InvalidImageContentException($"Could not find any converter for JpegColorSpace {colorSpace}!"); - } - - return converter; - } + => Array.Find(Converters, c => c.ColorSpace == colorSpace && c.Precision == precision) + ?? throw new InvalidImageContentException($"Could not find any converter for JpegColorSpace {colorSpace}!"); /// - /// Converts planar jpeg component values in to RGB color space inplace. + /// Converts planar jpeg component values in to RGB color space in-place. /// - /// The input/ouptut as a stack-only struct - public abstract void ConvertToRgbInplace(in ComponentValues values); + /// The input/output as a stack-only struct + public abstract void ConvertToRgbInPlace(in ComponentValues values); /// /// Converts RGB lanes to jpeg component values. @@ -101,31 +90,25 @@ internal abstract partial class JpegColorConverterBase public abstract void ConvertFromRgb(in ComponentValues values, Span rLane, Span gLane, Span bLane); /// - /// Returns the s for all supported colorspaces and precisions. + /// Returns the s for all supported color spaces and precisions. /// private static JpegColorConverterBase[] CreateConverters() - { - // 5 color types with 2 supported precisions: 8 bit & 12 bit - const int colorConvertersCount = 5 * 2; - - JpegColorConverterBase[] converters = new JpegColorConverterBase[colorConvertersCount]; - - // 8-bit converters - converters[0] = GetYCbCrConverter(8); - converters[1] = GetYccKConverter(8); - converters[2] = GetCmykConverter(8); - converters[3] = GetGrayScaleConverter(8); - converters[4] = GetRgbConverter(8); - - // 12-bit converters - converters[5] = GetYCbCrConverter(12); - converters[6] = GetYccKConverter(12); - converters[7] = GetCmykConverter(12); - converters[8] = GetGrayScaleConverter(12); - converters[9] = GetRgbConverter(12); - - return converters; - } + => [ + + // 8-bit converters + GetYCbCrConverter(8), + GetYccKConverter(8), + GetCmykConverter(8), + GetGrayScaleConverter(8), + GetRgbConverter(8), + + // 12-bit converters + GetYCbCrConverter(12), + GetYccKConverter(12), + GetCmykConverter(12), + GetGrayScaleConverter(12), + GetRgbConverter(12), + ]; /// /// Returns the s for the YCbCr colorspace. @@ -133,16 +116,6 @@ internal abstract partial class JpegColorConverterBase /// The precision in bits. private static JpegColorConverterBase GetYCbCrConverter(int precision) { - if (JpegColorConverterAvx.IsSupported) - { - return new YCbCrAvx(precision); - } - - if (JpegColorConverterArm.IsSupported) - { - return new YCbCrArm(precision); - } - if (JpegColorConverterVector.IsSupported) { return new YCbCrVector(precision); @@ -157,16 +130,6 @@ internal abstract partial class JpegColorConverterBase /// The precision in bits. private static JpegColorConverterBase GetYccKConverter(int precision) { - if (JpegColorConverterAvx.IsSupported) - { - return new YccKAvx(precision); - } - - if (JpegColorConverterArm64.IsSupported) - { - return new YccKArm64(precision); - } - if (JpegColorConverterVector.IsSupported) { return new YccKVector(precision); @@ -181,16 +144,6 @@ internal abstract partial class JpegColorConverterBase /// The precision in bits. private static JpegColorConverterBase GetCmykConverter(int precision) { - if (JpegColorConverterAvx.IsSupported) - { - return new CmykAvx(precision); - } - - if (JpegColorConverterArm64.IsSupported) - { - return new CmykArm64(precision); - } - if (JpegColorConverterVector.IsSupported) { return new CmykVector(precision); @@ -205,16 +158,6 @@ internal abstract partial class JpegColorConverterBase /// The precision in bits. private static JpegColorConverterBase GetGrayScaleConverter(int precision) { - if (JpegColorConverterAvx.IsSupported) - { - return new GrayscaleAvx(precision); - } - - if (JpegColorConverterArm.IsSupported) - { - return new GrayscaleArm(precision); - } - if (JpegColorConverterVector.IsSupported) { return new GrayScaleVector(precision); @@ -229,16 +172,6 @@ internal abstract partial class JpegColorConverterBase /// The precision in bits. private static JpegColorConverterBase GetRgbConverter(int precision) { - if (JpegColorConverterAvx.IsSupported) - { - return new RgbAvx(precision); - } - - if (JpegColorConverterArm.IsSupported) - { - return new RgbArm(precision); - } - if (JpegColorConverterVector.IsSupported) { return new RgbVector(precision); @@ -295,7 +228,7 @@ internal abstract partial class JpegColorConverterBase // In case of grayscale, Component1 and Component2 point to Component0 memory area this.Component1 = this.ComponentCount > 1 ? componentBuffers[1].DangerousGetRowSpan(row) : this.Component0; this.Component2 = this.ComponentCount > 2 ? componentBuffers[2].DangerousGetRowSpan(row) : this.Component0; - this.Component3 = this.ComponentCount > 3 ? componentBuffers[3].DangerousGetRowSpan(row) : Span.Empty; + this.Component3 = this.ComponentCount > 3 ? componentBuffers[3].DangerousGetRowSpan(row) : []; } /// @@ -314,7 +247,7 @@ internal abstract partial class JpegColorConverterBase // In case of grayscale, Component1 and Component2 point to Component0 memory area this.Component1 = this.ComponentCount > 1 ? processors[1].GetColorBufferRowSpan(row) : this.Component0; this.Component2 = this.ComponentCount > 2 ? processors[2].GetColorBufferRowSpan(row) : this.Component0; - this.Component3 = this.ComponentCount > 3 ? processors[3].GetColorBufferRowSpan(row) : Span.Empty; + this.Component3 = this.ComponentCount > 3 ? processors[3].GetColorBufferRowSpan(row) : []; } /// @@ -333,7 +266,7 @@ internal abstract partial class JpegColorConverterBase // In case of grayscale, Component1 and Component2 point to Component0 memory area this.Component1 = this.ComponentCount > 1 ? processors[1].GetColorBufferRowSpan(row) : this.Component0; this.Component2 = this.ComponentCount > 2 ? processors[2].GetColorBufferRowSpan(row) : this.Component0; - this.Component3 = this.ComponentCount > 3 ? processors[3].GetColorBufferRowSpan(row) : Span.Empty; + this.Component3 = this.ComponentCount > 3 ? processors[3].GetColorBufferRowSpan(row) : []; } internal ComponentValues( @@ -353,9 +286,9 @@ internal abstract partial class JpegColorConverterBase public ComponentValues Slice(int start, int length) { Span c0 = this.Component0.Slice(start, length); - Span c1 = this.Component1.Length > 0 ? this.Component1.Slice(start, length) : Span.Empty; - Span c2 = this.Component2.Length > 0 ? this.Component2.Slice(start, length) : Span.Empty; - Span c3 = this.Component3.Length > 0 ? this.Component3.Slice(start, length) : Span.Empty; + Span c1 = this.Component1.Length > 0 ? this.Component1.Slice(start, length) : []; + Span c2 = this.Component2.Length > 0 ? this.Component2.Slice(start, length) : []; + Span c3 = this.Component3.Length > 0 ? this.Component3.Slice(start, length) : []; return new ComponentValues(this.ComponentCount, c0, c1, c2, c3); } diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterVector.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterVector.cs index 5f9688a79..1c37f5eef 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterVector.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterVector.cs @@ -36,7 +36,7 @@ internal abstract partial class JpegColorConverterBase public override int ElementsPerBatch => Vector.Count; /// - public sealed override void ConvertToRgbInplace(in ComponentValues values) + public sealed override void ConvertToRgbInPlace(in ComponentValues values) { DebugGuard.IsTrue(this.IsAvailable, $"{this.GetType().Name} converter is not supported on current hardware."); diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/SpectralConverter{TPixel}.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/SpectralConverter{TPixel}.cs index 7f89baba5..561d273e6 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/SpectralConverter{TPixel}.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/SpectralConverter{TPixel}.cs @@ -141,7 +141,7 @@ internal class SpectralConverter : SpectralConverter, IDisposable JpegColorConverterBase.ComponentValues values = new(this.componentProcessors, y); - this.colorConverter.ConvertToRgbInplace(values); + this.colorConverter.ConvertToRgbInPlace(values); values = values.Slice(0, width); // slice away Jpeg padding Span r = this.rgbBuffer.Slice(0, width); diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/CmykColorConversion.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/CmykColorConversion.cs index 9189bec37..e377a6f97 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/CmykColorConversion.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/CmykColorConversion.cs @@ -19,7 +19,7 @@ public class CmykColorConversion : ColorConversionBenchmark { var values = new JpegColorConverterBase.ComponentValues(this.Input, 0); - new JpegColorConverterBase.CmykScalar(8).ConvertToRgbInplace(values); + new JpegColorConverterBase.CmykScalar(8).ConvertToRgbInPlace(values); } [Benchmark] @@ -27,22 +27,6 @@ public class CmykColorConversion : ColorConversionBenchmark { var values = new JpegColorConverterBase.ComponentValues(this.Input, 0); - new JpegColorConverterBase.CmykVector(8).ConvertToRgbInplace(values); - } - - [Benchmark] - public void SimdVectorAvx() - { - var values = new JpegColorConverterBase.ComponentValues(this.Input, 0); - - new JpegColorConverterBase.CmykAvx(8).ConvertToRgbInplace(values); - } - - [Benchmark] - public void SimdVectorArm64() - { - var values = new JpegColorConverterBase.ComponentValues(this.Input, 0); - - new JpegColorConverterBase.CmykArm64(8).ConvertToRgbInplace(values); + new JpegColorConverterBase.CmykVector(8).ConvertToRgbInPlace(values); } } diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/GrayscaleColorConversion.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/GrayscaleColorConversion.cs index a1d85ef46..a63a97152 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/GrayscaleColorConversion.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/GrayscaleColorConversion.cs @@ -19,22 +19,14 @@ public class GrayscaleColorConversion : ColorConversionBenchmark { var values = new JpegColorConverterBase.ComponentValues(this.Input, 0); - new JpegColorConverterBase.GrayscaleScalar(8).ConvertToRgbInplace(values); + new JpegColorConverterBase.GrayscaleScalar(8).ConvertToRgbInPlace(values); } [Benchmark] - public void SimdVectorAvx() + public void SimdVector8() { var values = new JpegColorConverterBase.ComponentValues(this.Input, 0); - new JpegColorConverterBase.GrayscaleAvx(8).ConvertToRgbInplace(values); - } - - [Benchmark] - public void SimdVectorArm() - { - var values = new JpegColorConverterBase.ComponentValues(this.Input, 0); - - new JpegColorConverterBase.GrayscaleArm(8).ConvertToRgbInplace(values); + new JpegColorConverterBase.GrayScaleVector(8).ConvertToRgbInPlace(values); } } diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/RgbColorConversion.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/RgbColorConversion.cs index 5e2b6fe86..62bf75d42 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/RgbColorConversion.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/RgbColorConversion.cs @@ -19,7 +19,7 @@ public class RgbColorConversion : ColorConversionBenchmark { var values = new JpegColorConverterBase.ComponentValues(this.Input, 0); - new JpegColorConverterBase.RgbScalar(8).ConvertToRgbInplace(values); + new JpegColorConverterBase.RgbScalar(8).ConvertToRgbInPlace(values); } [Benchmark] @@ -27,22 +27,6 @@ public class RgbColorConversion : ColorConversionBenchmark { var values = new JpegColorConverterBase.ComponentValues(this.Input, 0); - new JpegColorConverterBase.RgbVector(8).ConvertToRgbInplace(values); - } - - [Benchmark] - public void SimdVectorAvx() - { - var values = new JpegColorConverterBase.ComponentValues(this.Input, 0); - - new JpegColorConverterBase.RgbAvx(8).ConvertToRgbInplace(values); - } - - [Benchmark] - public void SimdVectorArm() - { - var values = new JpegColorConverterBase.ComponentValues(this.Input, 0); - - new JpegColorConverterBase.RgbArm(8).ConvertToRgbInplace(values); + new JpegColorConverterBase.RgbVector(8).ConvertToRgbInPlace(values); } } diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YCbCrColorConversion.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YCbCrColorConversion.cs index f8621c250..eb9224fee 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YCbCrColorConversion.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YCbCrColorConversion.cs @@ -19,7 +19,7 @@ public class YCbCrColorConversion : ColorConversionBenchmark { var values = new JpegColorConverterBase.ComponentValues(this.Input, 0); - new JpegColorConverterBase.YCbCrScalar(8).ConvertToRgbInplace(values); + new JpegColorConverterBase.YCbCrScalar(8).ConvertToRgbInPlace(values); } [Benchmark] @@ -27,22 +27,6 @@ public class YCbCrColorConversion : ColorConversionBenchmark { var values = new JpegColorConverterBase.ComponentValues(this.Input, 0); - new JpegColorConverterBase.YCbCrVector(8).ConvertToRgbInplace(values); - } - - [Benchmark] - public void SimdVectorAvx() - { - var values = new JpegColorConverterBase.ComponentValues(this.Input, 0); - - new JpegColorConverterBase.YCbCrAvx(8).ConvertToRgbInplace(values); - } - - [Benchmark] - public void SimdVectorArm() - { - var values = new JpegColorConverterBase.ComponentValues(this.Input, 0); - - new JpegColorConverterBase.YCbCrArm(8).ConvertToRgbInplace(values); + new JpegColorConverterBase.YCbCrVector(8).ConvertToRgbInPlace(values); } } diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YccKColorConverter.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YccKColorConverter.cs index a414b6ed4..1a81c2190 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YccKColorConverter.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YccKColorConverter.cs @@ -19,7 +19,7 @@ public class YccKColorConverter : ColorConversionBenchmark { var values = new JpegColorConverterBase.ComponentValues(this.Input, 0); - new JpegColorConverterBase.YccKScalar(8).ConvertToRgbInplace(values); + new JpegColorConverterBase.YccKScalar(8).ConvertToRgbInPlace(values); } [Benchmark] @@ -27,22 +27,6 @@ public class YccKColorConverter : ColorConversionBenchmark { var values = new JpegColorConverterBase.ComponentValues(this.Input, 0); - new JpegColorConverterBase.YccKVector(8).ConvertToRgbInplace(values); - } - - [Benchmark] - public void SimdVectorAvx2() - { - var values = new JpegColorConverterBase.ComponentValues(this.Input, 0); - - new JpegColorConverterBase.YccKAvx(8).ConvertToRgbInplace(values); - } - - [Benchmark] - public void SimdVectorArm64() - { - var values = new JpegColorConverterBase.ComponentValues(this.Input, 0); - - new JpegColorConverterBase.YccKArm64(8).ConvertToRgbInplace(values); + new JpegColorConverterBase.YccKVector(8).ConvertToRgbInPlace(values); } } diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegColorConverterTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegColorConverterTests.cs index 7aabdaa58..02a5d8907 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegColorConverterTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegColorConverterTests.cs @@ -83,7 +83,7 @@ public class JpegColorConverterTests Type expectedType = typeof(JpegColorConverterBase.RgbScalar); if (Avx.IsSupported) { - expectedType = typeof(JpegColorConverterBase.RgbAvx); + expectedType = typeof(JpegColorConverterBase.RgbVector); } else if (Sse2.IsSupported) { @@ -91,7 +91,7 @@ public class JpegColorConverterTests } else if (AdvSimd.IsSupported) { - expectedType = typeof(JpegColorConverterBase.RgbArm); + expectedType = typeof(JpegColorConverterBase.RgbVector); } // act @@ -116,7 +116,7 @@ public class JpegColorConverterTests Type expectedType = typeof(JpegColorConverterBase.GrayscaleScalar); if (Avx.IsSupported) { - expectedType = typeof(JpegColorConverterBase.GrayscaleAvx); + expectedType = typeof(JpegColorConverterBase.GrayScaleVector); } else if (Sse2.IsSupported) { @@ -124,7 +124,7 @@ public class JpegColorConverterTests } else if (AdvSimd.IsSupported) { - expectedType = typeof(JpegColorConverterBase.GrayscaleArm); + expectedType = typeof(JpegColorConverterBase.GrayScaleVector); } // act @@ -149,7 +149,7 @@ public class JpegColorConverterTests Type expectedType = typeof(JpegColorConverterBase.CmykScalar); if (Avx.IsSupported) { - expectedType = typeof(JpegColorConverterBase.CmykAvx); + expectedType = typeof(JpegColorConverterBase.CmykVector); } else if (Sse2.IsSupported) { @@ -157,7 +157,7 @@ public class JpegColorConverterTests } else if (AdvSimd.Arm64.IsSupported) { - expectedType = typeof(JpegColorConverterBase.CmykArm64); + expectedType = typeof(JpegColorConverterBase.CmykVector); } // act @@ -182,7 +182,7 @@ public class JpegColorConverterTests Type expectedType = typeof(JpegColorConverterBase.YCbCrScalar); if (Avx.IsSupported) { - expectedType = typeof(JpegColorConverterBase.YCbCrAvx); + expectedType = typeof(JpegColorConverterBase.YCbCrVector); } else if (Sse2.IsSupported) { @@ -190,7 +190,7 @@ public class JpegColorConverterTests } else if (AdvSimd.IsSupported) { - expectedType = typeof(JpegColorConverterBase.YCbCrArm); + expectedType = typeof(JpegColorConverterBase.YCbCrVector); } // act @@ -215,7 +215,7 @@ public class JpegColorConverterTests Type expectedType = typeof(JpegColorConverterBase.YccKScalar); if (Avx.IsSupported) { - expectedType = typeof(JpegColorConverterBase.YccKAvx); + expectedType = typeof(JpegColorConverterBase.YccKVector); } else if (Sse2.IsSupported) { @@ -223,7 +223,7 @@ public class JpegColorConverterTests } else if (AdvSimd.Arm64.IsSupported) { - expectedType = typeof(JpegColorConverterBase.YccKArm64); + expectedType = typeof(JpegColorConverterBase.YccKVector); } // act @@ -405,176 +405,6 @@ public class JpegColorConverterTests new JpegColorConverterBase.YccKScalar(8)); } - [Theory] - [MemberData(nameof(Seeds))] - public void FromYCbCrAvx2(int seed) => - this.TestConversionToRgb( - new JpegColorConverterBase.YCbCrAvx(8), - 3, - seed, - new JpegColorConverterBase.YCbCrScalar(8)); - - [Theory] - [MemberData(nameof(Seeds))] - public void FromRgbToYCbCrAvx2(int seed) => - this.TestConversionFromRgb( - new JpegColorConverterBase.YCbCrAvx(8), - 3, - seed, - new JpegColorConverterBase.YCbCrScalar(8), - precísion: 2); - - [Theory] - [MemberData(nameof(Seeds))] - public void FromYCbCrArm(int seed) => - this.TestConversionToRgb( - new JpegColorConverterBase.YCbCrArm(8), - 3, - seed, - new JpegColorConverterBase.YCbCrScalar(8)); - - [Theory] - [MemberData(nameof(Seeds))] - public void FromRgbToYCbCrArm(int seed) => - this.TestConversionFromRgb( - new JpegColorConverterBase.YCbCrArm(8), - 3, - seed, - new JpegColorConverterBase.YCbCrScalar(8), - precísion: 2); - - [Theory] - [MemberData(nameof(Seeds))] - public void FromCmykAvx2(int seed) => - this.TestConversionToRgb( - new JpegColorConverterBase.CmykAvx(8), - 4, - seed, - new JpegColorConverterBase.CmykScalar(8)); - - [Theory] - [MemberData(nameof(Seeds))] - public void FromRgbToCmykAvx2(int seed) => - this.TestConversionFromRgb( - new JpegColorConverterBase.CmykAvx(8), - 4, - seed, - new JpegColorConverterBase.CmykScalar(8), - precísion: 4); - - [Theory] - [MemberData(nameof(Seeds))] - public void FromCmykArm(int seed) => - this.TestConversionToRgb( - new JpegColorConverterBase.CmykArm64(8), - 4, - seed, - new JpegColorConverterBase.CmykScalar(8)); - - [Theory] - [MemberData(nameof(Seeds))] - public void FromRgbToCmykArm(int seed) => - this.TestConversionFromRgb( - new JpegColorConverterBase.CmykArm64(8), - 4, - seed, - new JpegColorConverterBase.CmykScalar(8), - precísion: 4); - - [Theory] - [MemberData(nameof(Seeds))] - public void FromGrayscaleAvx2(int seed) => - this.TestConversionToRgb( - new JpegColorConverterBase.GrayscaleAvx(8), - 1, - seed, - new JpegColorConverterBase.GrayscaleScalar(8)); - - [Theory] - [MemberData(nameof(Seeds))] - public void FromRgbToGrayscaleAvx2(int seed) => - this.TestConversionFromRgb( - new JpegColorConverterBase.GrayscaleAvx(8), - 1, - seed, - new JpegColorConverterBase.GrayscaleScalar(8), - precísion: 3); - - [Theory] - [MemberData(nameof(Seeds))] - public void FromGrayscaleArm(int seed) => - this.TestConversionToRgb( - new JpegColorConverterBase.GrayscaleArm(8), - 1, - seed, - new JpegColorConverterBase.GrayscaleScalar(8)); - - [Theory] - [MemberData(nameof(Seeds))] - public void FromRgbToGrayscaleArm(int seed) => - this.TestConversionFromRgb( - new JpegColorConverterBase.GrayscaleArm(8), - 1, - seed, - new JpegColorConverterBase.GrayscaleScalar(8), - precísion: 3); - - [Theory] - [MemberData(nameof(Seeds))] - public void FromRgbAvx2(int seed) => - this.TestConversionToRgb( - new JpegColorConverterBase.RgbAvx(8), - 3, - seed, - new JpegColorConverterBase.RgbScalar(8)); - - [Theory] - [MemberData(nameof(Seeds))] - public void FromRgbArm(int seed) => - this.TestConversionToRgb( - new JpegColorConverterBase.RgbArm(8), - 3, - seed, - new JpegColorConverterBase.RgbScalar(8)); - - [Theory] - [MemberData(nameof(Seeds))] - public void FromYccKAvx2(int seed) => - this.TestConversionToRgb( - new JpegColorConverterBase.YccKAvx(8), - 4, - seed, - new JpegColorConverterBase.YccKScalar(8)); - - [Theory] - [MemberData(nameof(Seeds))] - public void FromRgbToYccKAvx2(int seed) => - this.TestConversionFromRgb( - new JpegColorConverterBase.YccKAvx(8), - 4, - seed, - new JpegColorConverterBase.YccKScalar(8), - precísion: 4); - - [Theory] - [MemberData(nameof(Seeds))] - public void FromYccKArm64(int seed) => - this.TestConversionToRgb( - new JpegColorConverterBase.YccKArm64(8), - 4, - seed, - new JpegColorConverterBase.YccKScalar(8)); - - [Theory] - [MemberData(nameof(Seeds))] - public void FromRgbToYccKArm64(int seed) => - this.TestConversionFromRgb( - new JpegColorConverterBase.YccKArm64(8), - 4, - seed, - new JpegColorConverterBase.YccKScalar(8), - precísion: 4); - private void TestConversionToRgb( JpegColorConverterBase converter, int componentCount, @@ -595,28 +425,6 @@ public class JpegColorConverterTests baseLineConverter); } - private void TestConversionFromRgb( - JpegColorConverterBase converter, - int componentCount, - int seed, - JpegColorConverterBase baseLineConverter, - int precísion) - { - if (!converter.IsAvailable) - { - this.Output.WriteLine( - $"Skipping test - {converter.GetType().Name} is not supported on current hardware."); - return; - } - - ValidateConversionFromRgb( - converter, - componentCount, - seed, - baseLineConverter, - precísion); - } - private static JpegColorConverterBase.ComponentValues CreateRandomValues( int length, int componentCount, @@ -669,7 +477,7 @@ public class JpegColorConverterTests original.Component2.ToArray(), original.Component3.ToArray()); - converter.ConvertToRgbInplace(actual); + converter.ConvertToRgbInPlace(actual); for (int i = 0; i < TestBufferLength; i++) { @@ -685,7 +493,7 @@ public class JpegColorConverterTests original.Component1.ToArray(), original.Component2.ToArray(), original.Component3.ToArray()); - baseLineConverter.ConvertToRgbInplace(expected); + baseLineConverter.ConvertToRgbInPlace(expected); if (componentCount == 1) { Assert.True(expected.Component0.SequenceEqual(actual.Component0)); @@ -781,7 +589,7 @@ public class JpegColorConverterTests ValidateYCbCr(original, result, i); break; default: - Assert.True(false, $"Invalid Colorspace enum value: {colorSpace}."); + Assert.Fail($"Invalid Colorspace enum value: {colorSpace}."); break; } }