diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoder.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/GolangJpegDecoder.cs similarity index 92% rename from src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoder.cs rename to src/ImageSharp/Formats/Jpeg/GolangPort/GolangJpegDecoder.cs index 03afa770fc..29255204b4 100644 --- a/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoder.cs +++ b/src/ImageSharp/Formats/Jpeg/GolangPort/GolangJpegDecoder.cs @@ -9,7 +9,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort /// /// Image decoder for generating an image out of a jpg stream. /// - internal sealed class OrigJpegDecoder : IImageDecoder, IJpegDecoderOptions, IImageInfoDetector + internal sealed class GolangJpegDecoder : IImageDecoder, IJpegDecoderOptions, IImageInfoDetector { /// /// Gets or sets a value indicating whether the metadata should be ignored when the image is being decoded. diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg.cs index 47325476cf..f86919dd15 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg.cs @@ -49,7 +49,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg { using (var memoryStream = new MemoryStream(this.jpegBytes)) { - using (var image = Image.Load(memoryStream, new OrigJpegDecoder())) + using (var image = Image.Load(memoryStream, new GolangJpegDecoder())) { return new CoreSize(image.Width, image.Height); } diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpegMultiple.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpegMultiple.cs index a1083e8ebf..c4ee732f5e 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpegMultiple.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpegMultiple.cs @@ -24,7 +24,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg [Benchmark(Description = "DecodeJpegMultiple - ImageSharp")] public void DecodeJpegImageSharpOrig() { - this.ForEachStream(ms => Image.Load(ms, new OrigJpegDecoder())); + this.ForEachStream(ms => Image.Load(ms, new GolangJpegDecoder())); } [Benchmark(Description = "DecodeJpegMultiple - ImageSharp PDFJs")] diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/IdentifyJpeg.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/IdentifyJpeg.cs index c3c1281001..b6ad20d128 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/IdentifyJpeg.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/IdentifyJpeg.cs @@ -33,7 +33,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg { using (var memoryStream = new MemoryStream(this.jpegBytes)) { - var decoder = new OrigJpegDecoder(); + var decoder = new GolangJpegDecoder(); return decoder.Identify(Configuration.Default, memoryStream); } diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.MetaData.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.MetaData.cs index 7fc949b091..c65bc8e23e 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.MetaData.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.MetaData.cs @@ -11,6 +11,7 @@ using Xunit; // ReSharper disable InconsistentNaming namespace SixLabors.ImageSharp.Tests.Formats.Jpg { + using System; using System.Runtime.CompilerServices; using SixLabors.ImageSharp.Formats.Jpeg; @@ -50,7 +51,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg { TestMetaDataImpl( useIdentify, - OrigJpegDecoder, + GolangJpegDecoder, imagePath, expectedPixelSize, exifProfilePresent, @@ -75,6 +76,18 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg iccProfilePresent); } + private static void TestImageInfo(string imagePath, IImageDecoder decoder, bool useIdentify, Action test) + { + var testFile = TestFile.Create(imagePath); + using (var stream = new MemoryStream(testFile.Bytes, false)) + { + IImageInfo imageInfo = useIdentify + ? ((IImageInfoDetector)decoder).Identify(Configuration.Default, stream) + : decoder.Decode(Configuration.Default, stream); + test(imageInfo); + } + } + private static void TestMetaDataImpl( bool useIdentify, IImageDecoder decoder, @@ -83,51 +96,50 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg bool exifProfilePresent, bool iccProfilePresent) { - var testFile = TestFile.Create(imagePath); - using (var stream = new MemoryStream(testFile.Bytes, false)) - { - IImageInfo imageInfo = useIdentify - ? ((IImageInfoDetector)decoder).Identify(Configuration.Default, stream) - : decoder.Decode(Configuration.Default, stream); + TestImageInfo( + imagePath, + decoder, + useIdentify, + imageInfo => + { + Assert.NotNull(imageInfo); + Assert.NotNull(imageInfo.PixelType); - Assert.NotNull(imageInfo); - Assert.NotNull(imageInfo.PixelType); - - if (useIdentify) - { - Assert.Equal(expectedPixelSize, imageInfo.PixelType.BitsPerPixel); - } - else - { - // When full Image decoding is performed, BitsPerPixel will match TPixel - int bpp32 = Unsafe.SizeOf() * 8; - Assert.Equal(bpp32, imageInfo.PixelType.BitsPerPixel); - } + if (useIdentify) + { + Assert.Equal(expectedPixelSize, imageInfo.PixelType.BitsPerPixel); + } + else + { + // When full Image decoding is performed, BitsPerPixel will match TPixel + int bpp32 = Unsafe.SizeOf() * 8; + Assert.Equal(bpp32, imageInfo.PixelType.BitsPerPixel); + } - ExifProfile exifProfile = imageInfo.MetaData.ExifProfile; + ExifProfile exifProfile = imageInfo.MetaData.ExifProfile; - if (exifProfilePresent) - { - Assert.NotNull(exifProfile); - Assert.NotEmpty(exifProfile.Values); - } - else - { - Assert.Null(exifProfile); - } + if (exifProfilePresent) + { + Assert.NotNull(exifProfile); + Assert.NotEmpty(exifProfile.Values); + } + else + { + Assert.Null(exifProfile); + } - IccProfile iccProfile = imageInfo.MetaData.IccProfile; + IccProfile iccProfile = imageInfo.MetaData.IccProfile; - if (iccProfilePresent) - { - Assert.NotNull(iccProfile); - Assert.NotEmpty(iccProfile.Entries); - } - else - { - Assert.Null(iccProfile); - } - } + if (iccProfilePresent) + { + Assert.NotNull(iccProfile); + Assert.NotEmpty(iccProfile.Entries); + } + else + { + Assert.Null(iccProfile); + } + }); } [Theory] @@ -154,5 +166,37 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg } } } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public void Decoder_Reads_Correct_Resolution_From_Jfif(bool useIdentify) + { + TestImageInfo(TestImages.Jpeg.Baseline.Floorplan, DefaultJpegDecoder, useIdentify, + imageInfo => + { + Assert.Equal(300, imageInfo.MetaData.HorizontalResolution); + Assert.Equal(300, imageInfo.MetaData.VerticalResolution); + }); + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public void Decoder_Reads_Correct_Resolution_From_Exif(bool useIdentify) + { + TestImageInfo(TestImages.Jpeg.Baseline.Jpeg420Exif, DefaultJpegDecoder, useIdentify, + imageInfo => + { + Assert.Equal(72, imageInfo.MetaData.HorizontalResolution); + Assert.Equal(72, imageInfo.MetaData.VerticalResolution); + }); + + using (Image image = TestFile.Create(TestImages.Jpeg.Baseline.Jpeg420Exif).CreateImage()) + { + Assert.Equal(72, image.MetaData.HorizontalResolution); + Assert.Equal(72, image.MetaData.VerticalResolution); + } + } } } \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs index 3138300b90..f3744acfdf 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs @@ -115,10 +115,12 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg private ITestOutputHelper Output { get; } - private static OrigJpegDecoder OrigJpegDecoder => new OrigJpegDecoder(); + private static GolangJpegDecoder GolangJpegDecoder => new GolangJpegDecoder(); private static PdfJsJpegDecoder PdfJsJpegDecoder => new PdfJsJpegDecoder(); + private static JpegDecoder DefaultJpegDecoder => new JpegDecoder(); + [Fact] public void ParseStream_BasicPropertiesAreCorrect1_PdfJs() { @@ -151,7 +153,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg // For 32 bit test enviroments: provider.Configuration.MemoryManager = ArrayPoolMemoryManager.CreateWithModeratePooling(); - IImageDecoder decoder = useOldDecoder ? (IImageDecoder)OrigJpegDecoder : PdfJsJpegDecoder; + IImageDecoder decoder = useOldDecoder ? (IImageDecoder)GolangJpegDecoder : PdfJsJpegDecoder; using (Image image = provider.GetImage(decoder)) { image.DebugSave(provider); @@ -176,7 +178,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg // For 32 bit test enviroments: provider.Configuration.MemoryManager = ArrayPoolMemoryManager.CreateWithModeratePooling(); - using (Image image = provider.GetImage(OrigJpegDecoder)) + using (Image image = provider.GetImage(GolangJpegDecoder)) { image.DebugSave(provider); provider.Utility.TestName = DecodeBaselineJpegOutputName; @@ -240,11 +242,20 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg [Theory] [WithFile(TestImages.Jpeg.Issues.CriticalEOF214, PixelTypes.Rgba32)] - public void DecodeBaselineJpeg_CriticalEOF_ShouldThrow_Orig(TestImageProvider provider) + public void DecodeBaselineJpeg_CriticalEOF_ShouldThrow_Golang(TestImageProvider provider) where TPixel : struct, IPixel { // TODO: We need a public ImageDecoderException class in ImageSharp! - Assert.ThrowsAny(() => provider.GetImage(OrigJpegDecoder)); + Assert.ThrowsAny(() => provider.GetImage(GolangJpegDecoder)); + } + + [Theory] + [WithFile(TestImages.Jpeg.Issues.CriticalEOF214, PixelTypes.Rgba32)] + public void DecodeBaselineJpeg_CriticalEOF_ShouldThrow_PdfJs(TestImageProvider provider) + where TPixel : struct, IPixel + { + // TODO: We need a public ImageDecoderException class in ImageSharp! + Assert.ThrowsAny(() => provider.GetImage(PdfJsJpegDecoder)); } public const string DecodeProgressiveJpegOutputName = "DecodeProgressiveJpeg"; @@ -254,15 +265,16 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg public void DecodeProgressiveJpeg_Orig(TestImageProvider provider) where TPixel : struct, IPixel { - if (SkipTest(provider)) + if (TestEnvironment.RunsOnCI && !TestEnvironment.Is64BitProcess) { + // skipping to avoid OutOfMemoryException on CI return; } - + // For 32 bit test enviroments: provider.Configuration.MemoryManager = ArrayPoolMemoryManager.CreateWithModeratePooling(); - using (Image image = provider.GetImage(OrigJpegDecoder)) + using (Image image = provider.GetImage(GolangJpegDecoder)) { image.DebugSave(provider); @@ -281,7 +293,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg public void DecodeProgressiveJpeg_PdfJs(TestImageProvider provider) where TPixel : struct, IPixel { - if (TestEnvironment.RunsOnCI && !TestEnvironment.Is64BitProcess) + if (SkipTest(provider)) { // skipping to avoid OutOfMemoryException on CI return; @@ -329,7 +341,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg this.Output.WriteLine(provider.SourceFileOrDescription); provider.Utility.TestName = testName; - using (Image image = provider.GetImage(OrigJpegDecoder)) + using (Image image = provider.GetImage(GolangJpegDecoder)) { string d = this.GetDifferenceInPercentageString(image, provider); @@ -365,7 +377,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg [WithSolidFilledImages(16, 16, 255, 0, 0, PixelTypes.Rgba32, JpegSubsample.Ratio444, 75)] [WithSolidFilledImages(16, 16, 255, 0, 0, PixelTypes.Rgba32, JpegSubsample.Ratio444, 100)] [WithSolidFilledImages(8, 8, 255, 0, 0, PixelTypes.Rgba32, JpegSubsample.Ratio444, 100)] - public void DecodeGenerated_Orig( + public void DecodeGenerated( TestImageProvider provider, JpegSubsample subsample, int quality) @@ -383,30 +395,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg } } - var mirror = Image.Load(data, OrigJpegDecoder); + var mirror = Image.Load(data, GolangJpegDecoder); mirror.DebugSave(provider, $"_{subsample}_Q{quality}"); } - [Fact] - public void Decoder_Reads_Correct_Resolution_From_Jfif() - { - using (Image image = TestFile.Create(TestImages.Jpeg.Baseline.Floorplan).CreateImage()) - { - Assert.Equal(300, image.MetaData.HorizontalResolution); - Assert.Equal(300, image.MetaData.VerticalResolution); - } - } - - [Fact] - public void Decoder_Reads_Correct_Resolution_From_Exif() - { - using (Image image = TestFile.Create(TestImages.Jpeg.Baseline.Jpeg420Exif).CreateImage()) - { - Assert.Equal(72, image.MetaData.HorizontalResolution); - Assert.Equal(72, image.MetaData.VerticalResolution); - } - } - // DEBUG ONLY! // The PDF.js output should be saved by "tests\ImageSharp.Tests\Formats\Jpg\pdfjs\jpeg-converter.htm" // into "\tests\Images\ActualOutput\JpegDecoderTests\" diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegProfilingBenchmarks.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegProfilingBenchmarks.cs index 49c76dc4ec..b0f342f5ab 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegProfilingBenchmarks.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegProfilingBenchmarks.cs @@ -38,7 +38,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg //[MemberData(nameof(DecodeJpegData))] public void DecodeJpeg_Original(string fileName) { - this.DecodeJpegBenchmarkImpl(fileName, new OrigJpegDecoder()); + this.DecodeJpegBenchmarkImpl(fileName, new GolangJpegDecoder()); } // [Theory] // Benchmark, enable manually diff --git a/tests/ImageSharp.Tests/Formats/Jpg/SpectralJpegTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/SpectralJpegTests.cs index 26b9a06cb1..811af96757 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/SpectralJpegTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/SpectralJpegTests.cs @@ -40,7 +40,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg public static readonly string[] AllTestJpegs = BaselineTestJpegs.Concat(ProgressiveTestJpegs).ToArray(); - [Theory] + [Theory(Skip = "Debug only, enable manually!")] [WithFileCollection(nameof(AllTestJpegs), PixelTypes.Rgba32)] public void PdfJsDecoder_ParseStream_SaveSpectralResult(TestImageProvider provider) where TPixel : struct, IPixel @@ -58,7 +58,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg } } - [Theory] + [Theory(Skip = "Debug only, enable manually!")] [WithFileCollection(nameof(AllTestJpegs), PixelTypes.Rgba32)] public void OriginalDecoder_ParseStream_SaveSpectralResult(TestImageProvider provider) where TPixel : struct, IPixel @@ -81,7 +81,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg LibJpegTools.SpectralData imageSharpData) where TPixel : struct, IPixel { - var libJpegData = LibJpegTools.ExtractSpectralData(provider.SourceFileOrDescription); + LibJpegTools.SpectralData libJpegData = LibJpegTools.ExtractSpectralData(provider.SourceFileOrDescription); bool equality = libJpegData.Equals(imageSharpData); this.Output.WriteLine("Spectral data equality: " + equality); @@ -145,7 +145,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg [Theory] [WithFileCollection(nameof(AllTestJpegs), PixelTypes.Rgba32)] - public void VerifySpectralResults_OriginalDecoder(TestImageProvider provider) + public void VerifySpectralCorrectness_Golang(TestImageProvider provider) where TPixel : struct, IPixel { if (!TestEnvironment.IsWindows) @@ -153,7 +153,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg return; } - var decoder = new GolangJpegDecoderCore(Configuration.Default, new JpegDecoder()); + var decoder = new GolangJpegDecoderCore(Configuration.Default, new GolangJpegDecoder()); byte[] sourceBytes = TestFile.Create(provider.SourceFileOrDescription).Bytes;