// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // // ReSharper disable InconsistentNaming namespace ImageSharp.Tests { using System; using System.IO; using ImageSharp.Formats; using ImageSharp.PixelFormats; using ImageSharp.Tests.TestUtilities.ImageComparison; using Xunit; public class JpegDecoderTests { public static string[] BaselineTestJpegs = { TestImages.Jpeg.Baseline.Calliphora, TestImages.Jpeg.Baseline.Cmyk, TestImages.Jpeg.Baseline.Jpeg400, TestImages.Jpeg.Baseline.Jpeg444, TestImages.Jpeg.Baseline.Testimgorig }; public static string[] ProgressiveTestJpegs = TestImages.Jpeg.Progressive.All; // TODO: We should make this comparer less tolerant ... private static readonly ImageComparer VeryTolerantJpegComparer = ImageComparer.Tolerant(0.005f, pixelThresholdInPixelByteSum: 4); [Theory] [WithFileCollection(nameof(BaselineTestJpegs), PixelTypes.Rgba32 | PixelTypes.Rgba32 | PixelTypes.Argb32)] public void DecodeBaselineJpeg(TestImageProvider provider) where TPixel : struct, IPixel { using (Image image = provider.GetImage()) { image.DebugSave(provider); image.CompareToReferenceOutput(provider, VeryTolerantJpegComparer, appendPixelTypeToFileName: false); } } [Theory] [WithFileCollection(nameof(ProgressiveTestJpegs), PixelTypes.Rgba32 | PixelTypes.Rgba32 | PixelTypes.Argb32)] public void DecodeProgressiveJpeg(TestImageProvider provider) where TPixel : struct, IPixel { using (Image image = provider.GetImage()) { image.DebugSave(provider, VeryTolerantJpegComparer); } } [Theory] [WithSolidFilledImages(16, 16, 255, 0, 0, PixelTypes.Rgba32, JpegSubsample.Ratio420, 75)] [WithSolidFilledImages(16, 16, 255, 0, 0, PixelTypes.Rgba32, JpegSubsample.Ratio420, 100)] [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( TestImageProvider provider, JpegSubsample subsample, int quality) where TPixel : struct, IPixel { byte[] data; using (Image image = provider.GetImage()) { JpegEncoder encoder = new JpegEncoder { Subsample = subsample, Quality = quality }; data = new byte[65536]; using (MemoryStream ms = new MemoryStream(data)) { image.Save(ms, encoder); } } Image mirror = Image.Load(data); mirror.DebugSave(provider, $"_{subsample}_Q{quality}"); } [Theory] [WithSolidFilledImages(42, 88, 255, 0, 0, PixelTypes.Rgba32)] public void DecodeGenerated_MetadataOnly( TestImageProvider provider) where TPixel : struct, IPixel { using (Image image = provider.GetImage()) { using (MemoryStream ms = new MemoryStream()) { image.Save(ms, new JpegEncoder()); ms.Seek(0, SeekOrigin.Begin); using (JpegDecoderCore decoder = new JpegDecoderCore(null, new JpegDecoder())) { Image mirror = decoder.Decode(ms); Assert.Equal(decoder.ImageWidth, image.Width); Assert.Equal(decoder.ImageHeight, image.Height); } } } } [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.Jpeg420).CreateImage()) { Assert.Equal(72, image.MetaData.HorizontalResolution); Assert.Equal(72, image.MetaData.VerticalResolution); } } [Fact] public void Decode_IgnoreMetadataIsFalse_ExifProfileIsRead() { JpegDecoder decoder = new JpegDecoder() { IgnoreMetadata = false }; TestFile testFile = TestFile.Create(TestImages.Jpeg.Baseline.Floorplan); using (Image image = testFile.CreateImage(decoder)) { Assert.NotNull(image.MetaData.ExifProfile); } } [Fact] public void Decode_IgnoreMetadataIsTrue_ExifProfileIgnored() { JpegDecoder options = new JpegDecoder() { IgnoreMetadata = true }; TestFile testFile = TestFile.Create(TestImages.Jpeg.Baseline.Floorplan); using (Image image = testFile.CreateImage(options)) { Assert.Null(image.MetaData.ExifProfile); } } } }