From b176a0ec17b1569471b91855af70f85c5bdc91fc Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Mon, 9 Jul 2018 16:43:48 +1000 Subject: [PATCH] Add bmp and jpeg tests --- src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs | 11 ++- .../Formats/Bmp/BmpDecoderTests.cs | 52 ++++++++++- .../Formats/Bmp/BmpEncoderTests.cs | 49 ++++++++-- .../Formats/Jpg/JpegDecoderTests.MetaData.cs | 88 +++++++++++++----- .../Formats/Jpg/JpegEncoderTests.cs | 65 +++++++++---- .../Formats/Png/PngDecoderTests.cs | 2 - tests/ImageSharp.Tests/TestImages.cs | 16 ++-- tests/Images/Input/Jpg/baseline/ratio-1x1.jpg | Bin 0 -> 34674 bytes 8 files changed, 221 insertions(+), 62 deletions(-) create mode 100644 tests/Images/Input/Jpg/baseline/ratio-1x1.jpg diff --git a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs index d690a3a75e..c135ab6d68 100644 --- a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs +++ b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs @@ -5,6 +5,7 @@ using System; using System.Buffers.Binary; using System.IO; using System.Runtime.CompilerServices; +using SixLabors.ImageSharp.Common.Helpers; using SixLabors.ImageSharp.MetaData; using SixLabors.ImageSharp.PixelFormats; using SixLabors.Memory; @@ -524,13 +525,19 @@ namespace SixLabors.ImageSharp.Formats.Bmp } // Resolution is stored in PPM. - ImageMetaData meta = new ImageMetaData(); + var meta = new ImageMetaData(); + meta.ResolutionUnits = PixelResolutionUnit.PixelsPerMeter; if (this.infoHeader.XPelsPerMeter > 0 && this.infoHeader.YPelsPerMeter > 0) { - meta.ResolutionUnits = PixelResolutionUnit.PixelsPerMeter; meta.HorizontalResolution = this.infoHeader.XPelsPerMeter; meta.VerticalResolution = this.infoHeader.YPelsPerMeter; } + else + { + // Convert default metadata values to PPM. + meta.HorizontalResolution = Math.Round(UnitConverter.InchToMeter(ImageMetaData.DefaultHorizontalResolution)); + meta.VerticalResolution = Math.Round(UnitConverter.InchToMeter(ImageMetaData.DefaultVerticalResolution)); + } this.metaData = meta; diff --git a/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs index b994af0566..09c3d1545f 100644 --- a/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs @@ -10,17 +10,25 @@ using Xunit; namespace SixLabors.ImageSharp.Tests { + using SixLabors.ImageSharp.MetaData; using static TestImages.Bmp; public class BmpDecoderTests { - public const PixelTypes CommonNonDefaultPixelTypes = - PixelTypes.Rgba32 | PixelTypes.Bgra32 | PixelTypes.RgbaVector; + public const PixelTypes CommonNonDefaultPixelTypes = PixelTypes.Rgba32 | PixelTypes.Bgra32 | PixelTypes.RgbaVector; public static readonly string[] AllBmpFiles = - { - Car, F, NegHeight, CoreHeader, V5Header, RLE, RLEInverted, Bit8, Bit8Inverted, Bit16, Bit16Inverted - }; + { + Car, F, NegHeight, CoreHeader, V5Header, RLE, RLEInverted, Bit8, Bit8Inverted, Bit16, Bit16Inverted + }; + + public static readonly TheoryData RatioFiles = + new TheoryData + { + { TestImages.Bmp.Car, 3780, 3780 , PixelResolutionUnit.PixelsPerMeter }, + { TestImages.Bmp.V5Header, 3780, 3780 , PixelResolutionUnit.PixelsPerMeter }, + { TestImages.Bmp.RLE, 2835, 2835, PixelResolutionUnit.PixelsPerMeter } + }; [Theory] [WithFileCollection(nameof(AllBmpFiles), PixelTypes.Rgba32)] @@ -64,5 +72,39 @@ namespace SixLabors.ImageSharp.Tests Assert.Equal(expectedPixelSize, Image.Identify(stream)?.PixelType?.BitsPerPixel); } } + + [Theory] + [MemberData(nameof(RatioFiles))] + public void Decode_VerifyRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit) + { + var testFile = TestFile.Create(imagePath); + using (var stream = new MemoryStream(testFile.Bytes, false)) + { + var decoder = new BmpDecoder(); + using (Image image = decoder.Decode(Configuration.Default, stream)) + { + ImageMetaData meta = image.MetaData; + Assert.Equal(xResolution, meta.HorizontalResolution); + Assert.Equal(yResolution, meta.VerticalResolution); + Assert.Equal(resolutionUnit, meta.ResolutionUnits); + } + } + } + + [Theory] + [MemberData(nameof(RatioFiles))] + public void Identify_VerifyRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit) + { + var testFile = TestFile.Create(imagePath); + using (var stream = new MemoryStream(testFile.Bytes, false)) + { + var decoder = new BmpDecoder(); + IImageInfo image = decoder.Identify(Configuration.Default, stream); + ImageMetaData meta = image.MetaData; + Assert.Equal(xResolution, meta.HorizontalResolution); + Assert.Equal(yResolution, meta.VerticalResolution); + Assert.Equal(resolutionUnit, meta.ResolutionUnits); + } + } } } \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs index 8d29536b26..d887d23ade 100644 --- a/tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs @@ -1,7 +1,9 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using System.IO; using SixLabors.ImageSharp.Formats.Bmp; +using SixLabors.ImageSharp.MetaData; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; using Xunit; @@ -12,11 +14,19 @@ namespace SixLabors.ImageSharp.Tests public class BmpEncoderTests : FileTestBase { public static readonly TheoryData BitsPerPixel = - new TheoryData - { - BmpBitsPerPixel.Pixel24, - BmpBitsPerPixel.Pixel32 - }; + new TheoryData + { + BmpBitsPerPixel.Pixel24, + BmpBitsPerPixel.Pixel32 + }; + + public static readonly TheoryData RatioFiles = + new TheoryData + { + { TestImages.Bmp.Car, 3780, 3780 , PixelResolutionUnit.PixelsPerMeter }, + { TestImages.Bmp.V5Header, 3780, 3780 , PixelResolutionUnit.PixelsPerMeter }, + { TestImages.Bmp.RLE, 2835, 2835, PixelResolutionUnit.PixelsPerMeter } + }; public BmpEncoderTests(ITestOutputHelper output) { @@ -25,6 +35,31 @@ namespace SixLabors.ImageSharp.Tests private ITestOutputHelper Output { get; } + [Theory] + [MemberData(nameof(RatioFiles))] + public void Encode_PreserveRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit) + { + var options = new BmpEncoder(); + + var testFile = TestFile.Create(imagePath); + using (Image input = testFile.CreateImage()) + { + using (var memStream = new MemoryStream()) + { + input.Save(memStream, options); + + memStream.Position = 0; + using (var output = Image.Load(memStream)) + { + ImageMetaData meta = output.MetaData; + Assert.Equal(xResolution, meta.HorizontalResolution); + Assert.Equal(yResolution, meta.VerticalResolution); + Assert.Equal(resolutionUnit, meta.ResolutionUnits); + } + } + } + } + [Theory] [WithTestPatternImages(nameof(BitsPerPixel), 24, 24, PixelTypes.Rgba32 | PixelTypes.Bgra32 | PixelTypes.Rgb24)] public void Encode_IsNotBoundToSinglePixelType(TestImageProvider provider, BmpBitsPerPixel bitsPerPixel) @@ -44,10 +79,10 @@ namespace SixLabors.ImageSharp.Tests { TestBmpEncoderCore(provider, bitsPerPixel); } - + private static void TestBmpEncoderCore(TestImageProvider provider, BmpBitsPerPixel bitsPerPixel) where TPixel : struct, IPixel - { + { using (Image image = provider.GetImage()) { // there is no alpha in bmp! diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.MetaData.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.MetaData.cs index 10b098d924..f217f0df14 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.MetaData.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.MetaData.cs @@ -15,30 +15,39 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg using System.Runtime.CompilerServices; using SixLabors.ImageSharp.Formats.Jpeg; + using SixLabors.ImageSharp.MetaData; public partial class JpegDecoderTests { // TODO: A JPEGsnoop & metadata expert should review if the Exif/Icc expectations are correct. // I'm seeing several entries with Exif-related names in images where we do not decode an exif profile. (- Anton) public static readonly TheoryData MetaDataTestData = - new TheoryData - { - { false, TestImages.Jpeg.Progressive.Progress, 24, false, false }, - { false, TestImages.Jpeg.Progressive.Fb, 24, false, true }, - { false, TestImages.Jpeg.Baseline.Cmyk, 32, false, true }, - { false, TestImages.Jpeg.Baseline.Ycck, 32, true, true }, - { false, TestImages.Jpeg.Baseline.Jpeg400, 8, false, false }, - { false, TestImages.Jpeg.Baseline.Snake, 24, true, true }, - { false, TestImages.Jpeg.Baseline.Jpeg420Exif, 24, true, false }, - - { true, TestImages.Jpeg.Progressive.Progress, 24, false, false }, - { true, TestImages.Jpeg.Progressive.Fb, 24, false, true }, - { true, TestImages.Jpeg.Baseline.Cmyk, 32, false, true }, - { true, TestImages.Jpeg.Baseline.Ycck, 32, true, true }, - { true, TestImages.Jpeg.Baseline.Jpeg400, 8, false, false }, - { true, TestImages.Jpeg.Baseline.Snake, 24, true, true }, - { true, TestImages.Jpeg.Baseline.Jpeg420Exif, 24, true, false }, - }; + new TheoryData + { + { false, TestImages.Jpeg.Progressive.Progress, 24, false, false }, + { false, TestImages.Jpeg.Progressive.Fb, 24, false, true }, + { false, TestImages.Jpeg.Baseline.Cmyk, 32, false, true }, + { false, TestImages.Jpeg.Baseline.Ycck, 32, true, true }, + { false, TestImages.Jpeg.Baseline.Jpeg400, 8, false, false }, + { false, TestImages.Jpeg.Baseline.Snake, 24, true, true }, + { false, TestImages.Jpeg.Baseline.Jpeg420Exif, 24, true, false }, + + { true, TestImages.Jpeg.Progressive.Progress, 24, false, false }, + { true, TestImages.Jpeg.Progressive.Fb, 24, false, true }, + { true, TestImages.Jpeg.Baseline.Cmyk, 32, false, true }, + { true, TestImages.Jpeg.Baseline.Ycck, 32, true, true }, + { true, TestImages.Jpeg.Baseline.Jpeg400, 8, false, false }, + { true, TestImages.Jpeg.Baseline.Snake, 24, true, true }, + { true, TestImages.Jpeg.Baseline.Jpeg420Exif, 24, true, false }, + }; + + public static readonly TheoryData RatioFiles = + new TheoryData + { + { TestImages.Jpeg.Baseline.Ratio1x1, 1, 1 , PixelResolutionUnit.AspectRatio}, + { TestImages.Jpeg.Baseline.Snake, 300, 300 , PixelResolutionUnit.PixelsPerInch}, + { TestImages.Jpeg.Baseline.GammaDalaiLamaGray, 72, 72, PixelResolutionUnit.PixelsPerInch } + }; [Theory] [MemberData(nameof(MetaDataTestData))] @@ -76,14 +85,49 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg iccProfilePresent); } + [Theory] + [MemberData(nameof(RatioFiles))] + public void Decode_VerifyRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit) + { + var testFile = TestFile.Create(imagePath); + using (var stream = new MemoryStream(testFile.Bytes, false)) + { + var decoder = new JpegDecoder(); + using (Image image = decoder.Decode(Configuration.Default, stream)) + { + ImageMetaData meta = image.MetaData; + Assert.Equal(xResolution, meta.HorizontalResolution); + Assert.Equal(yResolution, meta.VerticalResolution); + Assert.Equal(resolutionUnit, meta.ResolutionUnits); + } + } + } + + [Theory] + [MemberData(nameof(RatioFiles))] + public void Identify_VerifyRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit) + { + var testFile = TestFile.Create(imagePath); + using (var stream = new MemoryStream(testFile.Bytes, false)) + { + var decoder = new JpegDecoder(); + IImageInfo image = decoder.Identify(Configuration.Default, stream); + ImageMetaData meta = image.MetaData; + Assert.Equal(xResolution, meta.HorizontalResolution); + Assert.Equal(yResolution, meta.VerticalResolution); + Assert.Equal(resolutionUnit, meta.ResolutionUnits); + } + } + 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); + ? ((IImageInfoDetector)decoder).Identify(Configuration.Default, stream) + : decoder.Decode(Configuration.Default, stream); + test(imageInfo); } } @@ -141,7 +185,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg } }); } - + [Theory] [InlineData(false)] [InlineData(true)] @@ -166,7 +210,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg } } } - + [Theory] [InlineData(false)] [InlineData(true)] diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs index 911812ebb2..a31ae37b75 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs @@ -3,6 +3,7 @@ using System.IO; using SixLabors.ImageSharp.Formats.Jpeg; +using SixLabors.ImageSharp.MetaData; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; @@ -14,16 +15,24 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg public class JpegEncoderTests { public static readonly TheoryData BitsPerPixel_Quality = - new TheoryData - { - { JpegSubsample.Ratio420, 40 }, - { JpegSubsample.Ratio420, 60 }, - { JpegSubsample.Ratio420, 100 }, + new TheoryData + { + { JpegSubsample.Ratio420, 40 }, + { JpegSubsample.Ratio420, 60 }, + { JpegSubsample.Ratio420, 100 }, - { JpegSubsample.Ratio444, 40 }, - { JpegSubsample.Ratio444, 60 }, - { JpegSubsample.Ratio444, 100 }, - }; + { JpegSubsample.Ratio444, 40 }, + { JpegSubsample.Ratio444, 60 }, + { JpegSubsample.Ratio444, 100 }, + }; + + public static readonly TheoryData RatioFiles = + new TheoryData + { + { TestImages.Jpeg.Baseline.Ratio1x1, 1, 1 , PixelResolutionUnit.AspectRatio}, + { TestImages.Jpeg.Baseline.Snake, 300, 300 , PixelResolutionUnit.PixelsPerInch}, + { TestImages.Jpeg.Baseline.GammaDalaiLamaGray, 72, 72, PixelResolutionUnit.PixelsPerInch } + }; [Theory] [WithFile(TestImages.Png.CalliphoraPartial, nameof(BitsPerPixel_Quality), PixelTypes.Rgba32)] @@ -82,10 +91,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg image.Mutate(c => c.MakeOpaque()); var encoder = new JpegEncoder() - { - Subsample = subsample, - Quality = quality - }; + { + Subsample = subsample, + Quality = quality + }; string info = $"{subsample}-Q{quality}"; ImageComparer comparer = GetComparer(quality, subsample); @@ -93,7 +102,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg image.VerifyEncoder(provider, "jpeg", info, encoder, comparer, referenceImageExtension: "png"); } } - [Theory] [InlineData(false)] @@ -104,7 +112,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg { IgnoreMetadata = ignoreMetaData }; - + using (Image input = TestFile.Create(TestImages.Jpeg.Baseline.Floorplan).CreateImage()) { using (var memStream = new MemoryStream()) @@ -126,7 +134,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg } } } - + [Fact] public void Quality_0_And_1_Are_Identical() { @@ -172,5 +180,30 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg Assert.NotEqual(memStream0.ToArray(), memStream1.ToArray()); } } + + [Theory] + [MemberData(nameof(RatioFiles))] + public void Encode_PreserveRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit) + { + var options = new JpegEncoder(); + + var testFile = TestFile.Create(imagePath); + using (Image input = testFile.CreateImage()) + { + using (var memStream = new MemoryStream()) + { + input.Save(memStream, options); + + memStream.Position = 0; + using (var output = Image.Load(memStream)) + { + ImageMetaData meta = output.MetaData; + Assert.Equal(xResolution, meta.HorizontalResolution); + Assert.Equal(yResolution, meta.VerticalResolution); + Assert.Equal(resolutionUnit, meta.ResolutionUnits); + } + } + } + } } } \ No newline at end of file diff --git a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs index d2672fe245..54f3e397c3 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs @@ -20,8 +20,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png { private const PixelTypes PixelTypes = Tests.PixelTypes.Rgba32 | Tests.PixelTypes.RgbaVector | Tests.PixelTypes.Argb32; - - public static readonly string[] CommonTestImages = { TestImages.Png.Splash, diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index 9c9848d246..142b923ed1 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -82,7 +82,7 @@ namespace SixLabors.ImageSharp.Tests Powerpoint, SplashInterlaced, Interlaced, Filter0, Filter1, Filter2, Filter3, Filter4, FilterVar, VimImage1, VimImage2, VersioningImage1, - VersioningImage2 + VersioningImage2, Ratio4x1, Ratio1x4 }; } @@ -127,13 +127,14 @@ namespace SixLabors.ImageSharp.Tests public const string Jpeg420Small = "Jpg/baseline/jpeg420small.jpg"; public const string Testorig420 = "Jpg/baseline/testorig.jpg"; public const string MultiScanBaselineCMYK = "Jpg/baseline/MultiScanBaselineCMYK.jpg"; + public const string Ratio1x1 = "Jpg/baseline/ratio-1x1.jpg"; public static readonly string[] All = - { - Cmyk, Ycck, Exif, Floorplan, - Calliphora, Turtle, GammaDalaiLamaGray, - Hiyamugi, Jpeg400, Jpeg420Exif, Jpeg444, - }; + { + Cmyk, Ycck, Exif, Floorplan, + Calliphora, Turtle, GammaDalaiLamaGray, + Hiyamugi, Jpeg400, Jpeg420Exif, Jpeg444, Ratio1x1 + }; } public static class Issues @@ -182,8 +183,7 @@ namespace SixLabors.ImageSharp.Tests public const string Ratio4x1 = "Gif/base_4x1.gif"; public const string Ratio1x4 = "Gif/base_1x4.gif"; - - public class Issues + public static class Issues { public const string BadAppExtLength = "Gif/issues/issue405_badappextlength252.gif"; public const string BadAppExtLength_2 = "Gif/issues/issue405_badappextlength252-2.gif"; diff --git a/tests/Images/Input/Jpg/baseline/ratio-1x1.jpg b/tests/Images/Input/Jpg/baseline/ratio-1x1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0162ac9aedba988372e8bdf055c6862e47c3db3e GIT binary patch literal 34674 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 literal 0 HcmV?d00001