diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterAvx.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterAvx.cs
index d7b619fca9..429b8677b6 100644
--- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterAvx.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterAvx.cs
@@ -25,8 +25,13 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
{
}
+ ///
+ /// Gets a value indicating whether this converter is supported on current hardware.
+ ///
+ public static bool IsSupported => Avx.IsSupported;
+
///
- public override bool IsAvailable => Avx.IsSupported;
+ public override bool IsAvailable => IsSupported;
}
}
}
diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterBase.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterBase.cs
index 34b48c2fe6..8048f3233d 100644
--- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterBase.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterBase.cs
@@ -93,73 +93,116 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
///
private static JpegColorConverterBase[] CreateConverters()
{
- var converters = new List();
+ // 5 color types with 2 supported precisions: 8 bit & 12 bit
+ const int colorConvertersCount = 5 * 2;
+
+ var converters = new JpegColorConverterBase[colorConvertersCount];
// 8-bit converters
- converters.AddRange(GetYCbCrConverters(8));
- converters.AddRange(GetYccKConverters(8));
- converters.AddRange(GetCmykConverters(8));
- converters.AddRange(GetGrayScaleConverters(8));
- converters.AddRange(GetRgbConverters(8));
+ converters[0] = GetYCbCrConverter(8);
+ converters[1] = GetYccKConverter(8);
+ converters[2] = GetCmykConverter(8);
+ converters[3] = GetGrayScaleConverter(8);
+ converters[4] = GetRgbConverter(8);
// 12-bit converters
- converters.AddRange(GetYCbCrConverters(12));
- converters.AddRange(GetYccKConverters(12));
- converters.AddRange(GetCmykConverters(12));
- converters.AddRange(GetGrayScaleConverters(12));
- converters.AddRange(GetRgbConverters(12));
+ converters[5] = GetYCbCrConverter(12);
+ converters[6] = GetYccKConverter(12);
+ converters[7] = GetCmykConverter(12);
+ converters[8] = GetGrayScaleConverter(12);
+ converters[9] = GetRgbConverter(12);
- return converters.Where(x => x.IsAvailable).ToArray();
+ return converters;
}
///
/// Returns the s for the YCbCr colorspace.
///
- private static IEnumerable GetYCbCrConverters(int precision)
+ private static JpegColorConverterBase GetYCbCrConverter(int precision)
{
- yield return new YCbCrAvx(precision);
- yield return new YCbCrVector(precision);
- yield return new YCbCrScalar(precision);
+ if (JpegColorConverterAvx.IsSupported)
+ {
+ return new YCbCrAvx(precision);
+ }
+
+ if (JpegColorConverterVector.IsSupported)
+ {
+ return new YCbCrVector(precision);
+ }
+
+ return new YCbCrScalar(precision);
}
///
/// Returns the s for the YccK colorspace.
///
- private static IEnumerable GetYccKConverters(int precision)
+ private static JpegColorConverterBase GetYccKConverter(int precision)
{
- yield return new YccKAvx(precision);
- yield return new YccKVector(precision);
- yield return new YccKScalar(precision);
+ if (JpegColorConverterAvx.IsSupported)
+ {
+ return new YccKAvx(precision);
+ }
+
+ if (JpegColorConverterVector.IsSupported)
+ {
+ return new YccKVector(precision);
+ }
+
+ return new YccKScalar(precision);
}
///
/// Returns the s for the CMYK colorspace.
///
- private static IEnumerable GetCmykConverters(int precision)
+ private static JpegColorConverterBase GetCmykConverter(int precision)
{
- yield return new CmykAvx(precision);
- yield return new CmykVector(precision);
- yield return new CmykScalar(precision);
+ if (JpegColorConverterAvx.IsSupported)
+ {
+ return new CmykAvx(precision);
+ }
+
+ if (JpegColorConverterVector.IsSupported)
+ {
+ return new CmykVector(precision);
+ }
+
+ return new CmykScalar(precision);
}
///
/// Returns the s for the gray scale colorspace.
///
- private static IEnumerable GetGrayScaleConverters(int precision)
+ private static JpegColorConverterBase GetGrayScaleConverter(int precision)
{
- yield return new GrayscaleAvx(precision);
- yield return new GrayScaleVector(precision);
- yield return new GrayscaleScalar(precision);
+ if (JpegColorConverterAvx.IsSupported)
+ {
+ return new GrayscaleAvx(precision);
+ }
+
+ if (JpegColorConverterVector.IsSupported)
+ {
+ return new GrayScaleVector(precision);
+ }
+
+ return new GrayscaleScalar(precision);
}
///
/// Returns the s for the RGB colorspace.
///
- private static IEnumerable GetRgbConverters(int precision)
+ private static JpegColorConverterBase GetRgbConverter(int precision)
{
- yield return new RgbAvx(precision);
- yield return new RgbVector(precision);
- yield return new RgbScalar(precision);
+ if (JpegColorConverterAvx.IsSupported)
+ {
+ return new RgbAvx(precision);
+ }
+
+ if (JpegColorConverterVector.IsSupported)
+ {
+ return new RgbScalar(precision);
+ }
+
+ return new GrayscaleScalar(precision);
}
///
diff --git a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterVector.cs b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterVector.cs
index 3c8b16943b..92d388fc8f 100644
--- a/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterVector.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverterVector.cs
@@ -26,8 +26,13 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
{
}
+ ///
+ /// Gets a value indicating whether this converter is supported on current hardware.
+ ///
+ public static bool IsSupported => Vector.IsHardwareAccelerated && Vector.Count % 4 == 0;
+
///
- public sealed override bool IsAvailable => Vector.IsHardwareAccelerated && Vector.Count % 4 == 0;
+ public sealed override bool IsAvailable => IsSupported;
///
public sealed override void ConvertToRgbInplace(in ComponentValues values)
diff --git a/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs b/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs
index 4268f862c2..7274b51961 100644
--- a/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs
@@ -149,7 +149,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder
{
case JpegEncodingColor.YCbCrRatio444:
case JpegEncodingColor.Rgb:
- this.EncodeThreeComponentScanBaselineInterleaved444(frame, converter, cancellationToken);
+ this.EncodeThreeComponentBaselineInterleavedScanNoSubsampling(frame, converter, cancellationToken);
break;
default:
this.EncodeScanBaselineInterleaved(frame, converter, cancellationToken);
@@ -310,12 +310,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder
}
///
- /// Encodes scan in baseline interleaved mode with exactly 3 components with 4:4:4 sampling.
+ /// Encodes scan in baseline interleaved mode with exactly 3 components with no subsampling.
///
/// Frame to encode.
/// Converter from color to spectral.
/// The token to request cancellation.
- private void EncodeThreeComponentScanBaselineInterleaved444(JpegFrame frame, SpectralConverter converter, CancellationToken cancellationToken)
+ private void EncodeThreeComponentBaselineInterleavedScanNoSubsampling(JpegFrame frame, SpectralConverter converter, CancellationToken cancellationToken)
where TPixel : unmanaged, IPixel
{
nint mcusPerColumn = frame.McusPerColumn;
diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/EncodeJpegFeatures.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/EncodeJpegFeatures.cs
index 6844883486..a593f0489a 100644
--- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/EncodeJpegFeatures.cs
+++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/EncodeJpegFeatures.cs
@@ -84,16 +84,16 @@ Intel Core i7-6700K CPU 4.00GHz (Skylake), 1 CPU, 8 logical and 4 physical cores
| Method | TargetColorSpace | Quality | Mean | Error | StdDev |
|---------- |----------------- |-------- |----------:|----------:|----------:|
-| Benchmark | Luminance | 75 | 4.575 ms | 0.0233 ms | 0.0207 ms |
-| Benchmark | Rgb | 75 | 12.477 ms | 0.1051 ms | 0.0932 ms |
-| Benchmark | YCbCrRatio420 | 75 | 6.421 ms | 0.0464 ms | 0.0434 ms |
-| Benchmark | YCbCrRatio444 | 75 | 8.449 ms | 0.1246 ms | 0.1166 ms |
-| Benchmark | Luminance | 90 | 4.863 ms | 0.0120 ms | 0.0106 ms |
-| Benchmark | Rgb | 90 | 13.287 ms | 0.0548 ms | 0.0513 ms |
-| Benchmark | YCbCrRatio420 | 90 | 7.012 ms | 0.0533 ms | 0.0499 ms |
-| Benchmark | YCbCrRatio444 | 90 | 8.916 ms | 0.1285 ms | 0.1202 ms |
-| Benchmark | Luminance | 100 | 6.665 ms | 0.0136 ms | 0.0113 ms |
-| Benchmark | Rgb | 100 | 19.734 ms | 0.0477 ms | 0.0446 ms |
-| Benchmark | YCbCrRatio420 | 100 | 10.541 ms | 0.0925 ms | 0.0865 ms |
-| Benchmark | YCbCrRatio444 | 100 | 15.587 ms | 0.1695 ms | 0.1586 ms |
+| Benchmark | Luminance | 75 | 4.618 ms | 0.0263 ms | 0.0233 ms |
+| Benchmark | Rgb | 75 | 12.543 ms | 0.0650 ms | 0.0608 ms |
+| Benchmark | YCbCrRatio420 | 75 | 6.639 ms | 0.0778 ms | 0.1256 ms |
+| Benchmark | YCbCrRatio444 | 75 | 8.590 ms | 0.0570 ms | 0.0505 ms |
+| Benchmark | Luminance | 90 | 4.902 ms | 0.0307 ms | 0.0288 ms |
+| Benchmark | Rgb | 90 | 13.447 ms | 0.0468 ms | 0.0415 ms |
+| Benchmark | YCbCrRatio420 | 90 | 7.218 ms | 0.0586 ms | 0.0548 ms |
+| Benchmark | YCbCrRatio444 | 90 | 9.150 ms | 0.0779 ms | 0.0729 ms |
+| Benchmark | Luminance | 100 | 6.731 ms | 0.0325 ms | 0.0304 ms |
+| Benchmark | Rgb | 100 | 19.831 ms | 0.1009 ms | 0.0788 ms |
+| Benchmark | YCbCrRatio420 | 100 | 10.541 ms | 0.0423 ms | 0.0396 ms |
+| Benchmark | YCbCrRatio444 | 100 | 15.345 ms | 0.3276 ms | 0.3065 ms |
*/