Skip to content

Commit aebe375

Browse files
Reduce JPEG color conversion to two pipelines
1 parent 22a06d6 commit aebe375

29 files changed

+99
-1467
lines changed

src/ImageSharp/Common/Helpers/SimdUtils.cs

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
// Copyright (c) Six Labors.
1+
// Copyright (c) Six Labors.
22
// Licensed under the Six Labors Split License.
33

44
using System.Diagnostics;
55
using System.Numerics;
66
using System.Runtime.CompilerServices;
7-
using System.Runtime.InteropServices;
87
using System.Runtime.Intrinsics;
98
using System.Runtime.Intrinsics.X86;
109

@@ -36,30 +35,37 @@ internal static Vector4 PseudoRound(this Vector4 v)
3635

3736
/// <summary>
3837
/// Rounds all values in 'v' to the nearest integer following <see cref="MidpointRounding.ToEven"/> semantics.
39-
/// Source:
40-
/// <see>
41-
/// <cref>https://github.com/g-truc/glm/blob/master/glm/simd/common.h#L110</cref>
42-
/// </see>
4338
/// </summary>
4439
/// <param name="v">The vector</param>
4540
[MethodImpl(MethodImplOptions.AggressiveInlining)]
4641
internal static Vector<float> FastRound(this Vector<float> v)
4742
{
48-
if (Avx2.IsSupported)
43+
if (Avx512F.IsSupported && Vector<float>.Count == Vector512<float>.Count)
44+
{
45+
ref Vector512<float> v512 = ref Unsafe.As<Vector<float>, Vector512<float>>(ref v);
46+
47+
// imm8 = 0b1000:
48+
// imm8[7:4] = 0b0000 -> preserve 0 fractional bits (round to whole numbers)
49+
// imm8[3:0] = 0b1000 -> _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC (round to nearest even, suppress exceptions)
50+
Vector512<float> vRound = Avx512F.RoundScale(v512, 0b0000_1000);
51+
return Unsafe.As<Vector512<float>, Vector<float>>(ref vRound);
52+
}
53+
54+
if (Avx2.IsSupported && Vector<float>.Count == Vector256<float>.Count)
4955
{
5056
ref Vector256<float> v256 = ref Unsafe.As<Vector<float>, Vector256<float>>(ref v);
5157
Vector256<float> vRound = Avx.RoundToNearestInteger(v256);
5258
return Unsafe.As<Vector256<float>, Vector<float>>(ref vRound);
5359
}
54-
else
55-
{
56-
var magic0 = new Vector<int>(int.MinValue); // 0x80000000
57-
var sgn0 = Vector.AsVectorSingle(magic0);
58-
var and0 = Vector.BitwiseAnd(sgn0, v);
59-
var or0 = Vector.BitwiseOr(and0, new Vector<float>(8388608.0f));
60-
var add0 = Vector.Add(v, or0);
61-
return Vector.Subtract(add0, or0);
62-
}
60+
61+
// https://github.com/g-truc/glm/blob/master/glm/simd/common.h#L11
62+
Vector<int> magic0 = new(int.MinValue); // 0x80000000
63+
Vector<float> sgn0 = Vector.AsVectorSingle(magic0);
64+
Vector<float> and0 = Vector.BitwiseAnd(sgn0, v);
65+
Vector<float> or0 = Vector.BitwiseOr(and0, new Vector<float>(8388608.0f));
66+
Vector<float> add0 = Vector.Add(v, or0);
67+
68+
return Vector.Subtract(add0, or0);
6369
}
6470

6571
[Conditional("DEBUG")]

src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.CmykArm64.cs

Lines changed: 0 additions & 95 deletions
This file was deleted.

src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.CmykAvx.cs

Lines changed: 0 additions & 95 deletions
This file was deleted.

src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.CmykScalar.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public CmykScalar(int precision)
1313
}
1414

1515
/// <inheritdoc/>
16-
public override void ConvertToRgbInplace(in ComponentValues values) =>
16+
public override void ConvertToRgbInPlace(in ComponentValues values) =>
1717
ConvertToRgbInplace(values, this.MaximumValue);
1818

1919
/// <inheritdoc/>

src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.GrayScaleArm.cs

Lines changed: 0 additions & 68 deletions
This file was deleted.

0 commit comments

Comments
 (0)