diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs b/src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs
index 00c0d89f0..caeb694a9 100644
--- a/src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs
+++ b/src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs
@@ -577,6 +577,24 @@ namespace SixLabors.ImageSharp
}
}
+ ///
+ /// Scales 8x8 matrix to 4x2 using 2x2 average
+ ///
+ /// Input matrix consisting of 4 256bit vectors, first row: (v[0], v[2]), second row: (v[1], v[3])
+ /// 256bit vector containing upper and lower scaled parts of the input matrix
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static Vector256 Scale16x2_8x1(ReadOnlySpan> v)
+ {
+ DebugGuard.IsTrue(v.Length == 4, "Input span must consist of 4 elements");
+
+ var f025 = Vector256.Create(0.25f);
+
+ Vector256 left = Avx.Add(v[0], v[2]);
+ Vector256 right = Avx.Add(v[1], v[3]);
+ Vector256 avg2x2 = Avx.Multiply(Avx.HorizontalAdd(left, right), f025);
+
+ return Avx2.Permute4x64(avg2x2.AsDouble(), 0b11_01_10_00).AsSingle();
+ }
///
/// as many elements as possible, slicing them down (keeping the remainder).
diff --git a/src/ImageSharp/Formats/Jpeg/Components/Encoder/RgbToYCbCrConverterVectorized.cs b/src/ImageSharp/Formats/Jpeg/Components/Encoder/RgbToYCbCrConverterVectorized.cs
index 49b974404..56da8acc7 100644
--- a/src/ImageSharp/Formats/Jpeg/Components/Encoder/RgbToYCbCrConverterVectorized.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Encoder/RgbToYCbCrConverterVectorized.cs
@@ -221,9 +221,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder
bDataLanes[j] = b;
}
- r = Scale_8x4_4x2(rDataLanes);
- g = Scale_8x4_4x2(gDataLanes);
- b = Scale_8x4_4x2(bDataLanes);
+ r = SimdUtils.HwIntrinsics.Scale16x2_8x1(rDataLanes);
+ g = SimdUtils.HwIntrinsics.Scale16x2_8x1(gDataLanes);
+ b = SimdUtils.HwIntrinsics.Scale16x2_8x1(bDataLanes);
// 128F + ((-0.168736F * r) - (0.331264F * g) + (0.5F * b))
Unsafe.Add(ref destCbRef, i) = Avx.Add(f128, SimdUtils.HwIntrinsics.MultiplyAdd(SimdUtils.HwIntrinsics.MultiplyAdd(Avx.Multiply(f05, b), fn0331264, g), fn0168736, r));
@@ -233,27 +233,5 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder
}
#endif
}
-
-#if SUPPORTS_RUNTIME_INTRINSICS
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector256 Scale_8x4_4x2(Span> v)
- {
- Vector256 switchInnerDoubleWords = Unsafe.As>(ref MemoryMarshal.GetReference(SimdUtils.HwIntrinsics.PermuteMaskSwitchInnerDWords8x32));
- var f025 = Vector256.Create(0.25f);
-
- Vector256 topPairSum = SumHorizontalPairs(v[0], v[2]);
- Vector256 botPairSum = SumHorizontalPairs(v[1], v[3]);
-
- return Avx2.PermuteVar8x32(Avx.Multiply(SumVerticalPairs(topPairSum, botPairSum), f025), switchInnerDoubleWords);
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector256 SumHorizontalPairs(Vector256 v0, Vector256 v1)
- => Avx.Add(Avx.Shuffle(v0, v1, 0b10_00_10_00), Avx.Shuffle(v0, v1, 0b11_01_11_01));
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Vector256 SumVerticalPairs(Vector256 v0, Vector256 v1)
- => Avx.Add(Avx.Shuffle(v0, v1, 0b01_00_01_00), Avx.Shuffle(v0, v1, 0b11_10_11_10));
-#endif
}
}