Browse Source

Merge branch 'master' into more-aot-compiling

af/merge-core
Shane Woolcock 7 years ago
parent
commit
ca2afcd131
  1. 20
      src/ImageSharp.Drawing/ImageSharp.Drawing.csproj
  2. 8
      src/ImageSharp/ColorSpaces/CieLab.cs
  3. 5
      src/ImageSharp/ColorSpaces/CieLch.cs
  4. 8
      src/ImageSharp/ColorSpaces/CieLchuv.cs
  5. 8
      src/ImageSharp/ColorSpaces/CieLuv.cs
  6. 2
      src/ImageSharp/ColorSpaces/CieXyChromaticityCoordinates.cs
  7. 7
      src/ImageSharp/ColorSpaces/CieXyy.cs
  8. 7
      src/ImageSharp/ColorSpaces/CieXyz.cs
  9. 8
      src/ImageSharp/ColorSpaces/Cmyk.cs
  10. 10
      src/ImageSharp/ColorSpaces/Conversion/Implementation/RGBPrimariesChromaticityCoordinates.cs
  11. 10
      src/ImageSharp/ColorSpaces/Conversion/Implementation/WorkingSpaces/GammaWorkingSpace.cs
  12. 5
      src/ImageSharp/ColorSpaces/Conversion/Implementation/WorkingSpaces/RgbWorkingSpaceBase.cs
  13. 7
      src/ImageSharp/ColorSpaces/Hsl.cs
  14. 7
      src/ImageSharp/ColorSpaces/Hsv.cs
  15. 5
      src/ImageSharp/ColorSpaces/HunterLab.cs
  16. 7
      src/ImageSharp/ColorSpaces/LinearRgb.cs
  17. 7
      src/ImageSharp/ColorSpaces/Lms.cs
  18. 7
      src/ImageSharp/ColorSpaces/Rgb.cs
  19. 7
      src/ImageSharp/ColorSpaces/YCbCr.cs
  20. 9
      src/ImageSharp/Common/Helpers/TolerantMath.cs
  21. 4
      src/ImageSharp/Common/ParallelUtils/ParallelHelper.cs
  22. 12
      src/ImageSharp/Formats/Jpeg/Components/Decoder/AdobeMarker.cs
  23. 13
      src/ImageSharp/Formats/Jpeg/Components/Decoder/JFifMarker.cs
  24. 4
      src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
  25. 2
      src/ImageSharp/Formats/Png/PngEncoderCore.cs
  26. 22
      src/ImageSharp/ImageSharp.csproj
  27. 14
      src/ImageSharp/MetaData/ImageProperty.cs
  28. 6
      src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs
  29. 20
      src/ImageSharp/MetaData/Profiles/Exif/ExifValue.cs
  30. 21
      src/ImageSharp/MetaData/Profiles/ICC/Curves/IccParametricCurve.cs
  31. 11
      src/ImageSharp/MetaData/Profiles/ICC/Curves/IccResponseCurve.cs
  32. 8
      src/ImageSharp/MetaData/Profiles/ICC/IccTagDataEntry.cs
  33. 11
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccChromaticityTagDataEntry.cs
  34. 5
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccColorantOrderTagDataEntry.cs
  35. 5
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccColorantTableTagDataEntry.cs
  36. 17
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccCrdInfoTagDataEntry.cs
  37. 8
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccCurveTagDataEntry.cs
  38. 11
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccDataTagDataEntry.cs
  39. 5
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccDateTimeTagDataEntry.cs
  40. 8
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccFix16ArrayTagDataEntry.cs
  41. 24
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLut16TagDataEntry.cs
  42. 24
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLut8TagDataEntry.cs
  43. 28
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLutAToBTagDataEntry.cs
  44. 28
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLutBToATagDataEntry.cs
  45. 17
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccMeasurementTagDataEntry.cs
  46. 8
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccMultiLocalizedUnicodeTagDataEntry.cs
  47. 13
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccMultiProcessElementsTagDataEntry.cs
  48. 18
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccNamedColor2TagDataEntry.cs
  49. 10
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccParametricCurveTagDataEntry.cs
  50. 8
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccProfileSequenceDescTagDataEntry.cs
  51. 8
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccProfileSequenceIdentifierTagDataEntry.cs
  52. 11
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccResponseCurveSet16TagDataEntry.cs
  53. 8
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccScreeningTagDataEntry.cs
  54. 8
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccSignatureTagDataEntry.cs
  55. 17
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccTextDescriptionTagDataEntry.cs
  56. 8
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccTextTagDataEntry.cs
  57. 8
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUFix16ArrayTagDataEntry.cs
  58. 10
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt16ArrayTagDataEntry.cs
  59. 8
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt32ArrayTagDataEntry.cs
  60. 8
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt64ArrayTagDataEntry.cs
  61. 8
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt8ArrayTagDataEntry.cs
  62. 13
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUcrBgTagDataEntry.cs
  63. 8
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUnknownTagDataEntry.cs
  64. 13
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccViewingConditionsTagDataEntry.cs
  65. 15
      src/ImageSharp/MetaData/Profiles/ICC/Various/IccClut.cs
  66. 13
      src/ImageSharp/MetaData/Profiles/ICC/Various/IccColorantTableEntry.cs
  67. 26
      src/ImageSharp/MetaData/Profiles/ICC/Various/IccNamedColor.cs
  68. 10
      src/ImageSharp/MetaData/Profiles/ICC/Various/IccPositionNumber.cs
  69. 24
      src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileDescription.cs
  70. 13
      src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileId.cs
  71. 12
      src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileSequenceIdentifier.cs
  72. 15
      src/ImageSharp/MetaData/Profiles/ICC/Various/IccResponseNumber.cs
  73. 8
      src/ImageSharp/MetaData/Profiles/ICC/Various/IccScreeningChannel.cs
  74. 14
      src/ImageSharp/MetaData/Profiles/ICC/Various/IccTagTableEntry.cs
  75. 7
      src/ImageSharp/PixelFormats/PixelImplementations/Bgr24.cs
  76. 7
      src/ImageSharp/PixelFormats/PixelImplementations/Rgb24.cs
  77. 7
      src/ImageSharp/PixelFormats/PixelImplementations/Rgb48.cs
  78. 7
      src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.cs
  79. 7
      src/ImageSharp/Primitives/ValueSize.cs
  80. 2
      src/ImageSharp/Processing/Processors/Dithering/PaletteDitherProcessorBase.cs
  81. 3
      src/ImageSharp/Processing/Processors/Dithering/PixelPair.cs
  82. 13
      src/ImageSharp/Processing/Processors/Transforms/ProjectiveTransformProcessor.cs
  83. 79
      src/ImageSharp/Processing/Processors/Transforms/TransformUtils.cs
  84. 26
      src/Shared/AssemblyInfo.Common.cs
  85. 1
      tests/ImageSharp.Benchmarks/General/BasicMath/ModuloPowerOfTwoConstant.cs
  86. 1
      tests/ImageSharp.Benchmarks/General/BasicMath/ModuloPowerOfTwoVariable.cs
  87. 1
      tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Bgra32.cs
  88. 2
      tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj
  89. 8
      tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj
  90. 7
      tests/ImageSharp.Tests/ImageSharp.Tests.csproj
  91. 5
      tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeKernelMapTests.cs
  92. 98
      tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs
  93. 27
      tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformTests.cs
  94. 2
      tests/ImageSharp.Tests/TestUtilities/Attributes/ImageDataAttributeBase.cs
  95. 13
      tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestPatternProvider.cs
  96. 47
      tests/ImageSharp.Tests/TestUtilities/TestUtils.cs
  97. 12
      tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs
  98. 2
      tests/Images/External

20
src/ImageSharp.Drawing/ImageSharp.Drawing.csproj

@ -1,10 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>An extension to ImageSharp that allows the drawing of images, paths, and text.</Description>
<PropertyGroup>
<AssemblyTitle>SixLabors.ImageSharp.Drawing</AssemblyTitle>
<Authors>SixLabors and contributors</Authors>
<Company>Six Labors</Company>
<Copyright>Copyright (c) Six Labors and contributors.</Copyright>
<Product>SixLabors.ImageSharp</Product>
<Description>An extension to ImageSharp that allows the drawing of images, paths, and text.</Description>
<NeutralLanguage>en</NeutralLanguage>
<VersionPrefix Condition="$(packageversion) != ''">$(packageversion)</VersionPrefix>
<VersionPrefix Condition="$(packageversion) == ''">0.0.1</VersionPrefix>
<Authors>SixLabors and contributors</Authors>
<TargetFrameworks>netstandard1.3;netstandard2.0</TargetFrameworks>
<LangVersion>7.3</LangVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
@ -17,15 +22,6 @@
<PackageLicenseUrl>http://www.apache.org/licenses/LICENSE-2.0</PackageLicenseUrl>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/SixLabors/ImageSharp</RepositoryUrl>
<GenerateAssemblyDescriptionAttribute>false</GenerateAssemblyDescriptionAttribute>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute>
<GenerateNeutralResourcesLanguageAttribute>false</GenerateNeutralResourcesLanguageAttribute>
<GenerateAssemblyVersionAttribute>false</GenerateAssemblyVersionAttribute>
<GenerateAssemblyFileVersionAttribute>false</GenerateAssemblyFileVersionAttribute>
<GenerateAssemblyInformationalVersionAttribute>false</GenerateAssemblyInformationalVersionAttribute>
<DebugType Condition="$(codecov) != ''">full</DebugType>
<DebugType Condition="$(codecov) == ''">portable</DebugType>
<DebugSymbols>True</DebugSymbols>

8
src/ImageSharp/ColorSpaces/CieLab.cs

@ -118,13 +118,7 @@ namespace SixLabors.ImageSharp.ColorSpaces
public static bool operator !=(CieLab left, CieLab right) => !left.Equals(right);
/// <inheritdoc/>
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());
}
public override int GetHashCode() => HashCode.Combine(this.L, this.A, this.B, this.WhitePoint);
/// <inheritdoc/>
public override string ToString() => FormattableString.Invariant($"CieLab({this.L:#0.##}, {this.A:#0.##}, {this.B:#0.##})");

5
src/ImageSharp/ColorSpaces/CieLch.cs

@ -122,10 +122,7 @@ namespace SixLabors.ImageSharp.ColorSpaces
/// <inheritdoc/>
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 HashCode.Combine(this.L, this.C, this.H, this.WhitePoint);
}
/// <inheritdoc/>

8
src/ImageSharp/ColorSpaces/CieLchuv.cs

@ -119,13 +119,7 @@ namespace SixLabors.ImageSharp.ColorSpaces
public static bool operator !=(CieLchuv left, CieLchuv right) => !left.Equals(right);
/// <inheritdoc/>
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());
}
public override int GetHashCode() => HashCode.Combine(this.L, this.C, this.H, this.WhitePoint);
/// <inheritdoc/>
public override string ToString() => FormattableString.Invariant($"CieLchuv({this.L:#0.##}, {this.C:#0.##}, {this.H:#0.##})");

8
src/ImageSharp/ColorSpaces/CieLuv.cs

@ -119,13 +119,7 @@ namespace SixLabors.ImageSharp.ColorSpaces
public static bool operator !=(CieLuv left, CieLuv right) => !left.Equals(right);
/// <inheritdoc/>
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());
}
public override int GetHashCode() => HashCode.Combine(this.L, this.U, this.V, this.WhitePoint);
/// <inheritdoc/>
public override string ToString() => FormattableString.Invariant($"CieLuv({this.L:#0.##}, {this.U:#0.##}, {this.V:#0.##})");

2
src/ImageSharp/ColorSpaces/CieXyChromaticityCoordinates.cs

@ -64,7 +64,7 @@ namespace SixLabors.ImageSharp.ColorSpaces
/// <inheritdoc />
[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);
/// <inheritdoc/>
public override string ToString() => FormattableString.Invariant($"CieXyChromaticityCoordinates({this.X:#0.##}, {this.Y:#0.##})");

7
src/ImageSharp/ColorSpaces/CieXyy.cs

@ -83,12 +83,7 @@ namespace SixLabors.ImageSharp.ColorSpaces
public static bool operator !=(CieXyy left, CieXyy right) => !left.Equals(right);
/// <inheritdoc/>
public override int GetHashCode()
{
int hash = this.X.GetHashCode();
hash = HashHelpers.Combine(hash, this.Y.GetHashCode());
return HashHelpers.Combine(hash, this.Yl.GetHashCode());
}
public override int GetHashCode() => HashCode.Combine(this.X, this.Y, this.Yl);
/// <inheritdoc/>
public override string ToString() => FormattableString.Invariant($"CieXyy({this.X:#0.##}, {this.Y:#0.##}, {this.Yl:#0.##})");

7
src/ImageSharp/ColorSpaces/CieXyz.cs

@ -86,12 +86,7 @@ namespace SixLabors.ImageSharp.ColorSpaces
public Vector3 ToVector3() => new Vector3(this.X, this.Y, this.Z);
/// <inheritdoc/>
public override int GetHashCode()
{
int hash = this.X.GetHashCode();
hash = HashHelpers.Combine(hash, this.Y.GetHashCode());
return HashHelpers.Combine(hash, this.Z.GetHashCode());
}
public override int GetHashCode() => HashCode.Combine(this.X, this.Y, this.Z);
/// <inheritdoc/>
public override string ToString() => FormattableString.Invariant($"CieXyz({this.X:#0.##}, {this.Y:#0.##}, {this.Z:#0.##})");

8
src/ImageSharp/ColorSpaces/Cmyk.cs

@ -90,13 +90,7 @@ namespace SixLabors.ImageSharp.ColorSpaces
/// <inheritdoc/>
[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());
}
public override int GetHashCode() => HashCode.Combine(this.C, this.M, this.Y, this.K);
/// <inheritdoc/>
public override string ToString() => FormattableString.Invariant($"Cmyk({this.C:#0.##}, {this.M:#0.##}, {this.Y:#0.##}, {this.K:#0.##})");

10
src/ImageSharp/ColorSpaces/Conversion/Implementation/RGBPrimariesChromaticityCoordinates.cs

@ -86,14 +86,6 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation
}
/// <inheritdoc />
public override int GetHashCode()
{
unchecked
{
int hashCode = this.R.GetHashCode();
hashCode = (hashCode * 397) ^ this.G.GetHashCode();
return (hashCode * 397) ^ this.B.GetHashCode();
}
}
public override int GetHashCode() => HashCode.Combine(this.R, this.G, this.B);
}
}

10
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,10 +58,9 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation
}
/// <inheritdoc/>
public override int GetHashCode()
{
int hash = base.GetHashCode();
return HashHelpers.Combine(hash, this.Gamma.GetHashCode());
}
public override int GetHashCode() => HashCode.Combine(
this.WhitePoint,
this.ChromaticityCoordinates,
this.Gamma);
}
}

5
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
{
/// <summary>
@ -76,8 +78,7 @@ namespace SixLabors.ImageSharp.ColorSpaces.Conversion.Implementation
/// <inheritdoc/>
public override int GetHashCode()
{
int hash = this.WhitePoint.GetHashCode();
return HashHelpers.Combine(hash, this.ChromaticityCoordinates.GetHashCode());
return HashCode.Combine(this.WhitePoint, this.ChromaticityCoordinates);
}
}
}

7
src/ImageSharp/ColorSpaces/Hsl.cs

@ -84,12 +84,7 @@ namespace SixLabors.ImageSharp.ColorSpaces
/// <inheritdoc/>
[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());
}
public override int GetHashCode() => HashCode.Combine(this.H, this.S, this.L);
/// <inheritdoc/>
public override string ToString() => FormattableString.Invariant($"Hsl({this.H:#0.##}, {this.S:#0.##}, {this.L:#0.##})");

7
src/ImageSharp/ColorSpaces/Hsv.cs

@ -82,12 +82,7 @@ namespace SixLabors.ImageSharp.ColorSpaces
/// <inheritdoc/>
[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());
}
public override int GetHashCode() => HashCode.Combine(this.H, this.S, this.V);
/// <inheritdoc/>
public override string ToString() => FormattableString.Invariant($"Hsv({this.H:#0.##}, {this.S:#0.##}, {this.V:#0.##})");

5
src/ImageSharp/ColorSpaces/HunterLab.cs

@ -119,10 +119,7 @@ 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 HashCode.Combine(this.L, this.A, this.B, this.WhitePoint);
}
/// <inheritdoc/>

7
src/ImageSharp/ColorSpaces/LinearRgb.cs

@ -126,12 +126,7 @@ namespace SixLabors.ImageSharp.ColorSpaces
/// <inheritdoc/>
[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());
}
public override int GetHashCode() => HashCode.Combine(this.R, this.G, this.B);
/// <inheritdoc/>
public override string ToString() => FormattableString.Invariant($"LinearRgb({this.R:#0.##}, {this.G:#0.##}, {this.B:#0.##})");

7
src/ImageSharp/ColorSpaces/Lms.cs

@ -87,12 +87,7 @@ namespace SixLabors.ImageSharp.ColorSpaces
public Vector3 ToVector3() => new Vector3(this.L, this.M, this.S);
/// <inheritdoc/>
public override int GetHashCode()
{
int hash = this.L.GetHashCode();
hash = HashHelpers.Combine(hash, this.M.GetHashCode());
return HashHelpers.Combine(hash, this.S.GetHashCode());
}
public override int GetHashCode() => HashCode.Combine(this.L, this.M, this.S);
/// <inheritdoc/>
public override string ToString() => FormattableString.Invariant($"Lms({this.L:#0.##}, {this.M:#0.##}, {this.S:#0.##})");

7
src/ImageSharp/ColorSpaces/Rgb.cs

@ -147,12 +147,7 @@ namespace SixLabors.ImageSharp.ColorSpaces
public Vector3 ToVector3() => new Vector3(this.R, this.G, this.B);
/// <inheritdoc/>
public override int GetHashCode()
{
int hash = this.R.GetHashCode();
hash = HashHelpers.Combine(hash, this.G.GetHashCode());
return HashHelpers.Combine(hash, this.B.GetHashCode());
}
public override int GetHashCode() => HashCode.Combine(this.R, this.G, this.B);
/// <inheritdoc/>
public override string ToString() => FormattableString.Invariant($"Rgb({this.R:#0.##}, {this.G:#0.##}, {this.B:#0.##})");

7
src/ImageSharp/ColorSpaces/YCbCr.cs

@ -83,12 +83,7 @@ namespace SixLabors.ImageSharp.ColorSpaces
/// <inheritdoc/>
[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());
}
public override int GetHashCode() => HashCode.Combine(this.Y, this.Cb, this.Cr);
/// <inheritdoc/>
public override string ToString() => FormattableString.Invariant($"YCbCr({this.Y}, {this.Cb}, {this.Cr})");

9
src/ImageSharp/Common/Helpers/TolerantMath.cs

@ -16,6 +16,13 @@ namespace SixLabors.ImageSharp
private readonly double negEpsilon;
/// <summary>
/// A read-only default instance for <see cref="TolerantMath"/> 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!
/// </summary>
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);
/// <summary>
/// <paramref name="a"/> == 0
/// </summary>

4
src/ImageSharp/Common/ParallelUtils/ParallelHelper.cs

@ -85,7 +85,7 @@ namespace SixLabors.ImageSharp.ParallelUtils
Rectangle rectangle,
in ParallelExecutionSettings parallelSettings,
Action<RowInterval, Memory<T>> 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<RowInterval, Memory<T>> body)
where T : struct
where T : unmanaged
{
IterateRowsWithTempBuffer(rectangle, configuration.GetParallelSettings(), body);
}

12
src/ImageSharp/Formats/Jpeg/Components/Decoder/AdobeMarker.cs

@ -100,13 +100,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
/// <inheritdoc/>
public override int GetHashCode()
{
return HashHelpers.Combine(
this.DCTEncodeVersion.GetHashCode(),
HashHelpers.Combine(
this.APP14Flags0.GetHashCode(),
HashHelpers.Combine(
this.APP14Flags1.GetHashCode(),
this.ColorTransform.GetHashCode())));
return HashCode.Combine(
this.DCTEncodeVersion,
this.APP14Flags0,
this.APP14Flags1,
this.ColorTransform);
}
}
}

13
src/ImageSharp/Formats/Jpeg/Components/Decoder/JFifMarker.cs

@ -112,13 +112,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
/// <inheritdoc/>
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);
}
}
}

4
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());
}
}
}

2
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));
}

22
src/ImageSharp/ImageSharp.csproj

@ -1,10 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>A cross-platform library for the processing of image files; written in C#</Description>
<AssemblyTitle>SixLabors.ImageSharp</AssemblyTitle>
<Authors>Six Labors and contributors</Authors>
<Company>Six Labors</Company>
<Copyright>Copyright (c) Six Labors and contributors.</Copyright>
<Product>SixLabors.ImageSharp</Product>
<Description>A cross-platform library for the processing of image files; written in C#</Description>
<NeutralLanguage>en</NeutralLanguage>
<VersionPrefix Condition="$(packageversion) != ''">$(packageversion)</VersionPrefix>
<VersionPrefix Condition="$(packageversion) == ''">0.0.1</VersionPrefix>
<Authors>Six Labors and contributors</Authors>
<TargetFrameworks>netstandard1.3;netstandard2.0;netcoreapp2.1;net472</TargetFrameworks>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
@ -16,20 +21,11 @@
<PackageLicenseUrl>http://www.apache.org/licenses/LICENSE-2.0</PackageLicenseUrl>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/SixLabors/ImageSharp</RepositoryUrl>
<GenerateAssemblyDescriptionAttribute>false</GenerateAssemblyDescriptionAttribute>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute>
<GenerateNeutralResourcesLanguageAttribute>false</GenerateNeutralResourcesLanguageAttribute>
<GenerateAssemblyVersionAttribute>false</GenerateAssemblyVersionAttribute>
<GenerateAssemblyFileVersionAttribute>false</GenerateAssemblyFileVersionAttribute>
<GenerateAssemblyInformationalVersionAttribute>false</GenerateAssemblyInformationalVersionAttribute>
<DebugType Condition="$(codecov) != ''">full</DebugType>
<DebugType Condition="$(codecov) == ''">portable</DebugType>
<DebugSymbols>True</DebugSymbols>
<Features>IOperation</Features>
<LangVersion>Latest</LangVersion>
<LangVersion>7.3</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'netcoreapp2.1' OR '$(TargetFramework)' == 'net472' ">
@ -42,7 +38,7 @@
<ItemGroup>
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.5.1" />
<PackageReference Include="SixLabors.Core" Version="1.0.0-dev000089" />
<PackageReference Include="SixLabors.Core" Version="1.0.0-dev000094" />
<AdditionalFiles Include="..\..\stylecop.json" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.0-beta007">
<PrivateAssets>All</PrivateAssets>

14
src/ImageSharp/MetaData/ImageProperty.cs

@ -99,19 +99,7 @@ namespace SixLabors.ImageSharp.MetaData
/// <returns>
/// A 32-bit signed integer that is the hash code for this instance.
/// </returns>
public override int GetHashCode()
{
unchecked
{
int hashCode = this.Name.GetHashCode();
if (this.Value != null)
{
hashCode = (hashCode * 397) ^ this.Value.GetHashCode();
}
return hashCode;
}
}
public override int GetHashCode() => HashCode.Combine(this.Name, this.Value);
/// <summary>
/// Returns the fully qualified type name of this instance.

6
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<TDataType>(ReadOnlySpan<byte> data);
@ -374,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<ExifTag>();
}

20
src/ImageSharp/MetaData/Profiles/Exif/ExifValue.cs

@ -198,7 +198,10 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif
}
/// <inheritdoc/>
public override int GetHashCode() => this.GetHashCode(this);
public override int GetHashCode()
{
return HashCode.Combine(this.Tag, this.DataType, this.Value);
}
/// <inheritdoc/>
public override string ToString()
@ -714,20 +717,5 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif
throw new NotSupportedException();
}
}
/// <summary>
/// Returns the hash code for this instance.
/// </summary>
/// <param name="exif">
/// The instance of <see cref="ExifValue"/> to return the hash code for.
/// </param>
/// <returns>
/// A 32-bit signed integer that is the hash code for this instance.
/// </returns>
private int GetHashCode(ExifValue exif)
{
int hashCode = exif.Tag.GetHashCode() ^ exif.DataType.GetHashCode();
return hashCode ^ exif.Value?.GetHashCode() ?? hashCode;
}
}
}

21
src/ImageSharp/MetaData/Profiles/ICC/Curves/IccParametricCurve.cs

@ -154,18 +154,15 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override int GetHashCode()
{
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();
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());
}
}
}

11
src/ImageSharp/MetaData/Profiles/ICC/Curves/IccResponseCurve.cs

@ -73,13 +73,10 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc />
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 HashCode.Combine(
this.CurveType,
this.XyzValues,
this.ResponseArrays);
}
private bool EqualsResponseArray(IccResponseCurve other)

8
src/ImageSharp/MetaData/Profiles/ICC/IccTagDataEntry.cs

@ -64,12 +64,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
}
/// <inheritdoc/>
public override int GetHashCode()
{
unchecked
{
return (int)this.Signature * 397;
}
}
public override int GetHashCode() => this.Signature.GetHashCode();
}
}

11
src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccChromaticityTagDataEntry.cs

@ -110,13 +110,10 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
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 HashCode.Combine(
this.Signature,
this.ColorantType,
this.ChannelValues);
}
private static double[][] GetColorantArray(IccColorantEncoding colorantType)

5
src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccColorantOrderTagDataEntry.cs

@ -70,10 +70,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override int GetHashCode()
{
unchecked
{
return (base.GetHashCode() * 397) ^ (this.ColorantNumber?.GetHashCode() ?? 0);
}
return HashCode.Combine(this.Signature, this.ColorantNumber);
}
}
}

5
src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccColorantTableTagDataEntry.cs

@ -72,10 +72,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override int GetHashCode()
{
unchecked
{
return (base.GetHashCode() * 397) ^ (this.ColorantData?.GetHashCode() ?? 0);
}
return HashCode.Combine(this.Signature, this.ColorantData);
}
}
}

17
src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccCrdInfoTagDataEntry.cs

@ -121,16 +121,13 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override int GetHashCode()
{
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);
return hashCode;
}
return HashCode.Combine(
this.Signature,
this.PostScriptProductName,
this.RenderingIntent0Crd,
this.RenderingIntent1Crd,
this.RenderingIntent2Crd,
this.RenderingIntent3Crd);
}
}
}

8
src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccCurveTagDataEntry.cs

@ -116,12 +116,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
}
/// <inheritdoc/>
public override int GetHashCode()
{
unchecked
{
return (base.GetHashCode() * 397) ^ (this.CurveData?.GetHashCode() ?? 0);
}
}
public override int GetHashCode() => HashCode.Combine(this.Signature, this.CurveData);
}
}

11
src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccDataTagDataEntry.cs

@ -91,13 +91,10 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
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 HashCode.Combine(
this.Signature,
this.Data,
this.IsAscii);
}
}
}

5
src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccDateTimeTagDataEntry.cs

@ -66,10 +66,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override int GetHashCode()
{
unchecked
{
return (base.GetHashCode() * 397) ^ this.Value.GetHashCode();
}
return HashCode.Combine(this.Signature, this.Value);
}
}
}

8
src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccFix16ArrayTagDataEntry.cs

@ -64,12 +64,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
}
/// <inheritdoc/>
public override int GetHashCode()
{
unchecked
{
return (base.GetHashCode() * 397) ^ (this.Data?.GetHashCode() ?? 0);
}
}
public override int GetHashCode() => HashCode.Combine(this.Signature, this.Data);
}
}

24
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");
@ -143,15 +140,12 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override int GetHashCode()
{
unchecked
{
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);
return hashCode;
}
return HashCode.Combine(
this.Signature,
this.Matrix,
this.InputValues,
this.ClutValues,
this.OutputValues);
}
private Matrix4x4 CreateMatrix(float[,] matrix)

24
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");
@ -146,15 +143,12 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override int GetHashCode()
{
unchecked
{
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);
return hashCode;
}
return HashCode.Combine(
this.Signature,
this.Matrix,
this.InputValues,
this.ClutValues,
this.OutputValues);
}
private Matrix4x4 CreateMatrix(float[,] matrix)

28
src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLutAToBTagDataEntry.cs

@ -183,19 +183,21 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
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;
}
#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)

28
src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLutBToATagDataEntry.cs

@ -183,19 +183,21 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
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;
}
#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)

17
src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccMeasurementTagDataEntry.cs

@ -106,16 +106,13 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
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;
}
return HashCode.Combine(
this.Signature,
this.Observer,
this.XyzBacking,
this.Geometry,
this.Flare,
this.Illuminant);
}
}
}

8
src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccMultiLocalizedUnicodeTagDataEntry.cs

@ -66,12 +66,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
}
/// <inheritdoc />
public override int GetHashCode()
{
unchecked
{
return (base.GetHashCode() * 397) ^ (this.Texts?.GetHashCode() ?? 0);
}
}
public override int GetHashCode() => HashCode.Combine(this.Signature, this.Texts);
}
}

13
src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccMultiProcessElementsTagDataEntry.cs

@ -90,14 +90,11 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
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 HashCode.Combine(
this.Signature,
this.InputChannelCount,
this.OutputChannelCount,
this.Data);
}
}
}

18
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
/// <inheritdoc/>
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;
}
return HashCode.Combine(
this.Signature,
this.CoordinateCount,
this.Prefix,
this.Suffix,
this.VendorFlags,
this.Colors);
}
}
}

10
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));
}
/// <summary>
@ -65,12 +65,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
}
/// <inheritdoc />
public override int GetHashCode()
{
unchecked
{
return (base.GetHashCode() * 397) ^ (this.Curve?.GetHashCode() ?? 0);
}
}
public override int GetHashCode() => HashCode.Combine(this.Signature, this.Curve);
}
}

8
src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccProfileSequenceDescTagDataEntry.cs

@ -67,12 +67,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
}
/// <inheritdoc />
public override int GetHashCode()
{
unchecked
{
return (base.GetHashCode() * 397) ^ (this.Descriptions?.GetHashCode() ?? 0);
}
}
public override int GetHashCode() => HashCode.Combine(this.Signature, this.Descriptions);
}
}

8
src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccProfileSequenceIdentifierTagDataEntry.cs

@ -65,12 +65,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
}
/// <inheritdoc />
public override int GetHashCode()
{
unchecked
{
return (base.GetHashCode() * 397) ^ (this.Data?.GetHashCode() ?? 0);
}
}
public override int GetHashCode() => HashCode.Combine(this.Signature, this.Data);
}
}

11
src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccResponseCurveSet16TagDataEntry.cs

@ -83,13 +83,10 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc />
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 HashCode.Combine(
this.Signature,
this.ChannelCount,
this.Curves);
}
}
}

8
src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccScreeningTagDataEntry.cs

@ -77,13 +77,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
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 HashCode.Combine(this.Signature, this.Flags, this.Channels);
}
}
}

8
src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccSignatureTagDataEntry.cs

@ -65,12 +65,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
}
/// <inheritdoc />
public override int GetHashCode()
{
unchecked
{
return (base.GetHashCode() * 397) ^ (this.SignatureData?.GetHashCode() ?? 0);
}
}
public override int GetHashCode() => HashCode.Combine(this.Signature, this.SignatureData);
}
}

17
src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccTextDescriptionTagDataEntry.cs

@ -166,16 +166,13 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc />
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;
}
return HashCode.Combine(
this.Signature,
this.Ascii,
this.Unicode,
this.ScriptCode,
this.UnicodeLanguageCode,
this.ScriptCodeCode);
}
}
}

8
src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccTextTagDataEntry.cs

@ -64,12 +64,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
}
/// <inheritdoc />
public override int GetHashCode()
{
unchecked
{
return (base.GetHashCode() * 397) ^ (this.Text?.GetHashCode() ?? 0);
}
}
public override int GetHashCode() => HashCode.Combine(this.Signature, this.Text);
}
}

8
src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUFix16ArrayTagDataEntry.cs

@ -64,12 +64,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
}
/// <inheritdoc/>
public override int GetHashCode()
{
unchecked
{
return (base.GetHashCode() * 397) ^ (this.Data?.GetHashCode() ?? 0);
}
}
public override int GetHashCode() => HashCode.Combine(this.Signature, this.Data);
}
}

10
src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt16ArrayTagDataEntry.cs

@ -64,12 +64,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
}
/// <inheritdoc/>
public override int GetHashCode()
{
unchecked
{
return (base.GetHashCode() * 397) ^ (this.Data?.GetHashCode() ?? 0);
}
}
public override int GetHashCode() => HashCode.Combine(this.Signature, this.Data);
}
}
}

8
src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt32ArrayTagDataEntry.cs

@ -64,12 +64,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
}
/// <inheritdoc/>
public override int GetHashCode()
{
unchecked
{
return (base.GetHashCode() * 397) ^ (this.Data?.GetHashCode() ?? 0);
}
}
public override int GetHashCode() => HashCode.Combine(this.Signature, this.Data);
}
}

8
src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt64ArrayTagDataEntry.cs

@ -65,12 +65,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
}
/// <inheritdoc/>
public override int GetHashCode()
{
unchecked
{
return (base.GetHashCode() * 397) ^ (this.Data?.GetHashCode() ?? 0);
}
}
public override int GetHashCode() => HashCode.Combine(this.Signature, this.Data);
}
}

8
src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt8ArrayTagDataEntry.cs

@ -64,12 +64,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
}
/// <inheritdoc/>
public override int GetHashCode()
{
unchecked
{
return (base.GetHashCode() * 397) ^ (this.Data?.GetHashCode() ?? 0);
}
}
public override int GetHashCode() => HashCode.Combine(this.Signature, this.Data);
}
}

13
src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUcrBgTagDataEntry.cs

@ -86,14 +86,11 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
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 HashCode.Combine(
this.Signature,
this.UcrCurve,
this.BgCurve,
this.Description);
}
}
}

8
src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUnknownTagDataEntry.cs

@ -64,12 +64,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
}
/// <inheritdoc/>
public override int GetHashCode()
{
unchecked
{
return (base.GetHashCode() * 397) ^ (this.Data?.GetHashCode() ?? 0);
}
}
public override int GetHashCode() => HashCode.Combine(this.Signature, this.Data);
}
}

13
src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccViewingConditionsTagDataEntry.cs

@ -86,14 +86,11 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
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 HashCode.Combine(
this.Signature,
this.IlluminantXyz,
this.SurroundXyz,
this.Illuminant);
}
}
}

15
src/ImageSharp/MetaData/Profiles/ICC/Various/IccClut.cs

@ -142,15 +142,12 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override int GetHashCode()
{
unchecked
{
int hashCode = this.Values?.GetHashCode() ?? 0;
hashCode = (hashCode * 397) ^ (int)this.DataType;
hashCode = (hashCode * 397) ^ this.InputChannelCount;
hashCode = (hashCode * 397) ^ this.OutputChannelCount;
hashCode = (hashCode * 397) ^ (this.GridPointCount?.GetHashCode() ?? 0);
return hashCode;
}
return HashCode.Combine(
this.Values,
this.DataType,
this.InputChannelCount,
this.OutputChannelCount,
this.GridPointCount);
}
private bool EqualsValuesArray(IccClut other)

13
src/ImageSharp/MetaData/Profiles/ICC/Various/IccColorantTableEntry.cs

@ -102,14 +102,11 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
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 HashCode.Combine(
this.Name,
this.Pcs1,
this.Pcs2,
this.Pcs3);
}
/// <inheritdoc/>

26
src/ImageSharp/MetaData/Profiles/ICC/Various/IccNamedColor.cs

@ -80,27 +80,23 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
}
/// <inheritdoc/>
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);
}
/// <inheritdoc/>
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 HashCode.Combine(
this.Name,
this.PcsCoordinates,
this.DeviceCoordinates);
}
/// <inheritdoc/>
public override string ToString()
{
return this.Name;
}
public override string ToString() => this.Name;
}
}

10
src/ImageSharp/MetaData/Profiles/ICC/Various/IccPositionNumber.cs

@ -73,15 +73,9 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
this.Size == other.Size;
/// <inheritdoc/>
public override int GetHashCode()
{
return unchecked((int)(this.Offset ^ this.Size));
}
public override int GetHashCode() => unchecked((int)(this.Offset ^ this.Size));
/// <inheritdoc/>
public override string ToString()
{
return $"{this.Offset}; {this.Size}";
}
public override string ToString() => $"{this.Offset}; {this.Size}";
}
}

24
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));
}
/// <summary>
@ -87,16 +84,13 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc />
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() ?? 0);
hashCode = (hashCode * 397) ^ (this.DeviceModelInfo?.GetHashCode() ?? 0);
return hashCode;
}
return HashCode.Combine(
this.DeviceManufacturer,
this.DeviceModel,
this.DeviceAttributes,
this.TechnologyInformation,
this.DeviceManufacturerInfo,
this.DeviceModelInfo);
}
}
}

13
src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileId.cs

@ -101,14 +101,11 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
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 HashCode.Combine(
this.Part1,
this.Part2,
this.Part3,
this.Part4);
}
/// <inheritdoc/>

12
src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileSequenceIdentifier.cs

@ -18,10 +18,8 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <param name="description">Description of the profile</param>
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));
}
/// <summary>
@ -46,12 +44,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
}
/// <inheritdoc />
public override int GetHashCode()
{
unchecked
{
return (this.Id.GetHashCode() * 397) ^ (this.Description?.GetHashCode() ?? 0);
}
}
public override int GetHashCode() => HashCode.Combine(this.Id, this.Description);
}
}

15
src/ImageSharp/MetaData/Profiles/ICC/Various/IccResponseNumber.cs

@ -73,20 +73,9 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
this.MeasurementValue == other.MeasurementValue;
/// <inheritdoc/>
public override int GetHashCode()
{
unchecked
{
int hashCode = this.DeviceCode.GetHashCode();
hashCode = (hashCode * 397) ^ this.MeasurementValue.GetHashCode();
return hashCode;
}
}
public override int GetHashCode() => HashCode.Combine(this.DeviceCode, this.MeasurementValue);
/// <inheritdoc/>
public override string ToString()
{
return $"Code: {this.DeviceCode}; Value: {this.MeasurementValue}";
}
public override string ToString() => $"Code: {this.DeviceCode}; Value: {this.MeasurementValue}";
}
}

8
src/ImageSharp/MetaData/Profiles/ICC/Various/IccScreeningChannel.cs

@ -85,13 +85,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
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 HashCode.Combine(this.Frequency, this.Angle, this.SpotShape);
}
/// <inheritdoc/>

14
src/ImageSharp/MetaData/Profiles/ICC/Various/IccTagTableEntry.cs

@ -76,20 +76,14 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
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);
/// <inheritdoc/>
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 HashCode.Combine(this.Signature, this.Offset, this.DataSize);
}
/// <inheritdoc/>

7
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,10 +190,6 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public override int GetHashCode()
{
int hash = HashHelpers.Combine(this.R.GetHashCode(), this.G.GetHashCode());
return HashHelpers.Combine(hash, this.B.GetHashCode());
}
public override int GetHashCode() => HashCode.Combine(this.R, this.B, this.G);
}
}

7
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,11 +201,7 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public override int GetHashCode()
{
int hash = HashHelpers.Combine(this.R.GetHashCode(), this.G.GetHashCode());
return HashHelpers.Combine(hash, this.B.GetHashCode());
}
public override int GetHashCode() => HashCode.Combine(this.R, this.B, this.G);
/// <inheritdoc/>
public override string ToString() => $"Rgb24({this.R}, {this.G}, {this.B})";

7
src/ImageSharp/PixelFormats/PixelImplementations/Rgb48.cs

@ -189,11 +189,6 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public override int GetHashCode()
{
return HashHelpers.Combine(
this.R.GetHashCode(),
HashHelpers.Combine(this.G.GetHashCode(), this.B.GetHashCode()));
}
public override int GetHashCode() => HashCode.Combine(this.R, this.G, this.B);
}
}

7
src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.cs

@ -197,11 +197,6 @@ namespace SixLabors.ImageSharp.PixelFormats
}
/// <inheritdoc/>
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);
}
}

7
src/ImageSharp/Primitives/ValueSize.cs

@ -133,9 +133,6 @@ namespace SixLabors.ImageSharp.Primitives
}
/// <inheritdoc/>
public override int GetHashCode()
{
return HashHelpers.Combine(this.Value.GetHashCode(), this.Type.GetHashCode());
}
public override int GetHashCode() => HashCode.Combine(this.Value, this.Type);
}
}
}

2
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<TPixel>.Instance.ToScaledVector4(configuration, this.Palette, this.paletteVector);

3
src/ImageSharp/Processing/Processors/Dithering/PixelPair.cs

@ -43,7 +43,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering
=> obj is PixelPair<TPixel> other && this.First.Equals(other.First) && this.Second.Equals(other.Second);
/// <inheritdoc/>
public override int GetHashCode()
=> HashHelpers.Combine(this.First.GetHashCode(), this.Second.GetHashCode());
public override int GetHashCode() => HashCode.Combine(this.First, this.Second);
}
}

13
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);
}

79
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
/// </summary>
internal static class TransformUtils
{
/// <summary>
/// Applies the projective transform against the given coordinates flattened into the 2D space.
/// </summary>
/// <param name="x">The "x" vector coordinate.</param>
/// <param name="y">The "y" vector coordinate.</param>
/// <param name="matrix">The transform matrix.</param>
/// <returns>The <see cref="Vector2"/>.</returns>
[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);
}
/// <summary>
/// Creates a centered rotation matrix using the given rotation in degrees and the source size.
/// </summary>
@ -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);
}

26
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")]

1
tests/ImageSharp.Benchmarks/General/BasicMath/ModuloPowerOfTwoConstant.cs

@ -1,5 +1,4 @@
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Attributes.Jobs;
namespace SixLabors.ImageSharp.Benchmarks.General.BasicMath
{

1
tests/ImageSharp.Benchmarks/General/BasicMath/ModuloPowerOfTwoVariable.cs

@ -1,5 +1,4 @@
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Attributes.Jobs;
namespace SixLabors.ImageSharp.Benchmarks.General.BasicMath
{

1
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;

2
tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj

@ -16,7 +16,7 @@
<Compile Include="..\ImageSharp.Tests\TestUtilities\TestEnvironment.cs" Link="Tests\TestEnvironment.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.10.14" />
<PackageReference Include="BenchmarkDotNet" Version="0.11.3" />
<PackageReference Include="Colourful" Version="2.0.0" />
<PackageReference Include="SixLabors.Shapes.Text" Version="1.0.0-beta0007" />
<PackageReference Include="System.Drawing.Common" Version="4.5.0" />

8
tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj

@ -18,19 +18,13 @@
<ProjectReference Include="..\..\src\ImageSharp\ImageSharp.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="BitMiracle.LibJpeg.NET" Version="1.4.280" />
<PackageReference Include="Magick.NET-Q16-AnyCPU" Version="7.9.0.1" />
<PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="Moq" Version="4.8.3" />
<!--<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />-->
<!--<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />-->
<PackageReference Include="Moq" Version="4.10.0" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\ImageSharp.Tests\**\*.cs" Exclude="bin\**;obj\**" Link="Tests\%(RecursiveDir)%(Filename)%(Extension)" />
<Compile Remove="..\ImageSharp.Tests\obj\**\*.cs" />
<Compile Remove="..\ImageSharp.Tests\bin\**\*.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
</Project>

7
tests/ImageSharp.Tests/ImageSharp.Tests.csproj

@ -28,15 +28,12 @@
<ItemGroup>
<PackageReference Include="Magick.NET-Q16-AnyCPU" Version="7.9.0.1" />
<PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
<PackageReference Include="System.Drawing.Common" Version="4.5.0" />
<PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="xunit.runner.console" Version="2.3.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.2" />
<PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
<PackageReference Include="Moq" Version="4.8.3" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
<PackageReference Include="Moq" Version="4.10.0" />
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="..\..\stylecop.json" />

5
tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeKernelMapTests.cs

@ -208,10 +208,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms
{
var result = new TheoryData<string, int, int>();
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 =
{

98
tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs

@ -20,42 +20,82 @@ 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<string, IResampler> AllResamplers =
new TheoryData<string, IResampler>
public static readonly string[] AllResamplerNames = TestUtils.GetAllResamplerNames();
public static readonly string[] SmokeTestResamplerNames =
{
{ "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 }
nameof(KnownResamplers.NearestNeighbor),
nameof(KnownResamplers.Bicubic),
nameof(KnownResamplers.Box),
nameof(KnownResamplers.Lanczos5),
};
[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<TPixel>(TestImageProvider<TPixel> provider, string name, IResampler sampler, float ratio)
[WithFileCollection(nameof(CommonTestImages), nameof(AllResamplerNames), DefaultPixelType, 0.5f, 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<TPixel>(
TestImageProvider<TPixel> provider,
string samplerName,
float? ratio,
int? specificDestWidth,
int? specificDestHeight)
where TPixel : struct, IPixel<TPixel>
{
using (Image<TPixel> 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)}";
IResampler sampler = TestUtils.GetResampler(samplerName);
image.DebugSave(provider, details);
image.CompareToReferenceOutput(ImageComparer.TolerantPercentage(0.02f), provider, details);
}
// 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.017f);
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]

27
tests/ImageSharp.Tests/Processing/Transforms/ProjectiveTransformTests.cs

@ -111,7 +111,32 @@ namespace SixLabors.ImageSharp.Tests.Processing.Transforms
using (Image<TPixel> 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<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
// https://jsfiddle.net/dFrHS/545/
// https://github.com/SixLabors/ImageSharp/issues/787
using (Image<TPixel> 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);

2
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 });
}
}
}

13
tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestPatternProvider.cs

@ -16,10 +16,9 @@ namespace SixLabors.ImageSharp.Tests
/// <summary>
/// A test image provider that produces test patterns.
/// </summary>
/// <typeparam name="TPixel"></typeparam>
private class TestPatternProvider : BlankProvider
{
static Dictionary<string, Image<TPixel>> testImages = new Dictionary<string, Image<TPixel>>();
static readonly Dictionary<string, Image<TPixel>> TestImages = new Dictionary<string, Image<TPixel>>();
public TestPatternProvider(int width, int height)
: base(width, height)
@ -35,17 +34,17 @@ namespace SixLabors.ImageSharp.Tests
public override Image<TPixel> GetImage()
{
lock (testImages)
lock (TestImages)
{
if (!testImages.ContainsKey(this.SourceFileOrDescription))
if (!TestImages.ContainsKey(this.SourceFileOrDescription))
{
Image<TPixel> image = new Image<TPixel>(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();
}
/// <summary>
@ -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;
}
}
}
}
}

47
tests/ImageSharp.Tests/TestUtilities/TestUtils.cs

@ -193,6 +193,45 @@ namespace SixLabors.ImageSharp.Tests
}
}
internal static void RunValidatingProcessorTest<TPixel>(
this TestImageProvider<TPixel> provider,
Func<IImageProcessingContext<TPixel>, FormattableString> processAndGetTestOutputDetails,
ImageComparer comparer = null,
bool appendPixelTypeToFileName = true,
bool appendSourceFileOrDescription = true)
where TPixel : struct, IPixel<TPixel>
{
if (comparer == null)
{
comparer = ImageComparer.TolerantPercentage(0.001f);
}
using (Image<TPixel> 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<TPixel>(
this TestImageProvider<TPixel> provider,
Action<IImageProcessingContext<TPixel>> process,
@ -297,5 +336,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();
}
}
}

12
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<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
using (Image<TPixel> img = provider.GetImage())
{
img.DebugSave(provider);
}
}
public static readonly TheoryData<object> BasicData = new TheoryData<object>()
{
TestImageProvider<Rgba32>.Blank(10, 20),

2
tests/Images/External

@ -1 +1 @@
Subproject commit 5b18d8c95acffb773012881870ba6f521ba13128
Subproject commit 69603ee5b6f7dd64114fc44d321e50d9b2d439be
Loading…
Cancel
Save