From 92db6af2bddd90f30655846aa6f64d14036d8b24 Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Tue, 20 Nov 2018 08:50:48 -0800 Subject: [PATCH 01/40] Remove redundant package references --- tests/ImageSharp.Tests/ImageSharp.Tests.csproj | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj index 86c1a7a259..3ba9fba180 100644 --- a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj +++ b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj @@ -34,8 +34,6 @@ - - From d3c717a5ce99baad4b4d92cc0e62f7849e62f033 Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Tue, 20 Nov 2018 08:54:46 -0800 Subject: [PATCH 02/40] Update BenchmarkDotNet to 0.11.3 --- .../General/BasicMath/ModuloPowerOfTwoConstant.cs | 1 - .../General/BasicMath/ModuloPowerOfTwoVariable.cs | 1 - .../General/PixelConversion/PixelConversion_Rgba32_To_Bgra32.cs | 1 - tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj | 2 +- 4 files changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/ImageSharp.Benchmarks/General/BasicMath/ModuloPowerOfTwoConstant.cs b/tests/ImageSharp.Benchmarks/General/BasicMath/ModuloPowerOfTwoConstant.cs index 9ddfad7222..94349b20b6 100644 --- a/tests/ImageSharp.Benchmarks/General/BasicMath/ModuloPowerOfTwoConstant.cs +++ b/tests/ImageSharp.Benchmarks/General/BasicMath/ModuloPowerOfTwoConstant.cs @@ -1,5 +1,4 @@ using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Attributes.Jobs; namespace SixLabors.ImageSharp.Benchmarks.General.BasicMath { diff --git a/tests/ImageSharp.Benchmarks/General/BasicMath/ModuloPowerOfTwoVariable.cs b/tests/ImageSharp.Benchmarks/General/BasicMath/ModuloPowerOfTwoVariable.cs index 5c2fe81fa2..d5683673fe 100644 --- a/tests/ImageSharp.Benchmarks/General/BasicMath/ModuloPowerOfTwoVariable.cs +++ b/tests/ImageSharp.Benchmarks/General/BasicMath/ModuloPowerOfTwoVariable.cs @@ -1,5 +1,4 @@ using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Attributes.Jobs; namespace SixLabors.ImageSharp.Benchmarks.General.BasicMath { diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Bgra32.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Bgra32.cs index a8fea68661..3b288260c5 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Bgra32.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Bgra32.cs @@ -4,7 +4,6 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using BenchmarkDotNet.Attributes; -using BenchmarkDotNet.Attributes.Jobs; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Tuples; diff --git a/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj b/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj index a705c9bacb..f941203db1 100644 --- a/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj +++ b/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj @@ -16,7 +16,7 @@ - + From 5f4e66f751c0323720214f818196d0d405e10651 Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Tue, 20 Nov 2018 08:55:02 -0800 Subject: [PATCH 03/40] Update Moq to 4.10.0 --- tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj | 2 +- tests/ImageSharp.Tests/ImageSharp.Tests.csproj | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj b/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj index 4d7b7de759..ae6acf0913 100644 --- a/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj +++ b/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj @@ -21,7 +21,7 @@ - + diff --git a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj index 3ba9fba180..271a7ae32d 100644 --- a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj +++ b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj @@ -33,8 +33,8 @@ - - + + From ab5ded8ca0afeaf8442390bfec07ba36c95189cd Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Tue, 20 Nov 2018 08:56:16 -0800 Subject: [PATCH 04/40] Use unmanaged constraint on internal api --- src/ImageSharp/Common/ParallelUtils/ParallelHelper.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ImageSharp/Common/ParallelUtils/ParallelHelper.cs b/src/ImageSharp/Common/ParallelUtils/ParallelHelper.cs index 1d1734a863..782333219f 100644 --- a/src/ImageSharp/Common/ParallelUtils/ParallelHelper.cs +++ b/src/ImageSharp/Common/ParallelUtils/ParallelHelper.cs @@ -85,7 +85,7 @@ namespace SixLabors.ImageSharp.ParallelUtils Rectangle rectangle, in ParallelExecutionSettings parallelSettings, Action> body) - where T : struct + where T : unmanaged { int maxSteps = DivideCeil(rectangle.Width * rectangle.Height, parallelSettings.MinimumPixelsProcessedPerTask); @@ -135,7 +135,7 @@ namespace SixLabors.ImageSharp.ParallelUtils Rectangle rectangle, Configuration configuration, Action> body) - where T : struct + where T : unmanaged { IterateRowsWithTempBuffer(rectangle, configuration.GetParallelSettings(), body); } From af7d2395d772dec8f300bd3b8c2c109e1c61e5ef Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Tue, 20 Nov 2018 08:57:31 -0800 Subject: [PATCH 05/40] Remove linq use in JpegDecoderCode --- src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs index f6da9cb2ec..faa7c3bc9a 100644 --- a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs +++ b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs @@ -553,12 +553,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg if (this.exifData is null) { // The first 6 bytes (Exif00) will be skipped, because this is Jpeg specific - this.exifData = profile.Skip(Exif00).ToArray(); + this.exifData = profile.AsSpan(Exif00).ToArray(); } else { // If the EXIF information exceeds 64K, it will be split over multiple APP1 markers - this.ExtendProfile(ref this.exifData, profile.Skip(Exif00).ToArray()); + this.ExtendProfile(ref this.exifData, profile.AsSpan(Exif00).ToArray()); } } } From 8b9600f9df91f2b32ee62fb229d4cbdb019d1749 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Thu, 29 Nov 2018 16:26:15 +0100 Subject: [PATCH 06/40] wip --- .../Transforms/ResizeKernelMapTests.cs | 5 +-- .../Processors/Transforms/ResizeTests.cs | 33 +++++-------------- .../TestUtilities/TestUtils.cs | 8 +++++ 3 files changed, 18 insertions(+), 28 deletions(-) diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeKernelMapTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeKernelMapTests.cs index 08b2949139..5d3790f071 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeKernelMapTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeKernelMapTests.cs @@ -208,10 +208,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms { var result = new TheoryData(); - string[] resamplerNames = typeof(KnownResamplers).GetProperties(BindingFlags.Public | BindingFlags.Static) - .Select(p => p.Name) - .Where(name => name != nameof(KnownResamplers.NearestNeighbor)) - .ToArray(); + string[] resamplerNames = TestUtils.GetAllResamplerNames(false); int[] dimensionVals = { diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs index b4aff53e82..fc4cd3f112 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs @@ -20,38 +20,23 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms public static readonly string[] CommonTestImages = { TestImages.Png.CalliphoraPartial }; private static readonly ImageComparer ValidatorComparer = ImageComparer.TolerantPercentage(0.07F); - - public static readonly TheoryData AllResamplers = - new TheoryData - { - { "Bicubic", KnownResamplers.Bicubic }, - { "Triangle", KnownResamplers.Triangle}, - { "NearestNeighbor", KnownResamplers.NearestNeighbor }, - { "Box", KnownResamplers.Box }, - // { "Lanczos2", KnownResamplers.Lanczos2 }, TODO: Add expected file - { "Lanczos3", KnownResamplers.Lanczos3 }, - { "Lanczos5", KnownResamplers.Lanczos5 }, - { "MitchellNetravali", KnownResamplers.MitchellNetravali }, - { "Lanczos8", KnownResamplers.Lanczos8 }, - { "Hermite", KnownResamplers.Hermite }, - { "Spline", KnownResamplers.Spline }, - { "Robidoux", KnownResamplers.Robidoux }, - { "RobidouxSharp", KnownResamplers.RobidouxSharp }, - { "Welch", KnownResamplers.Welch } - }; + + public static readonly string[] AllResamplerNames = TestUtils.GetAllResamplerNames(); [Theory] - [WithTestPatternImages(nameof(AllResamplers), 100, 100, DefaultPixelType, 0.5f)] - [WithFileCollection(nameof(CommonTestImages), nameof(AllResamplers), DefaultPixelType, 0.5f)] - [WithFileCollection(nameof(CommonTestImages), nameof(AllResamplers), DefaultPixelType, 0.3f)] - public void Resize_WorksWithAllResamplers(TestImageProvider provider, string name, IResampler sampler, float ratio) + [WithTestPatternImages(nameof(AllResamplerNames), 100, 100, DefaultPixelType, 0.5f)] + [WithFileCollection(nameof(CommonTestImages), nameof(AllResamplerNames), DefaultPixelType, 0.5f)] + [WithFileCollection(nameof(CommonTestImages), nameof(AllResamplerNames), DefaultPixelType, 0.3f)] + public void Resize_WorksWithAllResamplers(TestImageProvider provider, string samplerName, float ratio) where TPixel : struct, IPixel { + IResampler sampler = TestUtils.GetResampler(samplerName); + using (Image image = provider.GetImage()) { SizeF newSize = image.Size() * ratio; image.Mutate(x => x.Resize((Size)newSize, sampler, false)); - FormattableString details = $"{name}-{ratio.ToString(System.Globalization.CultureInfo.InvariantCulture)}"; + FormattableString details = $"{samplerName}-{ratio.ToString(System.Globalization.CultureInfo.InvariantCulture)}"; image.DebugSave(provider, details); image.CompareToReferenceOutput(ImageComparer.TolerantPercentage(0.02f), provider, details); diff --git a/tests/ImageSharp.Tests/TestUtilities/TestUtils.cs b/tests/ImageSharp.Tests/TestUtilities/TestUtils.cs index 5ea0bccf06..a21e55e2b6 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestUtils.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestUtils.cs @@ -297,5 +297,13 @@ namespace SixLabors.ImageSharp.Tests return (IResampler)property.GetValue(null); } + + public static string[] GetAllResamplerNames(bool includeNearestNeighbour = true) + { + return typeof(KnownResamplers).GetProperties(BindingFlags.Public | BindingFlags.Static) + .Select(p => p.Name) + .Where(name => includeNearestNeighbour || name != nameof(KnownResamplers.NearestNeighbor)) + .ToArray(); + } } } \ No newline at end of file From cd6d07e3fc222ce9e264d204978b49c28316205a Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Thu, 29 Nov 2018 17:21:31 +0100 Subject: [PATCH 07/40] Made TolerantMath.Default a readonly property, allow consuming one-dimensional input in ImageDataAttribute. --- src/ImageSharp/Common/Helpers/TolerantMath.cs | 9 +++++++-- .../TestUtilities/Attributes/ImageDataAttributeBase.cs | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/ImageSharp/Common/Helpers/TolerantMath.cs b/src/ImageSharp/Common/Helpers/TolerantMath.cs index 5347efcc09..bef7eb1610 100644 --- a/src/ImageSharp/Common/Helpers/TolerantMath.cs +++ b/src/ImageSharp/Common/Helpers/TolerantMath.cs @@ -16,6 +16,13 @@ namespace SixLabors.ImageSharp private readonly double negEpsilon; + /// + /// A read-only default instance for using 1e-8 as epsilon. + /// It is a field so it can be passed as an 'in' parameter. + /// Does not necessarily fit all use cases! + /// + public static readonly TolerantMath Default = new TolerantMath(1e-8); + public TolerantMath(double epsilon) { DebugGuard.MustBeGreaterThan(epsilon, 0, nameof(epsilon)); @@ -24,8 +31,6 @@ namespace SixLabors.ImageSharp this.negEpsilon = -epsilon; } - public static TolerantMath Default { get; } = new TolerantMath(1e-8); - /// /// == 0 /// diff --git a/tests/ImageSharp.Tests/TestUtilities/Attributes/ImageDataAttributeBase.cs b/tests/ImageSharp.Tests/TestUtilities/Attributes/ImageDataAttributeBase.cs index ec3254921f..6107154d0e 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Attributes/ImageDataAttributeBase.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Attributes/ImageDataAttributeBase.cs @@ -61,7 +61,7 @@ namespace SixLabors.ImageSharp.Tests addedRows = memberItems.Select(x => x as object[]); if (addedRows.Any(x => x == null)) { - throw new ArgumentException($"Property {this.MemberName} on {this.MemberType ?? testMethod.DeclaringType} yielded an item that is not an object[]"); + addedRows = memberItems.Select(x => new[] { x }); } } } From 2929fcf8f931637cfd8d146b9915fa1d0607a0c1 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Thu, 29 Nov 2018 18:01:40 +0100 Subject: [PATCH 08/40] add more test cases to Resize_WorksWithAllResamplers --- .../Processors/Transforms/ResizeTests.cs | 38 ++++++++++++++++--- 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs index fc4cd3f112..f7e056ae9d 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs @@ -24,19 +24,45 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms public static readonly string[] AllResamplerNames = TestUtils.GetAllResamplerNames(); [Theory] - [WithTestPatternImages(nameof(AllResamplerNames), 100, 100, DefaultPixelType, 0.5f)] - [WithFileCollection(nameof(CommonTestImages), nameof(AllResamplerNames), DefaultPixelType, 0.5f)] - [WithFileCollection(nameof(CommonTestImages), nameof(AllResamplerNames), DefaultPixelType, 0.3f)] - public void Resize_WorksWithAllResamplers(TestImageProvider provider, string samplerName, float ratio) + [WithTestPatternImages(nameof(AllResamplerNames), 100, 100, DefaultPixelType, 0.5f, null, null)] + [WithTestPatternImages(nameof(AllResamplerNames), 50, 50, DefaultPixelType, 8f, null, null)] + [WithTestPatternImages(nameof(AllResamplerNames), 201, 199, DefaultPixelType, null, 100, 99)] + [WithTestPatternImages(nameof(AllResamplerNames), 301, 300, DefaultPixelType, null, 1180, 480)] + [WithTestPatternImages(nameof(AllResamplerNames), 49, 80, DefaultPixelType, null, 301, 100)] + [WithFileCollection(nameof(CommonTestImages), nameof(AllResamplerNames), DefaultPixelType, 0.5f, null, null)] + [WithFileCollection(nameof(CommonTestImages), nameof(AllResamplerNames), DefaultPixelType, 0.3f, null, null)] + public void Resize_WorksWithAllResamplers( + TestImageProvider provider, + string samplerName, + float? ratio, + int? specificDestWidth, + int? specificDestHeight) where TPixel : struct, IPixel { IResampler sampler = TestUtils.GetResampler(samplerName); using (Image image = provider.GetImage()) { - SizeF newSize = image.Size() * ratio; + SizeF newSize; + string destSizeInfo; + if (ratio.HasValue) + { + newSize = image.Size() * ratio.Value; + destSizeInfo = ratio.Value.ToString(System.Globalization.CultureInfo.InvariantCulture); + } + else + { + if (!specificDestWidth.HasValue || !specificDestHeight.HasValue) + { + throw new InvalidOperationException("invalid dimensional input for Resize_WorksWithAllResamplers!"); + } + + newSize = new SizeF(specificDestWidth.Value, specificDestHeight.Value); + destSizeInfo = $"{newSize.Width}x{newSize.Height}"; + } + image.Mutate(x => x.Resize((Size)newSize, sampler, false)); - FormattableString details = $"{samplerName}-{ratio.ToString(System.Globalization.CultureInfo.InvariantCulture)}"; + FormattableString details = $"{samplerName}-{destSizeInfo}"; image.DebugSave(provider, details); image.CompareToReferenceOutput(ImageComparer.TolerantPercentage(0.02f), provider, details); From e9dddc5d4af90dec0af2755e1e3d263d7c130d94 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Thu, 29 Nov 2018 18:02:09 +0100 Subject: [PATCH 09/40] temporary simplification of build targets --- src/ImageSharp.Drawing/ImageSharp.Drawing.csproj | 3 ++- src/ImageSharp/ImageSharp.csproj | 3 ++- tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj | 3 ++- tests/ImageSharp.Tests/ImageSharp.Tests.csproj | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj b/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj index ae5069be1d..a785832a57 100644 --- a/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj +++ b/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj @@ -5,7 +5,8 @@ $(packageversion) 0.0.1 SixLabors and contributors - netstandard1.3;netstandard2.0 + + netcoreapp2.1 7.3 true true diff --git a/src/ImageSharp/ImageSharp.csproj b/src/ImageSharp/ImageSharp.csproj index c19c92426f..20b1cdee0b 100644 --- a/src/ImageSharp/ImageSharp.csproj +++ b/src/ImageSharp/ImageSharp.csproj @@ -5,7 +5,8 @@ $(packageversion) 0.0.1 Six Labors and contributors - netstandard1.3;netstandard2.0;netcoreapp2.1;net472 + + netcoreapp2.1 true true SixLabors.ImageSharp diff --git a/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj b/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj index a705c9bacb..04a4541b21 100644 --- a/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj +++ b/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj @@ -1,6 +1,7 @@  - netcoreapp2.1;net461 + + netcoreapp2.1 Exe True SixLabors.ImageSharp.Benchmarks diff --git a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj index 86c1a7a259..75ac7450c8 100644 --- a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj +++ b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj @@ -1,6 +1,7 @@  - net462;net472;netcoreapp2.1 + + netcoreapp2.1 True latest full From 53222f7ce259091e1a0edbc96a6f55a89bde5382 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Fri, 30 Nov 2018 01:07:20 +0100 Subject: [PATCH 10/40] revisted test cases in Resize_WorksWithAllResamplers --- .../Processors/Transforms/ResizeTests.cs | 82 ++++++++++++------- .../ImageProviders/TestPatternProvider.cs | 13 +-- .../TestUtilities/TestUtils.cs | 39 +++++++++ .../Tests/TestImageProviderTests.cs | 12 +++ tests/Images/External | 2 +- 5 files changed, 110 insertions(+), 38 deletions(-) diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs index f7e056ae9d..cdaf3cea3a 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs @@ -23,14 +23,24 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms public static readonly string[] AllResamplerNames = TestUtils.GetAllResamplerNames(); + public static readonly string[] SmokeTestResamplerNames = + { + nameof(KnownResamplers.NearestNeighbor), + nameof(KnownResamplers.Bicubic), + nameof(KnownResamplers.Box), + nameof(KnownResamplers.Lanczos5), + }; + [Theory] - [WithTestPatternImages(nameof(AllResamplerNames), 100, 100, DefaultPixelType, 0.5f, null, null)] - [WithTestPatternImages(nameof(AllResamplerNames), 50, 50, DefaultPixelType, 8f, null, null)] - [WithTestPatternImages(nameof(AllResamplerNames), 201, 199, DefaultPixelType, null, 100, 99)] - [WithTestPatternImages(nameof(AllResamplerNames), 301, 300, DefaultPixelType, null, 1180, 480)] - [WithTestPatternImages(nameof(AllResamplerNames), 49, 80, DefaultPixelType, null, 301, 100)] [WithFileCollection(nameof(CommonTestImages), nameof(AllResamplerNames), DefaultPixelType, 0.5f, null, null)] - [WithFileCollection(nameof(CommonTestImages), nameof(AllResamplerNames), DefaultPixelType, 0.3f, null, null)] + [WithFileCollection(nameof(CommonTestImages), nameof(SmokeTestResamplerNames), DefaultPixelType, 0.3f, null, null)] + [WithFileCollection(nameof(CommonTestImages), nameof(SmokeTestResamplerNames), DefaultPixelType, 1.8f, null, null)] + [WithTestPatternImages(nameof(SmokeTestResamplerNames), 100, 100, DefaultPixelType, 0.5f, null, null)] + [WithTestPatternImages(nameof(SmokeTestResamplerNames), 100, 100, DefaultPixelType, 1f, null, null)] + [WithTestPatternImages(nameof(SmokeTestResamplerNames), 50, 50, DefaultPixelType, 8f, null, null)] + [WithTestPatternImages(nameof(SmokeTestResamplerNames), 201, 199, DefaultPixelType, null, 100, 99)] + [WithTestPatternImages(nameof(SmokeTestResamplerNames), 301, 1180, DefaultPixelType, null, 300, 480)] + [WithTestPatternImages(nameof(SmokeTestResamplerNames), 49, 80, DefaultPixelType, null, 301, 100)] public void Resize_WorksWithAllResamplers( TestImageProvider provider, string samplerName, @@ -41,32 +51,42 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms { IResampler sampler = TestUtils.GetResampler(samplerName); - using (Image image = provider.GetImage()) - { - SizeF newSize; - string destSizeInfo; - if (ratio.HasValue) - { - newSize = image.Size() * ratio.Value; - destSizeInfo = ratio.Value.ToString(System.Globalization.CultureInfo.InvariantCulture); - } - else - { - if (!specificDestWidth.HasValue || !specificDestHeight.HasValue) - { - throw new InvalidOperationException("invalid dimensional input for Resize_WorksWithAllResamplers!"); - } - - newSize = new SizeF(specificDestWidth.Value, specificDestHeight.Value); - destSizeInfo = $"{newSize.Width}x{newSize.Height}"; - } - - image.Mutate(x => x.Resize((Size)newSize, sampler, false)); - FormattableString details = $"{samplerName}-{destSizeInfo}"; + var comparer = ImageComparer.TolerantPercentage(0.02f); - image.DebugSave(provider, details); - image.CompareToReferenceOutput(ImageComparer.TolerantPercentage(0.02f), provider, details); - } + provider.RunValidatingProcessorTest( + ctx => + { + + SizeF newSize; + string destSizeInfo; + if (ratio.HasValue) + { + newSize = ctx.GetCurrentSize() * ratio.Value; + destSizeInfo = ratio.Value.ToString(System.Globalization.CultureInfo.InvariantCulture); + } + else + { + if (!specificDestWidth.HasValue || !specificDestHeight.HasValue) + { + throw new InvalidOperationException( + "invalid dimensional input for Resize_WorksWithAllResamplers!"); + } + + newSize = new SizeF(specificDestWidth.Value, specificDestHeight.Value); + destSizeInfo = $"{newSize.Width}x{newSize.Height}"; + } + + FormattableString testOutputDetails = $"{samplerName}-{destSizeInfo}"; + ctx.Apply( + img => img.DebugSave( + provider, + $"{testOutputDetails}-ORIGINAL", + appendPixelTypeToFileName: false)); + ctx.Resize((Size)newSize, sampler, false); + return testOutputDetails; + }, + comparer, + appendPixelTypeToFileName: false); } [Theory] diff --git a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestPatternProvider.cs b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestPatternProvider.cs index cc09dc0573..17e5369d48 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestPatternProvider.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestPatternProvider.cs @@ -16,10 +16,9 @@ namespace SixLabors.ImageSharp.Tests /// /// A test image provider that produces test patterns. /// - /// private class TestPatternProvider : BlankProvider { - static Dictionary> testImages = new Dictionary>(); + static readonly Dictionary> TestImages = new Dictionary>(); public TestPatternProvider(int width, int height) : base(width, height) @@ -35,17 +34,17 @@ namespace SixLabors.ImageSharp.Tests public override Image GetImage() { - lock (testImages) + lock (TestImages) { - if (!testImages.ContainsKey(this.SourceFileOrDescription)) + if (!TestImages.ContainsKey(this.SourceFileOrDescription)) { Image image = new Image(this.Width, this.Height); DrawTestPattern(image); - testImages.Add(this.SourceFileOrDescription, image); + TestImages.Add(this.SourceFileOrDescription, image); } } - return testImages[this.SourceFileOrDescription].Clone(); + return TestImages[this.SourceFileOrDescription].Clone(); } /// @@ -202,6 +201,7 @@ namespace SixLabors.ImageSharp.Tests Rgba32 t = new Rgba32(0); for (int x = left; x < right; x++) + { for (int y = top; y < bottom; y++) { t.PackedValue += stepsPerPixel; @@ -210,6 +210,7 @@ namespace SixLabors.ImageSharp.Tests c.FromVector4(v); pixels[x, y] = c; } + } } } } diff --git a/tests/ImageSharp.Tests/TestUtilities/TestUtils.cs b/tests/ImageSharp.Tests/TestUtilities/TestUtils.cs index a21e55e2b6..e51aa28d8f 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestUtils.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestUtils.cs @@ -193,6 +193,45 @@ namespace SixLabors.ImageSharp.Tests } } + internal static void RunValidatingProcessorTest( + this TestImageProvider provider, + Func, FormattableString> processAndGetTestOutputDetails, + ImageComparer comparer = null, + bool appendPixelTypeToFileName = true, + bool appendSourceFileOrDescription = true) + where TPixel : struct, IPixel + { + if (comparer == null) + { + comparer = ImageComparer.TolerantPercentage(0.001f); + } + + using (Image image = provider.GetImage()) + { + FormattableString testOutputDetails = $""; + image.Mutate( + ctx => { testOutputDetails = processAndGetTestOutputDetails(ctx); } + ); + + image.DebugSave( + provider, + testOutputDetails, + appendPixelTypeToFileName: appendPixelTypeToFileName, + appendSourceFileOrDescription: appendSourceFileOrDescription); + + // TODO: Investigate the cause of pixel inaccuracies under Linux + if (TestEnvironment.IsWindows) + { + image.CompareToReferenceOutput( + comparer, + provider, + testOutputDetails, + appendPixelTypeToFileName: appendPixelTypeToFileName, + appendSourceFileOrDescription: appendSourceFileOrDescription); + } + } + } + public static void RunValidatingProcessorTestOnWrappedMemoryImage( this TestImageProvider provider, Action> process, diff --git a/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs b/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs index a8140e39d4..cac7828e96 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs @@ -9,6 +9,7 @@ using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; using Xunit; using Xunit.Abstractions; +// ReSharper disable InconsistentNaming namespace SixLabors.ImageSharp.Tests { @@ -313,6 +314,17 @@ namespace SixLabors.ImageSharp.Tests } + [Theory] + [WithTestPatternImages(49,20, PixelTypes.Rgba32)] + public void Use_WithTestPatternImages(TestImageProvider provider) + where TPixel : struct, IPixel + { + using (Image img = provider.GetImage()) + { + img.DebugSave(provider); + } + } + public static readonly TheoryData BasicData = new TheoryData() { TestImageProvider.Blank(10, 20), diff --git a/tests/Images/External b/tests/Images/External index 5b18d8c95a..1edb0f3e04 160000 --- a/tests/Images/External +++ b/tests/Images/External @@ -1 +1 @@ -Subproject commit 5b18d8c95acffb773012881870ba6f521ba13128 +Subproject commit 1edb0f3e04c18974821a3012a87f7c2e073c8019 From 0fb40155be537e4c5ac4acc8bcefb9c30230f195 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Fri, 30 Nov 2018 01:08:04 +0100 Subject: [PATCH 11/40] Revert "temporary simplification of build targets" This reverts commit e9dddc5d4af90dec0af2755e1e3d263d7c130d94. --- src/ImageSharp.Drawing/ImageSharp.Drawing.csproj | 3 +-- src/ImageSharp/ImageSharp.csproj | 3 +-- tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj | 3 +-- tests/ImageSharp.Tests/ImageSharp.Tests.csproj | 3 +-- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj b/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj index a785832a57..ae5069be1d 100644 --- a/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj +++ b/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj @@ -5,8 +5,7 @@ $(packageversion) 0.0.1 SixLabors and contributors - - netcoreapp2.1 + netstandard1.3;netstandard2.0 7.3 true true diff --git a/src/ImageSharp/ImageSharp.csproj b/src/ImageSharp/ImageSharp.csproj index 20b1cdee0b..c19c92426f 100644 --- a/src/ImageSharp/ImageSharp.csproj +++ b/src/ImageSharp/ImageSharp.csproj @@ -5,8 +5,7 @@ $(packageversion) 0.0.1 Six Labors and contributors - - netcoreapp2.1 + netstandard1.3;netstandard2.0;netcoreapp2.1;net472 true true SixLabors.ImageSharp diff --git a/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj b/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj index 04a4541b21..a705c9bacb 100644 --- a/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj +++ b/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj @@ -1,7 +1,6 @@  - - netcoreapp2.1 + netcoreapp2.1;net461 Exe True SixLabors.ImageSharp.Benchmarks diff --git a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj index 75ac7450c8..86c1a7a259 100644 --- a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj +++ b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj @@ -1,7 +1,6 @@  - - netcoreapp2.1 + net462;net472;netcoreapp2.1 True latest full From e4c7febccb4dc9bb4557afe68e19b8adafbec564 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Fri, 30 Nov 2018 03:17:48 +0100 Subject: [PATCH 12/40] less strict tolerance for 32bit .NET + NearestNeighborResampler, more strict tolerance for the rest --- .../Processing/Processors/Transforms/ResizeTests.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs index cdaf3cea3a..5c2dffe582 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs @@ -51,7 +51,16 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms { IResampler sampler = TestUtils.GetResampler(samplerName); - var comparer = ImageComparer.TolerantPercentage(0.02f); + // NeirestNeighbourResampler is producing slightly different results With classic .NET framework on 32bit + // most likely because of differences in numeric behavior. + // The difference is well visible when comparing output for + // Resize_WorksWithAllResamplers_TestPattern301x1180_NearestNeighbor-300x480.png + // TODO: Should we investigate this? + bool allowHigherInaccuracy = !TestEnvironment.Is64BitProcess + && string.IsNullOrEmpty(TestEnvironment.NetCoreVersion) + && sampler is NearestNeighborResampler; + + var comparer = ImageComparer.TolerantPercentage(allowHigherInaccuracy ? 0.3f : 0.01f); provider.RunValidatingProcessorTest( ctx => From 7eb0c3c349aaec992433543ae761fc6c2bfbb586 Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Wed, 5 Dec 2018 08:02:45 -0800 Subject: [PATCH 13/40] Ensure exifData is set --- src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs b/src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs index 100649c0fd..514959312b 100644 --- a/src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs +++ b/src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs @@ -27,9 +27,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif public ExifReader(byte[] exifData) { - DebugGuard.NotNull(exifData, nameof(exifData)); - - this.exifData = exifData; + this.exifData = exifData ?? throw new ArgumentNullException(nameof(exifData)); } private delegate TDataType ConverterMethod(ReadOnlySpan data); From ac22630fba6abadb0fdd88c4c4e8cfec99de459d Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Wed, 5 Dec 2018 09:12:41 -0800 Subject: [PATCH 14/40] Use new HashHelper overloads --- src/ImageSharp/ColorSpaces/CieLab.cs | 9 ++++--- src/ImageSharp/ColorSpaces/CieLch.cs | 9 ++++--- src/ImageSharp/ColorSpaces/CieLchuv.cs | 9 ++++--- src/ImageSharp/ColorSpaces/CieLuv.cs | 9 ++++--- src/ImageSharp/ColorSpaces/CieXyy.cs | 7 ++--- src/ImageSharp/ColorSpaces/CieXyz.cs | 7 ++--- src/ImageSharp/ColorSpaces/Cmyk.cs | 9 ++++--- .../RGBPrimariesChromaticityCoordinates.cs | 7 +---- .../WorkingSpaces/GammaWorkingSpace.cs | 6 +---- .../WorkingSpaces/RgbWorkingSpaceBase.cs | 3 +-- src/ImageSharp/ColorSpaces/Hsl.cs | 7 ++--- src/ImageSharp/ColorSpaces/Hsv.cs | 7 ++--- src/ImageSharp/ColorSpaces/HunterLab.cs | 9 ++++--- src/ImageSharp/ColorSpaces/LinearRgb.cs | 7 ++--- src/ImageSharp/ColorSpaces/Lms.cs | 7 ++--- src/ImageSharp/ColorSpaces/Rgb.cs | 7 ++--- src/ImageSharp/ColorSpaces/YCbCr.cs | 7 ++--- .../Jpeg/Components/Decoder/AdobeMarker.cs | 8 +++--- .../Profiles/ICC/Curves/IccResponseCurve.cs | 11 +++----- .../IccChromaticityTagDataEntry.cs | 11 +++----- .../IccColorantOrderTagDataEntry.cs | 5 +--- .../IccColorantTableTagDataEntry.cs | 5 +--- .../TagDataEntries/IccCurveTagDataEntry.cs | 5 +--- .../ICC/TagDataEntries/IccDataTagDataEntry.cs | 11 +++----- .../TagDataEntries/IccDateTimeTagDataEntry.cs | 5 +--- .../IccFix16ArrayTagDataEntry.cs | 5 +--- .../TagDataEntries/IccLut16TagDataEntry.cs | 15 +++++------ .../ICC/TagDataEntries/IccLut8TagDataEntry.cs | 15 +++++------ .../IccMultiLocalizedUnicodeTagDataEntry.cs | 5 +--- .../IccMultiProcessElementsTagDataEntry.cs | 13 ++++------ .../IccParametricCurveTagDataEntry.cs | 7 ++--- .../IccProfileSequenceDescTagDataEntry.cs | 5 +--- ...ccProfileSequenceIdentifierTagDataEntry.cs | 5 +--- .../IccResponseCurveSet16TagDataEntry.cs | 11 +++----- .../IccScreeningTagDataEntry.cs | 11 +++----- .../IccSignatureTagDataEntry.cs | 5 +--- .../ICC/TagDataEntries/IccTextTagDataEntry.cs | 5 +--- .../IccUFix16ArrayTagDataEntry.cs | 5 +--- .../IccUInt16ArrayTagDataEntry.cs | 5 +--- .../IccUInt32ArrayTagDataEntry.cs | 5 +--- .../IccUInt64ArrayTagDataEntry.cs | 5 +--- .../IccUInt8ArrayTagDataEntry.cs | 5 +--- .../TagDataEntries/IccUcrBgTagDataEntry.cs | 13 ++++------ .../TagDataEntries/IccUnknownTagDataEntry.cs | 5 +--- .../IccViewingConditionsTagDataEntry.cs | 13 ++++------ .../MetaData/Profiles/ICC/Various/IccClut.cs | 4 +-- .../ICC/Various/IccColorantTableEntry.cs | 13 ++++------ .../Profiles/ICC/Various/IccNamedColor.cs | 26 ++++++++----------- .../Profiles/ICC/Various/IccPositionNumber.cs | 10 ++----- .../ICC/Various/IccProfileDescription.cs | 11 +++----- .../Profiles/ICC/Various/IccProfileId.cs | 13 ++++------ .../Various/IccProfileSequenceIdentifier.cs | 9 ++----- .../Profiles/ICC/Various/IccResponseNumber.cs | 9 +++---- .../ICC/Various/IccScreeningChannel.cs | 11 +++----- .../Profiles/ICC/Various/IccTagTableEntry.cs | 11 +++----- .../PixelImplementations/Bgr24.cs | 3 +-- .../PixelImplementations/Rgb24.cs | 3 +-- .../PixelImplementations/Rgb48.cs | 4 +-- 58 files changed, 178 insertions(+), 294 deletions(-) diff --git a/src/ImageSharp/ColorSpaces/CieLab.cs b/src/ImageSharp/ColorSpaces/CieLab.cs index ea6df86e27..dd01ea5f4b 100644 --- a/src/ImageSharp/ColorSpaces/CieLab.cs +++ b/src/ImageSharp/ColorSpaces/CieLab.cs @@ -120,10 +120,11 @@ namespace SixLabors.ImageSharp.ColorSpaces /// public override int GetHashCode() { - int hash = this.L.GetHashCode(); - hash = HashHelpers.Combine(hash, this.A.GetHashCode()); - hash = HashHelpers.Combine(hash, this.B.GetHashCode()); - return HashHelpers.Combine(hash, this.WhitePoint.GetHashCode()); + return HashHelpers.Combine( + this.L.GetHashCode(), + this.A.GetHashCode(), + this.B.GetHashCode(), + this.WhitePoint.GetHashCode()); } /// diff --git a/src/ImageSharp/ColorSpaces/CieLch.cs b/src/ImageSharp/ColorSpaces/CieLch.cs index f1a7425e9e..fffd368fb4 100644 --- a/src/ImageSharp/ColorSpaces/CieLch.cs +++ b/src/ImageSharp/ColorSpaces/CieLch.cs @@ -122,10 +122,11 @@ namespace SixLabors.ImageSharp.ColorSpaces /// public override int GetHashCode() { - int hash = this.L.GetHashCode(); - hash = HashHelpers.Combine(hash, this.C.GetHashCode()); - hash = HashHelpers.Combine(hash, this.H.GetHashCode()); - return HashHelpers.Combine(hash, this.WhitePoint.GetHashCode()); + return HashHelpers.Combine( + this.L.GetHashCode(), + this.C.GetHashCode(), + this.H.GetHashCode(), + this.WhitePoint.GetHashCode()); } /// diff --git a/src/ImageSharp/ColorSpaces/CieLchuv.cs b/src/ImageSharp/ColorSpaces/CieLchuv.cs index 256b5dc0fd..829abbf0ec 100644 --- a/src/ImageSharp/ColorSpaces/CieLchuv.cs +++ b/src/ImageSharp/ColorSpaces/CieLchuv.cs @@ -121,10 +121,11 @@ namespace SixLabors.ImageSharp.ColorSpaces /// public override int GetHashCode() { - int hash = this.L.GetHashCode(); - hash = HashHelpers.Combine(hash, this.C.GetHashCode()); - hash = HashHelpers.Combine(hash, this.H.GetHashCode()); - return HashHelpers.Combine(hash, this.WhitePoint.GetHashCode()); + return HashHelpers.Combine( + this.L.GetHashCode(), + this.C.GetHashCode(), + this.H.GetHashCode(), + this.WhitePoint.GetHashCode()); } /// diff --git a/src/ImageSharp/ColorSpaces/CieLuv.cs b/src/ImageSharp/ColorSpaces/CieLuv.cs index 8fe073d6bf..b678084c38 100644 --- a/src/ImageSharp/ColorSpaces/CieLuv.cs +++ b/src/ImageSharp/ColorSpaces/CieLuv.cs @@ -121,10 +121,11 @@ namespace SixLabors.ImageSharp.ColorSpaces /// public override int GetHashCode() { - int hash = this.L.GetHashCode(); - hash = HashHelpers.Combine(hash, this.U.GetHashCode()); - hash = HashHelpers.Combine(hash, this.V.GetHashCode()); - return HashHelpers.Combine(hash, this.WhitePoint.GetHashCode()); + return HashHelpers.Combine( + this.L.GetHashCode(), + this.U.GetHashCode(), + this.V.GetHashCode(), + this.WhitePoint.GetHashCode()); } /// diff --git a/src/ImageSharp/ColorSpaces/CieXyy.cs b/src/ImageSharp/ColorSpaces/CieXyy.cs index 7137360e94..1d5d2de53c 100644 --- a/src/ImageSharp/ColorSpaces/CieXyy.cs +++ b/src/ImageSharp/ColorSpaces/CieXyy.cs @@ -85,9 +85,10 @@ namespace SixLabors.ImageSharp.ColorSpaces /// public override int GetHashCode() { - int hash = this.X.GetHashCode(); - hash = HashHelpers.Combine(hash, this.Y.GetHashCode()); - return HashHelpers.Combine(hash, this.Yl.GetHashCode()); + return HashHelpers.Combine( + this.X.GetHashCode(), + this.Y.GetHashCode(), + this.Yl.GetHashCode()); } /// diff --git a/src/ImageSharp/ColorSpaces/CieXyz.cs b/src/ImageSharp/ColorSpaces/CieXyz.cs index c0ed356601..6c9ea65e66 100644 --- a/src/ImageSharp/ColorSpaces/CieXyz.cs +++ b/src/ImageSharp/ColorSpaces/CieXyz.cs @@ -88,9 +88,10 @@ namespace SixLabors.ImageSharp.ColorSpaces /// public override int GetHashCode() { - int hash = this.X.GetHashCode(); - hash = HashHelpers.Combine(hash, this.Y.GetHashCode()); - return HashHelpers.Combine(hash, this.Z.GetHashCode()); + return HashHelpers.Combine( + this.X.GetHashCode(), + this.Y.GetHashCode(), + this.Z.GetHashCode()); } /// diff --git a/src/ImageSharp/ColorSpaces/Cmyk.cs b/src/ImageSharp/ColorSpaces/Cmyk.cs index 634667c0c6..241a8b325f 100644 --- a/src/ImageSharp/ColorSpaces/Cmyk.cs +++ b/src/ImageSharp/ColorSpaces/Cmyk.cs @@ -92,10 +92,11 @@ namespace SixLabors.ImageSharp.ColorSpaces [MethodImpl(InliningOptions.ShortMethod)] public override int GetHashCode() { - int hash = this.C.GetHashCode(); - hash = HashHelpers.Combine(hash, this.M.GetHashCode()); - hash = HashHelpers.Combine(hash, this.Y.GetHashCode()); - return HashHelpers.Combine(hash, this.K.GetHashCode()); + return HashHelpers.Combine( + this.C.GetHashCode(), + this.M.GetHashCode(), + this.Y.GetHashCode(), + this.K.GetHashCode()); } /// diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/RGBPrimariesChromaticityCoordinates.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/RGBPrimariesChromaticityCoordinates.cs index 68b4d95fc6..ba6da5a85a 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/RGBPrimariesChromaticityCoordinates.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/RGBPrimariesChromaticityCoordinates.cs @@ -88,12 +88,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation /// public override int GetHashCode() { - unchecked - { - int hashCode = this.R.GetHashCode(); - hashCode = (hashCode * 397) ^ this.G.GetHashCode(); - return (hashCode * 397) ^ this.B.GetHashCode(); - } + return HashHelpers.Combine(this.R.GetHashCode(), this.G.GetHashCode(), this.B.GetHashCode()); } } } \ No newline at end of file diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/WorkingSpaces/GammaWorkingSpace.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/WorkingSpaces/GammaWorkingSpace.cs index 73aa60b6cb..271278ad78 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/WorkingSpaces/GammaWorkingSpace.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/WorkingSpaces/GammaWorkingSpace.cs @@ -57,10 +57,6 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation } /// - public override int GetHashCode() - { - int hash = base.GetHashCode(); - return HashHelpers.Combine(hash, this.Gamma.GetHashCode()); - } + public override int GetHashCode() => HashHelpers.Combine(base.GetHashCode(), this.Gamma.GetHashCode()); } } \ No newline at end of file diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/WorkingSpaces/RgbWorkingSpaceBase.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/WorkingSpaces/RgbWorkingSpaceBase.cs index 5a89321c8f..70d3cccedc 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/WorkingSpaces/RgbWorkingSpaceBase.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/WorkingSpaces/RgbWorkingSpaceBase.cs @@ -76,8 +76,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation /// public override int GetHashCode() { - int hash = this.WhitePoint.GetHashCode(); - return HashHelpers.Combine(hash, this.ChromaticityCoordinates.GetHashCode()); + return HashHelpers.Combine(this.WhitePoint.GetHashCode(), this.ChromaticityCoordinates.GetHashCode()); } } } \ No newline at end of file diff --git a/src/ImageSharp/ColorSpaces/Hsl.cs b/src/ImageSharp/ColorSpaces/Hsl.cs index f6e531df35..1b92d5e88f 100644 --- a/src/ImageSharp/ColorSpaces/Hsl.cs +++ b/src/ImageSharp/ColorSpaces/Hsl.cs @@ -86,9 +86,10 @@ namespace SixLabors.ImageSharp.ColorSpaces [MethodImpl(InliningOptions.ShortMethod)] public override int GetHashCode() { - int hash = this.H.GetHashCode(); - hash = HashHelpers.Combine(hash, this.S.GetHashCode()); - return HashHelpers.Combine(hash, this.L.GetHashCode()); + return HashHelpers.Combine( + this.H.GetHashCode(), + this.S.GetHashCode(), + this.L.GetHashCode()); } /// diff --git a/src/ImageSharp/ColorSpaces/Hsv.cs b/src/ImageSharp/ColorSpaces/Hsv.cs index 631f03d09f..56d798af05 100644 --- a/src/ImageSharp/ColorSpaces/Hsv.cs +++ b/src/ImageSharp/ColorSpaces/Hsv.cs @@ -84,9 +84,10 @@ namespace SixLabors.ImageSharp.ColorSpaces [MethodImpl(InliningOptions.ShortMethod)] public override int GetHashCode() { - int hash = this.H.GetHashCode(); - hash = HashHelpers.Combine(hash, this.S.GetHashCode()); - return HashHelpers.Combine(hash, this.V.GetHashCode()); + return HashHelpers.Combine( + this.H.GetHashCode(), + this.S.GetHashCode(), + this.V.GetHashCode()); } /// diff --git a/src/ImageSharp/ColorSpaces/HunterLab.cs b/src/ImageSharp/ColorSpaces/HunterLab.cs index f4fa29d314..1aa7be601f 100644 --- a/src/ImageSharp/ColorSpaces/HunterLab.cs +++ b/src/ImageSharp/ColorSpaces/HunterLab.cs @@ -119,10 +119,11 @@ namespace SixLabors.ImageSharp.ColorSpaces [MethodImpl(InliningOptions.ShortMethod)] public override int GetHashCode() { - int hash = this.L.GetHashCode(); - hash = HashHelpers.Combine(hash, this.A.GetHashCode()); - hash = HashHelpers.Combine(hash, this.B.GetHashCode()); - return HashHelpers.Combine(hash, this.WhitePoint.GetHashCode()); + return HashHelpers.Combine( + this.L.GetHashCode(), + this.A.GetHashCode(), + this.B.GetHashCode(), + this.WhitePoint.GetHashCode()); } /// diff --git a/src/ImageSharp/ColorSpaces/LinearRgb.cs b/src/ImageSharp/ColorSpaces/LinearRgb.cs index ec6d18be2b..fba27a41e9 100644 --- a/src/ImageSharp/ColorSpaces/LinearRgb.cs +++ b/src/ImageSharp/ColorSpaces/LinearRgb.cs @@ -128,9 +128,10 @@ namespace SixLabors.ImageSharp.ColorSpaces [MethodImpl(InliningOptions.ShortMethod)] public override int GetHashCode() { - int hash = this.R.GetHashCode(); - hash = HashHelpers.Combine(hash, this.G.GetHashCode()); - return HashHelpers.Combine(hash, this.B.GetHashCode()); + return HashHelpers.Combine( + this.R.GetHashCode(), + this.G.GetHashCode(), + this.B.GetHashCode()); } /// diff --git a/src/ImageSharp/ColorSpaces/Lms.cs b/src/ImageSharp/ColorSpaces/Lms.cs index 0a8b7aa7b9..0177c9712f 100644 --- a/src/ImageSharp/ColorSpaces/Lms.cs +++ b/src/ImageSharp/ColorSpaces/Lms.cs @@ -89,9 +89,10 @@ namespace SixLabors.ImageSharp.ColorSpaces /// public override int GetHashCode() { - int hash = this.L.GetHashCode(); - hash = HashHelpers.Combine(hash, this.M.GetHashCode()); - return HashHelpers.Combine(hash, this.S.GetHashCode()); + return HashHelpers.Combine( + this.L.GetHashCode(), + this.M.GetHashCode(), + this.S.GetHashCode()); } /// diff --git a/src/ImageSharp/ColorSpaces/Rgb.cs b/src/ImageSharp/ColorSpaces/Rgb.cs index 97fafbaf37..ef44d217e9 100644 --- a/src/ImageSharp/ColorSpaces/Rgb.cs +++ b/src/ImageSharp/ColorSpaces/Rgb.cs @@ -149,9 +149,10 @@ namespace SixLabors.ImageSharp.ColorSpaces /// public override int GetHashCode() { - int hash = this.R.GetHashCode(); - hash = HashHelpers.Combine(hash, this.G.GetHashCode()); - return HashHelpers.Combine(hash, this.B.GetHashCode()); + return HashHelpers.Combine( + this.R.GetHashCode(), + this.G.GetHashCode(), + this.B.GetHashCode()); } /// diff --git a/src/ImageSharp/ColorSpaces/YCbCr.cs b/src/ImageSharp/ColorSpaces/YCbCr.cs index 6aa191c2de..2287d36894 100644 --- a/src/ImageSharp/ColorSpaces/YCbCr.cs +++ b/src/ImageSharp/ColorSpaces/YCbCr.cs @@ -85,9 +85,10 @@ namespace SixLabors.ImageSharp.ColorSpaces [MethodImpl(InliningOptions.ShortMethod)] public override int GetHashCode() { - int hash = this.Y.GetHashCode(); - hash = HashHelpers.Combine(hash, this.Cb.GetHashCode()); - return HashHelpers.Combine(hash, this.Cr.GetHashCode()); + return HashHelpers.Combine( + this.Y.GetHashCode(), + this.Cb.GetHashCode(), + this.Cr.GetHashCode()); } /// diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/AdobeMarker.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/AdobeMarker.cs index af0938d302..1fa09605ef 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/AdobeMarker.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/AdobeMarker.cs @@ -102,11 +102,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder { return HashHelpers.Combine( this.DCTEncodeVersion.GetHashCode(), - HashHelpers.Combine( - this.APP14Flags0.GetHashCode(), - HashHelpers.Combine( - this.APP14Flags1.GetHashCode(), - this.ColorTransform.GetHashCode()))); + this.APP14Flags0.GetHashCode(), + this.APP14Flags1.GetHashCode(), + this.ColorTransform.GetHashCode()); } } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Curves/IccResponseCurve.cs b/src/ImageSharp/MetaData/Profiles/ICC/Curves/IccResponseCurve.cs index 02ab301bd2..16b0ddbef9 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Curves/IccResponseCurve.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Curves/IccResponseCurve.cs @@ -73,13 +73,10 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - int hashCode = (int)this.CurveType; - hashCode = (hashCode * 397) ^ (this.XyzValues?.GetHashCode() ?? 0); - hashCode = (hashCode * 397) ^ (this.ResponseArrays?.GetHashCode() ?? 0); - return hashCode; - } + return HashHelpers.Combine( + (int)this.CurveType, + this.XyzValues.GetHashCode(), + this.ResponseArrays.GetHashCode()); } private bool EqualsResponseArray(IccResponseCurve other) diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccChromaticityTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccChromaticityTagDataEntry.cs index a87dae8c5d..0a27ce2d58 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccChromaticityTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccChromaticityTagDataEntry.cs @@ -110,13 +110,10 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - int hashCode = base.GetHashCode(); - hashCode = (hashCode * 397) ^ (int)this.ColorantType; - hashCode = (hashCode * 397) ^ (this.ChannelValues?.GetHashCode() ?? 0); - return hashCode; - } + return HashHelpers.Combine( + base.GetHashCode(), + (int)this.ColorantType, + this.ChannelValues.GetHashCode()); } private static double[][] GetColorantArray(IccColorantEncoding colorantType) diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccColorantOrderTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccColorantOrderTagDataEntry.cs index 54c2056151..5b8526b7de 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccColorantOrderTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccColorantOrderTagDataEntry.cs @@ -70,10 +70,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - return (base.GetHashCode() * 397) ^ (this.ColorantNumber?.GetHashCode() ?? 0); - } + return HashHelpers.Combine(base.GetHashCode(), this.ColorantNumber.GetHashCode()); } } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccColorantTableTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccColorantTableTagDataEntry.cs index dd99a2f9fb..572df8cb8d 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccColorantTableTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccColorantTableTagDataEntry.cs @@ -72,10 +72,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - return (base.GetHashCode() * 397) ^ (this.ColorantData?.GetHashCode() ?? 0); - } + return HashHelpers.Combine(base.GetHashCode(), this.ColorantData.GetHashCode()); } } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccCurveTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccCurveTagDataEntry.cs index 77a913b14e..2884a2216d 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccCurveTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccCurveTagDataEntry.cs @@ -118,10 +118,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - return (base.GetHashCode() * 397) ^ (this.CurveData?.GetHashCode() ?? 0); - } + return HashHelpers.Combine(base.GetHashCode(), this.CurveData.GetHashCode()); } } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccDataTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccDataTagDataEntry.cs index 4510882904..9567c690c9 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccDataTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccDataTagDataEntry.cs @@ -91,13 +91,10 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - int hashCode = base.GetHashCode(); - hashCode = (hashCode * 397) ^ (this.Data?.GetHashCode() ?? 0); - hashCode = (hashCode * 397) ^ this.IsAscii.GetHashCode(); - return hashCode; - } + return HashHelpers.Combine( + base.GetHashCode(), + this.Data.GetHashCode(), + this.IsAscii.GetHashCode()); } } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccDateTimeTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccDateTimeTagDataEntry.cs index 792c653f6c..12479bb61c 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccDateTimeTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccDateTimeTagDataEntry.cs @@ -66,10 +66,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - return (base.GetHashCode() * 397) ^ this.Value.GetHashCode(); - } + return HashHelpers.Combine(base.GetHashCode(), this.Value.GetHashCode()); } } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccFix16ArrayTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccFix16ArrayTagDataEntry.cs index a76310927b..3b9cce86bb 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccFix16ArrayTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccFix16ArrayTagDataEntry.cs @@ -66,10 +66,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - return (base.GetHashCode() * 397) ^ (this.Data?.GetHashCode() ?? 0); - } + return HashHelpers.Combine(base.GetHashCode(), this.Data.GetHashCode()); } } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLut16TagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLut16TagDataEntry.cs index 9a7f2123e2..e11562f448 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLut16TagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLut16TagDataEntry.cs @@ -62,17 +62,14 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc : base(IccTypeSignature.Lut16, tagSignature) { Guard.NotNull(matrix, nameof(matrix)); - Guard.NotNull(inputValues, nameof(inputValues)); - Guard.NotNull(clutValues, nameof(clutValues)); - Guard.NotNull(outputValues, nameof(outputValues)); bool is3By3 = matrix.GetLength(0) == 3 && matrix.GetLength(1) == 3; Guard.IsTrue(is3By3, nameof(matrix), "Matrix must have a size of three by three"); this.Matrix = this.CreateMatrix(matrix); - this.InputValues = inputValues; - this.ClutValues = clutValues; - this.OutputValues = outputValues; + this.InputValues = inputValues ?? throw new ArgumentNullException(nameof(inputValues)); + this.ClutValues = clutValues ?? throw new ArgumentNullException(nameof(clutValues)); + this.OutputValues = outputValues ?? throw new ArgumentNullException(nameof(outputValues)); Guard.IsTrue(this.InputChannelCount == clutValues.InputChannelCount, nameof(clutValues), "Input channel count does not match the CLUT size"); Guard.IsTrue(this.OutputChannelCount == clutValues.OutputChannelCount, nameof(clutValues), "Output channel count does not match the CLUT size"); @@ -147,9 +144,9 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc { int hashCode = base.GetHashCode(); hashCode = (hashCode * 397) ^ this.Matrix.GetHashCode(); - hashCode = (hashCode * 397) ^ (this.InputValues?.GetHashCode() ?? 0); - hashCode = (hashCode * 397) ^ (this.ClutValues?.GetHashCode() ?? 0); - hashCode = (hashCode * 397) ^ (this.OutputValues?.GetHashCode() ?? 0); + hashCode = (hashCode * 397) ^ this.InputValues.GetHashCode(); + hashCode = (hashCode * 397) ^ this.ClutValues.GetHashCode(); + hashCode = (hashCode * 397) ^ this.OutputValues.GetHashCode(); return hashCode; } } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLut8TagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLut8TagDataEntry.cs index bc0335cd8b..b448b481a3 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLut8TagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLut8TagDataEntry.cs @@ -62,17 +62,14 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc : base(IccTypeSignature.Lut8, tagSignature) { Guard.NotNull(matrix, nameof(matrix)); - Guard.NotNull(inputValues, nameof(inputValues)); - Guard.NotNull(clutValues, nameof(clutValues)); - Guard.NotNull(outputValues, nameof(outputValues)); bool is3By3 = matrix.GetLength(0) == 3 && matrix.GetLength(1) == 3; Guard.IsTrue(is3By3, nameof(matrix), "Matrix must have a size of three by three"); this.Matrix = this.CreateMatrix(matrix); - this.InputValues = inputValues; - this.ClutValues = clutValues; - this.OutputValues = outputValues; + this.InputValues = inputValues ?? throw new ArgumentNullException(nameof(inputValues)); + this.ClutValues = clutValues ?? throw new ArgumentNullException(nameof(clutValues)); + this.OutputValues = outputValues ?? throw new ArgumentNullException(nameof(outputValues)); Guard.IsTrue(this.InputChannelCount == clutValues.InputChannelCount, nameof(clutValues), "Input channel count does not match the CLUT size"); Guard.IsTrue(this.OutputChannelCount == clutValues.OutputChannelCount, nameof(clutValues), "Output channel count does not match the CLUT size"); @@ -150,9 +147,9 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc { int hashCode = base.GetHashCode(); hashCode = (hashCode * 397) ^ this.Matrix.GetHashCode(); - hashCode = (hashCode * 397) ^ (this.InputValues?.GetHashCode() ?? 0); - hashCode = (hashCode * 397) ^ (this.ClutValues?.GetHashCode() ?? 0); - hashCode = (hashCode * 397) ^ (this.OutputValues?.GetHashCode() ?? 0); + hashCode = (hashCode * 397) ^ this.InputValues.GetHashCode(); + hashCode = (hashCode * 397) ^ this.ClutValues.GetHashCode(); + hashCode = (hashCode * 397) ^ this.OutputValues.GetHashCode(); return hashCode; } } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccMultiLocalizedUnicodeTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccMultiLocalizedUnicodeTagDataEntry.cs index 48ed048bf9..6f579a6b59 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccMultiLocalizedUnicodeTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccMultiLocalizedUnicodeTagDataEntry.cs @@ -68,10 +68,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - return (base.GetHashCode() * 397) ^ (this.Texts?.GetHashCode() ?? 0); - } + return HashHelpers.Combine(base.GetHashCode(), this.Texts.GetHashCode()); } } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccMultiProcessElementsTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccMultiProcessElementsTagDataEntry.cs index 1429a0a878..2a983a7095 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccMultiProcessElementsTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccMultiProcessElementsTagDataEntry.cs @@ -90,14 +90,11 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - int hashCode = base.GetHashCode(); - hashCode = (hashCode * 397) ^ this.InputChannelCount; - hashCode = (hashCode * 397) ^ this.OutputChannelCount; - hashCode = (hashCode * 397) ^ (this.Data?.GetHashCode() ?? 0); - return hashCode; - } + return HashHelpers.Combine( + base.GetHashCode(), + this.InputChannelCount, + this.OutputChannelCount, + this.Data.GetHashCode()); } } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccParametricCurveTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccParametricCurveTagDataEntry.cs index 46719b80f7..384129245c 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccParametricCurveTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccParametricCurveTagDataEntry.cs @@ -28,7 +28,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc public IccParametricCurveTagDataEntry(IccParametricCurve curve, IccProfileTag tagSignature) : base(IccTypeSignature.ParametricCurve, tagSignature) { - this.Curve = curve; + this.Curve = curve ?? throw new ArgumentNullException(nameof(curve)); } /// @@ -67,10 +67,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - return (base.GetHashCode() * 397) ^ (this.Curve?.GetHashCode() ?? 0); - } + return HashHelpers.Combine(base.GetHashCode(), this.Curve.GetHashCode()); } } } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccProfileSequenceDescTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccProfileSequenceDescTagDataEntry.cs index da6fcd7a2a..a337d76ef5 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccProfileSequenceDescTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccProfileSequenceDescTagDataEntry.cs @@ -69,10 +69,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - return (base.GetHashCode() * 397) ^ (this.Descriptions?.GetHashCode() ?? 0); - } + return HashHelpers.Combine(base.GetHashCode(), this.Descriptions.GetHashCode()); } } } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccProfileSequenceIdentifierTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccProfileSequenceIdentifierTagDataEntry.cs index 51528a0736..9c199bfdb5 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccProfileSequenceIdentifierTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccProfileSequenceIdentifierTagDataEntry.cs @@ -67,10 +67,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - return (base.GetHashCode() * 397) ^ (this.Data?.GetHashCode() ?? 0); - } + return HashHelpers.Combine(base.GetHashCode(), this.Data.GetHashCode()); } } } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccResponseCurveSet16TagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccResponseCurveSet16TagDataEntry.cs index e2cd5860bc..6d321eb751 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccResponseCurveSet16TagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccResponseCurveSet16TagDataEntry.cs @@ -83,13 +83,10 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - int hashCode = base.GetHashCode(); - hashCode = (hashCode * 397) ^ this.ChannelCount.GetHashCode(); - hashCode = (hashCode * 397) ^ (this.Curves?.GetHashCode() ?? 0); - return hashCode; - } + return HashHelpers.Combine( + base.GetHashCode(), + this.ChannelCount.GetHashCode(), + this.Curves.GetHashCode()); } } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccScreeningTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccScreeningTagDataEntry.cs index 0bf8abfcac..d13c2af909 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccScreeningTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccScreeningTagDataEntry.cs @@ -77,13 +77,10 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - int hashCode = base.GetHashCode(); - hashCode = (hashCode * 397) ^ (int)this.Flags; - hashCode = (hashCode * 397) ^ (this.Channels?.GetHashCode() ?? 0); - return hashCode; - } + return HashHelpers.Combine( + base.GetHashCode(), + (int)this.Flags, + this.Channels.GetHashCode()); } } } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccSignatureTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccSignatureTagDataEntry.cs index da557e644f..d89f3ef244 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccSignatureTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccSignatureTagDataEntry.cs @@ -67,10 +67,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - return (base.GetHashCode() * 397) ^ (this.SignatureData?.GetHashCode() ?? 0); - } + return HashHelpers.Combine(base.GetHashCode(), this.SignatureData.GetHashCode()); } } } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccTextTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccTextTagDataEntry.cs index f10712d96c..0ff7de5512 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccTextTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccTextTagDataEntry.cs @@ -66,10 +66,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - return (base.GetHashCode() * 397) ^ (this.Text?.GetHashCode() ?? 0); - } + return HashHelpers.Combine(base.GetHashCode(), this.Text.GetHashCode()); } } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUFix16ArrayTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUFix16ArrayTagDataEntry.cs index 19430dc7b8..4b03f1b830 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUFix16ArrayTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUFix16ArrayTagDataEntry.cs @@ -66,10 +66,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - return (base.GetHashCode() * 397) ^ (this.Data?.GetHashCode() ?? 0); - } + return HashHelpers.Combine(base.GetHashCode(), this.Data.GetHashCode()); } } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt16ArrayTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt16ArrayTagDataEntry.cs index d9c093bda0..1536739846 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt16ArrayTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt16ArrayTagDataEntry.cs @@ -66,10 +66,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - return (base.GetHashCode() * 397) ^ (this.Data?.GetHashCode() ?? 0); - } + return HashHelpers.Combine(base.GetHashCode(), this.Data.GetHashCode()); } } } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt32ArrayTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt32ArrayTagDataEntry.cs index 8031919290..14ccebb2ab 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt32ArrayTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt32ArrayTagDataEntry.cs @@ -66,10 +66,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - return (base.GetHashCode() * 397) ^ (this.Data?.GetHashCode() ?? 0); - } + return HashHelpers.Combine(base.GetHashCode(), this.Data.GetHashCode()); } } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt64ArrayTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt64ArrayTagDataEntry.cs index 2973b9ae6b..1819c7724e 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt64ArrayTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt64ArrayTagDataEntry.cs @@ -67,10 +67,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - return (base.GetHashCode() * 397) ^ (this.Data?.GetHashCode() ?? 0); - } + return HashHelpers.Combine(base.GetHashCode(), this.Data.GetHashCode()); } } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt8ArrayTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt8ArrayTagDataEntry.cs index 2391ce96a6..ca4345e2b9 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt8ArrayTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt8ArrayTagDataEntry.cs @@ -66,10 +66,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - return (base.GetHashCode() * 397) ^ (this.Data?.GetHashCode() ?? 0); - } + return HashHelpers.Combine(base.GetHashCode(), this.Data.GetHashCode()); } } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUcrBgTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUcrBgTagDataEntry.cs index eed4f97d47..3992fde109 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUcrBgTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUcrBgTagDataEntry.cs @@ -86,14 +86,11 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - int hashCode = base.GetHashCode(); - hashCode = (hashCode * 397) ^ (this.UcrCurve?.GetHashCode() ?? 0); - hashCode = (hashCode * 397) ^ (this.BgCurve?.GetHashCode() ?? 0); - hashCode = (hashCode * 397) ^ (this.Description?.GetHashCode() ?? 0); - return hashCode; - } + return HashHelpers.Combine( + base.GetHashCode(), + this.UcrCurve.GetHashCode(), + this.BgCurve.GetHashCode(), + this.Description.GetHashCode()); } } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUnknownTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUnknownTagDataEntry.cs index da206a968b..f6a4149b46 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUnknownTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUnknownTagDataEntry.cs @@ -66,10 +66,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - return (base.GetHashCode() * 397) ^ (this.Data?.GetHashCode() ?? 0); - } + return HashHelpers.Combine(base.GetHashCode(), this.Data.GetHashCode()); } } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccViewingConditionsTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccViewingConditionsTagDataEntry.cs index 6be21dcc95..df53957b13 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccViewingConditionsTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccViewingConditionsTagDataEntry.cs @@ -86,14 +86,11 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - int hashCode = base.GetHashCode(); - hashCode = (hashCode * 397) ^ this.IlluminantXyz.GetHashCode(); - hashCode = (hashCode * 397) ^ this.SurroundXyz.GetHashCode(); - hashCode = (hashCode * 397) ^ (int)this.Illuminant; - return hashCode; - } + return HashHelpers.Combine( + base.GetHashCode(), + this.IlluminantXyz.GetHashCode(), + this.SurroundXyz.GetHashCode(), + (int)this.Illuminant); } } } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccClut.cs b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccClut.cs index 4878d96e4b..3424a11ed7 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccClut.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccClut.cs @@ -144,11 +144,11 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc { unchecked { - int hashCode = this.Values?.GetHashCode() ?? 0; + int hashCode = this.Values.GetHashCode(); hashCode = (hashCode * 397) ^ (int)this.DataType; hashCode = (hashCode * 397) ^ this.InputChannelCount; hashCode = (hashCode * 397) ^ this.OutputChannelCount; - hashCode = (hashCode * 397) ^ (this.GridPointCount?.GetHashCode() ?? 0); + hashCode = (hashCode * 397) ^ this.GridPointCount.GetHashCode(); return hashCode; } } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccColorantTableEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccColorantTableEntry.cs index 56aa8b335d..628934600a 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccColorantTableEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccColorantTableEntry.cs @@ -102,14 +102,11 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - int hashCode = this.Name.GetHashCode(); - hashCode = (hashCode * 397) ^ this.Pcs1.GetHashCode(); - hashCode = (hashCode * 397) ^ this.Pcs2.GetHashCode(); - hashCode = (hashCode * 397) ^ this.Pcs3.GetHashCode(); - return hashCode; - } + return HashHelpers.Combine( + this.Name.GetHashCode(), + this.Pcs1.GetHashCode(), + this.Pcs2.GetHashCode(), + this.Pcs3.GetHashCode()); } /// diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccNamedColor.cs b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccNamedColor.cs index 5b013fc2c1..5889e5c213 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccNamedColor.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccNamedColor.cs @@ -80,27 +80,23 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc } /// - public bool Equals(IccNamedColor other) => - this.Name == other.Name && - this.PcsCoordinates.SequenceEqual(other.PcsCoordinates) && - this.DeviceCoordinates.SequenceEqual(other.DeviceCoordinates); + public bool Equals(IccNamedColor other) + { + return this.Name.Equals(other.Name) + && this.PcsCoordinates.SequenceEqual(other.PcsCoordinates) + && this.DeviceCoordinates.SequenceEqual(other.DeviceCoordinates); + } /// public override int GetHashCode() { - unchecked - { - int hashCode = this.Name.GetHashCode(); - hashCode = (hashCode * 397) ^ this.PcsCoordinates.GetHashCode(); - hashCode = (hashCode * 397) ^ this.DeviceCoordinates.GetHashCode(); - return hashCode; - } + return HashHelpers.Combine( + this.Name.GetHashCode(), + this.PcsCoordinates.GetHashCode(), + this.DeviceCoordinates.GetHashCode()); } /// - public override string ToString() - { - return this.Name; - } + public override string ToString() => this.Name; } } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccPositionNumber.cs b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccPositionNumber.cs index aad130b0de..745312f563 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccPositionNumber.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccPositionNumber.cs @@ -73,15 +73,9 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc this.Size == other.Size; /// - public override int GetHashCode() - { - return unchecked((int)(this.Offset ^ this.Size)); - } + public override int GetHashCode() => unchecked((int)(this.Offset ^ this.Size)); /// - public override string ToString() - { - return $"{this.Offset}; {this.Size}"; - } + public override string ToString() => $"{this.Offset}; {this.Size}"; } } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileDescription.cs b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileDescription.cs index 9db4bb9c48..4319b0e8ba 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileDescription.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileDescription.cs @@ -28,15 +28,12 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc IccLocalizedString[] deviceManufacturerInfo, IccLocalizedString[] deviceModelInfo) { - Guard.NotNull(deviceManufacturerInfo, nameof(deviceManufacturerInfo)); - Guard.NotNull(deviceModelInfo, nameof(deviceModelInfo)); - this.DeviceManufacturer = deviceManufacturer; this.DeviceModel = deviceModel; this.DeviceAttributes = deviceAttributes; this.TechnologyInformation = technologyInformation; - this.DeviceManufacturerInfo = deviceManufacturerInfo; - this.DeviceModelInfo = deviceModelInfo; + this.DeviceManufacturerInfo = deviceManufacturerInfo ?? throw new ArgumentNullException(nameof(deviceManufacturerInfo)); + this.DeviceModelInfo = deviceModelInfo ?? throw new ArgumentNullException(nameof(deviceModelInfo)); } /// @@ -93,8 +90,8 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc hashCode = (hashCode * 397) ^ (int)this.DeviceModel; hashCode = (hashCode * 397) ^ this.DeviceAttributes.GetHashCode(); hashCode = (hashCode * 397) ^ (int)this.TechnologyInformation; - hashCode = (hashCode * 397) ^ (this.DeviceManufacturerInfo?.GetHashCode() ?? 0); - hashCode = (hashCode * 397) ^ (this.DeviceModelInfo?.GetHashCode() ?? 0); + hashCode = (hashCode * 397) ^ this.DeviceManufacturerInfo.GetHashCode(); + hashCode = (hashCode * 397) ^ this.DeviceModelInfo.GetHashCode(); return hashCode; } } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileId.cs b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileId.cs index 1389997109..2748e7da72 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileId.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileId.cs @@ -101,14 +101,11 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - int hashCode = this.Part1.GetHashCode(); - hashCode = (hashCode * 397) ^ this.Part2.GetHashCode(); - hashCode = (hashCode * 397) ^ this.Part3.GetHashCode(); - hashCode = (hashCode * 397) ^ this.Part4.GetHashCode(); - return hashCode; - } + return HashHelpers.Combine( + this.Part1.GetHashCode(), + this.Part2.GetHashCode(), + this.Part3.GetHashCode(), + this.Part4.GetHashCode()); } /// diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileSequenceIdentifier.cs b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileSequenceIdentifier.cs index d5362ad706..5422a1b5f1 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileSequenceIdentifier.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileSequenceIdentifier.cs @@ -18,10 +18,8 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// Description of the profile public IccProfileSequenceIdentifier(IccProfileId id, IccLocalizedString[] description) { - Guard.NotNull(description, nameof(description)); - this.Id = id; - this.Description = description; + this.Description = description ?? throw new ArgumentNullException(nameof(description)); } /// @@ -48,10 +46,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - return (this.Id.GetHashCode() * 397) ^ (this.Description?.GetHashCode() ?? 0); - } + return HashHelpers.Combine(this.Id.GetHashCode(), this.Description.GetHashCode()); } } } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccResponseNumber.cs b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccResponseNumber.cs index d1da2366e7..c0bae296d8 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccResponseNumber.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccResponseNumber.cs @@ -75,12 +75,9 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - int hashCode = this.DeviceCode.GetHashCode(); - hashCode = (hashCode * 397) ^ this.MeasurementValue.GetHashCode(); - return hashCode; - } + return HashHelpers.Combine( + this.DeviceCode.GetHashCode(), + this.MeasurementValue.GetHashCode()); } /// diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccScreeningChannel.cs b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccScreeningChannel.cs index 1c4ac8465c..f2e1f31a5f 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccScreeningChannel.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccScreeningChannel.cs @@ -85,13 +85,10 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - int hashCode = this.Frequency.GetHashCode(); - hashCode = (hashCode * 397) ^ this.Angle.GetHashCode(); - hashCode = (hashCode * 397) ^ (int)this.SpotShape; - return hashCode; - } + return HashHelpers.Combine( + this.Frequency.GetHashCode(), + this.Angle.GetHashCode(), + (int)this.SpotShape); } /// diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccTagTableEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccTagTableEntry.cs index 04357dcf67..082ffc6790 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccTagTableEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccTagTableEntry.cs @@ -83,13 +83,10 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - int hashCode = this.Signature.GetHashCode(); - hashCode = (hashCode * 397) ^ this.Offset.GetHashCode(); - hashCode = (hashCode * 397) ^ this.DataSize.GetHashCode(); - return hashCode; - } + return HashHelpers.Combine( + this.Signature.GetHashCode(), + this.Offset.GetHashCode(), + this.DataSize.GetHashCode()); } /// diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Bgr24.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Bgr24.cs index 9207f046c4..6afa33aff8 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Bgr24.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Bgr24.cs @@ -191,8 +191,7 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public override int GetHashCode() { - int hash = HashHelpers.Combine(this.R.GetHashCode(), this.G.GetHashCode()); - return HashHelpers.Combine(hash, this.B.GetHashCode()); + return HashHelpers.Combine(this.R.GetHashCode(), this.B.GetHashCode(), this.G.GetHashCode()); } } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Rgb24.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Rgb24.cs index 293fe0acbf..fe7c299d55 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Rgb24.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Rgb24.cs @@ -202,8 +202,7 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public override int GetHashCode() { - int hash = HashHelpers.Combine(this.R.GetHashCode(), this.G.GetHashCode()); - return HashHelpers.Combine(hash, this.B.GetHashCode()); + return HashHelpers.Combine(this.R.GetHashCode(), this.B.GetHashCode(), this.G.GetHashCode()); } /// diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Rgb48.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Rgb48.cs index 81497e5f18..8d06cdbc8f 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Rgb48.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Rgb48.cs @@ -191,9 +191,7 @@ namespace SixLabors.ImageSharp.PixelFormats [MethodImpl(InliningOptions.ShortMethod)] public override int GetHashCode() { - return HashHelpers.Combine( - this.R.GetHashCode(), - HashHelpers.Combine(this.G.GetHashCode(), this.B.GetHashCode())); + return HashHelpers.Combine(this.R.GetHashCode(), this.G.GetHashCode(), this.B.GetHashCode()); } } } \ No newline at end of file From c78fc1d2bda335f9a08672423166c371d8ab14ca Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Wed, 5 Dec 2018 09:45:18 -0800 Subject: [PATCH 15/40] Replace == null with is null --- src/ImageSharp/Formats/Png/PngEncoderCore.cs | 2 +- src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs | 2 +- .../Processors/Dithering/PaletteDitherProcessorBase.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ImageSharp/Formats/Png/PngEncoderCore.cs b/src/ImageSharp/Formats/Png/PngEncoderCore.cs index 292de007ca..216f3129f9 100644 --- a/src/ImageSharp/Formats/Png/PngEncoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngEncoderCore.cs @@ -237,7 +237,7 @@ namespace SixLabors.ImageSharp.Formats.Png } // Use the metadata to determine what quantization depth to use if no quantizer has been set. - if (this.quantizer == null) + if (this.quantizer is null) { this.quantizer = new WuQuantizer(ImageMaths.GetColorCountForBitDepth(bits)); } diff --git a/src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs b/src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs index 514959312b..8ec9eea275 100644 --- a/src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs +++ b/src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs @@ -372,7 +372,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif private void AddInvalidTag(ExifTag tag) { - if (this.invalidTags == null) + if (this.invalidTags is null) { this.invalidTags = new List(); } diff --git a/src/ImageSharp/Processing/Processors/Dithering/PaletteDitherProcessorBase.cs b/src/ImageSharp/Processing/Processors/Dithering/PaletteDitherProcessorBase.cs index f01865ec05..43f6c8a454 100644 --- a/src/ImageSharp/Processing/Processors/Dithering/PaletteDitherProcessorBase.cs +++ b/src/ImageSharp/Processing/Processors/Dithering/PaletteDitherProcessorBase.cs @@ -95,7 +95,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering base.BeforeFrameApply(source, sourceRectangle, configuration); // Lazy init paletteVector: - if (this.paletteVector == null) + if (this.paletteVector is null) { this.paletteVector = new Vector4[this.Palette.Length]; PixelOperations.Instance.ToScaledVector4(configuration, this.Palette, this.paletteVector); From d0f78c2a87e45ef91e926747cf623bc776f4fc38 Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Thu, 6 Dec 2018 08:39:10 -0800 Subject: [PATCH 16/40] Update (hashCode * 397) pattern to use HashHelpers --- src/ImageSharp/MetaData/ImageProperty.cs | 2 +- .../Profiles/ICC/Curves/IccParametricCurve.cs | 14 +++++------ .../MetaData/Profiles/ICC/IccTagDataEntry.cs | 8 +------ .../TagDataEntries/IccCrdInfoTagDataEntry.cs | 10 ++++---- .../TagDataEntries/IccLut16TagDataEntry.cs | 15 +++++------- .../ICC/TagDataEntries/IccLut8TagDataEntry.cs | 15 +++++------- .../TagDataEntries/IccLutAToBTagDataEntry.cs | 23 ++++++++----------- .../TagDataEntries/IccLutBToATagDataEntry.cs | 19 +++++++-------- .../IccMeasurementTagDataEntry.cs | 17 ++++++-------- .../IccNamedColor2TagDataEntry.cs | 18 +++++++-------- .../IccTextDescriptionTagDataEntry.cs | 17 ++++++-------- .../MetaData/Profiles/ICC/Various/IccClut.cs | 15 +++++------- .../ICC/Various/IccProfileDescription.cs | 17 ++++++-------- 13 files changed, 79 insertions(+), 111 deletions(-) diff --git a/src/ImageSharp/MetaData/ImageProperty.cs b/src/ImageSharp/MetaData/ImageProperty.cs index a08a95fed4..4644f9b68d 100644 --- a/src/ImageSharp/MetaData/ImageProperty.cs +++ b/src/ImageSharp/MetaData/ImageProperty.cs @@ -106,7 +106,7 @@ namespace SixLabors.ImageSharp.MetaData int hashCode = this.Name.GetHashCode(); if (this.Value != null) { - hashCode = (hashCode * 397) ^ this.Value.GetHashCode(); + hashCode = HashHelpers.Combine(hashCode, this.Value.GetHashCode()); } return hashCode; diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Curves/IccParametricCurve.cs b/src/ImageSharp/MetaData/Profiles/ICC/Curves/IccParametricCurve.cs index a241acd216..f707ee595e 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Curves/IccParametricCurve.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Curves/IccParametricCurve.cs @@ -157,13 +157,13 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc unchecked { int hashCode = (int)this.Type; - hashCode = (hashCode * 397) ^ this.G.GetHashCode(); - hashCode = (hashCode * 397) ^ this.A.GetHashCode(); - hashCode = (hashCode * 397) ^ this.B.GetHashCode(); - hashCode = (hashCode * 397) ^ this.C.GetHashCode(); - hashCode = (hashCode * 397) ^ this.D.GetHashCode(); - hashCode = (hashCode * 397) ^ this.E.GetHashCode(); - hashCode = (hashCode * 397) ^ this.F.GetHashCode(); + hashCode = HashHelpers.Combine(hashCode, this.G.GetHashCode()); + hashCode = HashHelpers.Combine(hashCode, this.A.GetHashCode()); + hashCode = HashHelpers.Combine(hashCode, this.B.GetHashCode()); + hashCode = HashHelpers.Combine(hashCode, this.C.GetHashCode()); + hashCode = HashHelpers.Combine(hashCode, this.D.GetHashCode()); + hashCode = HashHelpers.Combine(hashCode, this.E.GetHashCode()); + hashCode = HashHelpers.Combine(hashCode, this.F.GetHashCode()); return hashCode; } } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/IccTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/IccTagDataEntry.cs index 2687e10b66..4c6bb07858 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/IccTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/IccTagDataEntry.cs @@ -64,12 +64,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc } /// - public override int GetHashCode() - { - unchecked - { - return (int)this.Signature * 397; - } - } + public override int GetHashCode() => this.Signature.GetHashCode(); } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccCrdInfoTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccCrdInfoTagDataEntry.cs index cc1aea3192..9af77ba7c4 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccCrdInfoTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccCrdInfoTagDataEntry.cs @@ -124,11 +124,11 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc unchecked { int hashCode = base.GetHashCode(); - hashCode = (hashCode * 397) ^ (this.PostScriptProductName?.GetHashCode() ?? 0); - hashCode = (hashCode * 397) ^ (this.RenderingIntent0Crd?.GetHashCode() ?? 0); - hashCode = (hashCode * 397) ^ (this.RenderingIntent1Crd?.GetHashCode() ?? 0); - hashCode = (hashCode * 397) ^ (this.RenderingIntent2Crd?.GetHashCode() ?? 0); - hashCode = (hashCode * 397) ^ (this.RenderingIntent3Crd?.GetHashCode() ?? 0); + hashCode = HashHelpers.Combine(hashCode, this.PostScriptProductName?.GetHashCode() ?? 0); + hashCode = HashHelpers.Combine(hashCode, this.RenderingIntent0Crd?.GetHashCode() ?? 0); + hashCode = HashHelpers.Combine(hashCode, this.RenderingIntent1Crd?.GetHashCode() ?? 0); + hashCode = HashHelpers.Combine(hashCode, this.RenderingIntent2Crd?.GetHashCode() ?? 0); + hashCode = HashHelpers.Combine(hashCode, this.RenderingIntent3Crd?.GetHashCode() ?? 0); return hashCode; } } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLut16TagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLut16TagDataEntry.cs index e11562f448..281b17ba96 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLut16TagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLut16TagDataEntry.cs @@ -140,15 +140,12 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - int hashCode = base.GetHashCode(); - hashCode = (hashCode * 397) ^ this.Matrix.GetHashCode(); - hashCode = (hashCode * 397) ^ this.InputValues.GetHashCode(); - hashCode = (hashCode * 397) ^ this.ClutValues.GetHashCode(); - hashCode = (hashCode * 397) ^ this.OutputValues.GetHashCode(); - return hashCode; - } + int hashCode = base.GetHashCode(); + hashCode = HashHelpers.Combine(hashCode, this.Matrix.GetHashCode()); + hashCode = HashHelpers.Combine(hashCode, this.InputValues.GetHashCode()); + hashCode = HashHelpers.Combine(hashCode, this.ClutValues.GetHashCode()); + hashCode = HashHelpers.Combine(hashCode, this.OutputValues.GetHashCode()); + return hashCode; } private Matrix4x4 CreateMatrix(float[,] matrix) diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLut8TagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLut8TagDataEntry.cs index b448b481a3..e3c45adb49 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLut8TagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLut8TagDataEntry.cs @@ -143,15 +143,12 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - int hashCode = base.GetHashCode(); - hashCode = (hashCode * 397) ^ this.Matrix.GetHashCode(); - hashCode = (hashCode * 397) ^ this.InputValues.GetHashCode(); - hashCode = (hashCode * 397) ^ this.ClutValues.GetHashCode(); - hashCode = (hashCode * 397) ^ this.OutputValues.GetHashCode(); - return hashCode; - } + int hashCode = base.GetHashCode(); + hashCode = HashHelpers.Combine(hashCode, this.Matrix.GetHashCode()); + hashCode = HashHelpers.Combine(hashCode, this.InputValues.GetHashCode()); + hashCode = HashHelpers.Combine(hashCode, this.ClutValues.GetHashCode()); + hashCode = HashHelpers.Combine(hashCode, this.OutputValues.GetHashCode()); + return hashCode; } private Matrix4x4 CreateMatrix(float[,] matrix) diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLutAToBTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLutAToBTagDataEntry.cs index 22d5f7b2f1..3dadee2da6 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLutAToBTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLutAToBTagDataEntry.cs @@ -183,19 +183,16 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - int hashCode = base.GetHashCode(); - hashCode = (hashCode * 397) ^ this.InputChannelCount; - hashCode = (hashCode * 397) ^ this.OutputChannelCount; - hashCode = (hashCode * 397) ^ this.Matrix3x3.GetHashCode(); - hashCode = (hashCode * 397) ^ this.Matrix3x1.GetHashCode(); - hashCode = (hashCode * 397) ^ (this.ClutValues?.GetHashCode() ?? 0); - hashCode = (hashCode * 397) ^ (this.CurveB?.GetHashCode() ?? 0); - hashCode = (hashCode * 397) ^ (this.CurveM?.GetHashCode() ?? 0); - hashCode = (hashCode * 397) ^ (this.CurveA?.GetHashCode() ?? 0); - return hashCode; - } + int hashCode = base.GetHashCode(); + hashCode = HashHelpers.Combine(hashCode, this.InputChannelCount.GetHashCode()); + hashCode = HashHelpers.Combine(hashCode, this.OutputChannelCount.GetHashCode()); + hashCode = HashHelpers.Combine(hashCode, this.Matrix3x3.GetHashCode()); + hashCode = HashHelpers.Combine(hashCode, this.Matrix3x1.GetHashCode()); + hashCode = HashHelpers.Combine(hashCode, this.ClutValues?.GetHashCode() ?? 0); + hashCode = HashHelpers.Combine(hashCode, this.CurveB?.GetHashCode() ?? 0); + hashCode = HashHelpers.Combine(hashCode, this.CurveM?.GetHashCode() ?? 0); + hashCode = HashHelpers.Combine(hashCode, this.CurveA?.GetHashCode() ?? 0); + return hashCode; } private bool EqualsCurve(IccTagDataEntry[] thisCurves, IccTagDataEntry[] entryCurves) diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLutBToATagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLutBToATagDataEntry.cs index a739358b56..09d0803802 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLutBToATagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLutBToATagDataEntry.cs @@ -183,19 +183,16 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { int hashCode = base.GetHashCode(); - hashCode = (hashCode * 397) ^ this.InputChannelCount; - hashCode = (hashCode * 397) ^ this.OutputChannelCount; - hashCode = (hashCode * 397) ^ this.Matrix3x3.GetHashCode(); - hashCode = (hashCode * 397) ^ this.Matrix3x1.GetHashCode(); - hashCode = (hashCode * 397) ^ (this.ClutValues?.GetHashCode() ?? 0); - hashCode = (hashCode * 397) ^ (this.CurveB?.GetHashCode() ?? 0); - hashCode = (hashCode * 397) ^ (this.CurveM?.GetHashCode() ?? 0); - hashCode = (hashCode * 397) ^ (this.CurveA?.GetHashCode() ?? 0); + hashCode = HashHelpers.Combine(hashCode, this.InputChannelCount.GetHashCode()); + hashCode = HashHelpers.Combine(hashCode, this.OutputChannelCount.GetHashCode()); + hashCode = HashHelpers.Combine(hashCode, this.Matrix3x3.GetHashCode()); + hashCode = HashHelpers.Combine(hashCode, this.Matrix3x1.GetHashCode()); + hashCode = HashHelpers.Combine(hashCode, this.ClutValues?.GetHashCode() ?? 0); + hashCode = HashHelpers.Combine(hashCode, this.CurveB?.GetHashCode() ?? 0); + hashCode = HashHelpers.Combine(hashCode, this.CurveM?.GetHashCode() ?? 0); + hashCode = HashHelpers.Combine(hashCode, this.CurveA?.GetHashCode() ?? 0); return hashCode; - } } private bool EqualsCurve(IccTagDataEntry[] thisCurves, IccTagDataEntry[] entryCurves) diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccMeasurementTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccMeasurementTagDataEntry.cs index 262129a380..6f918660ff 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccMeasurementTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccMeasurementTagDataEntry.cs @@ -106,16 +106,13 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - int hashCode = base.GetHashCode(); - hashCode = (hashCode * 397) ^ (int)this.Observer; - hashCode = (hashCode * 397) ^ this.XyzBacking.GetHashCode(); - hashCode = (hashCode * 397) ^ (int)this.Geometry; - hashCode = (hashCode * 397) ^ this.Flare.GetHashCode(); - hashCode = (hashCode * 397) ^ (int)this.Illuminant; - return hashCode; - } + int hashCode = base.GetHashCode(); + hashCode = HashHelpers.Combine(hashCode, this.Observer.GetHashCode()); + hashCode = HashHelpers.Combine(hashCode, this.XyzBacking.GetHashCode()); + hashCode = HashHelpers.Combine(hashCode, this.Geometry.GetHashCode()); + hashCode = HashHelpers.Combine(hashCode, this.Flare.GetHashCode()); + hashCode = HashHelpers.Combine(hashCode, this.Illuminant.GetHashCode()); + return hashCode; } } } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccNamedColor2TagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccNamedColor2TagDataEntry.cs index c32a45182d..0da1f3e9fc 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccNamedColor2TagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccNamedColor2TagDataEntry.cs @@ -83,6 +83,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc if (colors.Length > 0) { coordinateCount = colors[0].DeviceCoordinates?.Length ?? 0; + Guard.IsFalse(colors.Any(t => (t.DeviceCoordinates?.Length ?? 0) != coordinateCount), nameof(colors), "Device coordinate count must be the same for all colors"); } @@ -154,16 +155,13 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - int hashCode = base.GetHashCode(); - hashCode = (hashCode * 397) ^ this.CoordinateCount; - hashCode = (hashCode * 397) ^ (this.Prefix?.GetHashCode() ?? 0); - hashCode = (hashCode * 397) ^ (this.Suffix?.GetHashCode() ?? 0); - hashCode = (hashCode * 397) ^ this.VendorFlags; - hashCode = (hashCode * 397) ^ (this.Colors?.GetHashCode() ?? 0); - return hashCode; - } + int hashCode = base.GetHashCode(); + hashCode = HashHelpers.Combine(hashCode, this.CoordinateCount.GetHashCode()); + hashCode = HashHelpers.Combine(hashCode, this.Prefix?.GetHashCode() ?? 0); + hashCode = HashHelpers.Combine(hashCode, this.Suffix?.GetHashCode() ?? 0); + hashCode = HashHelpers.Combine(hashCode, this.VendorFlags.GetHashCode()); + hashCode = HashHelpers.Combine(hashCode, this.Colors.GetHashCode()); + return hashCode; } } } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccTextDescriptionTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccTextDescriptionTagDataEntry.cs index ca1e4c4915..9f9e5cef7b 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccTextDescriptionTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccTextDescriptionTagDataEntry.cs @@ -166,16 +166,13 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - int hashCode = base.GetHashCode(); - hashCode = (hashCode * 397) ^ (this.Ascii?.GetHashCode() ?? 0); - hashCode = (hashCode * 397) ^ (this.Unicode?.GetHashCode() ?? 0); - hashCode = (hashCode * 397) ^ (this.ScriptCode?.GetHashCode() ?? 0); - hashCode = (hashCode * 397) ^ (int)this.UnicodeLanguageCode; - hashCode = (hashCode * 397) ^ this.ScriptCodeCode.GetHashCode(); - return hashCode; - } + int hashCode = base.GetHashCode(); + hashCode = HashHelpers.Combine(hashCode, this.Ascii?.GetHashCode() ?? 0); + hashCode = HashHelpers.Combine(hashCode, this.Unicode?.GetHashCode() ?? 0); + hashCode = HashHelpers.Combine(hashCode, this.ScriptCode?.GetHashCode() ?? 0); + hashCode = HashHelpers.Combine(hashCode, this.UnicodeLanguageCode.GetHashCode()); + hashCode = HashHelpers.Combine(hashCode, this.ScriptCodeCode.GetHashCode()); + return hashCode; } } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccClut.cs b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccClut.cs index 3424a11ed7..685b5884fb 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccClut.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccClut.cs @@ -142,15 +142,12 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - int hashCode = this.Values.GetHashCode(); - hashCode = (hashCode * 397) ^ (int)this.DataType; - hashCode = (hashCode * 397) ^ this.InputChannelCount; - hashCode = (hashCode * 397) ^ this.OutputChannelCount; - hashCode = (hashCode * 397) ^ this.GridPointCount.GetHashCode(); - return hashCode; - } + int hashCode = this.Values.GetHashCode(); + hashCode = HashHelpers.Combine(hashCode, this.DataType.GetHashCode()); + hashCode = HashHelpers.Combine(hashCode, this.InputChannelCount.GetHashCode()); + hashCode = HashHelpers.Combine(hashCode, this.OutputChannelCount.GetHashCode()); + hashCode = HashHelpers.Combine(hashCode, this.GridPointCount.GetHashCode()); + return hashCode; } private bool EqualsValuesArray(IccClut other) diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileDescription.cs b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileDescription.cs index 4319b0e8ba..3af6dc6a8f 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileDescription.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileDescription.cs @@ -84,16 +84,13 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - int hashCode = (int)this.DeviceManufacturer; - hashCode = (hashCode * 397) ^ (int)this.DeviceModel; - hashCode = (hashCode * 397) ^ this.DeviceAttributes.GetHashCode(); - hashCode = (hashCode * 397) ^ (int)this.TechnologyInformation; - hashCode = (hashCode * 397) ^ this.DeviceManufacturerInfo.GetHashCode(); - hashCode = (hashCode * 397) ^ this.DeviceModelInfo.GetHashCode(); - return hashCode; - } + int hashCode = this.DeviceManufacturer.GetHashCode(); + hashCode = HashHelpers.Combine(hashCode, this.DeviceModel.GetHashCode()); + hashCode = HashHelpers.Combine(hashCode, this.DeviceAttributes.GetHashCode()); + hashCode = HashHelpers.Combine(hashCode, this.TechnologyInformation.GetHashCode()); + hashCode = HashHelpers.Combine(hashCode, this.DeviceManufacturerInfo.GetHashCode()); + hashCode = HashHelpers.Combine(hashCode, this.DeviceModelInfo.GetHashCode()); + return hashCode; } } } From 44edf7df38844bd461432b840d2c4af6064bb06f Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Thu, 6 Dec 2018 08:50:28 -0800 Subject: [PATCH 17/40] Remove indirection getting HashCode on ExifValue --- .../MetaData/Profiles/Exif/ExifValue.cs | 24 +++++++------------ 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/src/ImageSharp/MetaData/Profiles/Exif/ExifValue.cs b/src/ImageSharp/MetaData/Profiles/Exif/ExifValue.cs index ccacfd0bf9..c5332788f3 100644 --- a/src/ImageSharp/MetaData/Profiles/Exif/ExifValue.cs +++ b/src/ImageSharp/MetaData/Profiles/Exif/ExifValue.cs @@ -198,7 +198,14 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif } /// - public override int GetHashCode() => this.GetHashCode(this); + public override int GetHashCode() + { + int hashCode = HashHelpers.Combine(this.Tag.GetHashCode(), this.DataType.GetHashCode()); + + return this.Value != null + ? HashHelpers.Combine(hashCode, this.Value.GetHashCode()) + : hashCode; + } /// public override string ToString() @@ -714,20 +721,5 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif throw new NotSupportedException(); } } - - /// - /// Returns the hash code for this instance. - /// - /// - /// The instance of to return the hash code for. - /// - /// - /// A 32-bit signed integer that is the hash code for this instance. - /// - private int GetHashCode(ExifValue exif) - { - int hashCode = exif.Tag.GetHashCode() ^ exif.DataType.GetHashCode(); - return hashCode ^ exif.Value?.GetHashCode() ?? hashCode; - } } } \ No newline at end of file From 31c2d4add6d5c7f477ede870d0645b931805463e Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Thu, 6 Dec 2018 08:52:55 -0800 Subject: [PATCH 18/40] Use GetHashCode when combining int values --- .../MetaData/Profiles/ICC/Curves/IccParametricCurve.cs | 2 +- src/ImageSharp/MetaData/Profiles/ICC/Curves/IccResponseCurve.cs | 2 +- .../Profiles/ICC/TagDataEntries/IccChromaticityTagDataEntry.cs | 2 +- .../ICC/TagDataEntries/IccViewingConditionsTagDataEntry.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Curves/IccParametricCurve.cs b/src/ImageSharp/MetaData/Profiles/ICC/Curves/IccParametricCurve.cs index f707ee595e..0f50b366c7 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Curves/IccParametricCurve.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Curves/IccParametricCurve.cs @@ -156,7 +156,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc { unchecked { - int hashCode = (int)this.Type; + int hashCode = this.Type.GetHashCode(); hashCode = HashHelpers.Combine(hashCode, this.G.GetHashCode()); hashCode = HashHelpers.Combine(hashCode, this.A.GetHashCode()); hashCode = HashHelpers.Combine(hashCode, this.B.GetHashCode()); diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Curves/IccResponseCurve.cs b/src/ImageSharp/MetaData/Profiles/ICC/Curves/IccResponseCurve.cs index 16b0ddbef9..04984a4f24 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Curves/IccResponseCurve.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Curves/IccResponseCurve.cs @@ -74,7 +74,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc public override int GetHashCode() { return HashHelpers.Combine( - (int)this.CurveType, + this.CurveType.GetHashCode(), this.XyzValues.GetHashCode(), this.ResponseArrays.GetHashCode()); } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccChromaticityTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccChromaticityTagDataEntry.cs index 0a27ce2d58..0b2aa7afc8 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccChromaticityTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccChromaticityTagDataEntry.cs @@ -112,7 +112,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc { return HashHelpers.Combine( base.GetHashCode(), - (int)this.ColorantType, + this.ColorantType.GetHashCode(), this.ChannelValues.GetHashCode()); } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccViewingConditionsTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccViewingConditionsTagDataEntry.cs index df53957b13..5b12c9d7ec 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccViewingConditionsTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccViewingConditionsTagDataEntry.cs @@ -90,7 +90,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc base.GetHashCode(), this.IlluminantXyz.GetHashCode(), this.SurroundXyz.GetHashCode(), - (int)this.Illuminant); + this.Illuminant.GetHashCode()); } } } From 18a75f4144f1cf6d513cd444edc5eb2a57a5b7eb Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Thu, 6 Dec 2018 12:42:32 -0800 Subject: [PATCH 19/40] Cleanup assembly properties --- .../ImageSharp.Drawing.csproj | 20 ++++++-------- src/ImageSharp/ImageSharp.csproj | 20 ++++++-------- src/Shared/AssemblyInfo.Common.cs | 26 ------------------- 3 files changed, 16 insertions(+), 50 deletions(-) diff --git a/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj b/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj index ae5069be1d..a6f529ee36 100644 --- a/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj +++ b/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj @@ -1,10 +1,15 @@  - - An extension to ImageSharp that allows the drawing of images, paths, and text. + SixLabors.ImageSharp.Drawing + SixLabors and contributors + Six Labors + Copyright (c) Six Labors and contributors. + SixLabors.ImageSharp + An extension to ImageSharp that allows the drawing of images, paths, and text. + en + $(packageversion) 0.0.1 - SixLabors and contributors netstandard1.3;netstandard2.0 7.3 true @@ -17,15 +22,6 @@ http://www.apache.org/licenses/LICENSE-2.0 git https://github.com/SixLabors/ImageSharp - false - false - false - false - false - false - false - false - false full portable True diff --git a/src/ImageSharp/ImageSharp.csproj b/src/ImageSharp/ImageSharp.csproj index c19c92426f..98132edd68 100644 --- a/src/ImageSharp/ImageSharp.csproj +++ b/src/ImageSharp/ImageSharp.csproj @@ -1,10 +1,15 @@  - A cross-platform library for the processing of image files; written in C# SixLabors.ImageSharp + Six Labors and contributors + Six Labors + Copyright (c) Six Labors and contributors. + SixLabors.ImageSharp + A cross-platform library for the processing of image files; written in C# + en + $(packageversion) 0.0.1 - Six Labors and contributors netstandard1.3;netstandard2.0;netcoreapp2.1;net472 true true @@ -16,20 +21,11 @@ http://www.apache.org/licenses/LICENSE-2.0 git https://github.com/SixLabors/ImageSharp - false - false - false - false - false - false - false - false - false full portable True IOperation - Latest + 7.3 diff --git a/src/Shared/AssemblyInfo.Common.cs b/src/Shared/AssemblyInfo.Common.cs index 327d3abd75..82e1dac6c4 100644 --- a/src/Shared/AssemblyInfo.Common.cs +++ b/src/Shared/AssemblyInfo.Common.cs @@ -5,32 +5,6 @@ using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyDescription("A cross-platform library for processing of image files; written in C#")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Six Labors")] -[assembly: AssemblyProduct("SixLabors.ImageSharp")] -[assembly: AssemblyCopyright("Copyright (c) Six Labors and contributors.")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] -[assembly: NeutralResourcesLanguage("en")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] -[assembly: AssemblyInformationalVersion("1.0.0.0")] - // Ensure the internals can be built and tested. [assembly: InternalsVisibleTo("SixLabors.ImageSharp.Drawing")] [assembly: InternalsVisibleTo("ImageSharp.Benchmarks")] From 196b748153b5fc528dc633cf3a2d85db8b3b7e24 Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Thu, 6 Dec 2018 12:49:10 -0800 Subject: [PATCH 20/40] Remove unused BitMiracle.LibJpeg.NET depedency --- tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj b/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj index ae6acf0913..cb286cc286 100644 --- a/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj +++ b/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj @@ -18,19 +18,13 @@ - - - - - - \ No newline at end of file From 690c5515a747a2534795a67364049602c6c7bf18 Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Thu, 6 Dec 2018 12:51:17 -0800 Subject: [PATCH 21/40] Remove unused Microsoft.CSharp dependency --- tests/ImageSharp.Tests/ImageSharp.Tests.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj index 271a7ae32d..7452d6e498 100644 --- a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj +++ b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj @@ -28,7 +28,6 @@ - From 308e02eb2f5940e9c5bbef9c68a62318e654f1a2 Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Sat, 8 Dec 2018 13:04:39 +1030 Subject: [PATCH 22/40] Adds more to the AoT compiler. --- src/ImageSharp/Advanced/AotCompilerTools.cs | 41 +++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/ImageSharp/Advanced/AotCompilerTools.cs b/src/ImageSharp/Advanced/AotCompilerTools.cs index 9e7624480d..9f20704cf7 100644 --- a/src/ImageSharp/Advanced/AotCompilerTools.cs +++ b/src/ImageSharp/Advanced/AotCompilerTools.cs @@ -1,6 +1,9 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using System.Numerics; +using SixLabors.ImageSharp.Formats; +using SixLabors.ImageSharp.Formats.Jpeg.Components; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing.Processors.Dithering; using SixLabors.ImageSharp.Processing.Processors.Quantization; @@ -15,6 +18,20 @@ namespace SixLabors.ImageSharp.Advanced /// public static class AotCompilerTools { + /// + /// Seeds the calls. + /// + public static void SeedUnsafe() + { + System.Runtime.CompilerServices.Unsafe.SizeOf(); + System.Runtime.CompilerServices.Unsafe.SizeOf(); + System.Runtime.CompilerServices.Unsafe.SizeOf(); + System.Runtime.CompilerServices.Unsafe.SizeOf(); + System.Runtime.CompilerServices.Unsafe.SizeOf(); + System.Runtime.CompilerServices.Unsafe.SizeOf(); + System.Runtime.CompilerServices.Unsafe.SizeOf(); + } + /// /// Seeds the compiler using the given pixel format. /// @@ -27,6 +44,13 @@ namespace SixLabors.ImageSharp.Advanced AotCompileWuQuantizer(); AotCompileDithering(); + System.Runtime.CompilerServices.Unsafe.SizeOf(); + + AotDecoder(new Formats.Png.PngDecoder()); + AotDecoder(new Formats.Bmp.BmpDecoder()); + AotDecoder(new Formats.Gif.GifDecoder()); + AotDecoder(new Formats.Jpeg.JpegDecoder()); + // TODO: Do the discovery work to figure out what works and what doesn't. } @@ -99,5 +123,22 @@ namespace SixLabors.ImageSharp.Advanced TPixel pixel = default; test.Dither(new ImageFrame(Configuration.Default, 1, 1), pixel, pixel, 0, 0, 0, 0, 0, 0); } + + /// + /// This method pre-seeds the decoder for a given pixel format in the AoT compiler for iOS. + /// + /// The image decoder to seed.. + /// The pixel format. + private static void AotDecoder(IImageDecoder decoder) + where TPixel : struct, IPixel + { + try + { + decoder.Decode(Configuration.Default, null); + } + catch + { + } + } } } \ No newline at end of file From 0274eae25396fc417adf2e0723ff25d117bf93b0 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Tue, 11 Dec 2018 06:50:39 +1100 Subject: [PATCH 23/40] Bump lower tolerance for Box. --- .../Processing/Processors/Transforms/ResizeTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs index 5c2dffe582..034b66ae9a 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs @@ -60,7 +60,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms && string.IsNullOrEmpty(TestEnvironment.NetCoreVersion) && sampler is NearestNeighborResampler; - var comparer = ImageComparer.TolerantPercentage(allowHigherInaccuracy ? 0.3f : 0.01f); + var comparer = ImageComparer.TolerantPercentage(allowHigherInaccuracy ? 0.3f : 0.017f); provider.RunValidatingProcessorTest( ctx => From 3917e397f597fc74eab3fee90e6006cd28fbf5a1 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Tue, 11 Dec 2018 13:59:04 +1100 Subject: [PATCH 24/40] Fix #787 --- .../ProjectiveTransformProcessor.cs | 13 +-- .../Processors/Transforms/TransformUtils.cs | 79 ++++++++++++------- .../Transforms/ProjectiveTransformTests.cs | 27 ++++++- tests/Images/External | 2 +- 4 files changed, 83 insertions(+), 38 deletions(-) diff --git a/src/ImageSharp/Processing/Processors/Transforms/ProjectiveTransformProcessor.cs b/src/ImageSharp/Processing/Processors/Transforms/ProjectiveTransformProcessor.cs index 98d488a420..0b5627e19b 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/ProjectiveTransformProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/ProjectiveTransformProcessor.cs @@ -75,7 +75,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms // Convert from screen to world space. Matrix4x4.Invert(this.TransformMatrix, out Matrix4x4 matrix); - const float Epsilon = 0.0000001F; if (this.Sampler is NearestNeighborResampler) { @@ -90,11 +89,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms for (int x = 0; x < width; x++) { - var v3 = Vector3.Transform(new Vector3(x, y, 1), matrix); - - float z = MathF.Max(v3.Z, Epsilon); - int px = (int)MathF.Round(v3.X / z); - int py = (int)MathF.Round(v3.Y / z); + Vector2 point = TransformUtils.ProjectiveTransform2D(x, y, matrix); + int px = (int)MathF.Round(point.X); + int py = (int)MathF.Round(point.Y); if (sourceRectangle.Contains(px, py)) { @@ -127,9 +124,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms { // Use the single precision position to calculate correct bounding pixels // otherwise we get rogue pixels outside of the bounds. - var v3 = Vector3.Transform(new Vector3(x, y, 1F), matrix); - Vector2 point = new Vector2(v3.X, v3.Y) / MathF.Max(v3.Z, Epsilon); - + Vector2 point = TransformUtils.ProjectiveTransform2D(x, y, matrix); kernel.Convolve(point, x, ref ySpanRef, ref xSpanRef, source.PixelBuffer, vectorSpan); } diff --git a/src/ImageSharp/Processing/Processors/Transforms/TransformUtils.cs b/src/ImageSharp/Processing/Processors/Transforms/TransformUtils.cs index 24b15d3098..0ec8c83939 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/TransformUtils.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/TransformUtils.cs @@ -3,6 +3,7 @@ using System; using System.Numerics; +using System.Runtime.CompilerServices; using SixLabors.Primitives; namespace SixLabors.ImageSharp.Processing.Processors.Transforms @@ -12,6 +13,21 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// internal static class TransformUtils { + /// + /// Applies the projective transform against the given coordinates flattened into the 2D space. + /// + /// The "x" vector coordinate. + /// The "y" vector coordinate. + /// The transform matrix. + /// The . + [MethodImpl(InliningOptions.ShortMethod)] + public static Vector2 ProjectiveTransform2D(float x, float y, Matrix4x4 matrix) + { + const float Epsilon = 0.0000001F; + var v4 = Vector4.Transform(new Vector4(x, y, 0, 1F), matrix); + return new Vector2(v4.X, v4.Y) / MathF.Max(v4.W, Epsilon); + } + /// /// Creates a centered rotation matrix using the given rotation in degrees and the source size. /// @@ -94,12 +110,28 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms { Matrix4x4 matrix = Matrix4x4.Identity; + /* + * SkMatrix is layed out in the following manner: + * + * [ ScaleX SkewY Persp0 ] + * [ SkewX ScaleY Persp1 ] + * [ TransX TransY Persp2 ] + * + * When converting from Matrix4x4 to SkMatrix, the third row and + * column is dropped. When converting from SkMatrix to Matrix4x4 + * the third row and column remain as identity: + * + * [ a b c ] [ a b 0 c ] + * [ d e f ] -> [ d e 0 f ] + * [ g h i ] [ 0 0 1 0 ] + * [ g h 0 i ] + */ switch (side) { case TaperSide.Left: matrix.M11 = fraction; matrix.M22 = fraction; - matrix.M13 = (fraction - 1) / size.Width; + matrix.M14 = (fraction - 1) / size.Width; switch (corner) { @@ -107,13 +139,13 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms break; case TaperCorner.LeftOrTop: - matrix.M12 = size.Height * matrix.M13; - matrix.M32 = size.Height * (1 - fraction); + matrix.M12 = size.Height * matrix.M14; + matrix.M42 = size.Height * (1 - fraction); break; case TaperCorner.Both: - matrix.M12 = size.Height * .5F * matrix.M13; - matrix.M32 = size.Height * (1 - fraction) / 2; + matrix.M12 = size.Height * .5F * matrix.M14; + matrix.M42 = size.Height * (1 - fraction) / 2; break; } @@ -122,7 +154,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms case TaperSide.Top: matrix.M11 = fraction; matrix.M22 = fraction; - matrix.M23 = (fraction - 1) / size.Height; + matrix.M24 = (fraction - 1) / size.Height; switch (corner) { @@ -130,13 +162,13 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms break; case TaperCorner.LeftOrTop: - matrix.M21 = size.Width * matrix.M23; - matrix.M31 = size.Width * (1 - fraction); + matrix.M21 = size.Width * matrix.M24; + matrix.M41 = size.Width * (1 - fraction); break; case TaperCorner.Both: - matrix.M21 = size.Width * .5F * matrix.M23; - matrix.M31 = size.Width * (1 - fraction) / 2; + matrix.M21 = size.Width * .5F * matrix.M24; + matrix.M41 = size.Width * (1 - fraction) * .5F; break; } @@ -144,7 +176,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms case TaperSide.Right: matrix.M11 = 1 / fraction; - matrix.M13 = (1 - fraction) / (size.Width * fraction); + matrix.M14 = (1 - fraction) / (size.Width * fraction); switch (corner) { @@ -152,11 +184,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms break; case TaperCorner.LeftOrTop: - matrix.M12 = size.Height * matrix.M13; + matrix.M12 = size.Height * matrix.M14; break; case TaperCorner.Both: - matrix.M12 = size.Height * .5F * matrix.M13; + matrix.M12 = size.Height * .5F * matrix.M14; break; } @@ -164,7 +196,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms case TaperSide.Bottom: matrix.M22 = 1 / fraction; - matrix.M23 = (1 - fraction) / (size.Height * fraction); + matrix.M24 = (1 - fraction) / (size.Height * fraction); switch (corner) { @@ -172,11 +204,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms break; case TaperCorner.LeftOrTop: - matrix.M21 = size.Width * matrix.M23; + matrix.M21 = size.Width * matrix.M24; break; case TaperCorner.Both: - matrix.M21 = size.Width * .5F * matrix.M23; + matrix.M21 = size.Width * .5F * matrix.M24; break; } @@ -260,17 +292,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms return rectangle; } - Vector2 GetVector(float x, float y) - { - const float Epsilon = 0.0000001F; - var v3 = Vector3.Transform(new Vector3(x, y, 1F), matrix); - return new Vector2(v3.X, v3.Y) / MathF.Max(v3.Z, Epsilon); - } - - Vector2 tl = GetVector(rectangle.Left, rectangle.Top); - Vector2 tr = GetVector(rectangle.Right, rectangle.Top); - Vector2 bl = GetVector(rectangle.Left, rectangle.Bottom); - Vector2 br = GetVector(rectangle.Right, rectangle.Bottom); + Vector2 tl = ProjectiveTransform2D(rectangle.Left, rectangle.Top, matrix); + Vector2 tr = ProjectiveTransform2D(rectangle.Right, rectangle.Top, matrix); + Vector2 bl = ProjectiveTransform2D(rectangle.Left, rectangle.Bottom, matrix); + Vector2 br = ProjectiveTransform2D(rectangle.Right, rectangle.Bottom, matrix); return GetBoundingRectangle(tl, tr, bl, br); } diff --git a/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformTests.cs b/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformTests.cs index 1da660d222..056f66af7f 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformTests.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformTests.cs @@ -111,7 +111,32 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms using (Image image = provider.GetImage()) { Matrix4x4 matrix = Matrix4x4.Identity; - matrix.M13 = 0.01F; + matrix.M14 = 0.01F; + + ProjectiveTransformBuilder builder = new ProjectiveTransformBuilder() + .AppendMatrix(matrix); + + image.Mutate(i => i.Transform(builder)); + + image.DebugSave(provider); + image.CompareToReferenceOutput(TolerantComparer, provider); + } + } + + [Theory] + [WithSolidFilledImages(290, 154, 0, 0, 255, PixelTypes.Rgba32)] + public void PerspectiveTransformMatchesCSS(TestImageProvider provider) + where TPixel : struct, IPixel + { + // https://jsfiddle.net/dFrHS/545/ + // https://github.com/SixLabors/ImageSharp/issues/787 + using (Image image = provider.GetImage()) + { + var matrix = new Matrix4x4( + 0.260987f, -0.434909f, 0, -0.0022184f, + 0.373196f, 0.949882f, 0, -0.000312129f, + 0, 0, 1, 0, + 52, 165, 0, 1); ProjectiveTransformBuilder builder = new ProjectiveTransformBuilder() .AppendMatrix(matrix); diff --git a/tests/Images/External b/tests/Images/External index 1edb0f3e04..69603ee5b6 160000 --- a/tests/Images/External +++ b/tests/Images/External @@ -1 +1 @@ -Subproject commit 1edb0f3e04c18974821a3012a87f7c2e073c8019 +Subproject commit 69603ee5b6f7dd64114fc44d321e50d9b2d439be From 77c54662a2b3283eb26ca09b3671d34912dc8a1a Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Tue, 11 Dec 2018 17:46:51 -0800 Subject: [PATCH 25/40] Replace HashHelpers with HashCode.Combine --- src/ImageSharp/ColorSpaces/CieLab.cs | 9 +------- src/ImageSharp/ColorSpaces/CieLch.cs | 6 +----- src/ImageSharp/ColorSpaces/CieLchuv.cs | 9 +------- src/ImageSharp/ColorSpaces/CieLuv.cs | 9 +------- .../CieXyChromaticityCoordinates.cs | 2 +- src/ImageSharp/ColorSpaces/CieXyy.cs | 8 +------ src/ImageSharp/ColorSpaces/CieXyz.cs | 8 +------ src/ImageSharp/ColorSpaces/Cmyk.cs | 9 +------- .../RGBPrimariesChromaticityCoordinates.cs | 5 +---- .../WorkingSpaces/GammaWorkingSpace.cs | 6 +++++- .../WorkingSpaces/RgbWorkingSpaceBase.cs | 4 +++- src/ImageSharp/ColorSpaces/Hsl.cs | 8 +------ src/ImageSharp/ColorSpaces/Hsv.cs | 8 +------ src/ImageSharp/ColorSpaces/HunterLab.cs | 6 +----- src/ImageSharp/ColorSpaces/LinearRgb.cs | 8 +------ src/ImageSharp/ColorSpaces/Lms.cs | 8 +------ src/ImageSharp/ColorSpaces/Rgb.cs | 8 +------ src/ImageSharp/ColorSpaces/YCbCr.cs | 8 +------ .../Jpeg/Components/Decoder/AdobeMarker.cs | 10 ++++----- .../Jpeg/Components/Decoder/JFifMarker.cs | 13 ++++++------ src/ImageSharp/ImageSharp.csproj | 2 +- src/ImageSharp/MetaData/ImageProperty.cs | 14 +------------ .../MetaData/Profiles/Exif/ExifValue.cs | 6 +----- .../Profiles/ICC/Curves/IccParametricCurve.cs | 21 ++++++++----------- .../Profiles/ICC/Curves/IccResponseCurve.cs | 8 +++---- .../IccChromaticityTagDataEntry.cs | 8 +++---- .../IccColorantOrderTagDataEntry.cs | 2 +- .../IccColorantTableTagDataEntry.cs | 2 +- .../TagDataEntries/IccCrdInfoTagDataEntry.cs | 17 +++++++-------- .../TagDataEntries/IccCurveTagDataEntry.cs | 5 +---- .../ICC/TagDataEntries/IccDataTagDataEntry.cs | 8 +++---- .../TagDataEntries/IccDateTimeTagDataEntry.cs | 2 +- .../IccFix16ArrayTagDataEntry.cs | 5 +---- .../TagDataEntries/IccLut16TagDataEntry.cs | 12 +++++------ .../ICC/TagDataEntries/IccLut8TagDataEntry.cs | 12 +++++------ .../TagDataEntries/IccLutAToBTagDataEntry.cs | 18 +++++++--------- .../TagDataEntries/IccLutBToATagDataEntry.cs | 18 +++++++--------- .../IccMeasurementTagDataEntry.cs | 14 ++++++------- .../IccMultiLocalizedUnicodeTagDataEntry.cs | 5 +---- .../IccMultiProcessElementsTagDataEntry.cs | 6 +++--- .../IccNamedColor2TagDataEntry.cs | 14 ++++++------- .../IccParametricCurveTagDataEntry.cs | 5 +---- .../IccProfileSequenceDescTagDataEntry.cs | 5 +---- ...ccProfileSequenceIdentifierTagDataEntry.cs | 5 +---- .../IccResponseCurveSet16TagDataEntry.cs | 8 +++---- .../IccScreeningTagDataEntry.cs | 5 +---- .../IccSignatureTagDataEntry.cs | 5 +---- .../IccTextDescriptionTagDataEntry.cs | 14 ++++++------- .../ICC/TagDataEntries/IccTextTagDataEntry.cs | 5 +---- .../IccUFix16ArrayTagDataEntry.cs | 5 +---- .../IccUInt16ArrayTagDataEntry.cs | 7 ++----- .../IccUInt32ArrayTagDataEntry.cs | 5 +---- .../IccUInt64ArrayTagDataEntry.cs | 5 +---- .../IccUInt8ArrayTagDataEntry.cs | 5 +---- .../TagDataEntries/IccUcrBgTagDataEntry.cs | 10 ++++----- .../TagDataEntries/IccUnknownTagDataEntry.cs | 5 +---- .../IccViewingConditionsTagDataEntry.cs | 10 ++++----- .../MetaData/Profiles/ICC/Various/IccClut.cs | 12 +++++------ .../ICC/Various/IccColorantTableEntry.cs | 10 ++++----- .../Profiles/ICC/Various/IccNamedColor.cs | 8 +++---- .../ICC/Various/IccProfileDescription.cs | 14 ++++++------- .../Profiles/ICC/Various/IccProfileId.cs | 10 ++++----- .../Various/IccProfileSequenceIdentifier.cs | 5 +---- .../Profiles/ICC/Various/IccResponseNumber.cs | 12 ++--------- .../ICC/Various/IccScreeningChannel.cs | 5 +---- .../Profiles/ICC/Various/IccTagTableEntry.cs | 11 ++++------ .../PixelImplementations/Bgr24.cs | 6 ++---- .../PixelImplementations/Rgb24.cs | 6 ++---- .../PixelImplementations/Rgb48.cs | 5 +---- .../PixelImplementations/RgbaVector.cs | 7 +------ src/ImageSharp/Primitives/ValueSize.cs | 7 ++----- .../Processors/Dithering/PixelPair.cs | 3 +-- 72 files changed, 195 insertions(+), 381 deletions(-) diff --git a/src/ImageSharp/ColorSpaces/CieLab.cs b/src/ImageSharp/ColorSpaces/CieLab.cs index dd01ea5f4b..146acf12ee 100644 --- a/src/ImageSharp/ColorSpaces/CieLab.cs +++ b/src/ImageSharp/ColorSpaces/CieLab.cs @@ -118,14 +118,7 @@ namespace SixLabors.ImageSharp.ColorSpaces public static bool operator !=(CieLab left, CieLab right) => !left.Equals(right); /// - public override int GetHashCode() - { - return HashHelpers.Combine( - this.L.GetHashCode(), - this.A.GetHashCode(), - this.B.GetHashCode(), - this.WhitePoint.GetHashCode()); - } + public override int GetHashCode() => HashCode.Combine(this.L, this.A, this.B, this.WhitePoint); /// public override string ToString() => FormattableString.Invariant($"CieLab({this.L:#0.##}, {this.A:#0.##}, {this.B:#0.##})"); diff --git a/src/ImageSharp/ColorSpaces/CieLch.cs b/src/ImageSharp/ColorSpaces/CieLch.cs index fffd368fb4..074bc1516b 100644 --- a/src/ImageSharp/ColorSpaces/CieLch.cs +++ b/src/ImageSharp/ColorSpaces/CieLch.cs @@ -122,11 +122,7 @@ namespace SixLabors.ImageSharp.ColorSpaces /// public override int GetHashCode() { - return HashHelpers.Combine( - this.L.GetHashCode(), - this.C.GetHashCode(), - this.H.GetHashCode(), - this.WhitePoint.GetHashCode()); + return HashCode.Combine(this.L, this.C, this.H, this.WhitePoint); } /// diff --git a/src/ImageSharp/ColorSpaces/CieLchuv.cs b/src/ImageSharp/ColorSpaces/CieLchuv.cs index 829abbf0ec..ab6f639a2b 100644 --- a/src/ImageSharp/ColorSpaces/CieLchuv.cs +++ b/src/ImageSharp/ColorSpaces/CieLchuv.cs @@ -119,14 +119,7 @@ namespace SixLabors.ImageSharp.ColorSpaces public static bool operator !=(CieLchuv left, CieLchuv right) => !left.Equals(right); /// - public override int GetHashCode() - { - return HashHelpers.Combine( - this.L.GetHashCode(), - this.C.GetHashCode(), - this.H.GetHashCode(), - this.WhitePoint.GetHashCode()); - } + public override int GetHashCode() => HashCode.Combine(this.L, this.C, this.H, this.WhitePoint); /// public override string ToString() => FormattableString.Invariant($"CieLchuv({this.L:#0.##}, {this.C:#0.##}, {this.H:#0.##})"); diff --git a/src/ImageSharp/ColorSpaces/CieLuv.cs b/src/ImageSharp/ColorSpaces/CieLuv.cs index b678084c38..d54d92b62a 100644 --- a/src/ImageSharp/ColorSpaces/CieLuv.cs +++ b/src/ImageSharp/ColorSpaces/CieLuv.cs @@ -119,14 +119,7 @@ namespace SixLabors.ImageSharp.ColorSpaces public static bool operator !=(CieLuv left, CieLuv right) => !left.Equals(right); /// - public override int GetHashCode() - { - return HashHelpers.Combine( - this.L.GetHashCode(), - this.U.GetHashCode(), - this.V.GetHashCode(), - this.WhitePoint.GetHashCode()); - } + public override int GetHashCode() => HashCode.Combine(this.L, this.U, this.V, this.WhitePoint); /// public override string ToString() => FormattableString.Invariant($"CieLuv({this.L:#0.##}, {this.U:#0.##}, {this.V:#0.##})"); diff --git a/src/ImageSharp/ColorSpaces/CieXyChromaticityCoordinates.cs b/src/ImageSharp/ColorSpaces/CieXyChromaticityCoordinates.cs index f625bb7616..49c1da9f10 100644 --- a/src/ImageSharp/ColorSpaces/CieXyChromaticityCoordinates.cs +++ b/src/ImageSharp/ColorSpaces/CieXyChromaticityCoordinates.cs @@ -64,7 +64,7 @@ namespace SixLabors.ImageSharp.ColorSpaces /// [MethodImpl(InliningOptions.ShortMethod)] - public override int GetHashCode() => HashHelpers.Combine(this.X.GetHashCode(), this.Y.GetHashCode()); + public override int GetHashCode() => HashCode.Combine(this.X, this.Y); /// public override string ToString() => FormattableString.Invariant($"CieXyChromaticityCoordinates({this.X:#0.##}, {this.Y:#0.##})"); diff --git a/src/ImageSharp/ColorSpaces/CieXyy.cs b/src/ImageSharp/ColorSpaces/CieXyy.cs index 1d5d2de53c..fff296945e 100644 --- a/src/ImageSharp/ColorSpaces/CieXyy.cs +++ b/src/ImageSharp/ColorSpaces/CieXyy.cs @@ -83,13 +83,7 @@ namespace SixLabors.ImageSharp.ColorSpaces public static bool operator !=(CieXyy left, CieXyy right) => !left.Equals(right); /// - public override int GetHashCode() - { - return HashHelpers.Combine( - this.X.GetHashCode(), - this.Y.GetHashCode(), - this.Yl.GetHashCode()); - } + public override int GetHashCode() => HashCode.Combine(this.X, this.Y, this.Yl); /// public override string ToString() => FormattableString.Invariant($"CieXyy({this.X:#0.##}, {this.Y:#0.##}, {this.Yl:#0.##})"); diff --git a/src/ImageSharp/ColorSpaces/CieXyz.cs b/src/ImageSharp/ColorSpaces/CieXyz.cs index 6c9ea65e66..30521476e5 100644 --- a/src/ImageSharp/ColorSpaces/CieXyz.cs +++ b/src/ImageSharp/ColorSpaces/CieXyz.cs @@ -86,13 +86,7 @@ namespace SixLabors.ImageSharp.ColorSpaces public Vector3 ToVector3() => new Vector3(this.X, this.Y, this.Z); /// - public override int GetHashCode() - { - return HashHelpers.Combine( - this.X.GetHashCode(), - this.Y.GetHashCode(), - this.Z.GetHashCode()); - } + public override int GetHashCode() => HashCode.Combine(this.X, this.Y, this.Z); /// public override string ToString() => FormattableString.Invariant($"CieXyz({this.X:#0.##}, {this.Y:#0.##}, {this.Z:#0.##})"); diff --git a/src/ImageSharp/ColorSpaces/Cmyk.cs b/src/ImageSharp/ColorSpaces/Cmyk.cs index 241a8b325f..04901126c1 100644 --- a/src/ImageSharp/ColorSpaces/Cmyk.cs +++ b/src/ImageSharp/ColorSpaces/Cmyk.cs @@ -90,14 +90,7 @@ namespace SixLabors.ImageSharp.ColorSpaces /// [MethodImpl(InliningOptions.ShortMethod)] - public override int GetHashCode() - { - return HashHelpers.Combine( - this.C.GetHashCode(), - this.M.GetHashCode(), - this.Y.GetHashCode(), - this.K.GetHashCode()); - } + public override int GetHashCode() => HashCode.Combine(this.C, this.M, this.Y, this.K); /// public override string ToString() => FormattableString.Invariant($"Cmyk({this.C:#0.##}, {this.M:#0.##}, {this.Y:#0.##}, {this.K:#0.##})"); diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/RGBPrimariesChromaticityCoordinates.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/RGBPrimariesChromaticityCoordinates.cs index ba6da5a85a..4c69133e0f 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/RGBPrimariesChromaticityCoordinates.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/RGBPrimariesChromaticityCoordinates.cs @@ -86,9 +86,6 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation } /// - public override int GetHashCode() - { - return HashHelpers.Combine(this.R.GetHashCode(), this.G.GetHashCode(), this.B.GetHashCode()); - } + public override int GetHashCode() => HashCode.Combine(this.R, this.G, this.B); } } \ No newline at end of file diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/WorkingSpaces/GammaWorkingSpace.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/WorkingSpaces/GammaWorkingSpace.cs index 271278ad78..639d0b2933 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/WorkingSpaces/GammaWorkingSpace.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/WorkingSpaces/GammaWorkingSpace.cs @@ -1,6 +1,7 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using System; using System.Runtime.CompilerServices; using SixLabors.ImageSharp.ColorSpaces.Companding; @@ -57,6 +58,9 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation } /// - public override int GetHashCode() => HashHelpers.Combine(base.GetHashCode(), this.Gamma.GetHashCode()); + public override int GetHashCode() => HashCode.Combine( + this.WhitePoint, + this.ChromaticityCoordinates, + this.Gamma); } } \ No newline at end of file diff --git a/src/ImageSharp/ColorSpaces/Conversion/Implementation/WorkingSpaces/RgbWorkingSpaceBase.cs b/src/ImageSharp/ColorSpaces/Conversion/Implementation/WorkingSpaces/RgbWorkingSpaceBase.cs index 70d3cccedc..6051f52865 100644 --- a/src/ImageSharp/ColorSpaces/Conversion/Implementation/WorkingSpaces/RgbWorkingSpaceBase.cs +++ b/src/ImageSharp/ColorSpaces/Conversion/Implementation/WorkingSpaces/RgbWorkingSpaceBase.cs @@ -1,6 +1,8 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using System; + namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation { /// @@ -76,7 +78,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation /// public override int GetHashCode() { - return HashHelpers.Combine(this.WhitePoint.GetHashCode(), this.ChromaticityCoordinates.GetHashCode()); + return HashCode.Combine(this.WhitePoint, this.ChromaticityCoordinates); } } } \ No newline at end of file diff --git a/src/ImageSharp/ColorSpaces/Hsl.cs b/src/ImageSharp/ColorSpaces/Hsl.cs index 1b92d5e88f..04b3bea41f 100644 --- a/src/ImageSharp/ColorSpaces/Hsl.cs +++ b/src/ImageSharp/ColorSpaces/Hsl.cs @@ -84,13 +84,7 @@ namespace SixLabors.ImageSharp.ColorSpaces /// [MethodImpl(InliningOptions.ShortMethod)] - public override int GetHashCode() - { - return HashHelpers.Combine( - this.H.GetHashCode(), - this.S.GetHashCode(), - this.L.GetHashCode()); - } + public override int GetHashCode() => HashCode.Combine(this.H, this.S, this.L); /// public override string ToString() => FormattableString.Invariant($"Hsl({this.H:#0.##}, {this.S:#0.##}, {this.L:#0.##})"); diff --git a/src/ImageSharp/ColorSpaces/Hsv.cs b/src/ImageSharp/ColorSpaces/Hsv.cs index 56d798af05..8ccc74ae09 100644 --- a/src/ImageSharp/ColorSpaces/Hsv.cs +++ b/src/ImageSharp/ColorSpaces/Hsv.cs @@ -82,13 +82,7 @@ namespace SixLabors.ImageSharp.ColorSpaces /// [MethodImpl(InliningOptions.ShortMethod)] - public override int GetHashCode() - { - return HashHelpers.Combine( - this.H.GetHashCode(), - this.S.GetHashCode(), - this.V.GetHashCode()); - } + public override int GetHashCode() => HashCode.Combine(this.H, this.S, this.V); /// public override string ToString() => FormattableString.Invariant($"Hsv({this.H:#0.##}, {this.S:#0.##}, {this.V:#0.##})"); diff --git a/src/ImageSharp/ColorSpaces/HunterLab.cs b/src/ImageSharp/ColorSpaces/HunterLab.cs index 1aa7be601f..dcae65e425 100644 --- a/src/ImageSharp/ColorSpaces/HunterLab.cs +++ b/src/ImageSharp/ColorSpaces/HunterLab.cs @@ -119,11 +119,7 @@ namespace SixLabors.ImageSharp.ColorSpaces [MethodImpl(InliningOptions.ShortMethod)] public override int GetHashCode() { - return HashHelpers.Combine( - this.L.GetHashCode(), - this.A.GetHashCode(), - this.B.GetHashCode(), - this.WhitePoint.GetHashCode()); + return HashCode.Combine(this.L, this.A, this.B, this.WhitePoint); } /// diff --git a/src/ImageSharp/ColorSpaces/LinearRgb.cs b/src/ImageSharp/ColorSpaces/LinearRgb.cs index fba27a41e9..46b2275968 100644 --- a/src/ImageSharp/ColorSpaces/LinearRgb.cs +++ b/src/ImageSharp/ColorSpaces/LinearRgb.cs @@ -126,13 +126,7 @@ namespace SixLabors.ImageSharp.ColorSpaces /// [MethodImpl(InliningOptions.ShortMethod)] - public override int GetHashCode() - { - return HashHelpers.Combine( - this.R.GetHashCode(), - this.G.GetHashCode(), - this.B.GetHashCode()); - } + public override int GetHashCode() => HashCode.Combine(this.R, this.G, this.B); /// public override string ToString() => FormattableString.Invariant($"LinearRgb({this.R:#0.##}, {this.G:#0.##}, {this.B:#0.##})"); diff --git a/src/ImageSharp/ColorSpaces/Lms.cs b/src/ImageSharp/ColorSpaces/Lms.cs index 0177c9712f..0ee56abbc2 100644 --- a/src/ImageSharp/ColorSpaces/Lms.cs +++ b/src/ImageSharp/ColorSpaces/Lms.cs @@ -87,13 +87,7 @@ namespace SixLabors.ImageSharp.ColorSpaces public Vector3 ToVector3() => new Vector3(this.L, this.M, this.S); /// - public override int GetHashCode() - { - return HashHelpers.Combine( - this.L.GetHashCode(), - this.M.GetHashCode(), - this.S.GetHashCode()); - } + public override int GetHashCode() => HashCode.Combine(this.L, this.M, this.S); /// public override string ToString() => FormattableString.Invariant($"Lms({this.L:#0.##}, {this.M:#0.##}, {this.S:#0.##})"); diff --git a/src/ImageSharp/ColorSpaces/Rgb.cs b/src/ImageSharp/ColorSpaces/Rgb.cs index ef44d217e9..cdc9e90ad4 100644 --- a/src/ImageSharp/ColorSpaces/Rgb.cs +++ b/src/ImageSharp/ColorSpaces/Rgb.cs @@ -147,13 +147,7 @@ namespace SixLabors.ImageSharp.ColorSpaces public Vector3 ToVector3() => new Vector3(this.R, this.G, this.B); /// - public override int GetHashCode() - { - return HashHelpers.Combine( - this.R.GetHashCode(), - this.G.GetHashCode(), - this.B.GetHashCode()); - } + public override int GetHashCode() => HashCode.Combine(this.R, this.G, this.B); /// public override string ToString() => FormattableString.Invariant($"Rgb({this.R:#0.##}, {this.G:#0.##}, {this.B:#0.##})"); diff --git a/src/ImageSharp/ColorSpaces/YCbCr.cs b/src/ImageSharp/ColorSpaces/YCbCr.cs index 2287d36894..b0563bb899 100644 --- a/src/ImageSharp/ColorSpaces/YCbCr.cs +++ b/src/ImageSharp/ColorSpaces/YCbCr.cs @@ -83,13 +83,7 @@ namespace SixLabors.ImageSharp.ColorSpaces /// [MethodImpl(InliningOptions.ShortMethod)] - public override int GetHashCode() - { - return HashHelpers.Combine( - this.Y.GetHashCode(), - this.Cb.GetHashCode(), - this.Cr.GetHashCode()); - } + public override int GetHashCode() => HashCode.Combine(this.Y, this.Cb, this.Cr); /// public override string ToString() => FormattableString.Invariant($"YCbCr({this.Y}, {this.Cb}, {this.Cr})"); diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/AdobeMarker.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/AdobeMarker.cs index 1fa09605ef..43de39ac78 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/AdobeMarker.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/AdobeMarker.cs @@ -100,11 +100,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder /// public override int GetHashCode() { - return HashHelpers.Combine( - this.DCTEncodeVersion.GetHashCode(), - this.APP14Flags0.GetHashCode(), - this.APP14Flags1.GetHashCode(), - this.ColorTransform.GetHashCode()); + return HashCode.Combine( + this.DCTEncodeVersion, + this.APP14Flags0, + this.APP14Flags1, + this.ColorTransform); } } } \ No newline at end of file diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JFifMarker.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JFifMarker.cs index 4bff492486..c51a2f4da5 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JFifMarker.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JFifMarker.cs @@ -112,13 +112,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder /// public override int GetHashCode() { - return HashHelpers.Combine( - this.MajorVersion.GetHashCode(), - HashHelpers.Combine( - this.MinorVersion.GetHashCode(), - HashHelpers.Combine( - this.DensityUnits.GetHashCode(), - HashHelpers.Combine(this.XDensity, this.YDensity)))); + return HashCode.Combine( + this.MajorVersion, + this.MinorVersion, + this.DensityUnits, + this.XDensity, + this.YDensity); } } } \ No newline at end of file diff --git a/src/ImageSharp/ImageSharp.csproj b/src/ImageSharp/ImageSharp.csproj index 98132edd68..1cdee81a26 100644 --- a/src/ImageSharp/ImageSharp.csproj +++ b/src/ImageSharp/ImageSharp.csproj @@ -38,7 +38,7 @@ - + All diff --git a/src/ImageSharp/MetaData/ImageProperty.cs b/src/ImageSharp/MetaData/ImageProperty.cs index 4644f9b68d..24a3686de2 100644 --- a/src/ImageSharp/MetaData/ImageProperty.cs +++ b/src/ImageSharp/MetaData/ImageProperty.cs @@ -99,19 +99,7 @@ namespace SixLabors.ImageSharp.MetaData /// /// A 32-bit signed integer that is the hash code for this instance. /// - public override int GetHashCode() - { - unchecked - { - int hashCode = this.Name.GetHashCode(); - if (this.Value != null) - { - hashCode = HashHelpers.Combine(hashCode, this.Value.GetHashCode()); - } - - return hashCode; - } - } + public override int GetHashCode() => HashCode.Combine(this.Name, this.Value); /// /// Returns the fully qualified type name of this instance. diff --git a/src/ImageSharp/MetaData/Profiles/Exif/ExifValue.cs b/src/ImageSharp/MetaData/Profiles/Exif/ExifValue.cs index c5332788f3..409c55253a 100644 --- a/src/ImageSharp/MetaData/Profiles/Exif/ExifValue.cs +++ b/src/ImageSharp/MetaData/Profiles/Exif/ExifValue.cs @@ -200,11 +200,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif /// public override int GetHashCode() { - int hashCode = HashHelpers.Combine(this.Tag.GetHashCode(), this.DataType.GetHashCode()); - - return this.Value != null - ? HashHelpers.Combine(hashCode, this.Value.GetHashCode()) - : hashCode; + return HashCode.Combine(this.Tag, this.DataType, this.Value); } /// diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Curves/IccParametricCurve.cs b/src/ImageSharp/MetaData/Profiles/ICC/Curves/IccParametricCurve.cs index 0f50b366c7..efc2ca5377 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Curves/IccParametricCurve.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Curves/IccParametricCurve.cs @@ -154,18 +154,15 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - int hashCode = this.Type.GetHashCode(); - hashCode = HashHelpers.Combine(hashCode, this.G.GetHashCode()); - hashCode = HashHelpers.Combine(hashCode, this.A.GetHashCode()); - hashCode = HashHelpers.Combine(hashCode, this.B.GetHashCode()); - hashCode = HashHelpers.Combine(hashCode, this.C.GetHashCode()); - hashCode = HashHelpers.Combine(hashCode, this.D.GetHashCode()); - hashCode = HashHelpers.Combine(hashCode, this.E.GetHashCode()); - hashCode = HashHelpers.Combine(hashCode, this.F.GetHashCode()); - return hashCode; - } + return HashCode.Combine( + this.Type, + this.G.GetHashCode(), + this.A.GetHashCode(), + this.B.GetHashCode(), + this.C.GetHashCode(), + this.D.GetHashCode(), + this.E.GetHashCode(), + this.F.GetHashCode()); } } } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Curves/IccResponseCurve.cs b/src/ImageSharp/MetaData/Profiles/ICC/Curves/IccResponseCurve.cs index 04984a4f24..de08485ac8 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Curves/IccResponseCurve.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Curves/IccResponseCurve.cs @@ -73,10 +73,10 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - return HashHelpers.Combine( - this.CurveType.GetHashCode(), - this.XyzValues.GetHashCode(), - this.ResponseArrays.GetHashCode()); + return HashCode.Combine( + this.CurveType, + this.XyzValues, + this.ResponseArrays); } private bool EqualsResponseArray(IccResponseCurve other) diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccChromaticityTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccChromaticityTagDataEntry.cs index 0b2aa7afc8..e9a812d8ca 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccChromaticityTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccChromaticityTagDataEntry.cs @@ -110,10 +110,10 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - return HashHelpers.Combine( - base.GetHashCode(), - this.ColorantType.GetHashCode(), - this.ChannelValues.GetHashCode()); + return HashCode.Combine( + this.Signature, + this.ColorantType, + this.ChannelValues); } private static double[][] GetColorantArray(IccColorantEncoding colorantType) diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccColorantOrderTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccColorantOrderTagDataEntry.cs index 5b8526b7de..b5f8fd5c49 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccColorantOrderTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccColorantOrderTagDataEntry.cs @@ -70,7 +70,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - return HashHelpers.Combine(base.GetHashCode(), this.ColorantNumber.GetHashCode()); + return HashCode.Combine(this.Signature, this.ColorantNumber); } } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccColorantTableTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccColorantTableTagDataEntry.cs index 572df8cb8d..9f2b4c90ad 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccColorantTableTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccColorantTableTagDataEntry.cs @@ -72,7 +72,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - return HashHelpers.Combine(base.GetHashCode(), this.ColorantData.GetHashCode()); + return HashCode.Combine(this.Signature, this.ColorantData); } } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccCrdInfoTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccCrdInfoTagDataEntry.cs index 9af77ba7c4..4d393dfb33 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccCrdInfoTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccCrdInfoTagDataEntry.cs @@ -121,16 +121,13 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - unchecked - { - int hashCode = base.GetHashCode(); - hashCode = HashHelpers.Combine(hashCode, this.PostScriptProductName?.GetHashCode() ?? 0); - hashCode = HashHelpers.Combine(hashCode, this.RenderingIntent0Crd?.GetHashCode() ?? 0); - hashCode = HashHelpers.Combine(hashCode, this.RenderingIntent1Crd?.GetHashCode() ?? 0); - hashCode = HashHelpers.Combine(hashCode, this.RenderingIntent2Crd?.GetHashCode() ?? 0); - hashCode = HashHelpers.Combine(hashCode, this.RenderingIntent3Crd?.GetHashCode() ?? 0); - return hashCode; - } + return HashCode.Combine( + this.Signature, + this.PostScriptProductName, + this.RenderingIntent0Crd, + this.RenderingIntent1Crd, + this.RenderingIntent2Crd, + this.RenderingIntent3Crd); } } } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccCurveTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccCurveTagDataEntry.cs index 2884a2216d..0d34d3ceba 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccCurveTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccCurveTagDataEntry.cs @@ -116,9 +116,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc } /// - public override int GetHashCode() - { - return HashHelpers.Combine(base.GetHashCode(), this.CurveData.GetHashCode()); - } + public override int GetHashCode() => HashCode.Combine(this.Signature, this.CurveData); } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccDataTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccDataTagDataEntry.cs index 9567c690c9..0b8367303d 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccDataTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccDataTagDataEntry.cs @@ -91,10 +91,10 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - return HashHelpers.Combine( - base.GetHashCode(), - this.Data.GetHashCode(), - this.IsAscii.GetHashCode()); + return HashCode.Combine( + this.Signature, + this.Data, + this.IsAscii); } } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccDateTimeTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccDateTimeTagDataEntry.cs index 12479bb61c..104d243099 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccDateTimeTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccDateTimeTagDataEntry.cs @@ -66,7 +66,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - return HashHelpers.Combine(base.GetHashCode(), this.Value.GetHashCode()); + return HashCode.Combine(this.Signature, this.Value); } } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccFix16ArrayTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccFix16ArrayTagDataEntry.cs index 3b9cce86bb..0a114ea1f9 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccFix16ArrayTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccFix16ArrayTagDataEntry.cs @@ -64,9 +64,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc } /// - public override int GetHashCode() - { - return HashHelpers.Combine(base.GetHashCode(), this.Data.GetHashCode()); - } + public override int GetHashCode() => HashCode.Combine(this.Signature, this.Data); } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLut16TagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLut16TagDataEntry.cs index 281b17ba96..dd180b2997 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLut16TagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLut16TagDataEntry.cs @@ -140,12 +140,12 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - int hashCode = base.GetHashCode(); - hashCode = HashHelpers.Combine(hashCode, this.Matrix.GetHashCode()); - hashCode = HashHelpers.Combine(hashCode, this.InputValues.GetHashCode()); - hashCode = HashHelpers.Combine(hashCode, this.ClutValues.GetHashCode()); - hashCode = HashHelpers.Combine(hashCode, this.OutputValues.GetHashCode()); - return hashCode; + return HashCode.Combine( + this.Signature, + this.Matrix, + this.InputValues, + this.ClutValues, + this.OutputValues); } private Matrix4x4 CreateMatrix(float[,] matrix) diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLut8TagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLut8TagDataEntry.cs index e3c45adb49..b345d14a54 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLut8TagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLut8TagDataEntry.cs @@ -143,12 +143,12 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - int hashCode = base.GetHashCode(); - hashCode = HashHelpers.Combine(hashCode, this.Matrix.GetHashCode()); - hashCode = HashHelpers.Combine(hashCode, this.InputValues.GetHashCode()); - hashCode = HashHelpers.Combine(hashCode, this.ClutValues.GetHashCode()); - hashCode = HashHelpers.Combine(hashCode, this.OutputValues.GetHashCode()); - return hashCode; + return HashCode.Combine( + this.Signature, + this.Matrix, + this.InputValues, + this.ClutValues, + this.OutputValues); } private Matrix4x4 CreateMatrix(float[,] matrix) diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLutAToBTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLutAToBTagDataEntry.cs index 3dadee2da6..a6758e3330 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLutAToBTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLutAToBTagDataEntry.cs @@ -183,16 +183,14 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - int hashCode = base.GetHashCode(); - hashCode = HashHelpers.Combine(hashCode, this.InputChannelCount.GetHashCode()); - hashCode = HashHelpers.Combine(hashCode, this.OutputChannelCount.GetHashCode()); - hashCode = HashHelpers.Combine(hashCode, this.Matrix3x3.GetHashCode()); - hashCode = HashHelpers.Combine(hashCode, this.Matrix3x1.GetHashCode()); - hashCode = HashHelpers.Combine(hashCode, this.ClutValues?.GetHashCode() ?? 0); - hashCode = HashHelpers.Combine(hashCode, this.CurveB?.GetHashCode() ?? 0); - hashCode = HashHelpers.Combine(hashCode, this.CurveM?.GetHashCode() ?? 0); - hashCode = HashHelpers.Combine(hashCode, this.CurveA?.GetHashCode() ?? 0); - return hashCode; + return HashCode.Combine( + this.Signature, + this.InputChannelCount, + this.OutputChannelCount, + this.Matrix3x3, + this.Matrix3x1, + this.ClutValues, + HashCode.Combine(this.CurveB, this.CurveM, this.CurveA)); } private bool EqualsCurve(IccTagDataEntry[] thisCurves, IccTagDataEntry[] entryCurves) diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLutBToATagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLutBToATagDataEntry.cs index 09d0803802..6ee110199d 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLutBToATagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLutBToATagDataEntry.cs @@ -183,16 +183,14 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - int hashCode = base.GetHashCode(); - hashCode = HashHelpers.Combine(hashCode, this.InputChannelCount.GetHashCode()); - hashCode = HashHelpers.Combine(hashCode, this.OutputChannelCount.GetHashCode()); - hashCode = HashHelpers.Combine(hashCode, this.Matrix3x3.GetHashCode()); - hashCode = HashHelpers.Combine(hashCode, this.Matrix3x1.GetHashCode()); - hashCode = HashHelpers.Combine(hashCode, this.ClutValues?.GetHashCode() ?? 0); - hashCode = HashHelpers.Combine(hashCode, this.CurveB?.GetHashCode() ?? 0); - hashCode = HashHelpers.Combine(hashCode, this.CurveM?.GetHashCode() ?? 0); - hashCode = HashHelpers.Combine(hashCode, this.CurveA?.GetHashCode() ?? 0); - return hashCode; + return HashCode.Combine( + this.Signature, + this.InputChannelCount, + this.OutputChannelCount, + this.Matrix3x3, + this.Matrix3x1, + this.ClutValues, + HashCode.Combine(this.CurveB, this.CurveM, this.CurveA)); } private bool EqualsCurve(IccTagDataEntry[] thisCurves, IccTagDataEntry[] entryCurves) diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccMeasurementTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccMeasurementTagDataEntry.cs index 6f918660ff..9247ca593f 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccMeasurementTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccMeasurementTagDataEntry.cs @@ -106,13 +106,13 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - int hashCode = base.GetHashCode(); - hashCode = HashHelpers.Combine(hashCode, this.Observer.GetHashCode()); - hashCode = HashHelpers.Combine(hashCode, this.XyzBacking.GetHashCode()); - hashCode = HashHelpers.Combine(hashCode, this.Geometry.GetHashCode()); - hashCode = HashHelpers.Combine(hashCode, this.Flare.GetHashCode()); - hashCode = HashHelpers.Combine(hashCode, this.Illuminant.GetHashCode()); - return hashCode; + return HashCode.Combine( + this.Signature, + this.Observer, + this.XyzBacking, + this.Geometry, + this.Flare, + this.Illuminant); } } } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccMultiLocalizedUnicodeTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccMultiLocalizedUnicodeTagDataEntry.cs index 6f579a6b59..1a06eb5880 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccMultiLocalizedUnicodeTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccMultiLocalizedUnicodeTagDataEntry.cs @@ -66,9 +66,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc } /// - public override int GetHashCode() - { - return HashHelpers.Combine(base.GetHashCode(), this.Texts.GetHashCode()); - } + public override int GetHashCode() => HashCode.Combine(this.Signature, this.Texts); } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccMultiProcessElementsTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccMultiProcessElementsTagDataEntry.cs index 2a983a7095..f13fdb17fb 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccMultiProcessElementsTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccMultiProcessElementsTagDataEntry.cs @@ -90,11 +90,11 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - return HashHelpers.Combine( - base.GetHashCode(), + return HashCode.Combine( + this.Signature, this.InputChannelCount, this.OutputChannelCount, - this.Data.GetHashCode()); + this.Data); } } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccNamedColor2TagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccNamedColor2TagDataEntry.cs index 0da1f3e9fc..957b8d5c3f 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccNamedColor2TagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccNamedColor2TagDataEntry.cs @@ -155,13 +155,13 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - int hashCode = base.GetHashCode(); - hashCode = HashHelpers.Combine(hashCode, this.CoordinateCount.GetHashCode()); - hashCode = HashHelpers.Combine(hashCode, this.Prefix?.GetHashCode() ?? 0); - hashCode = HashHelpers.Combine(hashCode, this.Suffix?.GetHashCode() ?? 0); - hashCode = HashHelpers.Combine(hashCode, this.VendorFlags.GetHashCode()); - hashCode = HashHelpers.Combine(hashCode, this.Colors.GetHashCode()); - return hashCode; + return HashCode.Combine( + this.Signature, + this.CoordinateCount, + this.Prefix, + this.Suffix, + this.VendorFlags, + this.Colors); } } } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccParametricCurveTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccParametricCurveTagDataEntry.cs index 384129245c..9ec497d3be 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccParametricCurveTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccParametricCurveTagDataEntry.cs @@ -65,9 +65,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc } /// - public override int GetHashCode() - { - return HashHelpers.Combine(base.GetHashCode(), this.Curve.GetHashCode()); - } + public override int GetHashCode() => HashCode.Combine(this.Signature, this.Curve); } } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccProfileSequenceDescTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccProfileSequenceDescTagDataEntry.cs index a337d76ef5..ff69115267 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccProfileSequenceDescTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccProfileSequenceDescTagDataEntry.cs @@ -67,9 +67,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc } /// - public override int GetHashCode() - { - return HashHelpers.Combine(base.GetHashCode(), this.Descriptions.GetHashCode()); - } + public override int GetHashCode() => HashCode.Combine(this.Signature, this.Descriptions); } } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccProfileSequenceIdentifierTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccProfileSequenceIdentifierTagDataEntry.cs index 9c199bfdb5..c6cc0903c5 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccProfileSequenceIdentifierTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccProfileSequenceIdentifierTagDataEntry.cs @@ -65,9 +65,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc } /// - public override int GetHashCode() - { - return HashHelpers.Combine(base.GetHashCode(), this.Data.GetHashCode()); - } + public override int GetHashCode() => HashCode.Combine(this.Signature, this.Data); } } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccResponseCurveSet16TagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccResponseCurveSet16TagDataEntry.cs index 6d321eb751..494aa2888b 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccResponseCurveSet16TagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccResponseCurveSet16TagDataEntry.cs @@ -83,10 +83,10 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - return HashHelpers.Combine( - base.GetHashCode(), - this.ChannelCount.GetHashCode(), - this.Curves.GetHashCode()); + return HashCode.Combine( + this.Signature, + this.ChannelCount, + this.Curves); } } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccScreeningTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccScreeningTagDataEntry.cs index d13c2af909..a073291ad1 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccScreeningTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccScreeningTagDataEntry.cs @@ -77,10 +77,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - return HashHelpers.Combine( - base.GetHashCode(), - (int)this.Flags, - this.Channels.GetHashCode()); + return HashCode.Combine(this.Signature, this.Flags, this.Channels); } } } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccSignatureTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccSignatureTagDataEntry.cs index d89f3ef244..287f0efb0c 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccSignatureTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccSignatureTagDataEntry.cs @@ -65,9 +65,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc } /// - public override int GetHashCode() - { - return HashHelpers.Combine(base.GetHashCode(), this.SignatureData.GetHashCode()); - } + public override int GetHashCode() => HashCode.Combine(this.Signature, this.SignatureData); } } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccTextDescriptionTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccTextDescriptionTagDataEntry.cs index 9f9e5cef7b..8e6f4bc196 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccTextDescriptionTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccTextDescriptionTagDataEntry.cs @@ -166,13 +166,13 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - int hashCode = base.GetHashCode(); - hashCode = HashHelpers.Combine(hashCode, this.Ascii?.GetHashCode() ?? 0); - hashCode = HashHelpers.Combine(hashCode, this.Unicode?.GetHashCode() ?? 0); - hashCode = HashHelpers.Combine(hashCode, this.ScriptCode?.GetHashCode() ?? 0); - hashCode = HashHelpers.Combine(hashCode, this.UnicodeLanguageCode.GetHashCode()); - hashCode = HashHelpers.Combine(hashCode, this.ScriptCodeCode.GetHashCode()); - return hashCode; + return HashCode.Combine( + this.Signature, + this.Ascii, + this.Unicode, + this.ScriptCode, + this.UnicodeLanguageCode, + this.ScriptCodeCode); } } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccTextTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccTextTagDataEntry.cs index 0ff7de5512..ab3b3fb6fb 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccTextTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccTextTagDataEntry.cs @@ -64,9 +64,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc } /// - public override int GetHashCode() - { - return HashHelpers.Combine(base.GetHashCode(), this.Text.GetHashCode()); - } + public override int GetHashCode() => HashCode.Combine(this.Signature, this.Text); } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUFix16ArrayTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUFix16ArrayTagDataEntry.cs index 4b03f1b830..464cbb9e75 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUFix16ArrayTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUFix16ArrayTagDataEntry.cs @@ -64,9 +64,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc } /// - public override int GetHashCode() - { - return HashHelpers.Combine(base.GetHashCode(), this.Data.GetHashCode()); - } + public override int GetHashCode() => HashCode.Combine(this.Signature, this.Data); } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt16ArrayTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt16ArrayTagDataEntry.cs index 1536739846..1e7a7f8a90 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt16ArrayTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt16ArrayTagDataEntry.cs @@ -64,9 +64,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc } /// - public override int GetHashCode() - { - return HashHelpers.Combine(base.GetHashCode(), this.Data.GetHashCode()); - } + public override int GetHashCode() => HashCode.Combine(this.Signature, this.Data); } -} +} \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt32ArrayTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt32ArrayTagDataEntry.cs index 14ccebb2ab..affdc8720b 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt32ArrayTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt32ArrayTagDataEntry.cs @@ -64,9 +64,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc } /// - public override int GetHashCode() - { - return HashHelpers.Combine(base.GetHashCode(), this.Data.GetHashCode()); - } + public override int GetHashCode() => HashCode.Combine(this.Signature, this.Data); } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt64ArrayTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt64ArrayTagDataEntry.cs index 1819c7724e..36d48d6135 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt64ArrayTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt64ArrayTagDataEntry.cs @@ -65,9 +65,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc } /// - public override int GetHashCode() - { - return HashHelpers.Combine(base.GetHashCode(), this.Data.GetHashCode()); - } + public override int GetHashCode() => HashCode.Combine(this.Signature, this.Data); } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt8ArrayTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt8ArrayTagDataEntry.cs index ca4345e2b9..b2f2677575 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt8ArrayTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt8ArrayTagDataEntry.cs @@ -64,9 +64,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc } /// - public override int GetHashCode() - { - return HashHelpers.Combine(base.GetHashCode(), this.Data.GetHashCode()); - } + public override int GetHashCode() => HashCode.Combine(this.Signature, this.Data); } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUcrBgTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUcrBgTagDataEntry.cs index 3992fde109..510930e397 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUcrBgTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUcrBgTagDataEntry.cs @@ -86,11 +86,11 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - return HashHelpers.Combine( - base.GetHashCode(), - this.UcrCurve.GetHashCode(), - this.BgCurve.GetHashCode(), - this.Description.GetHashCode()); + return HashCode.Combine( + this.Signature, + this.UcrCurve, + this.BgCurve, + this.Description); } } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUnknownTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUnknownTagDataEntry.cs index f6a4149b46..a0089e7359 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUnknownTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUnknownTagDataEntry.cs @@ -64,9 +64,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc } /// - public override int GetHashCode() - { - return HashHelpers.Combine(base.GetHashCode(), this.Data.GetHashCode()); - } + public override int GetHashCode() => HashCode.Combine(this.Signature, this.Data); } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccViewingConditionsTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccViewingConditionsTagDataEntry.cs index 5b12c9d7ec..bd636d4f2c 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccViewingConditionsTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccViewingConditionsTagDataEntry.cs @@ -86,11 +86,11 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - return HashHelpers.Combine( - base.GetHashCode(), - this.IlluminantXyz.GetHashCode(), - this.SurroundXyz.GetHashCode(), - this.Illuminant.GetHashCode()); + return HashCode.Combine( + this.Signature, + this.IlluminantXyz, + this.SurroundXyz, + this.Illuminant); } } } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccClut.cs b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccClut.cs index 685b5884fb..3f7cad3afe 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccClut.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccClut.cs @@ -142,12 +142,12 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - int hashCode = this.Values.GetHashCode(); - hashCode = HashHelpers.Combine(hashCode, this.DataType.GetHashCode()); - hashCode = HashHelpers.Combine(hashCode, this.InputChannelCount.GetHashCode()); - hashCode = HashHelpers.Combine(hashCode, this.OutputChannelCount.GetHashCode()); - hashCode = HashHelpers.Combine(hashCode, this.GridPointCount.GetHashCode()); - return hashCode; + return HashCode.Combine( + this.Values, + this.DataType, + this.InputChannelCount, + this.OutputChannelCount, + this.GridPointCount); } private bool EqualsValuesArray(IccClut other) diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccColorantTableEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccColorantTableEntry.cs index 628934600a..8f273dd603 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccColorantTableEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccColorantTableEntry.cs @@ -102,11 +102,11 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - return HashHelpers.Combine( - this.Name.GetHashCode(), - this.Pcs1.GetHashCode(), - this.Pcs2.GetHashCode(), - this.Pcs3.GetHashCode()); + return HashCode.Combine( + this.Name, + this.Pcs1, + this.Pcs2, + this.Pcs3); } /// diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccNamedColor.cs b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccNamedColor.cs index 5889e5c213..b7cb5bc495 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccNamedColor.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccNamedColor.cs @@ -90,10 +90,10 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - return HashHelpers.Combine( - this.Name.GetHashCode(), - this.PcsCoordinates.GetHashCode(), - this.DeviceCoordinates.GetHashCode()); + return HashCode.Combine( + this.Name, + this.PcsCoordinates, + this.DeviceCoordinates); } /// diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileDescription.cs b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileDescription.cs index 3af6dc6a8f..7e7c527ead 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileDescription.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileDescription.cs @@ -84,13 +84,13 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - int hashCode = this.DeviceManufacturer.GetHashCode(); - hashCode = HashHelpers.Combine(hashCode, this.DeviceModel.GetHashCode()); - hashCode = HashHelpers.Combine(hashCode, this.DeviceAttributes.GetHashCode()); - hashCode = HashHelpers.Combine(hashCode, this.TechnologyInformation.GetHashCode()); - hashCode = HashHelpers.Combine(hashCode, this.DeviceManufacturerInfo.GetHashCode()); - hashCode = HashHelpers.Combine(hashCode, this.DeviceModelInfo.GetHashCode()); - return hashCode; + return HashCode.Combine( + this.DeviceManufacturer, + this.DeviceModel, + this.DeviceAttributes, + this.TechnologyInformation, + this.DeviceManufacturerInfo, + this.DeviceModelInfo); } } } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileId.cs b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileId.cs index 2748e7da72..f64d5409ae 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileId.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileId.cs @@ -101,11 +101,11 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - return HashHelpers.Combine( - this.Part1.GetHashCode(), - this.Part2.GetHashCode(), - this.Part3.GetHashCode(), - this.Part4.GetHashCode()); + return HashCode.Combine( + this.Part1, + this.Part2, + this.Part3, + this.Part4); } /// diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileSequenceIdentifier.cs b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileSequenceIdentifier.cs index 5422a1b5f1..ae451c5db8 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileSequenceIdentifier.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileSequenceIdentifier.cs @@ -44,9 +44,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc } /// - public override int GetHashCode() - { - return HashHelpers.Combine(this.Id.GetHashCode(), this.Description.GetHashCode()); - } + public override int GetHashCode() => HashCode.Combine(this.Id, this.Description); } } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccResponseNumber.cs b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccResponseNumber.cs index c0bae296d8..8cae869925 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccResponseNumber.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccResponseNumber.cs @@ -73,17 +73,9 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc this.MeasurementValue == other.MeasurementValue; /// - public override int GetHashCode() - { - return HashHelpers.Combine( - this.DeviceCode.GetHashCode(), - this.MeasurementValue.GetHashCode()); - } + public override int GetHashCode() => HashCode.Combine(this.DeviceCode, this.MeasurementValue); /// - public override string ToString() - { - return $"Code: {this.DeviceCode}; Value: {this.MeasurementValue}"; - } + public override string ToString() => $"Code: {this.DeviceCode}; Value: {this.MeasurementValue}"; } } diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccScreeningChannel.cs b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccScreeningChannel.cs index f2e1f31a5f..e8885a66bf 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccScreeningChannel.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccScreeningChannel.cs @@ -85,10 +85,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - return HashHelpers.Combine( - this.Frequency.GetHashCode(), - this.Angle.GetHashCode(), - (int)this.SpotShape); + return HashCode.Combine(this.Frequency, this.Angle, this.SpotShape); } /// diff --git a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccTagTableEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccTagTableEntry.cs index 082ffc6790..d93e068c52 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/Various/IccTagTableEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/Various/IccTagTableEntry.cs @@ -76,17 +76,14 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public bool Equals(IccTagTableEntry other) => - this.Signature == other.Signature && - this.Offset == other.Offset && - this.DataSize == other.DataSize; + this.Signature.Equals(other.Signature) && + this.Offset.Equals(other.Offset) && + this.DataSize.Equals(other.DataSize); /// public override int GetHashCode() { - return HashHelpers.Combine( - this.Signature.GetHashCode(), - this.Offset.GetHashCode(), - this.DataSize.GetHashCode()); + return HashCode.Combine(this.Signature, this.Offset, this.DataSize); } /// diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Bgr24.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Bgr24.cs index 6afa33aff8..96ff7da6f6 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Bgr24.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Bgr24.cs @@ -1,6 +1,7 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using System; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -189,9 +190,6 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public override int GetHashCode() - { - return HashHelpers.Combine(this.R.GetHashCode(), this.B.GetHashCode(), this.G.GetHashCode()); - } + public override int GetHashCode() => HashCode.Combine(this.R, this.B, this.G); } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Rgb24.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Rgb24.cs index fe7c299d55..86565731d2 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Rgb24.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Rgb24.cs @@ -1,6 +1,7 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using System; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -200,10 +201,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public override int GetHashCode() - { - return HashHelpers.Combine(this.R.GetHashCode(), this.B.GetHashCode(), this.G.GetHashCode()); - } + public override int GetHashCode() => HashCode.Combine(this.R, this.B, this.G); /// public override string ToString() => $"Rgb24({this.R}, {this.G}, {this.B})"; diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Rgb48.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Rgb48.cs index 8d06cdbc8f..eda116a46c 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Rgb48.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Rgb48.cs @@ -189,9 +189,6 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public override int GetHashCode() - { - return HashHelpers.Combine(this.R.GetHashCode(), this.G.GetHashCode(), this.B.GetHashCode()); - } + public override int GetHashCode() => HashCode.Combine(this.R, this.G, this.B); } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.cs b/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.cs index ff4c69d701..d65a5ade78 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.cs @@ -197,11 +197,6 @@ namespace SixLabors.ImageSharp.PixelFormats } /// - public override int GetHashCode() - { - int hash = HashHelpers.Combine(this.R.GetHashCode(), this.G.GetHashCode()); - hash = HashHelpers.Combine(hash, this.B.GetHashCode()); - return HashHelpers.Combine(hash, this.A.GetHashCode()); - } + public override int GetHashCode() => HashCode.Combine(this.R, this.G, this.B, this.A); } } \ No newline at end of file diff --git a/src/ImageSharp/Primitives/ValueSize.cs b/src/ImageSharp/Primitives/ValueSize.cs index 8af9ba2e48..e5e086540d 100644 --- a/src/ImageSharp/Primitives/ValueSize.cs +++ b/src/ImageSharp/Primitives/ValueSize.cs @@ -133,9 +133,6 @@ namespace SixLabors.ImageSharp.Primitives } /// - public override int GetHashCode() - { - return HashHelpers.Combine(this.Value.GetHashCode(), this.Type.GetHashCode()); - } + public override int GetHashCode() => HashCode.Combine(this.Value, this.Type); } -} +} \ No newline at end of file diff --git a/src/ImageSharp/Processing/Processors/Dithering/PixelPair.cs b/src/ImageSharp/Processing/Processors/Dithering/PixelPair.cs index b7bea2c746..13660d30ab 100644 --- a/src/ImageSharp/Processing/Processors/Dithering/PixelPair.cs +++ b/src/ImageSharp/Processing/Processors/Dithering/PixelPair.cs @@ -43,7 +43,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering => obj is PixelPair other && this.First.Equals(other.First) && this.Second.Equals(other.Second); /// - public override int GetHashCode() - => HashHelpers.Combine(this.First.GetHashCode(), this.Second.GetHashCode()); + public override int GetHashCode() => HashCode.Combine(this.First, this.Second); } } \ No newline at end of file From c0db8f16e25bef724beea1047763f7cd3aed2b4a Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Tue, 11 Dec 2018 18:16:21 -0800 Subject: [PATCH 26/40] Use HashCode.Add when combining more than 8 hashcodes --- .../TagDataEntries/IccLutAToBTagDataEntry.cs | 23 ++++++++++++------- .../TagDataEntries/IccLutBToATagDataEntry.cs | 23 ++++++++++++------- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLutAToBTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLutAToBTagDataEntry.cs index a6758e3330..f7c0946320 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLutAToBTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLutAToBTagDataEntry.cs @@ -183,14 +183,21 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - return HashCode.Combine( - this.Signature, - this.InputChannelCount, - this.OutputChannelCount, - this.Matrix3x3, - this.Matrix3x1, - this.ClutValues, - HashCode.Combine(this.CurveB, this.CurveM, this.CurveA)); +#pragma warning disable SA1129 // Do not use default value type constructor + var hashCode = new HashCode(); +#pragma warning restore SA1129 // Do not use default value type constructor + + hashCode.Add(this.Signature); + hashCode.Add(this.InputChannelCount); + hashCode.Add(this.OutputChannelCount); + hashCode.Add(this.Matrix3x3); + hashCode.Add(this.Matrix3x1); + hashCode.Add(this.ClutValues); + hashCode.Add(this.CurveB); + hashCode.Add(this.CurveM); + hashCode.Add(this.CurveA); + + return hashCode.ToHashCode(); } private bool EqualsCurve(IccTagDataEntry[] thisCurves, IccTagDataEntry[] entryCurves) diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLutBToATagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLutBToATagDataEntry.cs index 6ee110199d..27572acd0b 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLutBToATagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLutBToATagDataEntry.cs @@ -183,14 +183,21 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// public override int GetHashCode() { - return HashCode.Combine( - this.Signature, - this.InputChannelCount, - this.OutputChannelCount, - this.Matrix3x3, - this.Matrix3x1, - this.ClutValues, - HashCode.Combine(this.CurveB, this.CurveM, this.CurveA)); +#pragma warning disable SA1129 // Do not use default value type constructor + var hashCode = new HashCode(); +#pragma warning restore SA1129 // Do not use default value type constructor + + hashCode.Add(this.Signature); + hashCode.Add(this.InputChannelCount); + hashCode.Add(this.OutputChannelCount); + hashCode.Add(this.Matrix3x3); + hashCode.Add(this.Matrix3x1); + hashCode.Add(this.ClutValues); + hashCode.Add(this.CurveB); + hashCode.Add(this.CurveM); + hashCode.Add(this.CurveA); + + return hashCode.ToHashCode(); } private bool EqualsCurve(IccTagDataEntry[] thisCurves, IccTagDataEntry[] entryCurves) From 1b2e794c5b08d16c9b94a844352f389763321e06 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Thu, 13 Dec 2018 10:32:12 +1100 Subject: [PATCH 27/40] Use correct Kernel dimensions and optimize. Fix #786 --- src/ImageSharp/Primitives/DenseMatrix{T}.cs | 33 +++++-- .../Convolution/BoxBlurProcessor.cs | 18 ++-- .../Convolution/GaussianBlurProcessor.cs | 51 +++-------- .../Convolution/GaussianSharpenProcessor.cs | 86 +++++-------------- .../Primitives/DenseMatrixTests.cs | 24 ++++++ 5 files changed, 89 insertions(+), 123 deletions(-) diff --git a/src/ImageSharp/Primitives/DenseMatrix{T}.cs b/src/ImageSharp/Primitives/DenseMatrix{T}.cs index 7cfa98ec1b..170292e29e 100644 --- a/src/ImageSharp/Primitives/DenseMatrix{T}.cs +++ b/src/ImageSharp/Primitives/DenseMatrix{T}.cs @@ -110,7 +110,7 @@ namespace SixLabors.ImageSharp.Primitives /// The at the specified position. public ref T this[int row, int column] { - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] get { this.CheckCoordinates(row, column); @@ -125,7 +125,7 @@ namespace SixLabors.ImageSharp.Primitives /// /// The representation on the source data. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public static implicit operator DenseMatrix(T[,] data) => new DenseMatrix(data); /// @@ -135,9 +135,9 @@ namespace SixLabors.ImageSharp.Primitives /// /// The representation on the source data. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] #pragma warning disable SA1008 // Opening parenthesis should be spaced correctly - public static implicit operator T[,] (DenseMatrix data) + public static implicit operator T[,] (in DenseMatrix data) #pragma warning restore SA1008 // Opening parenthesis should be spaced correctly { var result = new T[data.Rows, data.Columns]; @@ -154,17 +154,38 @@ namespace SixLabors.ImageSharp.Primitives return result; } + /// + /// Transposes the rows and columns of the dense matrix. + /// + /// The . + [MethodImpl(InliningOptions.ShortMethod)] + public DenseMatrix Transpose() + { + var result = new DenseMatrix(this.Rows, this.Columns); + + for (int y = 0; y < this.Rows; y++) + { + for (int x = 0; x < this.Columns; x++) + { + ref T value = ref result[x, y]; + value = this[y, x]; + } + } + + return result; + } + /// /// Fills the matrix with the given value /// /// The value to fill each item with - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void Fill(T value) => this.Span.Fill(value); /// /// Clears the matrix setting each value to the default value for the element type /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] public void Clear() => this.Span.Clear(); /// diff --git a/src/ImageSharp/Processing/Processors/Convolution/BoxBlurProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/BoxBlurProcessor.cs index 38dc638b90..644d6c9e17 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/BoxBlurProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/BoxBlurProcessor.cs @@ -29,8 +29,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution { this.Radius = radius; this.kernelSize = (radius * 2) + 1; - this.KernelX = this.CreateBoxKernel(true); - this.KernelY = this.CreateBoxKernel(false); + this.KernelX = this.CreateBoxKernel(); + this.KernelY = this.KernelX.Transpose(); } /// @@ -49,24 +49,18 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution public DenseMatrix KernelY { get; } /// - protected override void OnFrameApply(ImageFrame source, Rectangle sourceRectangle, Configuration configuration) - { - new Convolution2PassProcessor(this.KernelX, this.KernelY).Apply(source, sourceRectangle, configuration); - } + protected override void OnFrameApply(ImageFrame source, Rectangle sourceRectangle, Configuration configuration) => new Convolution2PassProcessor(this.KernelX, this.KernelY).Apply(source, sourceRectangle, configuration); /// /// Create a 1 dimensional Box kernel. /// - /// Whether to calculate a horizontal kernel. /// The - private DenseMatrix CreateBoxKernel(bool horizontal) + private DenseMatrix CreateBoxKernel() { int size = this.kernelSize; - DenseMatrix kernel = horizontal - ? new DenseMatrix(size, 1) - : new DenseMatrix(1, size); + var kernel = new DenseMatrix(size, 1); - kernel.Fill(1.0F / size); + kernel.Fill(1F / size); return kernel; } diff --git a/src/ImageSharp/Processing/Processors/Convolution/GaussianBlurProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/GaussianBlurProcessor.cs index 3045b9993f..b3bc15d391 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/GaussianBlurProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/GaussianBlurProcessor.cs @@ -4,7 +4,6 @@ using System; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Primitives; -using SixLabors.ImageSharp.Processing.Processors; using SixLabors.Primitives; namespace SixLabors.ImageSharp.Processing.Processors.Convolution @@ -26,11 +25,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution /// /// The 'sigma' value representing the weight of the blur. public GaussianBlurProcessor(float sigma = 3F) + : this(sigma, (int)MathF.Ceiling(sigma * 3)) { - this.kernelSize = ((int)Math.Ceiling(sigma) * 2) + 1; - this.Sigma = sigma; - this.KernelX = this.CreateGaussianKernel(true); - this.KernelY = this.CreateGaussianKernel(false); + // Kernel radius is calculated using the minimum viable value. + // http://chemaguerra.com/gaussian-filter-radius/ } /// @@ -40,11 +38,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution /// The 'radius' value representing the size of the area to sample. /// public GaussianBlurProcessor(int radius) + : this(radius / 3F, radius) { - this.kernelSize = (radius * 2) + 1; - this.Sigma = radius; - this.KernelX = this.CreateGaussianKernel(true); - this.KernelY = this.CreateGaussianKernel(false); } /// @@ -61,8 +56,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution { this.kernelSize = (radius * 2) + 1; this.Sigma = sigma; - this.KernelX = this.CreateGaussianKernel(true); - this.KernelY = this.CreateGaussianKernel(false); + this.KernelX = this.CreateGaussianKernel(); + this.KernelY = this.KernelX.Transpose(); } /// @@ -82,22 +77,17 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution /// protected override void OnFrameApply(ImageFrame source, Rectangle sourceRectangle, Configuration configuration) - { - new Convolution2PassProcessor(this.KernelX, this.KernelY).Apply(source, sourceRectangle, configuration); - } + => new Convolution2PassProcessor(this.KernelX, this.KernelY).Apply(source, sourceRectangle, configuration); /// /// Create a 1 dimensional Gaussian kernel using the Gaussian G(x) function /// - /// Whether to calculate a horizontal kernel. /// The - private DenseMatrix CreateGaussianKernel(bool horizontal) + private DenseMatrix CreateGaussianKernel() { int size = this.kernelSize; float weight = this.Sigma; - DenseMatrix kernel = horizontal - ? new DenseMatrix(size, 1) - : new DenseMatrix(1, size); + var kernel = new DenseMatrix(size, 1); float sum = 0F; float midpoint = (size - 1) / 2F; @@ -107,30 +97,13 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution float x = i - midpoint; float gx = ImageMaths.Gaussian(x, weight); sum += gx; - if (horizontal) - { - kernel[0, i] = gx; - } - else - { - kernel[i, 0] = gx; - } + kernel[0, i] = gx; } // Normalize kernel so that the sum of all weights equals 1 - if (horizontal) - { - for (int i = 0; i < size; i++) - { - kernel[0, i] = kernel[0, i] / sum; - } - } - else + for (int i = 0; i < size; i++) { - for (int i = 0; i < size; i++) - { - kernel[i, 0] = kernel[i, 0] / sum; - } + kernel[0, i] /= sum; } return kernel; diff --git a/src/ImageSharp/Processing/Processors/Convolution/GaussianSharpenProcessor.cs b/src/ImageSharp/Processing/Processors/Convolution/GaussianSharpenProcessor.cs index 18963c73c0..786bf7757a 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/GaussianSharpenProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/GaussianSharpenProcessor.cs @@ -27,11 +27,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution /// The 'sigma' value representing the weight of the sharpening. /// public GaussianSharpenProcessor(float sigma = 3F) + : this(sigma, (int)MathF.Ceiling(sigma * 3)) { - this.kernelSize = ((int)Math.Ceiling(sigma) * 2) + 1; - this.Sigma = sigma; - this.KernelX = this.CreateGaussianKernel(true); - this.KernelY = this.CreateGaussianKernel(false); + // Kernel radius is calculated using the minimum viable value. + // http://chemaguerra.com/gaussian-filter-radius/ } /// @@ -41,11 +40,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution /// The 'radius' value representing the size of the area to sample. /// public GaussianSharpenProcessor(int radius) + : this(radius / 3F, radius) { - this.kernelSize = (radius * 2) + 1; - this.Sigma = radius; - this.KernelX = this.CreateGaussianKernel(true); - this.KernelY = this.CreateGaussianKernel(false); } /// @@ -62,8 +58,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution { this.kernelSize = (radius * 2) + 1; this.Sigma = sigma; - this.KernelX = this.CreateGaussianKernel(true); - this.KernelY = this.CreateGaussianKernel(false); + this.KernelX = this.CreateGaussianKernel(); + this.KernelY = this.KernelX.Transpose(); } /// @@ -83,91 +79,49 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution /// protected override void OnFrameApply(ImageFrame source, Rectangle sourceRectangle, Configuration configuration) - { - new Convolution2PassProcessor(this.KernelX, this.KernelY).Apply(source, sourceRectangle, configuration); - } + => new Convolution2PassProcessor(this.KernelX, this.KernelY).Apply(source, sourceRectangle, configuration); /// /// Create a 1 dimensional Gaussian kernel using the Gaussian G(x) function /// - /// Whether to calculate a horizontal kernel. /// The - private DenseMatrix CreateGaussianKernel(bool horizontal) + private DenseMatrix CreateGaussianKernel() { int size = this.kernelSize; float weight = this.Sigma; - DenseMatrix kernel = horizontal - ? new DenseMatrix(size, 1) - : new DenseMatrix(1, size); + var kernel = new DenseMatrix(size, 1); float sum = 0; - float midpoint = (size - 1) / 2f; + float midpoint = (size - 1) / 2F; for (int i = 0; i < size; i++) { float x = i - midpoint; float gx = ImageMaths.Gaussian(x, weight); sum += gx; - if (horizontal) - { - kernel[0, i] = gx; - } - else - { - kernel[i, 0] = gx; - } + kernel[0, i] = gx; } // Invert the kernel for sharpening. int midpointRounded = (int)midpoint; - - if (horizontal) + for (int i = 0; i < size; i++) { - for (int i = 0; i < size; i++) + if (i == midpointRounded) { - if (i == midpointRounded) - { - // Calculate central value - kernel[0, i] = (2F * sum) - kernel[0, i]; - } - else - { - // invert value - kernel[0, i] = -kernel[0, i]; - } + // Calculate central value + kernel[0, i] = (2F * sum) - kernel[0, i]; } - } - else - { - for (int i = 0; i < size; i++) + else { - if (i == midpointRounded) - { - // Calculate central value - kernel[i, 0] = (2 * sum) - kernel[i, 0]; - } - else - { - // invert value - kernel[i, 0] = -kernel[i, 0]; - } + // invert value + kernel[0, i] = -kernel[0, i]; } } // Normalize kernel so that the sum of all weights equals 1 - if (horizontal) - { - for (int i = 0; i < size; i++) - { - kernel[0, i] /= sum; - } - } - else + for (int i = 0; i < size; i++) { - for (int i = 0; i < size; i++) - { - kernel[i, 0] /= sum; - } + kernel[0, i] /= sum; } return kernel; diff --git a/tests/ImageSharp.Tests/Primitives/DenseMatrixTests.cs b/tests/ImageSharp.Tests/Primitives/DenseMatrixTests.cs index fa4862293f..0af8ae45f9 100644 --- a/tests/ImageSharp.Tests/Primitives/DenseMatrixTests.cs +++ b/tests/ImageSharp.Tests/Primitives/DenseMatrixTests.cs @@ -106,5 +106,29 @@ namespace SixLabors.ImageSharp.Tests.Primitives Assert.Equal(0, dense.Data[i]); } } + + [Fact] + public void DenseMatrixCorrectlyCasts() + { + float[,] actual = new DenseMatrix(FloydSteinbergMatrix); + Assert.Equal(FloydSteinbergMatrix, actual); + } + + [Fact] + public void DenseMatrixCanTranspose() + { + var dense = new DenseMatrix(3, 1); + dense[0, 0] = 1; + dense[0, 1] = 2; + dense[0, 2] = 3; + + DenseMatrix transposed = dense.Transpose(); + + Assert.Equal(dense.Columns, transposed.Rows); + Assert.Equal(dense.Rows, transposed.Columns); + Assert.Equal(1, transposed[0, 0]); + Assert.Equal(2, transposed[1, 0]); + Assert.Equal(3, transposed[2, 0]); + } } } \ No newline at end of file From 83d52d5f79f0f14b57e90346bd40de9012b3b1bc Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Thu, 13 Dec 2018 18:42:16 +1030 Subject: [PATCH 28/40] Seed unsafe calls from the static constructor. --- src/ImageSharp/Advanced/AotCompilerTools.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/ImageSharp/Advanced/AotCompilerTools.cs b/src/ImageSharp/Advanced/AotCompilerTools.cs index 9f20704cf7..c9c0e40146 100644 --- a/src/ImageSharp/Advanced/AotCompilerTools.cs +++ b/src/ImageSharp/Advanced/AotCompilerTools.cs @@ -18,10 +18,7 @@ namespace SixLabors.ImageSharp.Advanced /// public static class AotCompilerTools { - /// - /// Seeds the calls. - /// - public static void SeedUnsafe() + static AotCompilerTools() { System.Runtime.CompilerServices.Unsafe.SizeOf(); System.Runtime.CompilerServices.Unsafe.SizeOf(); From 520d181b0dcbb11a5b8226c4d38e1438178599a7 Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Fri, 14 Dec 2018 20:16:20 +1030 Subject: [PATCH 29/40] AoT seed image encoders as well as decoders --- src/ImageSharp/Advanced/AotCompilerTools.cs | 22 ++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/ImageSharp/Advanced/AotCompilerTools.cs b/src/ImageSharp/Advanced/AotCompilerTools.cs index c9c0e40146..db46ab4ad3 100644 --- a/src/ImageSharp/Advanced/AotCompilerTools.cs +++ b/src/ImageSharp/Advanced/AotCompilerTools.cs @@ -43,10 +43,10 @@ namespace SixLabors.ImageSharp.Advanced System.Runtime.CompilerServices.Unsafe.SizeOf(); - AotDecoder(new Formats.Png.PngDecoder()); - AotDecoder(new Formats.Bmp.BmpDecoder()); - AotDecoder(new Formats.Gif.GifDecoder()); - AotDecoder(new Formats.Jpeg.JpegDecoder()); + AotCodec(new Formats.Png.PngDecoder(), new Formats.Png.PngEncoder()); + AotCodec(new Formats.Bmp.BmpDecoder(), new Formats.Bmp.BmpEncoder()); + AotCodec(new Formats.Gif.GifDecoder(), new Formats.Gif.GifEncoder()); + AotCodec(new Formats.Jpeg.JpegDecoder(), new Formats.Jpeg.JpegEncoder()); // TODO: Do the discovery work to figure out what works and what doesn't. } @@ -122,11 +122,12 @@ namespace SixLabors.ImageSharp.Advanced } /// - /// This method pre-seeds the decoder for a given pixel format in the AoT compiler for iOS. + /// This method pre-seeds the decoder and encoder for a given pixel format in the AoT compiler for iOS. /// - /// The image decoder to seed.. + /// The image decoder to seed. + /// The image encoder to seed. /// The pixel format. - private static void AotDecoder(IImageDecoder decoder) + private static void AotCodec(IImageDecoder decoder, IImageEncoder encoder) where TPixel : struct, IPixel { try @@ -136,6 +137,13 @@ namespace SixLabors.ImageSharp.Advanced catch { } + try + { + encoder.Encode(null, null); + } + catch + { + } } } } \ No newline at end of file From 50c3d7fd7a41a018a6ea856b2a8c95e285b18284 Mon Sep 17 00:00:00 2001 From: Shane Woolcock Date: Fri, 14 Dec 2018 20:38:18 +1030 Subject: [PATCH 30/40] Code sanity --- src/ImageSharp/Advanced/AotCompilerTools.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ImageSharp/Advanced/AotCompilerTools.cs b/src/ImageSharp/Advanced/AotCompilerTools.cs index db46ab4ad3..eb6991e6a1 100644 --- a/src/ImageSharp/Advanced/AotCompilerTools.cs +++ b/src/ImageSharp/Advanced/AotCompilerTools.cs @@ -137,6 +137,7 @@ namespace SixLabors.ImageSharp.Advanced catch { } + try { encoder.Encode(null, null); From eb7d60b681b2c5ad49de2066e6bc4a9c440458bc Mon Sep 17 00:00:00 2001 From: popow Date: Sat, 15 Dec 2018 16:18:55 +0100 Subject: [PATCH 31/40] added parsing of the OS22XBITMAPHEADER short variant (16 bytes) --- src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs | 5 ++++ src/ImageSharp/Formats/Bmp/BmpInfoHeader.cs | 24 +++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs index ef3ca24ee8..f6eb78ea9d 100644 --- a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs +++ b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs @@ -510,6 +510,11 @@ namespace SixLabors.ImageSharp.Formats.Bmp // 12 bytes this.infoHeader = BmpInfoHeader.ParseCore(buffer); } + else if (headerSize == BmpInfoHeader.Os2Short) + { + // 16 bytes + this.infoHeader = BmpInfoHeader.ParseOs2Short(buffer); + } else if (headerSize >= BmpInfoHeader.Size) { // >= 40 bytes diff --git a/src/ImageSharp/Formats/Bmp/BmpInfoHeader.cs b/src/ImageSharp/Formats/Bmp/BmpInfoHeader.cs index 4dd63a9626..a32f806a94 100644 --- a/src/ImageSharp/Formats/Bmp/BmpInfoHeader.cs +++ b/src/ImageSharp/Formats/Bmp/BmpInfoHeader.cs @@ -26,6 +26,11 @@ namespace SixLabors.ImageSharp.Formats.Bmp /// public const int CoreSize = 12; + /// + /// Defines the size of the short variant of the OS22XBITMAPHEADER data structure in the bitmap file. + /// + public const int Os2Short = 16; + /// /// Defines the size of the biggest supported header data structure in the bitmap file. /// @@ -143,7 +148,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp /// /// Parses the BITMAPCOREHEADER consisting of the headerSize, width, height, planes, and bitsPerPixel fields (12 bytes). /// - /// The data to parse, + /// The data to parse. /// Parsed header /// public static BmpInfoHeader ParseCore(ReadOnlySpan data) @@ -156,6 +161,23 @@ namespace SixLabors.ImageSharp.Formats.Bmp bitsPerPixel: BinaryPrimitives.ReadInt16LittleEndian(data.Slice(10, 2))); } + /// + /// Parses a short variant of the OS22XBITMAPHEADER. It is identical to the BITMAPCOREHEADER, except that the width and height + /// are 4 bytes instead of 2. + /// + /// The data to parse. + /// Parsed header + /// + public static BmpInfoHeader ParseOs2Short(ReadOnlySpan data) + { + return new BmpInfoHeader( + headerSize: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(0, 4)), + width: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(4, 4)), + height: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(8, 4)), + planes: BinaryPrimitives.ReadInt16LittleEndian(data.Slice(12, 2)), + bitsPerPixel: BinaryPrimitives.ReadInt16LittleEndian(data.Slice(14, 2))); + } + public unsafe void WriteTo(Span buffer) { ref BmpInfoHeader dest = ref Unsafe.As(ref MemoryMarshal.GetReference(buffer)); From c25c34b4768a15f32f2c8c92b9b276d4f61df5ef Mon Sep 17 00:00:00 2001 From: popow Date: Sat, 15 Dec 2018 17:20:48 +0100 Subject: [PATCH 32/40] added unit test for decoding OS2 bitmap with 16 bytes header --- .../Formats/Bmp/BmpDecoderTests.cs | 30 +++++++++++++----- tests/Images/Input/Bmp/pal8os2v2-16.bmp | Bin 0 -> 9246 bytes 2 files changed, 22 insertions(+), 8 deletions(-) create mode 100644 tests/Images/Input/Bmp/pal8os2v2-16.bmp diff --git a/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs index 5f2de9f51e..dc858f9500 100644 --- a/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs @@ -88,19 +88,33 @@ namespace SixLabors.ImageSharp.Tests } } - [Theory] - [MemberData(nameof(RatioFiles))] - public void Identify_VerifyRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit) + [Fact] + public void DecodeOs22XShortHeader_VeryfyDimensions() { + string imagePath = @"Bmp/pal8os2v2-16.bmp"; 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); + using (Image image = decoder.Decode(Configuration.Default, stream)) + { + Assert.Equal(127, image.Width); + Assert.Equal(64, image.Height); + } + } + } + + [Fact] + public void IdentifyOs22XShortHeader_VeryfyDimensions() + { + string imagePath = @"Bmp/pal8os2v2-16.bmp"; + var testFile = TestFile.Create(imagePath); + using (var stream = new MemoryStream(testFile.Bytes, false)) + { + IImageInfo imageInfo = Image.Identify(stream); + Assert.Equal(127, imageInfo.Width); + Assert.Equal(64, imageInfo.Height); + Assert.Equal(8, imageInfo.PixelType.BitsPerPixel); } } } diff --git a/tests/Images/Input/Bmp/pal8os2v2-16.bmp b/tests/Images/Input/Bmp/pal8os2v2-16.bmp new file mode 100644 index 0000000000000000000000000000000000000000..95a1d2345aa1dd29cd03b29d0ea50879e24be9e3 GIT binary patch literal 9246 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 z zs~Ja*;NRX)1BMtW8i4-?@dx0T%uf8J{W5u-xw5n}Ha7Od*f`_vUHm7fXh4#oub-Qn zGs!D^p65PF{>9w?)!hF_xc}R^|NEgIN+p+5Y!ILrP!#_sKZH=seM>#tla5hIA*DT3Hc)@@L!=f9U}J(@A~3 z_=|DAm1IAeu(r_tg8;Mua1Mas_M!fN4GDcJwF&^$%TDa0`6oF4odnQH^KWqeQ?x&| zvNTWop8>D{z)JuYCzDgZC8c|EJ^qrvWG}g|EjcA>SvmP@f1N)8Wcbs8HGew5puF*D`QhW|_Q7k@gCT9)gz zzs@~h2gDzM>Vw?>EzRd>e}Dh*&@k;!3BZTdwezp@m-ed;$N@0<12F!K`+woyOWHp* zwU}I_{V4&MTQ%O=e*LEjBAx%yP4gFfrt!yK`9HxQyVR=5|JRS_FXlS=+@IE#EyY_t z!~bB*k(QQo&F9Wt>mME_fLQ{V6@L}L2?fx3k$Llm1R(7PVP$oGer*01{GTn{U08T| z@8!!^Q;UlPuuK5U_`5h~El^y&_?Ed@{+$1;{L}uFU-MTT*d%|>e@6b(%AW6)#y;Z_ z|1F(`QMf_XP$Nyi$=rc0?FMhSI|Kz6l(*fmA{)`3jUqB!K-xkql@cL%iCn?UNKJ5pf z1pvyo44)gmM)_e?9st#T0-(GCxOwsBP0A|(2|%?UfCT_3zp(gn@fGD4Re1m;d%gHx JfN{>U{tG?^9{2zN literal 0 HcmV?d00001 From 10af2ed98c206271457a40d0999c3a6a51c30655 Mon Sep 17 00:00:00 2001 From: popow Date: Sun, 16 Dec 2018 19:06:08 +0100 Subject: [PATCH 33/40] fix for Windows 2.0 or OS/2 1.x bitmaps only use 3 bytes per color palette entry --- src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs | 29 ++++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs index ef3ca24ee8..b11f7934d2 100644 --- a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs +++ b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs @@ -108,7 +108,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp { try { - this.ReadImageHeaders(stream, out bool inverted, out byte[] palette); + int bytesPerColorMapEntry = this.ReadImageHeaders(stream, out bool inverted, out byte[] palette); var image = new Image(this.configuration, this.infoHeader.Width, this.infoHeader.Height, this.metaData); @@ -137,6 +137,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp this.infoHeader.Width, this.infoHeader.Height, this.infoHeader.BitsPerPixel, + bytesPerColorMapEntry, inverted); } @@ -329,18 +330,20 @@ namespace SixLabors.ImageSharp.Formats.Bmp /// The containing the colors. /// The width of the bitmap. /// The height of the bitmap. - /// The number of bits per pixel. + /// The number of bits per pixel. + /// Usually 4 bytes, but in case of Windows 2.x bitmaps or OS/2 1.x bitmaps + /// the bytes per color palette entry's can be 3 bytes instead of 4. /// Whether the bitmap is inverted. - private void ReadRgbPalette(Buffer2D pixels, byte[] colors, int width, int height, int bits, bool inverted) + private void ReadRgbPalette(Buffer2D pixels, byte[] colors, int width, int height, int bitsPerPixel, int bytesPerColorMapEntry, bool inverted) where TPixel : struct, IPixel { // Pixels per byte (bits per pixel) - int ppb = 8 / bits; + int ppb = 8 / bitsPerPixel; int arrayWidth = (width + ppb - 1) / ppb; // Bit mask - int mask = 0xFF >> (8 - bits); + int mask = 0xFF >> (8 - bitsPerPixel); // Rows are aligned on 4 byte boundaries int padding = arrayWidth % 4; @@ -366,7 +369,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp int colOffset = x * ppb; for (int shift = 0, newX = colOffset; shift < ppb && newX < width; shift++, newX++) { - int colorIndex = ((rowSpan[offset] >> (8 - bits - (shift * bits))) & mask) * 4; + int colorIndex = ((rowSpan[offset] >> (8 - bitsPerPixel - (shift * bitsPerPixel))) & mask) * bytesPerColorMapEntry; color.FromBgr24(Unsafe.As(ref colors[colorIndex])); pixelRow[newX] = color; @@ -571,7 +574,9 @@ namespace SixLabors.ImageSharp.Formats.Bmp /// /// Reads the and from the stream and sets the corresponding fields. /// - private void ReadImageHeaders(Stream stream, out bool inverted, out byte[] palette) + /// Bytes per color palette entry. Usually 4 bytes, but in case of Windows 2.x bitmaps or OS/2 1.x bitmaps + /// the bytes per color palette entry's can be 3 bytes instead of 4. + private int ReadImageHeaders(Stream stream, out bool inverted, out byte[] palette) { this.stream = stream; @@ -591,6 +596,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp } int colorMapSize = -1; + int bytesPerColorMapEntry = 4; if (this.infoHeader.ClrUsed == 0) { @@ -598,12 +604,15 @@ namespace SixLabors.ImageSharp.Formats.Bmp || this.infoHeader.BitsPerPixel == 4 || this.infoHeader.BitsPerPixel == 8) { - colorMapSize = ImageMaths.GetColorCountForBitDepth(this.infoHeader.BitsPerPixel) * 4; + int colorMapSizeBytes = this.fileHeader.Offset - BmpFileHeader.Size - this.infoHeader.HeaderSize; + int colorCountForBitDepth = ImageMaths.GetColorCountForBitDepth(this.infoHeader.BitsPerPixel); + bytesPerColorMapEntry = colorMapSizeBytes / colorCountForBitDepth; + colorMapSize = colorMapSizeBytes; } } else { - colorMapSize = this.infoHeader.ClrUsed * 4; + colorMapSize = this.infoHeader.ClrUsed * bytesPerColorMapEntry; } palette = null; @@ -622,6 +631,8 @@ namespace SixLabors.ImageSharp.Formats.Bmp } this.infoHeader.VerifyDimensions(); + + return bytesPerColorMapEntry; } } } \ No newline at end of file From 377a2e50a2e8c1afb0c53f4cdfe1ac4aa9f18648 Mon Sep 17 00:00:00 2001 From: popow Date: Sun, 16 Dec 2018 21:36:29 +0100 Subject: [PATCH 34/40] Os2Short -> Os22ShortSize --- src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs | 4 ++-- src/ImageSharp/Formats/Bmp/BmpInfoHeader.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs index f6eb78ea9d..2226a1ec98 100644 --- a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs +++ b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs @@ -510,10 +510,10 @@ namespace SixLabors.ImageSharp.Formats.Bmp // 12 bytes this.infoHeader = BmpInfoHeader.ParseCore(buffer); } - else if (headerSize == BmpInfoHeader.Os2Short) + else if (headerSize == BmpInfoHeader.Os22ShortSize) { // 16 bytes - this.infoHeader = BmpInfoHeader.ParseOs2Short(buffer); + this.infoHeader = BmpInfoHeader.ParseOs22Short(buffer); } else if (headerSize >= BmpInfoHeader.Size) { diff --git a/src/ImageSharp/Formats/Bmp/BmpInfoHeader.cs b/src/ImageSharp/Formats/Bmp/BmpInfoHeader.cs index a32f806a94..5177bc325c 100644 --- a/src/ImageSharp/Formats/Bmp/BmpInfoHeader.cs +++ b/src/ImageSharp/Formats/Bmp/BmpInfoHeader.cs @@ -29,7 +29,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp /// /// Defines the size of the short variant of the OS22XBITMAPHEADER data structure in the bitmap file. /// - public const int Os2Short = 16; + public const int Os22ShortSize = 16; /// /// Defines the size of the biggest supported header data structure in the bitmap file. @@ -168,7 +168,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp /// The data to parse. /// Parsed header /// - public static BmpInfoHeader ParseOs2Short(ReadOnlySpan data) + public static BmpInfoHeader ParseOs22Short(ReadOnlySpan data) { return new BmpInfoHeader( headerSize: BinaryPrimitives.ReadInt32LittleEndian(data.Slice(0, 4)), From 0e41c13d3ccef2792db6fad809375f0a2d845f20 Mon Sep 17 00:00:00 2001 From: popow Date: Tue, 18 Dec 2018 19:34:28 +0100 Subject: [PATCH 35/40] added Test for decoding windows BMPv2 and one for a bitmap which has 4 bytes per color palette --- .../Formats/Bmp/BmpDecoderTests.cs | 24 ++++++++++++++++++ tests/ImageSharp.Tests/TestImages.cs | 3 +++ tests/Images/Input/Bmp/pal8-0.bmp | Bin 0 -> 9270 bytes tests/Images/Input/Bmp/pal8os2v1_winv2.bmp | Bin 0 -> 8986 bytes 4 files changed, 27 insertions(+) create mode 100644 tests/Images/Input/Bmp/pal8-0.bmp create mode 100644 tests/Images/Input/Bmp/pal8os2v1_winv2.bmp diff --git a/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs index 5f2de9f51e..d60d9d918a 100644 --- a/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs @@ -55,6 +55,30 @@ namespace SixLabors.ImageSharp.Tests } } + [Theory] + [WithFile(WinBmpv2, PixelTypes.Rgba32)] + public void BmpDecoder_CanDecodeBmpv2(TestImageProvider provider) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage(new BmpDecoder())) + { + image.DebugSave(provider, "png"); + image.CompareToOriginal(provider); + } + } + + [Theory] + [WithFile(Bit8Palette4, PixelTypes.Rgba32)] + public void BmpDecoder_CanDecode4BytePerEntryPalette(TestImageProvider provider) + where TPixel : struct, IPixel + { + using (Image image = provider.GetImage(new BmpDecoder())) + { + image.DebugSave(provider, "png"); + image.CompareToOriginal(provider); + } + } + [Theory] [InlineData(Car, 24)] [InlineData(F, 24)] diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index 1144a3f7c0..9c747dcb8a 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -201,6 +201,9 @@ namespace SixLabors.ImageSharp.Tests public const string Bit16 = "Bmp/test16.bmp"; public const string Bit16Inverted = "Bmp/test16-inverted.bmp"; public const string Bit32Rgb = "Bmp/rgb32.bmp"; + // Note: This format can be called OS/2 BMPv1, or Windows BMPv2 + public const string WinBmpv2 = "Bmp/pal8os2v1_winv2.bmp"; + public const string Bit8Palette4 = "Bmp/pal8-0.bmp"; public static readonly string[] All = { diff --git a/tests/Images/Input/Bmp/pal8-0.bmp b/tests/Images/Input/Bmp/pal8-0.bmp new file mode 100644 index 0000000000000000000000000000000000000000..ab8815a360d315ed119604c5a60feb81bfa65625 GIT binary patch literal 9270 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 IIA>Y^1(tjtKmY&$ literal 0 HcmV?d00001 diff --git a/tests/Images/Input/Bmp/pal8os2v1_winv2.bmp b/tests/Images/Input/Bmp/pal8os2v1_winv2.bmp new file mode 100644 index 0000000000000000000000000000000000000000..14901b3882cea0679832e4f45a49f6b10034d3ce GIT binary patch literal 8986 zcmbuDPiU0a-p5Z&O!`M%h=N>;i{5UU**H0BMoZ(%D=7#mU6|>jW??3JGKrvFNG=r2 zJB3OXH-gSYlanmWyAZ=rt{_xgB+@#$RmW$c!qB=X6$HgaZti{YPpgabetzdXNhbfi zeR+R}XP%ko$$5U?&-Z)IIQXBR{^`%k*Pm*YTF1NpQvac9)LY@AR>~-4m5P*dDxp+D ztAtSrs}hk)IF(i^tyS8nv{mUyrJc$tmD4I`RL-hgq;gIbl`3jgG^%J-F;YdRDoRzf zsu)$VsuHP+wA0!d?W}f@ zcIW_G8)b~LMn%Xn31t%6B#cQ|lZZ^hnY1!#ZPLc1tw~2F?MzOYoHjXQa@OP`lXIr1 zOi`PnF-2>NktsS;QKq6z#h8jUmB>__amqMtoH5QC7a4~IIIgWSR#~ee9I**y6WS(> zO<0?VY{J>JvT1G8#-^=JM>g$jPT8EcIb(Cy<|3POwy11T+oG{WYm1RBI$Ke;qHV?4 zinW!%BBV{6GBNY)wlu%JZM+p-pY?O$igp1NDO6w?XqO^_D zQIvL3PDME#8&pI6 z`i2b+8`f{yK>JNwH@~;_eFXgZ{SOh4ZO&%0opVP%lkZ$~c)WVyKP3F(0Q}#d_xOwW zrM;BkOM9unuj++=gYb(3@V~d!QR`4 zzXSdb+7BS$3IeXs{ucx^`uPnFDFn12pcVd4;BUkJ1HvEE=Q)RCkpseCoqymD`4hmh z`~yD@2z|_7oqymD`4hk!@*l*3!3_LK_>=H=!hhDBHN)`VJb&~1f5HC}e(tLz{0!(B z@H3!i!0+e7pMrnyroEe5;cwg8_TH!P9}xa{K%XJ|#X})L`TRRW{%6j{`AY!8?*m}{ z6Ts&L@bv)s6Tr7V0M=h4^CkaO$ba+RIDZL1__JhPedPHZjzP|}Z>Zw$CV%0_fgf+i z{N90>-#ZZVdk5g(F7spl7V;N<9C*LY^A|jIHWSWy&cT8BEc^)Ap4{HNtMgDd_Mbg7 ze0~`Fy?_@lRee1IlF39e+3|Tt2lfvPd_6F5<=ZP)5b(<{@FSoh+0eW`wV?(3_ik?8 z+KT;Nz=sEx(9b!MCwn>K{G0!u`8WTY{FkI2d%#syQ=@7c;7@k$>g?=3)ZGpLFag|z z|K`gVFTt;`hdkD^ejE_`z~8vNG0cab+Pk-vYQum} z+YTHM{>5Wa6od3n)`)$b$TTyNA#IFnkjMv`4@?p|5XFW*8kEr)5BYZQ$A! z=&wA&|74@YmrACZTT**l_O`U{{iL-G0klWJsw+S21mP!ts#Ewo!H55cVeqMH{y2Y$ ze{uee3kU>Be0VD9=K)@~9|K|C{ zfxw^X$asF};TH!U{nC#82N94#Ko$YV;r|i=eY8J`fH!0>4lK?8Y*qe&e_cHSk}~Gn zpB^~v+autYM~&cD!5E&UD zgeL_*<5&Ek$sGT+Yfpv0J>)O9eE#x=1=xoGpMN%9|4Yw#t`8RIzvitqO;joczi7;l zP`7TZ(BDHY<8S|>{oouw>reV0Ki-D{@SmK^f2Hij0QxtrX?iQwlxfPO_8?d&zzNfL!t~*#A`USIM6M$lsGMI51Bh9DrZLui@{4AEj9f|Lr;cCF>vi z=lOm9O0}P=;*X^*nxz6gPxelPGuAU?{nxSqH2HUtKLK!gWTZ5ofAy0j{Ve!%{MWBP zmD?C_DmcQw?BPxIEO|elyR3ml4#59*6@L%;3qKCXla>_i#i4lplYi(|#h+hc7OKTH z;T8v2gmL!bfbb)rNjL3Ib!B?wPx5xej@iqg&DSsd&w}nw9V@lQ5uBm++e%+Po>gvh#^uTWkAl`qAlAK!r zq4Dxp`90^qqZZBbS72Y!fmQOKU;n>t*|=rnzK#1nJ~p@i=K1||pZ3QcMH~OTgipuE z+5hA0|4S#4;$>U-Eh6G0&pBTr|JvHxw`(=EdpG=4pO(?EjuZk1eqJ zZS4Q=p5F5x3(ub8mxkA8pZ52M#U~&6r4#<<_&5S+-*@R!d`0MG1<+E+Wk8>o{4qfI zyM(_BeE3UtF8|-Rz`q6heY6j3fnWMf&kBEVAn*@{zZtdQQ}D;Lcx-;9L)Bsb4g?%V zKraGD;h#o8IXr3kN{abCJ^T~>-}GOWzvaRtzvsNhm1Zr^ex>{gU{U^yp5&XbI6{-@ z>FL>7;r}L%U?KnIvsR|(tE8@W2mE{BKMem+&rr`O{N=#EcwdsCYU{{<2l*c+e*)+kf}a3Z`u>&n$2>pTO9}r3 z23$VHB4qtf`utaDzhd^X9^iim{v9!YFZs{&%OjW8u?q;`qAk<@IRYm7{|5i%Q&+h- zIXJoW@5AT3{Hx**??IsV4hTO2^bWme_u;PIo?iG_y|&E$UtY&3&u=|_%#VOmmroJF z;3VsBdBM4A#reQ@8^3o6Y8fkK@AI##tF3zn{vC&RA3ogM)jI_L=(L?Kmv5KLuYP~EW!si5wBJYj zW5-T_e*pu^@cRJpf1-clZ}4Bf`q!&h31DifP%8QPI%K@bScaiej#4zC~>`1 zP;0S&CjyQj;3xvddPj%;J}TSm{{#V?!2AoW|1$QMpU>XM{s#zn zh=9ikn3*h1{i7uA$$a=Ff5~2QpFd=k_(LtpKk$eA380D}2j=;4fTF$Uug*X4hx`e^ z^V538fgIuA3I9&`kHCMf_gwE7{C7t0K=-=*8h+>r0Dc5Of5O|30NNwq{=@_LAHe?* z{wI@9CTHM(R(clZ3xA-;Y;nMkg|qN4%75tJ;MME-^&j#V`@I9Q0OI@+aQOlI|KZig*grKjQ<}m4 zvIw~MI_3`a3$JkybNPR?YW_mci20%S{CDApuKYUA|JOI?FXSQlrLSu3+Pbyx!oTy# zo+C$&9zJ^X+|bw<0o);gJHqb+*zX0L_=<7yf&?J;BjNe$`}ZgA{|x_whu=MX`1tDM z$4{naW(eRJ0X&1>!o27}iVX+9GFQu=^}i_pIeyyD^LqzY$)ELKmH)J-=XYgHUv-9m z?YnDtQXhQ;KXvZh7H4f$;$p;8}I**;{AUv-v4)G|Nnvf@5lT9*LeRwiTD4ru>M!gUfd9V z@~4gn{}J%v|N9vDR5kxspDp0uy(s)R;Q7g)dMNx4!H54JGvHI)UoHC*%{l0g{RlXM z0NNiJJ34lb_G7+10=)eMKzlFX;#U_h(%uV@0KEMOc!&VnKb(0y^Mv*@zC8jY`*85P J0OBQw`d{xg9_j!9 literal 0 HcmV?d00001 From 0f5df545be7d314f25fb6cb3d96bbf4c382ed053 Mon Sep 17 00:00:00 2001 From: popow Date: Tue, 18 Dec 2018 20:29:21 +0100 Subject: [PATCH 36/40] updated unit test to be in line with the other tests --- .../Formats/Bmp/BmpDecoderTests.cs | 33 +++++-------------- tests/ImageSharp.Tests/TestImages.cs | 1 + 2 files changed, 9 insertions(+), 25 deletions(-) diff --git a/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs index dc858f9500..2d6a5474d6 100644 --- a/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs @@ -11,6 +11,7 @@ using Xunit; namespace SixLabors.ImageSharp.Tests { using SixLabors.ImageSharp.MetaData; + using SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs; using static TestImages.Bmp; public class BmpDecoderTests @@ -88,33 +89,15 @@ namespace SixLabors.ImageSharp.Tests } } - [Fact] - public void DecodeOs22XShortHeader_VeryfyDimensions() - { - string imagePath = @"Bmp/pal8os2v2-16.bmp"; - 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)) - { - Assert.Equal(127, image.Width); - Assert.Equal(64, image.Height); - } - } - } - - [Fact] - public void IdentifyOs22XShortHeader_VeryfyDimensions() + [Theory] + [WithFile(Os2v2Short, PixelTypes.Rgba32)] + public void BmpDecoder_CanDecode_Os2v2XShortHeader(TestImageProvider provider) + where TPixel : struct, IPixel { - string imagePath = @"Bmp/pal8os2v2-16.bmp"; - var testFile = TestFile.Create(imagePath); - using (var stream = new MemoryStream(testFile.Bytes, false)) + using (Image image = provider.GetImage(new BmpDecoder())) { - IImageInfo imageInfo = Image.Identify(stream); - Assert.Equal(127, imageInfo.Width); - Assert.Equal(64, imageInfo.Height); - Assert.Equal(8, imageInfo.PixelType.BitsPerPixel); + image.DebugSave(provider, "png"); + image.CompareToOriginal(provider); } } } diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index 1144a3f7c0..8e226d337d 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -201,6 +201,7 @@ namespace SixLabors.ImageSharp.Tests public const string Bit16 = "Bmp/test16.bmp"; public const string Bit16Inverted = "Bmp/test16-inverted.bmp"; public const string Bit32Rgb = "Bmp/rgb32.bmp"; + public const string Os2v2Short = "Bmp/pal8os2v2-16.bmp"; public static readonly string[] All = { From 7e55d2277f405d8243c881187b411e5833fb88de Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Thu, 20 Dec 2018 20:30:07 +1100 Subject: [PATCH 37/40] Disable comparison since the reference decoders cannpt decode the image. --- tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs index 2d6a5474d6..98c3c194df 100644 --- a/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs @@ -11,7 +11,6 @@ using Xunit; namespace SixLabors.ImageSharp.Tests { using SixLabors.ImageSharp.MetaData; - using SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs; using static TestImages.Bmp; public class BmpDecoderTests @@ -97,7 +96,10 @@ namespace SixLabors.ImageSharp.Tests using (Image image = provider.GetImage(new BmpDecoder())) { image.DebugSave(provider, "png"); - image.CompareToOriginal(provider); + + // TODO: Neither System.Drawing not MagickReferenceDecoder + // can correctly decode this file. + // image.CompareToOriginal(provider); } } } From 5ef46927fcdb71f16db8a526349c7146f6d8f43c Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Thu, 20 Dec 2018 20:59:38 +1100 Subject: [PATCH 38/40] Use MagickReferenceDecoder for bmp. --- .../TestUtilities/TestEnvironment.Formats.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Formats.cs b/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Formats.cs index 334b6552ac..34a075ac7f 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Formats.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Formats.cs @@ -34,8 +34,7 @@ namespace SixLabors.ImageSharp.Tests { string extension = Path.GetExtension(filePath); - IImageFormat format = Configuration.ImageFormatsManager.FindFormatByFileExtension(extension); - return format; + return Configuration.ImageFormatsManager.FindFormatByFileExtension(extension); } private static void ConfigureCodecs( @@ -69,7 +68,7 @@ namespace SixLabors.ImageSharp.Tests cfg.ConfigureCodecs( BmpFormat.Instance, - SystemDrawingReferenceDecoder.Instance, + MagickReferenceDecoder.Instance, bmpEncoder, new BmpImageFormatDetector()); From 890134cec61a6c65a11562046635a248fd4d4158 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Thu, 20 Dec 2018 21:54:59 +1100 Subject: [PATCH 39/40] Fix reference tests --- .../TestUtilities/Tests/TestEnvironmentTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ImageSharp.Tests/TestUtilities/Tests/TestEnvironmentTests.cs b/tests/ImageSharp.Tests/TestUtilities/Tests/TestEnvironmentTests.cs index 30bb16c2a0..8abbd94bda 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Tests/TestEnvironmentTests.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Tests/TestEnvironmentTests.cs @@ -101,7 +101,7 @@ namespace SixLabors.ImageSharp.Tests [Theory] [InlineData("lol/foo.png", typeof(MagickReferenceDecoder))] - [InlineData("lol/Rofl.bmp", typeof(SystemDrawingReferenceDecoder))] + [InlineData("lol/Rofl.bmp", typeof(MagickReferenceDecoder))] [InlineData("lol/Baz.JPG", typeof(JpegDecoder))] [InlineData("lol/Baz.gif", typeof(GifDecoder))] public void GetReferenceDecoder_ReturnsCorrectDecoders_Windows(string fileName, Type expectedDecoderType) @@ -127,7 +127,7 @@ namespace SixLabors.ImageSharp.Tests [Theory] [InlineData("lol/foo.png", typeof(MagickReferenceDecoder))] - [InlineData("lol/Rofl.bmp", typeof(SystemDrawingReferenceDecoder))] + [InlineData("lol/Rofl.bmp", typeof(MagickReferenceDecoder))] [InlineData("lol/Baz.JPG", typeof(JpegDecoder))] [InlineData("lol/Baz.gif", typeof(GifDecoder))] public void GetReferenceDecoder_ReturnsCorrectDecoders_Linux(string fileName, Type expectedDecoderType) From 2f3c0fce47c8636c7f2102b0b89705eaa778f217 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Thu, 20 Dec 2018 23:25:23 +1100 Subject: [PATCH 40/40] Use S.D in Windows. --- tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Formats.cs | 2 +- .../TestUtilities/Tests/TestEnvironmentTests.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Formats.cs b/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Formats.cs index 34a075ac7f..7d06847223 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Formats.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Formats.cs @@ -68,7 +68,7 @@ namespace SixLabors.ImageSharp.Tests cfg.ConfigureCodecs( BmpFormat.Instance, - MagickReferenceDecoder.Instance, + IsWindows ? (IImageDecoder)SystemDrawingReferenceDecoder.Instance : MagickReferenceDecoder.Instance, bmpEncoder, new BmpImageFormatDetector()); diff --git a/tests/ImageSharp.Tests/TestUtilities/Tests/TestEnvironmentTests.cs b/tests/ImageSharp.Tests/TestUtilities/Tests/TestEnvironmentTests.cs index 8abbd94bda..122234ae89 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Tests/TestEnvironmentTests.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Tests/TestEnvironmentTests.cs @@ -101,7 +101,7 @@ namespace SixLabors.ImageSharp.Tests [Theory] [InlineData("lol/foo.png", typeof(MagickReferenceDecoder))] - [InlineData("lol/Rofl.bmp", typeof(MagickReferenceDecoder))] + [InlineData("lol/Rofl.bmp", typeof(SystemDrawingReferenceDecoder))] [InlineData("lol/Baz.JPG", typeof(JpegDecoder))] [InlineData("lol/Baz.gif", typeof(GifDecoder))] public void GetReferenceDecoder_ReturnsCorrectDecoders_Windows(string fileName, Type expectedDecoderType)