diff --git a/tests/ImageSharp.Tests/ComplexIntegrationTests.cs b/tests/ImageSharp.Tests/ComplexIntegrationTests.cs
new file mode 100644
index 0000000000..ad4676872f
--- /dev/null
+++ b/tests/ImageSharp.Tests/ComplexIntegrationTests.cs
@@ -0,0 +1,35 @@
+namespace SixLabors.ImageSharp.Tests
+{
+ using SixLabors.ImageSharp.Formats.Jpeg;
+ using SixLabors.ImageSharp.PixelFormats;
+ using SixLabors.ImageSharp.Processing;
+ using SixLabors.Primitives;
+
+ using Xunit;
+
+ ///
+ /// Might be useful to catch complex bugs
+ ///
+ public class ComplexIntegrationTests
+ {
+ [Theory]
+ [WithFile(TestImages.Jpeg.Baseline.Snake, PixelTypes.Rgba32, 75, JpegSubsample.Ratio420)]
+ [WithFile(TestImages.Jpeg.Baseline.Lake, PixelTypes.Rgba32, 75, JpegSubsample.Ratio420)]
+ [WithFile(TestImages.Jpeg.Baseline.Snake, PixelTypes.Rgba32, 75, JpegSubsample.Ratio444)]
+ [WithFile(TestImages.Jpeg.Baseline.Lake, PixelTypes.Rgba32, 75, JpegSubsample.Ratio444)]
+ public void LoadResizeSave(TestImageProvider provider, int quality, JpegSubsample subsample)
+ where TPixel : struct, IPixel
+ {
+ using (Image image = provider.GetImage(x => x.Resize(new ResizeOptions { Size = new Size(150, 100), Mode = ResizeMode.Max })))
+ {
+
+ image.MetaData.ExifProfile = null; // Reduce the size of the file
+ JpegEncoder options = new JpegEncoder { Subsample = subsample, Quality = quality };
+
+ provider.Utility.TestName += $"{subsample}_Q{quality}";
+ provider.Utility.SaveTestOutputFile(image, "png");
+ provider.Utility.SaveTestOutputFile(image, "jpg", options);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs
index c8d416beaf..8610356b56 100644
--- a/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs
@@ -10,117 +10,126 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
using System.Collections.Generic;
using System.IO;
+ using SixLabors.ImageSharp.Formats.Bmp;
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.PixelFormats;
- using SixLabors.ImageSharp.Processing;
- using SixLabors.Primitives;
+ using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
+ using SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs;
using Xunit;
using Xunit.Abstractions;
- public class JpegEncoderTests : MeasureFixture
+ public class JpegEncoderTests
{
- public static IEnumerable AllBmpFiles => TestImages.Bmp.All;
+ public static readonly TheoryData BitsPerPixel_Quality =
+ new TheoryData
+ {
+ { JpegSubsample.Ratio420, 40 },
+ { JpegSubsample.Ratio420, 60 },
+ { JpegSubsample.Ratio420, 100 },
+
+ { JpegSubsample.Ratio444, 40 },
+ { JpegSubsample.Ratio444, 60 },
+ { JpegSubsample.Ratio444, 100 },
+ };
- public JpegEncoderTests(ITestOutputHelper output)
- : base(output)
+ [Theory]
+ [WithFile(TestImages.Png.CalliphoraPartial, nameof(BitsPerPixel_Quality), PixelTypes.Rgba32)]
+ [WithTestPatternImages(nameof(BitsPerPixel_Quality), 73, 71, PixelTypes.Rgba32)]
+ [WithTestPatternImages(nameof(BitsPerPixel_Quality), 48, 24, PixelTypes.Rgba32)]
+ [WithTestPatternImages(nameof(BitsPerPixel_Quality), 46, 8, PixelTypes.Rgba32)]
+ [WithTestPatternImages(nameof(BitsPerPixel_Quality), 51, 7, PixelTypes.Rgba32)]
+ [WithSolidFilledImages(nameof(BitsPerPixel_Quality), 1, 1, 255, 100, 50, 255, PixelTypes.Rgba32)]
+ [WithTestPatternImages(nameof(BitsPerPixel_Quality), 7, 5, PixelTypes.Rgba32)]
+ public void EncodeBaseline_WorksWithDifferentSizes(TestImageProvider provider, JpegSubsample subsample, int quality)
+ where TPixel : struct, IPixel
{
+ TestJpegEncoderCore(provider, subsample, quality);
}
[Theory]
- [WithFile(TestImages.Jpeg.Baseline.Snake, PixelTypes.Rgba32, 75, JpegSubsample.Ratio420)]
- [WithFile(TestImages.Jpeg.Baseline.Lake, PixelTypes.Rgba32, 75, JpegSubsample.Ratio420)]
- [WithFile(TestImages.Jpeg.Baseline.Snake, PixelTypes.Rgba32, 75, JpegSubsample.Ratio444)]
- [WithFile(TestImages.Jpeg.Baseline.Lake, PixelTypes.Rgba32, 75, JpegSubsample.Ratio444)]
- public void LoadResizeSave(TestImageProvider provider, int quality, JpegSubsample subsample)
+ [WithTestPatternImages(nameof(BitsPerPixel_Quality), 48, 48, PixelTypes.Rgba32 | PixelTypes.Bgra32)]
+ public void EncodeBaseline_IsNotBoundToSinglePixelType(TestImageProvider provider, JpegSubsample subsample, int quality)
where TPixel : struct, IPixel
{
- using (Image image = provider.GetImage(x => x.Resize(new ResizeOptions { Size = new Size(150, 100), Mode = ResizeMode.Max })))
- {
-
- image.MetaData.ExifProfile = null; // Reduce the size of the file
- JpegEncoder options = new JpegEncoder { Subsample = subsample, Quality = quality };
-
- provider.Utility.TestName += $"{subsample}_Q{quality}";
- provider.Utility.SaveTestOutputFile(image, "png");
- provider.Utility.SaveTestOutputFile(image, "jpg", options);
- }
+ TestJpegEncoderCore(provider, subsample, quality);
}
- [Theory]
- [WithFileCollection(nameof(AllBmpFiles), PixelTypes.Rgba32 | PixelTypes.Rgba32 | PixelTypes.Argb32, JpegSubsample.Ratio420, 75)]
- [WithFileCollection(nameof(AllBmpFiles), PixelTypes.Rgba32 | PixelTypes.Rgba32 | PixelTypes.Argb32, JpegSubsample.Ratio444, 75)]
- public void OpenBmp_SaveJpeg(TestImageProvider provider, JpegSubsample subSample, int quality)
- where TPixel : struct, IPixel
+ private static ImageComparer GetComparer(int quality)
{
- using (Image image = provider.GetImage())
+ if (quality > 90)
{
- ImagingTestCaseUtility utility = provider.Utility;
- utility.TestName += "_" + subSample + "_Q" + quality;
-
- using (FileStream outputStream = File.OpenWrite(utility.GetTestOutputFileName("jpg")))
- {
- image.Save(outputStream, new JpegEncoder()
- {
- Subsample = subSample,
- Quality = quality
- });
- }
+ return ImageComparer.Tolerant(0.0005f / 100);
+ }
+ else if (quality > 50)
+ {
+ return ImageComparer.Tolerant(0.005f / 100);
+ }
+ else
+ {
+ return ImageComparer.Tolerant(0.01f / 100);
}
}
- [Fact]
- public void Encode_IgnoreMetadataIsFalse_ExifProfileIsWritten()
+ private static void TestJpegEncoderCore(
+ TestImageProvider provider,
+ JpegSubsample subsample,
+ int quality = 100)
+ where TPixel : struct, IPixel
{
- JpegEncoder options = new JpegEncoder()
- {
- IgnoreMetadata = false
- };
-
- TestFile testFile = TestFile.Create(TestImages.Jpeg.Baseline.Floorplan);
-
- using (Image input = testFile.CreateImage())
+ using (Image image = provider.GetImage())
{
- using (MemoryStream memStream = new MemoryStream())
- {
- input.Save(memStream, options);
-
- memStream.Position = 0;
- using (Image output = Image.Load(memStream))
- {
- Assert.NotNull(output.MetaData.ExifProfile);
- }
- }
+ // There is no alpha in Jpeg!
+ image.Mutate(c => c.Opacity(1));
+
+ var encoder = new JpegEncoder()
+ {
+ Subsample = subsample,
+ Quality = quality
+ };
+ string info = $"{subsample}-Q{quality}";
+ ImageComparer comparer = GetComparer(quality);
+
+ // Does DebugSave & load reference CompareToReferenceInput():
+ image.VerifyEncoder(provider, "jpeg", info, encoder, comparer, referenceImageExtension: "png");
}
}
+
- [Fact]
- public void Encode_IgnoreMetadataIsTrue_ExifProfileIgnored()
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ public void IgnoreMetadata_ControlsIfExifProfileIsWritten(bool ignoreMetaData)
{
- JpegEncoder options = new JpegEncoder()
+ var encoder = new JpegEncoder()
{
- IgnoreMetadata = true
+ IgnoreMetadata = ignoreMetaData
};
-
- TestFile testFile = TestFile.Create(TestImages.Jpeg.Baseline.Floorplan);
-
- using (Image input = testFile.CreateImage())
+
+ using (Image input = TestFile.Create(TestImages.Jpeg.Baseline.Floorplan).CreateImage())
{
- using (MemoryStream memStream = new MemoryStream())
+ using (var memStream = new MemoryStream())
{
- input.SaveAsJpeg(memStream, options);
+ input.Save(memStream, encoder);
memStream.Position = 0;
- using (Image output = Image.Load(memStream))
+ using (var output = Image.Load(memStream))
{
- Assert.Null(output.MetaData.ExifProfile);
+ if (ignoreMetaData)
+ {
+ Assert.Null(output.MetaData.ExifProfile);
+ }
+ else
+ {
+ Assert.NotNull(output.MetaData.ExifProfile);
+ }
}
}
}
}
-
+
[Fact]
- public void Encode_Quality_0_And_1_Are_Identical()
+ public void Quality_0_And_1_Are_Identical()
{
var options = new JpegEncoder
{
@@ -143,7 +152,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
}
[Fact]
- public void Encode_Quality_0_And_100_Are_Not_Identical()
+ public void Quality_0_And_100_Are_Not_Identical()
{
var options = new JpegEncoder
{
diff --git a/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs b/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs
index fcc28bf4eb..33dbc911e4 100644
--- a/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs
+++ b/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs
@@ -352,16 +352,19 @@ namespace SixLabors.ImageSharp.Tests
object testOutputDetails,
IImageEncoder encoder,
ImageComparer customComparer = null,
- bool appendPixelTypeToFileName = true
+ bool appendPixelTypeToFileName = true,
+ string referenceImageExtension = null
)
where TPixel : struct, IPixel
{
- string path = provider.Utility.SaveTestOutputFile(image, extension, encoder, testOutputDetails, appendPixelTypeToFileName);
-
- IImageDecoder referenceDecoder = TestEnvironment.GetReferenceDecoder(path);
- string referenceOutputFile = provider.Utility.GetReferenceOutputFileName(extension, testOutputDetails, appendPixelTypeToFileName);
+ provider.Utility.SaveTestOutputFile(image, extension, encoder, testOutputDetails, appendPixelTypeToFileName);
+ referenceImageExtension = referenceImageExtension ?? extension;
+ string referenceOutputFile = provider.Utility.GetReferenceOutputFileName(referenceImageExtension, testOutputDetails, appendPixelTypeToFileName);
+
+ IImageDecoder referenceDecoder = TestEnvironment.GetReferenceDecoder(referenceOutputFile);
+
using (var encodedImage = Image.Load(referenceOutputFile, referenceDecoder))
{
ImageComparer comparer = customComparer ?? ImageComparer.Exact;
diff --git a/tests/Images/External b/tests/Images/External
index 06809c1f24..550a157d8a 160000
--- a/tests/Images/External
+++ b/tests/Images/External
@@ -1 +1 @@
-Subproject commit 06809c1f2462332731f2a88bd866d5222f533aa5
+Subproject commit 550a157d8af7a6883646a010c609f9c7c5c015ac