Skip to content

Commit ae7b995

Browse files
Merge pull request #1864 from br3aker/dp/jpeg-decoder-color-converters
Automatic SSE color converters based on Vector API
2 parents bf7362c + 67c43c9 commit ae7b995

File tree

42 files changed

+822
-1074
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+822
-1074
lines changed

src/ImageSharp/Common/Helpers/SimdUtils.cs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,6 @@ internal static partial class SimdUtils
3333
public static bool HasVector4 { get; } =
3434
Vector.IsHardwareAccelerated && Vector<float>.Count == 4;
3535

36-
public static bool HasAvx2
37-
{
38-
get
39-
{
40-
#if SUPPORTS_RUNTIME_INTRINSICS
41-
return Avx2.IsSupported;
42-
#else
43-
return false;
44-
#endif
45-
}
46-
}
47-
4836
/// <summary>
4937
/// Transform all scalars in 'v' in a way that converting them to <see cref="int"/> would have rounding semantics.
5038
/// </summary>

src/ImageSharp/Common/Tuples/Vector4Pair.cs

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

src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.Avx2JpegColorConverter.cs

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

src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.BasicJpegColorConverter.cs

Lines changed: 0 additions & 18 deletions
This file was deleted.
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright (c) Six Labors.
2+
// Licensed under the Apache License, Version 2.0.
3+
4+
#if SUPPORTS_RUNTIME_INTRINSICS
5+
using System.Runtime.CompilerServices;
6+
using System.Runtime.InteropServices;
7+
using System.Runtime.Intrinsics;
8+
using System.Runtime.Intrinsics.X86;
9+
10+
namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
11+
{
12+
internal abstract partial class JpegColorConverterBase
13+
{
14+
internal sealed class FromCmykAvx : JpegColorConverterAvx
15+
{
16+
public FromCmykAvx(int precision)
17+
: base(JpegColorSpace.Cmyk, precision)
18+
{
19+
}
20+
21+
public override void ConvertToRgbInplace(in ComponentValues values)
22+
{
23+
ref Vector256<float> c0Base =
24+
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(values.Component0));
25+
ref Vector256<float> c1Base =
26+
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(values.Component1));
27+
ref Vector256<float> c2Base =
28+
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(values.Component2));
29+
ref Vector256<float> c3Base =
30+
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(values.Component3));
31+
32+
// Used for the color conversion
33+
var scale = Vector256.Create(1 / (this.MaximumValue * this.MaximumValue));
34+
35+
nint n = values.Component0.Length / Vector256<float>.Count;
36+
for (nint i = 0; i < n; i++)
37+
{
38+
ref Vector256<float> c = ref Unsafe.Add(ref c0Base, i);
39+
ref Vector256<float> m = ref Unsafe.Add(ref c1Base, i);
40+
ref Vector256<float> y = ref Unsafe.Add(ref c2Base, i);
41+
Vector256<float> k = Unsafe.Add(ref c3Base, i);
42+
43+
k = Avx.Multiply(k, scale);
44+
c = Avx.Multiply(c, k);
45+
m = Avx.Multiply(m, k);
46+
y = Avx.Multiply(y, k);
47+
}
48+
}
49+
}
50+
}
51+
}
52+
#endif

src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromCmykAvx2.cs

Lines changed: 0 additions & 60 deletions
This file was deleted.
Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
1-
// Copyright (c) Six Labors.
1+
// Copyright (c) Six Labors.
22
// Licensed under the Apache License, Version 2.0.
33

44
using System;
5-
using System.Numerics;
65

76
namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
87
{
9-
internal abstract partial class JpegColorConverter
8+
internal abstract partial class JpegColorConverterBase
109
{
11-
internal sealed class FromCmykBasic : BasicJpegColorConverter
10+
internal sealed class FromCmykScalar : JpegColorConverterScalar
1211
{
13-
public FromCmykBasic(int precision)
12+
public FromCmykScalar(int precision)
1413
: base(JpegColorSpace.Cmyk, precision)
1514
{
1615
}
@@ -25,17 +24,18 @@ internal static void ConvertCoreInplace(in ComponentValues values, float maxValu
2524
Span<float> c2 = values.Component2;
2625
Span<float> c3 = values.Component3;
2726

28-
float scale = 1 / maxValue;
27+
float scale = 1 / (maxValue * maxValue);
2928
for (int i = 0; i < c0.Length; i++)
3029
{
3130
float c = c0[i];
3231
float m = c1[i];
3332
float y = c2[i];
34-
float k = c3[i] / maxValue;
33+
float k = c3[i];
3534

36-
c0[i] = c * k * scale;
37-
c1[i] = m * k * scale;
38-
c2[i] = y * k * scale;
35+
k *= scale;
36+
c0[i] = c * k;
37+
c1[i] = m * k;
38+
c2[i] = y * k;
3939
}
4040
}
4141
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Copyright (c) Six Labors.
2+
// Licensed under the Apache License, Version 2.0.
3+
4+
using System.Numerics;
5+
using System.Runtime.CompilerServices;
6+
using System.Runtime.InteropServices;
7+
8+
namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
9+
{
10+
internal abstract partial class JpegColorConverterBase
11+
{
12+
internal sealed class FromCmykVector : JpegColorConverterVector
13+
{
14+
public FromCmykVector(int precision)
15+
: base(JpegColorSpace.Cmyk, precision)
16+
{
17+
}
18+
19+
protected override void ConvertCoreVectorizedInplace(in ComponentValues values)
20+
{
21+
ref Vector<float> cBase =
22+
ref Unsafe.As<float, Vector<float>>(ref MemoryMarshal.GetReference(values.Component0));
23+
ref Vector<float> mBase =
24+
ref Unsafe.As<float, Vector<float>>(ref MemoryMarshal.GetReference(values.Component1));
25+
ref Vector<float> yBase =
26+
ref Unsafe.As<float, Vector<float>>(ref MemoryMarshal.GetReference(values.Component2));
27+
ref Vector<float> kBase =
28+
ref Unsafe.As<float, Vector<float>>(ref MemoryMarshal.GetReference(values.Component3));
29+
30+
var scale = new Vector<float>(1 / (this.MaximumValue * this.MaximumValue));
31+
32+
nint n = values.Component0.Length / Vector<float>.Count;
33+
for (nint i = 0; i < n; i++)
34+
{
35+
ref Vector<float> c = ref Unsafe.Add(ref cBase, i);
36+
ref Vector<float> m = ref Unsafe.Add(ref mBase, i);
37+
ref Vector<float> y = ref Unsafe.Add(ref yBase, i);
38+
Vector<float> k = Unsafe.Add(ref kBase, i);
39+
40+
k *= scale;
41+
c *= k;
42+
m *= k;
43+
y *= k;
44+
}
45+
}
46+
47+
protected override void ConvertCoreInplace(in ComponentValues values) =>
48+
FromCmykScalar.ConvertCoreInplace(values, this.MaximumValue);
49+
}
50+
}
51+
}

0 commit comments

Comments
 (0)