Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix RgbScalar #2416

Merged
merged 12 commits into from
Mar 27, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -231,10 +231,10 @@ private static JpegColorConverterBase GetRgbConverter(int precision)

if (JpegColorConverterVector.IsSupported)
{
return new RgbScalar(precision);
return new RgbVector(precision);
}

return new GrayscaleScalar(precision);
return new RgbScalar(precision);
}

/// <summary>
Expand Down
203 changes: 191 additions & 12 deletions tests/ImageSharp.Tests/Formats/Jpg/JpegColorConverterTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.

using System.Runtime.Intrinsics.Arm;
using System.Runtime.Intrinsics.X86;
using SixLabors.ImageSharp.ColorSpaces;
using SixLabors.ImageSharp.ColorSpaces.Conversion;
using SixLabors.ImageSharp.Formats.Jpeg.Components;
Expand Down Expand Up @@ -69,6 +71,171 @@ internal void GetConverterReturnsValidConverter(JpegColorSpace colorSpace, int p
Assert.Equal(precision, converter.Precision);
}

[Fact]
public void GetConverterReturnsCorrectConverterWithRgbColorSpace()
{
FeatureTestRunner.RunWithHwIntrinsicsFeature(
RunTest,
HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX2 | HwIntrinsics.DisableSSE2 | HwIntrinsics.DisableHWIntrinsic);

static void RunTest(string arg)
{
// arrange
Type expectedType = typeof(JpegColorConverterBase.RgbScalar);
if (Avx.IsSupported)
{
expectedType = typeof(JpegColorConverterBase.RgbAvx);
}
else if (Sse2.IsSupported)
{
expectedType = typeof(JpegColorConverterBase.RgbVector);
}
else if (AdvSimd.IsSupported)
{
expectedType = typeof(JpegColorConverterBase.RgbArm);
}

// act
JpegColorConverterBase converter = JpegColorConverterBase.GetConverter(JpegColorSpace.RGB, 8);
Type actualType = converter.GetType();

// assert
Assert.Equal(expectedType, actualType);
}
}

[Fact]
public void GetConverterReturnsCorrectConverterWithGrayScaleColorSpace()
{
FeatureTestRunner.RunWithHwIntrinsicsFeature(
RunTest,
HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX2 | HwIntrinsics.DisableSSE2 | HwIntrinsics.DisableHWIntrinsic);

static void RunTest(string arg)
{
// arrange
Type expectedType = typeof(JpegColorConverterBase.GrayscaleScalar);
if (Avx.IsSupported)
{
expectedType = typeof(JpegColorConverterBase.GrayscaleAvx);
}
else if (Sse2.IsSupported)
{
expectedType = typeof(JpegColorConverterBase.GrayScaleVector);
}
else if (AdvSimd.IsSupported)
{
expectedType = typeof(JpegColorConverterBase.GrayscaleArm);
}

// act
JpegColorConverterBase converter = JpegColorConverterBase.GetConverter(JpegColorSpace.Grayscale, 8);
Type actualType = converter.GetType();

// assert
Assert.Equal(expectedType, actualType);
}
}

[Fact]
public void GetConverterReturnsCorrectConverterWithCmykColorSpace()
{
FeatureTestRunner.RunWithHwIntrinsicsFeature(
RunTest,
HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX2 | HwIntrinsics.DisableSSE2 | HwIntrinsics.DisableHWIntrinsic);

static void RunTest(string arg)
{
// arrange
Type expectedType = typeof(JpegColorConverterBase.CmykScalar);
if (Avx.IsSupported)
{
expectedType = typeof(JpegColorConverterBase.CmykAvx);
}
else if (Sse2.IsSupported)
{
expectedType = typeof(JpegColorConverterBase.CmykVector);
}
else if (AdvSimd.IsSupported)
{
expectedType = typeof(JpegColorConverterBase.CmykArm64);
}

// act
JpegColorConverterBase converter = JpegColorConverterBase.GetConverter(JpegColorSpace.Cmyk, 8);
Type actualType = converter.GetType();

// assert
Assert.Equal(expectedType, actualType);
}
}

[Fact]
public void GetConverterReturnsCorrectConverterWithYCbCrColorSpace()
{
FeatureTestRunner.RunWithHwIntrinsicsFeature(
RunTest,
HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX2 | HwIntrinsics.DisableSSE2 | HwIntrinsics.DisableHWIntrinsic);

static void RunTest(string arg)
{
// arrange
Type expectedType = typeof(JpegColorConverterBase.YCbCrScalar);
if (Avx.IsSupported)
{
expectedType = typeof(JpegColorConverterBase.YCbCrAvx);
}
else if (Sse2.IsSupported)
{
expectedType = typeof(JpegColorConverterBase.YCbCrVector);
}
else if (AdvSimd.IsSupported)
{
expectedType = typeof(JpegColorConverterBase.YCbCrVector);
}

// act
JpegColorConverterBase converter = JpegColorConverterBase.GetConverter(JpegColorSpace.YCbCr, 8);
Type actualType = converter.GetType();

// assert
Assert.Equal(expectedType, actualType);
}
}

[Fact]
public void GetConverterReturnsCorrectConverterWithYcckColorSpace()
{
FeatureTestRunner.RunWithHwIntrinsicsFeature(
RunTest,
HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX2 | HwIntrinsics.DisableSSE2 | HwIntrinsics.DisableHWIntrinsic);

static void RunTest(string arg)
{
// arrange
Type expectedType = typeof(JpegColorConverterBase.YccKScalar);
if (Avx.IsSupported)
{
expectedType = typeof(JpegColorConverterBase.YccKAvx);
}
else if (Sse2.IsSupported)
{
expectedType = typeof(JpegColorConverterBase.YccKVector);
}
else if (AdvSimd.IsSupported)
{
expectedType = typeof(JpegColorConverterBase.YccKVector);
}

// act
JpegColorConverterBase converter = JpegColorConverterBase.GetConverter(JpegColorSpace.Ycck, 8);
Type actualType = converter.GetType();

// assert
Assert.Equal(expectedType, actualType);
}
}

[Theory]
[InlineData(JpegColorSpace.Grayscale, 1)]
[InlineData(JpegColorSpace.Ycck, 4)]
Expand Down Expand Up @@ -242,15 +409,17 @@ static void RunTest(string arg) =>
[Theory]
[MemberData(nameof(Seeds))]
public void FromYCbCrAvx2(int seed) =>
this.TestConversionToRgb(new JpegColorConverterBase.YCbCrAvx(8),
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),
this.TestConversionFromRgb(
new JpegColorConverterBase.YCbCrAvx(8),
3,
seed,
new JpegColorConverterBase.YCbCrScalar(8),
Expand All @@ -259,15 +428,17 @@ public void FromRgbToYCbCrAvx2(int seed) =>
[Theory]
[MemberData(nameof(Seeds))]
public void FromCmykAvx2(int seed) =>
this.TestConversionToRgb(new JpegColorConverterBase.CmykAvx(8),
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),
this.TestConversionFromRgb(
new JpegColorConverterBase.CmykAvx(8),
4,
seed,
new JpegColorConverterBase.CmykScalar(8),
Expand All @@ -276,15 +447,17 @@ public void FromRgbToCmykAvx2(int seed) =>
[Theory]
[MemberData(nameof(Seeds))]
public void FromCmykArm(int seed) =>
this.TestConversionToRgb( new JpegColorConverterBase.CmykArm64(8),
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),
this.TestConversionFromRgb(
new JpegColorConverterBase.CmykArm64(8),
4,
seed,
new JpegColorConverterBase.CmykScalar(8),
Expand All @@ -293,15 +466,17 @@ public void FromRgbToCmykArm(int seed) =>
[Theory]
[MemberData(nameof(Seeds))]
public void FromGrayscaleAvx2(int seed) =>
this.TestConversionToRgb(new JpegColorConverterBase.GrayscaleAvx(8),
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),
this.TestConversionFromRgb(
new JpegColorConverterBase.GrayscaleAvx(8),
1,
seed,
new JpegColorConverterBase.GrayscaleScalar(8),
Expand All @@ -327,31 +502,35 @@ public void FromRgbToGrayscaleArm(int seed) =>
[Theory]
[MemberData(nameof(Seeds))]
public void FromRgbAvx2(int seed) =>
this.TestConversionToRgb(new JpegColorConverterBase.RgbAvx(8),
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),
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),
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),
this.TestConversionFromRgb(
new JpegColorConverterBase.YccKAvx(8),
4,
seed,
new JpegColorConverterBase.YccKScalar(8),
Expand Down