Browse Source

Remove JpegSubsample and use JpegColorType instead

pull/1734/head
Brian Popow 5 years ago
parent
commit
a531a2db24
  1. 8
      src/ImageSharp/Formats/Jpeg/IJpegEncoderOptions.cs
  2. 18
      src/ImageSharp/Formats/Jpeg/JpegColorType.cs
  3. 17
      src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
  4. 15
      src/ImageSharp/Formats/Jpeg/JpegEncoder.cs
  5. 45
      src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs
  6. 28
      src/ImageSharp/Formats/Jpeg/JpegSubsample.cs
  7. 2
      src/ImageSharp/Formats/Tiff/Compression/Compressors/TiffJpegCompressor.cs
  8. 4
      tests/ImageSharp.Benchmarks/Codecs/Jpeg/EncodeJpeg.cs
  9. 65
      tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs
  10. 2
      tests/ImageSharp.Tests/Formats/Jpg/JpegMetadataTests.cs
  11. 6
      tests/ImageSharp.Tests/Formats/Jpg/SpectralJpegTests.cs
  12. 14
      tests/ImageSharp.Tests/ProfilingBenchmarks/JpegProfilingBenchmarks.cs

8
src/ImageSharp/Formats/Jpeg/IJpegEncoderOptions.cs

@ -16,13 +16,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
public int? Quality { get; set; }
/// <summary>
/// Gets the subsample ration, that will be used to encode the image.
/// </summary>
/// <value>The subsample ratio of the jpg image.</value>
JpegSubsample? Subsample { get; }
/// <summary>
/// Gets the color type.
/// Gets the color type, that will be used to encode the image.
/// </summary>
JpegColorType? ColorType { get; }
}

18
src/ImageSharp/Formats/Jpeg/JpegColorType.cs

@ -10,12 +10,26 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
{
/// <summary>
/// YCbCr (luminance, blue chroma, red chroma) color as defined in the ITU-T T.871 specification.
/// Medium Quality - The horizontal sampling is halved and the Cb and Cr channels are only
/// sampled on each alternate line.
/// </summary>
YCbCr = 0,
YCbCrRatio420 = 0,
/// <summary>
/// YCbCr (luminance, blue chroma, red chroma) color as defined in the ITU-T T.871 specification.
/// High Quality - Each of the three Y'CbCr components have the same sample rate,
/// thus there is no chroma subsampling.
/// </summary>
YCbCrRatio444 = 1,
/// <summary>
/// Single channel, luminance.
/// </summary>
Luminance = 1
Luminance = 2,
/// <summary>
/// The pixel data will be preserved as RGB without any sub sampling.
/// </summary>
Rgb,
}
}

17
src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs

@ -312,7 +312,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
case JpegConstants.Markers.SOS:
if (!metadataOnly)
{
this.ProcessStartOfScanMarker(stream, remaining, cancellationToken);
this.ProcessStartOfScanMarker(stream, remaining);
break;
}
else
@ -953,7 +953,18 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
this.ColorSpace = this.DeduceJpegColorSpace(componentCount, this.Frame.Components);
this.Metadata.GetJpegMetadata().ColorType = this.ColorSpace == JpegColorSpace.Grayscale ? JpegColorType.Luminance : JpegColorType.YCbCr;
switch (this.ColorSpace)
{
case JpegColorSpace.Grayscale:
this.Metadata.GetJpegMetadata().ColorType = JpegColorType.Luminance;
break;
case JpegColorSpace.RGB:
this.Metadata.GetJpegMetadata().ColorType = JpegColorType.Rgb;
break;
default:
this.Metadata.GetJpegMetadata().ColorType = JpegColorType.YCbCrRatio420;
break;
}
if (!metadataOnly)
{
@ -1051,7 +1062,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
/// <summary>
/// Processes the SOS (Start of scan marker).
/// </summary>
private void ProcessStartOfScanMarker(BufferedReadStream stream, int remaining, CancellationToken cancellationToken)
private void ProcessStartOfScanMarker(BufferedReadStream stream, int remaining)
{
if (this.Frame is null)
{

15
src/ImageSharp/Formats/Jpeg/JpegEncoder.cs

@ -16,14 +16,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
/// <inheritdoc/>
public int? Quality { get; set; }
/// <summary>
/// Gets or sets the subsample ration, that will be used to encode the image.
/// </summary>
public JpegSubsample? Subsample { get; set; }
/// <summary>
/// Gets or sets the color type, that will be used to encode the image.
/// </summary>
/// <inheritdoc/>
public JpegColorType? ColorType { get; set; }
/// <summary>
@ -36,7 +29,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
where TPixel : unmanaged, IPixel<TPixel>
{
var encoder = new JpegEncoderCore(this);
this.InitializeColorType<TPixel>(image);
this.InitializeColorType(image);
encoder.Encode(image, stream);
}
@ -52,7 +45,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
where TPixel : unmanaged, IPixel<TPixel>
{
var encoder = new JpegEncoderCore(this);
this.InitializeColorType<TPixel>(image);
this.InitializeColorType(image);
return encoder.EncodeAsync(image, stream, cancellationToken);
}
@ -75,7 +68,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
bool isGrayscale =
typeof(TPixel) == typeof(L8) || typeof(TPixel) == typeof(L16) ||
typeof(TPixel) == typeof(La16) || typeof(TPixel) == typeof(La32);
this.ColorType = isGrayscale ? JpegColorType.Luminance : JpegColorType.YCbCr;
this.ColorType = isGrayscale ? JpegColorType.Luminance : JpegColorType.YCbCrRatio420;
}
}
}

45
src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs

@ -33,20 +33,15 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
/// </summary>
private readonly byte[] buffer = new byte[20];
/// <summary>
/// Gets or sets the subsampling method to use.
/// </summary>
private JpegSubsample? subsample;
/// <summary>
/// The quality, that will be used to encode the image.
/// </summary>
private readonly int? quality;
/// <summary>
/// Gets or sets the subsampling method to use.
/// Gets or sets the colorspace to use.
/// </summary>
private readonly JpegColorType? colorType;
private JpegColorType? colorType;
/// <summary>
/// The output stream. All attempted writes after the first error become no-ops.
@ -56,11 +51,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
/// <summary>
/// Initializes a new instance of the <see cref="JpegEncoderCore"/> class.
/// </summary>
/// <param name="options">The options</param>
/// <param name="options">The options.</param>
public JpegEncoderCore(IJpegEncoderOptions options)
{
this.quality = options.Quality;
this.subsample = options.Subsample;
this.colorType = options.ColorType;
}
@ -118,21 +112,22 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
var scanEncoder = new HuffmanScanEncoder(stream);
if (this.colorType == JpegColorType.Luminance)
{
// luminance quantization table only
// luminance quantization table only.
scanEncoder.EncodeGrayscale(image, ref luminanceQuantTable, cancellationToken);
}
else
{
// luminance and chrominance quantization tables
switch (this.subsample)
// luminance and chrominance quantization tables.
switch (this.colorType)
{
case JpegSubsample.Ratio444:
case JpegColorType.YCbCrRatio444:
case JpegColorType.Luminance:
scanEncoder.Encode444(image, ref luminanceQuantTable, ref chrominanceQuantTable, cancellationToken);
break;
case JpegSubsample.Ratio420:
case JpegColorType.YCbCrRatio420:
scanEncoder.Encode420(image, ref luminanceQuantTable, ref chrominanceQuantTable, cancellationToken);
break;
case JpegSubsample.Rgb:
case JpegColorType.Rgb:
scanEncoder.EncodeRgb(image, ref luminanceQuantTable, ref chrominanceQuantTable, cancellationToken);
break;
}
@ -151,7 +146,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
/// <returns>The component Ids.</returns>
private byte[] GetComponentIds()
{
if (this.subsample == JpegSubsample.Rgb)
if (this.colorType == JpegColorType.Rgb)
{
return new byte[] { 82, 71, 66 };
}
@ -268,7 +263,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
/// </summary>
private void WriteDefineQuantizationTables(ref Block8x8F luminanceQuantTable, ref Block8x8F chrominanceQuantTable)
{
// Marker + quantization table lengths
// Marker + quantization table lengths.
int markerlen = 2 + (QuantizationTableCount * (1 + Block8x8F.Size));
this.WriteMarkerHeader(JpegConstants.Markers.DQT, markerlen);
@ -404,7 +399,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
/// </summary>
/// <param name="iccProfile">The ICC profile to write.</param>
/// <exception cref="ImageFormatException">
/// Thrown if any of the ICC profiles size exceeds the limit
/// Thrown if any of the ICC profiles size exceeds the limit.
/// </exception>
private void WriteIccProfile(IccProfile iccProfile)
{
@ -424,7 +419,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
return;
}
// Calculate the number of markers we'll need, rounding up of course
// Calculate the number of markers we'll need, rounding up of course.
int dataLength = data.Length;
int count = dataLength / MaxData;
@ -531,10 +526,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
}
else
{
switch (this.subsample)
switch (this.colorType)
{
case JpegSubsample.Rgb:
case JpegSubsample.Ratio444:
case JpegColorType.YCbCrRatio444:
case JpegColorType.Rgb:
subsamples = stackalloc byte[]
{
0x11,
@ -542,7 +537,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
0x11
};
break;
case JpegSubsample.Ratio420:
case JpegColorType.YCbCrRatio420:
subsamples = stackalloc byte[]
{
0x22,
@ -685,9 +680,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
chromaQuality = Numerics.Clamp(chromaQuality, 1, 100);
chrominanceQuantTable = Quantization.ScaleChrominanceTable(chromaQuality);
if (!this.subsample.HasValue)
if (!this.colorType.HasValue)
{
this.subsample = chromaQuality >= 91 ? JpegSubsample.Ratio444 : JpegSubsample.Ratio420;
this.colorType = chromaQuality >= 91 ? JpegColorType.YCbCrRatio444 : JpegColorType.YCbCrRatio420;
}
}
}

28
src/ImageSharp/Formats/Jpeg/JpegSubsample.cs

@ -1,28 +0,0 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
namespace SixLabors.ImageSharp.Formats.Jpeg
{
/// <summary>
/// Enumerates the chroma subsampling method applied to the image.
/// </summary>
public enum JpegSubsample
{
/// <summary>
/// High Quality - Each of the three Y'CbCr components have the same sample rate,
/// thus there is no chroma subsampling.
/// </summary>
Ratio444,
/// <summary>
/// Medium Quality - The horizontal sampling is halved and the Cb and Cr channels are only
/// sampled on each alternate line.
/// </summary>
Ratio420,
/// <summary>
/// The pixel data will be preserved as RGB without any sub sampling.
/// </summary>
Rgb,
}
}

2
src/ImageSharp/Formats/Tiff/Compression/Compressors/TiffJpegCompressor.cs

@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Compressors
var image = Image.LoadPixelData<Rgb24>(rows, width, height);
image.Save(memoryStream, new JpegEncoder()
{
Subsample = JpegSubsample.Rgb
ColorType = JpegColorType.Rgb
});
memoryStream.Position = 0;
memoryStream.WriteTo(this.Output);

4
tests/ImageSharp.Benchmarks/Codecs/Jpeg/EncodeJpeg.cs

@ -40,8 +40,8 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg
this.bmpCore = Image.Load<Rgba32>(this.bmpStream);
this.bmpCore.Metadata.ExifProfile = null;
this.encoder420 = new JpegEncoder { Quality = this.Quality, Subsample = JpegSubsample.Ratio420 };
this.encoder444 = new JpegEncoder { Quality = this.Quality, Subsample = JpegSubsample.Ratio444 };
this.encoder420 = new JpegEncoder { Quality = this.Quality, ColorType = JpegColorType.YCbCrRatio420 };
this.encoder444 = new JpegEncoder { Quality = this.Quality, ColorType = JpegColorType.YCbCrRatio444 };
this.bmpStream.Position = 0;
this.bmpDrawing = SDImage.FromStream(this.bmpStream);

65
tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs

@ -31,15 +31,18 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
{ TestImages.Jpeg.Progressive.Fb, 75 }
};
public static readonly TheoryData<JpegSubsample, int> BitsPerPixel_Quality =
new TheoryData<JpegSubsample, int>
public static readonly TheoryData<JpegColorType, int> BitsPerPixel_Quality =
new TheoryData<JpegColorType, int>
{
{ JpegSubsample.Ratio420, 40 },
{ JpegSubsample.Ratio420, 60 },
{ JpegSubsample.Ratio420, 100 },
{ JpegSubsample.Ratio444, 40 },
{ JpegSubsample.Ratio444, 60 },
{ JpegSubsample.Ratio444, 100 },
{ JpegColorType.Rgb, 40 },
{ JpegColorType.Rgb, 60 },
{ JpegColorType.Rgb, 100 },
{ JpegColorType.YCbCrRatio420, 40 },
{ JpegColorType.YCbCrRatio420, 60 },
{ JpegColorType.YCbCrRatio420, 100 },
{ JpegColorType.YCbCrRatio444, 40 },
{ JpegColorType.YCbCrRatio444, 60 },
{ JpegColorType.YCbCrRatio444, 100 },
};
public static readonly TheoryData<int> Grayscale_Quality =
@ -91,8 +94,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
[WithTestPatternImages(nameof(BitsPerPixel_Quality), 7, 5, PixelTypes.Rgba32)]
[WithTestPatternImages(nameof(BitsPerPixel_Quality), 600, 400, PixelTypes.Rgba32)]
[WithSolidFilledImages(nameof(BitsPerPixel_Quality), 1, 1, 100, 100, 100, 255, PixelTypes.L8)]
public void EncodeBaseline_WorksWithDifferentSizes<TPixel>(TestImageProvider<TPixel> provider, JpegSubsample subsample, int quality)
where TPixel : unmanaged, IPixel<TPixel> => TestJpegEncoderCore(provider, subsample, quality);
public void EncodeBaseline_WorksWithDifferentSizes<TPixel>(TestImageProvider<TPixel> provider, JpegColorType colorType, int quality)
where TPixel : unmanaged, IPixel<TPixel> => TestJpegEncoderCore(provider, colorType, quality);
[Theory]
[WithFile(TestImages.Png.BikeGrayscale, nameof(Grayscale_Quality), PixelTypes.L8)]
@ -102,33 +105,33 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
[WithSolidFilledImages(1, 1, 100, 100, 100, 255, PixelTypes.La16, 100)]
[WithSolidFilledImages(1, 1, 100, 100, 100, 255, PixelTypes.La32, 100)]
public void EncodeBaseline_Grayscale<TPixel>(TestImageProvider<TPixel> provider, int quality)
where TPixel : unmanaged, IPixel<TPixel> => TestJpegEncoderCore(provider, null, quality, JpegColorType.Luminance);
where TPixel : unmanaged, IPixel<TPixel> => TestJpegEncoderCore(provider, JpegColorType.Luminance, quality);
[Theory]
[WithTestPatternImages(nameof(BitsPerPixel_Quality), 48, 48, PixelTypes.Rgba32 | PixelTypes.Bgra32)]
public void EncodeBaseline_IsNotBoundToSinglePixelType<TPixel>(TestImageProvider<TPixel> provider, JpegSubsample subsample, int quality)
where TPixel : unmanaged, IPixel<TPixel> => TestJpegEncoderCore(provider, subsample, quality);
public void EncodeBaseline_IsNotBoundToSinglePixelType<TPixel>(TestImageProvider<TPixel> provider, JpegColorType colorType, int quality)
where TPixel : unmanaged, IPixel<TPixel> => TestJpegEncoderCore(provider, colorType, quality);
[Theory]
[WithFile(TestImages.Png.CalliphoraPartial, PixelTypes.Rgba32, JpegSubsample.Ratio444)]
[WithTestPatternImages(587, 821, PixelTypes.Rgba32, JpegSubsample.Ratio444)]
[WithTestPatternImages(677, 683, PixelTypes.Bgra32, JpegSubsample.Ratio420)]
[WithSolidFilledImages(400, 400, "Red", PixelTypes.Bgr24, JpegSubsample.Ratio420)]
public void EncodeBaseline_WorksWithDiscontiguousBuffers<TPixel>(TestImageProvider<TPixel> provider, JpegSubsample subsample)
[WithFile(TestImages.Png.CalliphoraPartial, PixelTypes.Rgba32, JpegColorType.YCbCrRatio444)]
[WithTestPatternImages(587, 821, PixelTypes.Rgba32, JpegColorType.YCbCrRatio444)]
[WithTestPatternImages(677, 683, PixelTypes.Bgra32, JpegColorType.YCbCrRatio420)]
[WithSolidFilledImages(400, 400, "Red", PixelTypes.Bgr24, JpegColorType.YCbCrRatio420)]
public void EncodeBaseline_WorksWithDiscontiguousBuffers<TPixel>(TestImageProvider<TPixel> provider, JpegColorType colorType)
where TPixel : unmanaged, IPixel<TPixel>
{
ImageComparer comparer = subsample == JpegSubsample.Ratio444
ImageComparer comparer = colorType == JpegColorType.YCbCrRatio444
? ImageComparer.TolerantPercentage(0.1f)
: ImageComparer.TolerantPercentage(5f);
provider.LimitAllocatorBufferCapacity().InBytesSqrt(200);
TestJpegEncoderCore(provider, subsample, 100, JpegColorType.YCbCr, comparer);
TestJpegEncoderCore(provider, colorType, 100, comparer);
}
/// <summary>
/// Anton's SUPER-SCIENTIFIC tolerance threshold calculation
/// </summary>
private static ImageComparer GetComparer(int quality, JpegSubsample? subsample)
private static ImageComparer GetComparer(int quality, JpegColorType? colorType)
{
float tolerance = 0.015f; // ~1.5%
@ -136,10 +139,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
{
tolerance *= 10f;
}
else if (quality < 75 || subsample == JpegSubsample.Ratio420)
else if (quality < 75 || colorType == JpegColorType.YCbCrRatio420)
{
tolerance *= 5f;
if (subsample == JpegSubsample.Ratio420)
if (colorType == JpegColorType.YCbCrRatio420)
{
tolerance *= 2f;
}
@ -150,9 +153,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
private static void TestJpegEncoderCore<TPixel>(
TestImageProvider<TPixel> provider,
JpegSubsample? subsample,
JpegColorType colorType = JpegColorType.YCbCrRatio420,
int quality = 100,
JpegColorType colorType = JpegColorType.YCbCr,
ImageComparer comparer = null)
where TPixel : unmanaged, IPixel<TPixel>
{
@ -163,13 +165,12 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
var encoder = new JpegEncoder
{
Subsample = subsample,
Quality = quality,
ColorType = colorType
};
string info = $"{subsample}-Q{quality}";
string info = $"{colorType}-Q{quality}";
comparer ??= GetComparer(quality, subsample);
comparer ??= GetComparer(quality, colorType);
// Does DebugSave & load reference CompareToReferenceInput():
image.VerifyEncoder(provider, "jpeg", info, encoder, comparer, referenceImageExtension: "png");
@ -312,9 +313,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
}
[Theory]
[InlineData(JpegSubsample.Ratio420)]
[InlineData(JpegSubsample.Ratio444)]
public async Task Encode_IsCancellable(JpegSubsample subsample)
[InlineData(JpegColorType.YCbCrRatio420)]
[InlineData(JpegColorType.YCbCrRatio444)]
public async Task Encode_IsCancellable(JpegColorType colorType)
{
var cts = new CancellationTokenSource();
using var pausedStream = new PausedStream(new MemoryStream());
@ -336,7 +337,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
using var image = new Image<Rgba32>(5000, 5000);
await Assert.ThrowsAsync<TaskCanceledException>(async () =>
{
var encoder = new JpegEncoder() { Subsample = subsample };
var encoder = new JpegEncoder() { ColorType = colorType };
await image.SaveAsync(pausedStream, encoder, cts.Token);
});
}

2
tests/ImageSharp.Tests/Formats/Jpg/JpegMetadataTests.cs

@ -16,7 +16,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
var clone = (JpegMetadata)meta.DeepClone();
clone.Quality = 99;
clone.ColorType = JpegColorType.YCbCr;
clone.ColorType = JpegColorType.YCbCrRatio420;
Assert.False(meta.Quality.Equals(clone.Quality));
Assert.False(meta.ColorType.Equals(clone.ColorType));

6
tests/ImageSharp.Tests/Formats/Jpg/SpectralJpegTests.cs

@ -21,10 +21,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
[Trait("Format", "Jpg")]
public class SpectralJpegTests
{
public SpectralJpegTests(ITestOutputHelper output)
{
this.Output = output;
}
public SpectralJpegTests(ITestOutputHelper output) => this.Output = output;
private ITestOutputHelper Output { get; }
@ -46,7 +43,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
public static readonly string[] AllTestJpegs = BaselineTestJpegs.Concat(ProgressiveTestJpegs).ToArray();
[Theory(Skip = "Debug only, enable manually!")]
//[Theory]
[WithFileCollection(nameof(AllTestJpegs), PixelTypes.Rgba32)]
public void Decoder_ParseStream_SaveSpectralResult<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>

14
tests/ImageSharp.Tests/ProfilingBenchmarks/JpegProfilingBenchmarks.cs

@ -70,7 +70,7 @@ namespace SixLabors.ImageSharp.Tests.ProfilingBenchmarks
img.Dispose();
},
#pragma warning disable SA1515 // Single-line comment should be preceded by blank line
// ReSharper disable once ExplicitCallerInfoArgument
// ReSharper disable once ExplicitCallerInfoArgument
$"Decode {fileName}");
#pragma warning restore SA1515 // Single-line comment should be preceded by blank line
}
@ -92,11 +92,11 @@ namespace SixLabors.ImageSharp.Tests.ProfilingBenchmarks
// Benchmark, enable manually!
[Theory(Skip = ProfilingSetup.SkipProfilingTests)]
[InlineData(1, 75, JpegSubsample.Ratio420)]
[InlineData(30, 75, JpegSubsample.Ratio420)]
[InlineData(30, 75, JpegSubsample.Ratio444)]
[InlineData(30, 100, JpegSubsample.Ratio444)]
public void EncodeJpeg(int executionCount, int quality, JpegSubsample subsample)
[InlineData(1, 75, JpegColorType.YCbCrRatio420)]
[InlineData(30, 75, JpegColorType.YCbCrRatio420)]
[InlineData(30, 75, JpegColorType.YCbCrRatio444)]
[InlineData(30, 100, JpegColorType.YCbCrRatio444)]
public void EncodeJpeg(int executionCount, int quality, JpegColorType colorType)
{
// do not run this on CI even by accident
if (TestEnvironment.RunsOnCI)
@ -118,7 +118,7 @@ namespace SixLabors.ImageSharp.Tests.ProfilingBenchmarks
{
foreach (Image<Rgba32> img in testImages)
{
var options = new JpegEncoder { Quality = quality, Subsample = subsample };
var options = new JpegEncoder { Quality = quality, ColorType = colorType };
img.Save(ms, options);
ms.Seek(0, SeekOrigin.Begin);
}

Loading…
Cancel
Save