Skip to content

Commit 87438a3

Browse files
Port Grayscale converter
1 parent 3b430e1 commit 87438a3

13 files changed

+339
-74
lines changed

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ public override void ConvertToRgbInPlace(in ComponentValues values) =>
1717
ConvertToRgbInplace(values, this.MaximumValue);
1818

1919
/// <inheritdoc/>
20-
public override void ConvertFromRgb(in ComponentValues values, Span<float> r, Span<float> g, Span<float> b)
21-
=> ConvertFromRgb(values, this.MaximumValue, r, g, b);
20+
public override void ConvertFromRgb(in ComponentValues values, Span<float> rLane, Span<float> gLane, Span<float> bLane)
21+
=> ConvertFromRgb(values, this.MaximumValue, rLane, gLane, bLane);
2222

2323
public static void ConvertToRgbInplace(in ComponentValues values, float maxValue)
2424
{
@@ -42,7 +42,7 @@ public static void ConvertToRgbInplace(in ComponentValues values, float maxValue
4242
}
4343
}
4444

45-
public static void ConvertFromRgb(in ComponentValues values, float maxValue, Span<float> r, Span<float> g, Span<float> b)
45+
public static void ConvertFromRgb(in ComponentValues values, float maxValue, Span<float> rLane, Span<float> gLane, Span<float> bLane)
4646
{
4747
Span<float> c = values.Component0;
4848
Span<float> m = values.Component1;
@@ -51,9 +51,9 @@ public static void ConvertFromRgb(in ComponentValues values, float maxValue, Spa
5151

5252
for (int i = 0; i < c.Length; i++)
5353
{
54-
float ctmp = 255f - r[i];
55-
float mtmp = 255f - g[i];
56-
float ytmp = 255f - b[i];
54+
float ctmp = 255f - rLane[i];
55+
float mtmp = 255f - gLane[i];
56+
float ytmp = 255f - bLane[i];
5757
float ktmp = MathF.Min(MathF.Min(ctmp, mtmp), ytmp);
5858

5959
if (ktmp >= 255f)

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

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,22 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components;
88

99
internal abstract partial class JpegColorConverterBase
1010
{
11-
internal sealed class GrayscaleScalar : JpegColorConverterScalar
11+
internal sealed class GrayScaleScalar : JpegColorConverterScalar
1212
{
13-
public GrayscaleScalar(int precision)
13+
public GrayScaleScalar(int precision)
1414
: base(JpegColorSpace.Grayscale, precision)
1515
{
1616
}
1717

1818
/// <inheritdoc/>
1919
public override void ConvertToRgbInPlace(in ComponentValues values)
20-
=> ConvertToRgbInplace(values.Component0, this.MaximumValue);
20+
=> ConvertToRgbInPlace(values.Component0, this.MaximumValue);
2121

2222
/// <inheritdoc/>
23-
public override void ConvertFromRgb(in ComponentValues values, Span<float> r, Span<float> g, Span<float> b)
24-
=> ConvertCoreInplaceFromRgb(values, r, g, b);
23+
public override void ConvertFromRgb(in ComponentValues values, Span<float> rLane, Span<float> gLane, Span<float> bLane)
24+
=> ConvertFromRgbScalar(values, rLane, gLane, bLane);
2525

26-
internal static void ConvertToRgbInplace(Span<float> values, float maxValue)
26+
internal static void ConvertToRgbInPlace(Span<float> values, float maxValue)
2727
{
2828
ref float valuesRef = ref MemoryMarshal.GetReference(values);
2929
float scale = 1 / maxValue;
@@ -34,15 +34,14 @@ internal static void ConvertToRgbInplace(Span<float> values, float maxValue)
3434
}
3535
}
3636

37-
internal static void ConvertCoreInplaceFromRgb(in ComponentValues values, Span<float> rLane, Span<float> gLane, Span<float> bLane)
37+
internal static void ConvertFromRgbScalar(in ComponentValues values, Span<float> rLane, Span<float> gLane, Span<float> bLane)
3838
{
3939
Span<float> c0 = values.Component0;
4040

4141
for (int i = 0; i < c0.Length; i++)
4242
{
43-
// luminocity = (0.299 * r) + (0.587 * g) + (0.114 * b)
44-
float luma = (0.299f * rLane[i]) + (0.587f * gLane[i]) + (0.114f * bLane[i]);
45-
c0[i] = luma;
43+
// luminosity = (0.299 * r) + (0.587 * g) + (0.114 * b)
44+
c0[i] = (float)((0.299f * rLane[i]) + (0.587f * gLane[i]) + (0.114f * bLane[i]));
4645
}
4746
}
4847
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ protected override void ConvertToRgbInPlaceVectorized(in ComponentValues values)
3434

3535
/// <inheritdoc/>
3636
protected override void ConvertToRgbInPlaceScalarRemainder(in ComponentValues values)
37-
=> GrayscaleScalar.ConvertToRgbInplace(values.Component0, this.MaximumValue);
37+
=> GrayScaleScalar.ConvertToRgbInPlace(values.Component0, this.MaximumValue);
3838

3939
/// <inheritdoc/>
4040
protected override void ConvertFromRgbVectorized(in ComponentValues values, Span<float> rLane, Span<float> gLane, Span<float> bLane)
@@ -67,6 +67,6 @@ protected override void ConvertFromRgbVectorized(in ComponentValues values, Span
6767

6868
/// <inheritdoc/>
6969
protected override void ConvertFromRgbScalarRemainder(in ComponentValues values, Span<float> r, Span<float> g, Span<float> b)
70-
=> GrayscaleScalar.ConvertCoreInplaceFromRgb(values, r, g, b);
70+
=> GrayScaleScalar.ConvertFromRgbScalar(values, r, g, b);
7171
}
7272
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Copyright (c) Six Labors.
2+
// Licensed under the Six Labors Split License.
3+
4+
using System.Runtime.CompilerServices;
5+
using System.Runtime.InteropServices;
6+
using System.Runtime.Intrinsics;
7+
using SixLabors.ImageSharp.Common.Helpers;
8+
9+
namespace SixLabors.ImageSharp.Formats.Jpeg.Components;
10+
11+
internal abstract partial class JpegColorConverterBase
12+
{
13+
internal sealed class GrayScaleVector128 : JpegColorConverterVector128
14+
{
15+
public GrayScaleVector128(int precision)
16+
: base(JpegColorSpace.Grayscale, precision)
17+
{
18+
}
19+
20+
/// <inheritdoc/>
21+
public override void ConvertToRgbInPlace(in ComponentValues values)
22+
{
23+
ref Vector128<float> c0Base =
24+
ref Unsafe.As<float, Vector128<float>>(ref MemoryMarshal.GetReference(values.Component0));
25+
26+
// Used for the color conversion
27+
Vector128<float> scale = Vector128.Create(1 / this.MaximumValue);
28+
29+
nuint n = values.Component0.Vector128Count<float>();
30+
for (nuint i = 0; i < n; i++)
31+
{
32+
ref Vector128<float> c0 = ref Unsafe.Add(ref c0Base, i);
33+
c0 *= scale;
34+
}
35+
}
36+
37+
/// <inheritdoc/>
38+
public override void ConvertFromRgb(in ComponentValues values, Span<float> rLane, Span<float> gLane, Span<float> bLane)
39+
{
40+
ref Vector128<float> destLuminance =
41+
ref Unsafe.As<float, Vector128<float>>(ref MemoryMarshal.GetReference(values.Component0));
42+
43+
ref Vector128<float> srcRed =
44+
ref Unsafe.As<float, Vector128<float>>(ref MemoryMarshal.GetReference(rLane));
45+
ref Vector128<float> srcGreen =
46+
ref Unsafe.As<float, Vector128<float>>(ref MemoryMarshal.GetReference(gLane));
47+
ref Vector128<float> srcBlue =
48+
ref Unsafe.As<float, Vector128<float>>(ref MemoryMarshal.GetReference(bLane));
49+
50+
// Used for the color conversion
51+
Vector128<float> f0299 = Vector128.Create(0.299f);
52+
Vector128<float> f0587 = Vector128.Create(0.587f);
53+
Vector128<float> f0114 = Vector128.Create(0.114f);
54+
55+
nuint n = values.Component0.Vector128Count<float>();
56+
for (nuint i = 0; i < n; i++)
57+
{
58+
ref Vector128<float> r = ref Unsafe.Add(ref srcRed, i);
59+
ref Vector128<float> g = ref Unsafe.Add(ref srcGreen, i);
60+
ref Vector128<float> b = ref Unsafe.Add(ref srcBlue, i);
61+
62+
// luminosity = (0.299 * r) + (0.587 * g) + (0.114 * b)
63+
Unsafe.Add(ref destLuminance, i) = Vector128Utilities.MultiplyAdd(Vector128Utilities.MultiplyAdd(f0114 * b, f0587, g), f0299, r);
64+
}
65+
}
66+
}
67+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Copyright (c) Six Labors.
2+
// Licensed under the Six Labors Split License.
3+
4+
using System.Runtime.CompilerServices;
5+
using System.Runtime.InteropServices;
6+
using System.Runtime.Intrinsics;
7+
using SixLabors.ImageSharp.Common.Helpers;
8+
9+
namespace SixLabors.ImageSharp.Formats.Jpeg.Components;
10+
11+
internal abstract partial class JpegColorConverterBase
12+
{
13+
internal sealed class GrayScaleVector256 : JpegColorConverterVector256
14+
{
15+
public GrayScaleVector256(int precision)
16+
: base(JpegColorSpace.Grayscale, precision)
17+
{
18+
}
19+
20+
/// <inheritdoc/>
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+
26+
// Used for the color conversion
27+
Vector256<float> scale = Vector256.Create(1 / this.MaximumValue);
28+
29+
nuint n = values.Component0.Vector256Count<float>();
30+
for (nuint i = 0; i < n; i++)
31+
{
32+
ref Vector256<float> c0 = ref Unsafe.Add(ref c0Base, i);
33+
c0 *= scale;
34+
}
35+
}
36+
37+
/// <inheritdoc/>
38+
public override void ConvertFromRgb(in ComponentValues values, Span<float> rLane, Span<float> gLane, Span<float> bLane)
39+
{
40+
ref Vector256<float> destLuminance =
41+
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(values.Component0));
42+
43+
ref Vector256<float> srcRed =
44+
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(rLane));
45+
ref Vector256<float> srcGreen =
46+
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(gLane));
47+
ref Vector256<float> srcBlue =
48+
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(bLane));
49+
50+
// Used for the color conversion
51+
Vector256<float> f0299 = Vector256.Create(0.299f);
52+
Vector256<float> f0587 = Vector256.Create(0.587f);
53+
Vector256<float> f0114 = Vector256.Create(0.114f);
54+
55+
nuint n = values.Component0.Vector256Count<float>();
56+
for (nuint i = 0; i < n; i++)
57+
{
58+
ref Vector256<float> r = ref Unsafe.Add(ref srcRed, i);
59+
ref Vector256<float> g = ref Unsafe.Add(ref srcGreen, i);
60+
ref Vector256<float> b = ref Unsafe.Add(ref srcBlue, i);
61+
62+
// luminosity = (0.299 * r) + (0.587 * g) + (0.114 * b)
63+
Unsafe.Add(ref destLuminance, i) = Vector256Utilities.MultiplyAdd(Vector256Utilities.MultiplyAdd(f0114 * b, f0587, g), f0299, r);
64+
}
65+
}
66+
}
67+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Copyright (c) Six Labors.
2+
// Licensed under the Six Labors Split License.
3+
4+
using System.Runtime.CompilerServices;
5+
using System.Runtime.InteropServices;
6+
using System.Runtime.Intrinsics;
7+
using SixLabors.ImageSharp.Common.Helpers;
8+
9+
namespace SixLabors.ImageSharp.Formats.Jpeg.Components;
10+
11+
internal abstract partial class JpegColorConverterBase
12+
{
13+
internal sealed class GrayScaleVector512 : JpegColorConverterVector512
14+
{
15+
public GrayScaleVector512(int precision)
16+
: base(JpegColorSpace.Grayscale, precision)
17+
{
18+
}
19+
20+
/// <inheritdoc/>
21+
protected override void ConvertToRgbInPlaceVectorized(in ComponentValues values)
22+
{
23+
ref Vector512<float> c0Base =
24+
ref Unsafe.As<float, Vector512<float>>(ref MemoryMarshal.GetReference(values.Component0));
25+
26+
// Used for the color conversion
27+
Vector512<float> scale = Vector512.Create(1 / this.MaximumValue);
28+
29+
nuint n = values.Component0.Vector512Count<float>();
30+
for (nuint i = 0; i < n; i++)
31+
{
32+
ref Vector512<float> c0 = ref Unsafe.Add(ref c0Base, i);
33+
c0 *= scale;
34+
}
35+
}
36+
37+
/// <inheritdoc/>
38+
protected override void ConvertFromRgbVectorized(in ComponentValues values, Span<float> rLane, Span<float> gLane, Span<float> bLane)
39+
{
40+
ref Vector512<float> destLuminance =
41+
ref Unsafe.As<float, Vector512<float>>(ref MemoryMarshal.GetReference(values.Component0));
42+
43+
ref Vector512<float> srcRed =
44+
ref Unsafe.As<float, Vector512<float>>(ref MemoryMarshal.GetReference(rLane));
45+
ref Vector512<float> srcGreen =
46+
ref Unsafe.As<float, Vector512<float>>(ref MemoryMarshal.GetReference(gLane));
47+
ref Vector512<float> srcBlue =
48+
ref Unsafe.As<float, Vector512<float>>(ref MemoryMarshal.GetReference(bLane));
49+
50+
// Used for the color conversion
51+
Vector512<float> f0299 = Vector512.Create(0.299f);
52+
Vector512<float> f0587 = Vector512.Create(0.587f);
53+
Vector512<float> f0114 = Vector512.Create(0.114f);
54+
55+
nuint n = values.Component0.Vector512Count<float>();
56+
for (nuint i = 0; i < n; i++)
57+
{
58+
ref Vector512<float> r = ref Unsafe.Add(ref srcRed, i);
59+
ref Vector512<float> g = ref Unsafe.Add(ref srcGreen, i);
60+
ref Vector512<float> b = ref Unsafe.Add(ref srcBlue, i);
61+
62+
// luminosity = (0.299 * r) + (0.587 * g) + (0.114 * b)
63+
Unsafe.Add(ref destLuminance, i) = Vector512Utilities.MultiplyAdd(Vector512Utilities.MultiplyAdd(f0114 * b, f0587, g), f0299, r);
64+
}
65+
}
66+
67+
/// <inheritdoc/>
68+
protected override void ConvertToRgbInPlaceScalarRemainder(in ComponentValues values)
69+
=> GrayScaleScalar.ConvertToRgbInPlace(values.Component0, this.MaximumValue);
70+
71+
/// <inheritdoc/>
72+
protected override void ConvertFromRgbScalarRemainder(in ComponentValues values, Span<float> r, Span<float> g, Span<float> b)
73+
=> GrayScaleScalar.ConvertFromRgbScalar(values, r, g, b);
74+
}
75+
}

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

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,24 @@ public RgbScalar(int precision)
1414

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

1919
/// <inheritdoc/>
20-
public override void ConvertFromRgb(in ComponentValues values, Span<float> r, Span<float> g, Span<float> b)
21-
=> ConvertFromRgb(values, r, g, b);
20+
public override void ConvertFromRgb(in ComponentValues values, Span<float> rLane, Span<float> gLane, Span<float> bLane)
21+
=> ConvertFromRgb(values, rLane, gLane, bLane);
2222

23-
internal static void ConvertToRgbInplace(ComponentValues values, float maxValue)
23+
internal static void ConvertToRgbInPlace(ComponentValues values, float maxValue)
2424
{
25-
GrayscaleScalar.ConvertToRgbInplace(values.Component0, maxValue);
26-
GrayscaleScalar.ConvertToRgbInplace(values.Component1, maxValue);
27-
GrayscaleScalar.ConvertToRgbInplace(values.Component2, maxValue);
25+
GrayScaleScalar.ConvertToRgbInPlace(values.Component0, maxValue);
26+
GrayScaleScalar.ConvertToRgbInPlace(values.Component1, maxValue);
27+
GrayScaleScalar.ConvertToRgbInPlace(values.Component2, maxValue);
2828
}
2929

30-
internal static void ConvertFromRgb(ComponentValues values, Span<float> r, Span<float> g, Span<float> b)
30+
internal static void ConvertFromRgb(ComponentValues values, Span<float> rLane, Span<float> gLane, Span<float> bLane)
3131
{
32-
r.CopyTo(values.Component0);
33-
g.CopyTo(values.Component1);
34-
b.CopyTo(values.Component2);
32+
rLane.CopyTo(values.Component0);
33+
gLane.CopyTo(values.Component1);
34+
bLane.CopyTo(values.Component2);
3535
}
3636
}
3737
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ protected override void ConvertToRgbInPlaceVectorized(in ComponentValues values)
4242

4343
/// <inheritdoc/>
4444
protected override void ConvertToRgbInPlaceScalarRemainder(in ComponentValues values)
45-
=> RgbScalar.ConvertToRgbInplace(values, this.MaximumValue);
45+
=> RgbScalar.ConvertToRgbInPlace(values, this.MaximumValue);
4646

4747
/// <inheritdoc/>
4848
protected override void ConvertFromRgbVectorized(in ComponentValues values, Span<float> r, Span<float> g, Span<float> b)

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@ public YCbCrScalar(int precision)
2020

2121
/// <inheritdoc/>
2222
public override void ConvertToRgbInPlace(in ComponentValues values)
23-
=> ConvertToRgbInplace(values, this.MaximumValue, this.HalfValue);
23+
=> ConvertToRgbInPlace(values, this.MaximumValue, this.HalfValue);
2424

2525
/// <inheritdoc/>
26-
public override void ConvertFromRgb(in ComponentValues values, Span<float> r, Span<float> g, Span<float> b)
27-
=> ConvertFromRgb(values, this.HalfValue, r, g, b);
26+
public override void ConvertFromRgb(in ComponentValues values, Span<float> rLane, Span<float> gLane, Span<float> bLane)
27+
=> ConvertFromRgb(values, this.HalfValue, rLane, gLane, bLane);
2828

29-
public static void ConvertToRgbInplace(in ComponentValues values, float maxValue, float halfValue)
29+
public static void ConvertToRgbInPlace(in ComponentValues values, float maxValue, float halfValue)
3030
{
3131
Span<float> c0 = values.Component0;
3232
Span<float> c1 = values.Component1;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ protected override void ConvertFromRgbVectorized(in ComponentValues values, Span
114114

115115
/// <inheritdoc/>
116116
protected override void ConvertToRgbInPlaceScalarRemainder(in ComponentValues values)
117-
=> YCbCrScalar.ConvertToRgbInplace(values, this.MaximumValue, this.HalfValue);
117+
=> YCbCrScalar.ConvertToRgbInPlace(values, this.MaximumValue, this.HalfValue);
118118

119119
/// <inheritdoc/>
120120
protected override void ConvertFromRgbScalarRemainder(in ComponentValues values, Span<float> rLane, Span<float> gLane, Span<float> bLane)

0 commit comments

Comments
 (0)