From f7cf568a30b826f39a903141be8564b7da3f95e7 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Thu, 23 Aug 2018 21:09:50 +0100 Subject: [PATCH 1/3] Add image blending tests to match the SVG spec examples --- .../ImageSharp.Tests/Drawing/DrawImageTest.cs | 53 ++++++++++++++++--- tests/ImageSharp.Tests/TestImages.cs | 3 ++ tests/Images/External | 2 +- tests/Images/Input/Png/ducky.png | 3 ++ tests/Images/Input/Png/rainbow.png | 3 ++ 5 files changed, 57 insertions(+), 7 deletions(-) create mode 100644 tests/Images/Input/Png/ducky.png create mode 100644 tests/Images/Input/Png/rainbow.png diff --git a/tests/ImageSharp.Tests/Drawing/DrawImageTest.cs b/tests/ImageSharp.Tests/Drawing/DrawImageTest.cs index 740b30a8c3..496692d969 100644 --- a/tests/ImageSharp.Tests/Drawing/DrawImageTest.cs +++ b/tests/ImageSharp.Tests/Drawing/DrawImageTest.cs @@ -5,14 +5,14 @@ using System; using System.Numerics; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; +using SixLabors.ImageSharp.Processing.Processors.Transforms; +using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; using SixLabors.Primitives; using Xunit; namespace SixLabors.ImageSharp.Tests { - using SixLabors.ImageSharp.Processing; - using SixLabors.ImageSharp.Processing.Processors.Transforms; - + [GroupOutput("Drawing")] public class DrawImageTest : FileTestBase { private const PixelTypes PixelTypes = Tests.PixelTypes.Rgba32; @@ -41,11 +41,32 @@ namespace SixLabors.ImageSharp.Tests using (var blend = Image.Load(TestFile.Create(TestImages.Bmp.Car).Bytes)) { blend.Mutate(x => x.Resize(image.Width / 2, image.Height / 2)); - image.Mutate(x => x.DrawImage(blend, new Point(image.Width / 4, image.Height / 4), mode, .75f) ); + image.Mutate(x => x.DrawImage(blend, new Point(image.Width / 4, image.Height / 4), mode, .75f)); image.DebugSave(provider, new { mode }); } } + [Theory] + [WithFile(TestImages.Png.Rainbow, PixelTypes, PixelColorBlendingMode.Normal)] + [WithFile(TestImages.Png.Rainbow, PixelTypes, PixelColorBlendingMode.Multiply)] + [WithFile(TestImages.Png.Rainbow, PixelTypes, PixelColorBlendingMode.Add)] + [WithFile(TestImages.Png.Rainbow, PixelTypes, PixelColorBlendingMode.Subtract)] + [WithFile(TestImages.Png.Rainbow, PixelTypes, PixelColorBlendingMode.Screen)] + [WithFile(TestImages.Png.Rainbow, PixelTypes, PixelColorBlendingMode.Darken)] + [WithFile(TestImages.Png.Rainbow, PixelTypes, PixelColorBlendingMode.Lighten)] + [WithFile(TestImages.Png.Rainbow, PixelTypes, PixelColorBlendingMode.Overlay)] + [WithFile(TestImages.Png.Rainbow, PixelTypes, PixelColorBlendingMode.HardLight)] + public void ImageBlendingMatchesSvgSpecExamples(TestImageProvider provider, PixelColorBlendingMode mode) + where TPixel : struct, IPixel + { + using (Image background = provider.GetImage()) + using (var source = Image.Load(TestFile.Create(TestImages.Png.Ducky).Bytes)) + { + background.Mutate(x => x.DrawImage(source, mode, 1F)); + VerifyImage(provider, mode, background); + } + } + [Theory] [WithFileCollection(nameof(TestFiles), PixelTypes, PixelColorBlendingMode.Normal)] public void ImageShouldDrawTransformedImage(TestImageProvider provider, PixelColorBlendingMode mode) @@ -84,7 +105,7 @@ namespace SixLabors.ImageSharp.Tests { overlay.Mutate(x => x.Fill(Rgba32.Black)); - int xy = -25; + const int xy = -25; Rgba32 backgroundPixel = background[0, 0]; Rgba32 overlayPixel = overlay[Math.Abs(xy) + 1, Math.Abs(xy) + 1]; @@ -106,7 +127,7 @@ namespace SixLabors.ImageSharp.Tests { overlay.Mutate(x => x.Fill(Rgba32.Black)); - int xy = 25; + const int xy = 25; Rgba32 backgroundPixel = background[xy - 1, xy - 1]; Rgba32 overlayPixel = overlay[0, 0]; @@ -118,5 +139,25 @@ namespace SixLabors.ImageSharp.Tests background.DebugSave(provider, testOutputDetails: "Positive"); } } + + private static void VerifyImage( + TestImageProvider provider, + PixelColorBlendingMode mode, + Image img) + where TPixel : struct, IPixel + { + img.DebugSave( + provider, + new { mode }, + appendPixelTypeToFileName: false, + appendSourceFileOrDescription: false); + + var comparer = ImageComparer.TolerantPercentage(0.01F, 3); + img.CompareFirstFrameToReferenceOutput(comparer, + provider, + new { mode }, + appendPixelTypeToFileName: false, + appendSourceFileOrDescription: false); + } } } \ No newline at end of file diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index 5eb70117e3..1ee3f96757 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -68,6 +68,9 @@ namespace SixLabors.ImageSharp.Tests public const string Ratio1x4 = "Png/ratio-1x4.png"; public const string Ratio4x1 = "Png/ratio-4x1.png"; + public const string Ducky = "Png/ducky.png"; + public const string Rainbow = "Png/rainbow.png"; + public static class Bad { // Odd chunk lengths diff --git a/tests/Images/External b/tests/Images/External index 6a43d335f2..fcf311bf15 160000 --- a/tests/Images/External +++ b/tests/Images/External @@ -1 +1 @@ -Subproject commit 6a43d335f216d6325a6a9fd8d35942ade12b7c7b +Subproject commit fcf311bf15bea061e552e4cc357cafe2d4f4bd70 diff --git a/tests/Images/Input/Png/ducky.png b/tests/Images/Input/Png/ducky.png new file mode 100644 index 0000000000..8753a4a0e3 --- /dev/null +++ b/tests/Images/Input/Png/ducky.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0c2ea23adc981b8efba267c636b71190e74f798576467f26ed5cb4334a7ae421 +size 40960 diff --git a/tests/Images/Input/Png/rainbow.png b/tests/Images/Input/Png/rainbow.png new file mode 100644 index 0000000000..78dfa1aad5 --- /dev/null +++ b/tests/Images/Input/Png/rainbow.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:18993090b64a08939b4f8901e2b603bb8a49b053af7a0f327b4ae1205e64b987 +size 1447 From 3e7b84054d7f7878b6eab939e0dbf0b48b66d3f3 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Fri, 24 Aug 2018 19:41:33 +0100 Subject: [PATCH 2/3] Don't allow duplicate formats in configuration. --- src/ImageSharp/Formats/ImageFormatManager.cs | 17 +++++++++++++++-- tests/ImageSharp.Tests/ConfigurationTests.cs | 14 +++++++++----- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/ImageSharp/Formats/ImageFormatManager.cs b/src/ImageSharp/Formats/ImageFormatManager.cs index 63fd02d8d6..fdbc4ee442 100644 --- a/src/ImageSharp/Formats/ImageFormatManager.cs +++ b/src/ImageSharp/Formats/ImageFormatManager.cs @@ -13,6 +13,12 @@ namespace SixLabors.ImageSharp.Formats /// public class ImageFormatManager { + /// + /// Used for locking against as there is no ConcurrentSet type. + /// + /// + private static readonly object HashLock = new object(); + /// /// The list of supported keyed to mime types. /// @@ -26,7 +32,7 @@ namespace SixLabors.ImageSharp.Formats /// /// The list of supported s. /// - private readonly ConcurrentBag imageFormats = new ConcurrentBag(); + private readonly HashSet imageFormats = new HashSet(); /// /// The list of supported s. @@ -74,7 +80,14 @@ namespace SixLabors.ImageSharp.Formats Guard.NotNull(format, nameof(format)); Guard.NotNull(format.MimeTypes, nameof(format.MimeTypes)); Guard.NotNull(format.FileExtensions, nameof(format.FileExtensions)); - this.imageFormats.Add(format); + + lock (HashLock) + { + if (!this.imageFormats.Contains(format)) + { + this.imageFormats.Add(format); + } + } } /// diff --git a/tests/ImageSharp.Tests/ConfigurationTests.cs b/tests/ImageSharp.Tests/ConfigurationTests.cs index 1a7183df81..5c5eb9e9d9 100644 --- a/tests/ImageSharp.Tests/ConfigurationTests.cs +++ b/tests/ImageSharp.Tests/ConfigurationTests.cs @@ -2,13 +2,9 @@ // Licensed under the Apache License, Version 2.0. using System; -using System.Collections.Generic; -using System.IO; using System.Linq; -using SixLabors.ImageSharp.Formats; -using SixLabors.ImageSharp.IO; -using SixLabors.ImageSharp.PixelFormats; using Moq; +using SixLabors.ImageSharp.IO; using Xunit; // ReSharper disable InconsistentNaming @@ -96,5 +92,13 @@ namespace SixLabors.ImageSharp.Tests provider.Verify(x => x.Configure(config)); } + + [Fact] + public void DefaultConfigurationHasCorrectFormatCount() + { + Configuration config = Configuration.Default; + + Assert.Equal(4, config.ImageFormats.Count()); + } } } \ No newline at end of file From 970b1ba25a4657db25ee2228f6b69c2f7001a00e Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Fri, 24 Aug 2018 22:54:31 +0100 Subject: [PATCH 3/3] Add additional tests --- src/ImageSharp/Formats/ImageFormatManager.cs | 6 +++--- tests/ImageSharp.Tests/ConfigurationTests.cs | 17 +++++++++++++++-- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/ImageSharp/Formats/ImageFormatManager.cs b/src/ImageSharp/Formats/ImageFormatManager.cs index fdbc4ee442..e62805d478 100644 --- a/src/ImageSharp/Formats/ImageFormatManager.cs +++ b/src/ImageSharp/Formats/ImageFormatManager.cs @@ -99,9 +99,9 @@ namespace SixLabors.ImageSharp.Formats { Guard.NotNullOrWhiteSpace(extension, nameof(extension)); - if (extension[0] == '.') - { - extension = extension.Substring(1); + if (extension[0] == '.') + { + extension = extension.Substring(1); } return this.imageFormats.FirstOrDefault(x => x.FileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase)); diff --git a/tests/ImageSharp.Tests/ConfigurationTests.cs b/tests/ImageSharp.Tests/ConfigurationTests.cs index 5c5eb9e9d9..4bec25f7a2 100644 --- a/tests/ImageSharp.Tests/ConfigurationTests.cs +++ b/tests/ImageSharp.Tests/ConfigurationTests.cs @@ -15,8 +15,8 @@ namespace SixLabors.ImageSharp.Tests /// public class ConfigurationTests { - public Configuration ConfigurationEmpty { get; private set; } - public Configuration DefaultConfiguration { get; private set; } + public Configuration ConfigurationEmpty { get; } + public Configuration DefaultConfiguration { get; } public ConfigurationTests() { @@ -93,6 +93,19 @@ namespace SixLabors.ImageSharp.Tests provider.Verify(x => x.Configure(config)); } + [Fact] + public void ConfigurationCannotAddDuplicates() + { + const int count = 4; + Configuration config = Configuration.Default; + + Assert.Equal(count, config.ImageFormats.Count()); + + config.ImageFormatsManager.AddImageFormat(ImageFormats.Bmp); + + Assert.Equal(count, config.ImageFormats.Count()); + } + [Fact] public void DefaultConfigurationHasCorrectFormatCount() {