Browse Source

Merge branch 'master' into feature/pngExif

af/merge-core
James Jackson-South 8 years ago
committed by GitHub
parent
commit
511dca9100
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 7
      src/ImageSharp/ColorSpaces/CieLab.cs
  2. 46
      src/ImageSharp/Common/Extensions/ListExtensions.cs
  3. 9
      src/ImageSharp/Common/Helpers/DebugGuard.cs
  4. 3
      src/ImageSharp/Common/Helpers/Guard.cs
  5. 9
      src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs
  6. 2
      src/ImageSharp/MetaData/Profiles/Exif/ExifValue.cs
  7. 12
      src/ImageSharp/MetaData/Profiles/ICC/Curves/IccParametricCurve.cs
  8. 10
      src/ImageSharp/MetaData/Profiles/ICC/Curves/IccResponseCurve.cs
  9. 4
      src/ImageSharp/MetaData/Profiles/ICC/DataReader/IccDataReader.NonPrimitives.cs
  10. 9
      src/ImageSharp/MetaData/Profiles/ICC/DataReader/IccDataReader.Primitives.cs
  11. 16
      src/ImageSharp/MetaData/Profiles/ICC/DataWriter/IccDataWriter.NonPrimitives.cs
  12. 34
      src/ImageSharp/MetaData/Profiles/ICC/IccProfileHeader.cs
  13. 28
      src/ImageSharp/MetaData/Profiles/ICC/IccTagDataEntry.cs
  14. 14
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccChromaticityTagDataEntry.cs
  15. 10
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccColorantOrderTagDataEntry.cs
  16. 10
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccColorantTableTagDataEntry.cs
  17. 10
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccCrdInfoTagDataEntry.cs
  18. 10
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccCurveTagDataEntry.cs
  19. 10
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccDataTagDataEntry.cs
  20. 12
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccDateTimeTagDataEntry.cs
  21. 10
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccFix16ArrayTagDataEntry.cs
  22. 12
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLut16TagDataEntry.cs
  23. 12
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLut8TagDataEntry.cs
  24. 10
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLutAToBTagDataEntry.cs
  25. 10
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLutBToATagDataEntry.cs
  26. 12
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccMeasurementTagDataEntry.cs
  27. 12
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccMultiLocalizedUnicodeTagDataEntry.cs
  28. 10
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccMultiProcessElementsTagDataEntry.cs
  29. 12
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccNamedColor2TagDataEntry.cs
  30. 12
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccParametricCurveTagDataEntry.cs
  31. 12
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccProfileSequenceDescTagDataEntry.cs
  32. 12
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccProfileSequenceIdentifierTagDataEntry.cs
  33. 14
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccResponseCurveSet16TagDataEntry.cs
  34. 12
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccScreeningTagDataEntry.cs
  35. 12
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccSignatureTagDataEntry.cs
  36. 14
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccTextDescriptionTagDataEntry.cs
  37. 12
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccTextTagDataEntry.cs
  38. 12
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUFix16ArrayTagDataEntry.cs
  39. 12
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt16ArrayTagDataEntry.cs
  40. 12
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt32ArrayTagDataEntry.cs
  41. 12
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt64ArrayTagDataEntry.cs
  42. 10
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt8ArrayTagDataEntry.cs
  43. 10
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUcrBgTagDataEntry.cs
  44. 10
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUnknownTagDataEntry.cs
  45. 14
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccViewingConditionsTagDataEntry.cs
  46. 2
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccXyzTagDataEntry.cs
  47. 10
      src/ImageSharp/MetaData/Profiles/ICC/Various/IccClut.cs
  48. 2
      src/ImageSharp/MetaData/Profiles/ICC/Various/IccScreeningChannel.cs
  49. 53
      src/ImageSharp/MetaData/Profiles/ICC/Various/IccVersion.cs
  50. 2
      src/ImageSharp/PixelFormats/Bgr565.cs
  51. 2
      src/ImageSharp/PixelFormats/HalfSingle.cs
  52. 2
      src/ImageSharp/PixelFormats/HalfVector2.cs
  53. 2
      src/ImageSharp/PixelFormats/NormalizedShort2.cs
  54. 2
      src/ImageSharp/PixelFormats/Rg32.cs
  55. 1
      src/ImageSharp/Processing/Dithering/ErrorDiffusion/ErrorDiffuserBase.cs
  56. 1
      tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj
  57. 8
      tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs
  58. 127
      tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.Chunks.cs
  59. 207
      tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs
  60. 86
      tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs
  61. 8
      tests/ImageSharp.Tests/Helpers/GuardTests.cs
  62. 1
      tests/ImageSharp.Tests/ImageSharp.Tests.csproj
  63. 3
      tests/ImageSharp.Tests/Memory/BufferTestSuite.cs
  64. 4
      tests/ImageSharp.Tests/MetaData/Profiles/ICC/DataReader/IccDataReader.NonPrimitivesTests.cs
  65. 2
      tests/ImageSharp.Tests/MetaData/Profiles/ICC/DataWriter/IccDataWriter.NonPrimitivesTests.cs
  66. 8
      tests/ImageSharp.Tests/TestDataIcc/IccTestDataNonPrimitives.cs
  67. 2
      tests/ImageSharp.Tests/TestDataIcc/IccTestDataProfiles.cs
  68. 6
      tests/ImageSharp.Tests/TestUtilities/ImagingTestCaseUtility.cs
  69. 53
      tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs
  70. 2
      tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingReferenceEncoder.cs
  71. 44
      tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Formats.cs
  72. 11
      tests/ImageSharp.Tests/TestUtilities/TestEnvironment.cs
  73. 25
      tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs
  74. 89
      tests/ImageSharp.Tests/TestUtilities/Tests/MagickReferenceCodecTests.cs
  75. 96
      tests/ImageSharp.Tests/TestUtilities/Tests/ReferenceDecoderBenchmarks.cs
  76. 10
      tests/ImageSharp.Tests/TestUtilities/Tests/SystemDrawingReferenceCodecTests.cs
  77. 7
      tests/ImageSharp.Tests/TestUtilities/Tests/TestEnvironmentTests.cs
  78. 6
      tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs

7
src/ImageSharp/ColorSpaces/CieLab.cs

@ -194,12 +194,7 @@ namespace SixLabors.ImageSharp.ColorSpaces
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override bool Equals(object obj)
{
if (obj is CieLab)
{
return this.Equals((CieLab)obj);
}
return false;
return obj is CieLab other && this.Equals(other);
}
/// <inheritdoc/>

46
src/ImageSharp/Common/Extensions/ListExtensions.cs

@ -1,46 +0,0 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System.Collections.Generic;
namespace SixLabors.ImageSharp.Common.Extensions
{
/// <summary>
/// Encapsulates a series of time saving extension methods to the <see cref="T:System.Collections.Generic.List"/> class.
/// </summary>
internal static class ListExtensions
{
/// <summary>
/// Inserts an item at the given index automatically expanding the capacity if required.
/// </summary>
/// <typeparam name="T">The type of object within the list</typeparam>
/// <param name="list">The list</param>
/// <param name="index">The index</param>
/// <param name="item">The item to insert</param>
public static void SafeInsert<T>(this List<T> list, int index, T item)
{
if (index >= list.Count)
{
list.Add(item);
}
else
{
list[index] = item;
}
}
/// <summary>
/// Removes the last element from a list and returns that element. This method changes the length of the list.
/// </summary>
/// <typeparam name="T">The type of object within the list</typeparam>
/// <param name="list">The list</param>
/// <returns>The last element in the specified sequence.</returns>
public static T Pop<T>(this List<T> list)
{
int last = list.Count - 1;
T item = list[last];
list.RemoveAt(last);
return item;
}
}
}

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

@ -17,13 +17,14 @@ namespace SixLabors.ImageSharp
/// Verifies, that the method parameter with specified object value is not null
/// and throws an exception if it is found to be so.
/// </summary>
/// <param name="target">The target object, which cannot be null.</param>
/// <param name="value">The target object, which cannot be null.</param>
/// <param name="parameterName">The name of the parameter that is to be checked.</param>
/// <exception cref="ArgumentNullException"><paramref name="target"/> is null</exception>
/// <exception cref="ArgumentNullException"><paramref name="value"/> is null</exception>
[Conditional("DEBUG")]
public static void NotNull(object target, string parameterName)
public static void NotNull<T>(T value, string parameterName)
where T : class
{
if (target == null)
if (value == null)
{
throw new ArgumentNullException(parameterName);
}

3
src/ImageSharp/Common/Helpers/Guard.cs

@ -19,7 +19,8 @@ namespace SixLabors.ImageSharp
/// <param name="value">The target object, which cannot be null.</param>
/// <param name="parameterName">The name of the parameter that is to be checked.</param>
/// <exception cref="ArgumentNullException"><paramref name="value"/> is null</exception>
public static void NotNull(object value, string parameterName)
public static void NotNull<T>(T value, string parameterName)
where T : class
{
if (value == null)
{

9
src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs

@ -6,6 +6,7 @@ using System.Buffers.Binary;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using SixLabors.ImageSharp.IO;
@ -463,7 +464,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif
}
}
private unsafe double ConvertToDouble(ReadOnlySpan<byte> buffer)
private double ConvertToDouble(ReadOnlySpan<byte> buffer)
{
if (buffer.Length < 8)
{
@ -474,7 +475,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif
? BinaryPrimitives.ReadInt64BigEndian(buffer)
: BinaryPrimitives.ReadInt64LittleEndian(buffer);
return *((double*)&intValue);
return Unsafe.As<long, double>(ref intValue);
}
private uint ConvertToUInt32(ReadOnlySpan<byte> buffer)
@ -502,7 +503,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif
: BinaryPrimitives.ReadUInt16LittleEndian(buffer);
}
private unsafe float ConvertToSingle(ReadOnlySpan<byte> buffer)
private float ConvertToSingle(ReadOnlySpan<byte> buffer)
{
if (buffer.Length < 4)
{
@ -513,7 +514,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif
? BinaryPrimitives.ReadInt32BigEndian(buffer)
: BinaryPrimitives.ReadInt32LittleEndian(buffer);
return *((float*)&intValue);
return Unsafe.As<int, float>(ref intValue);
}
private Rational ToRational(ReadOnlySpan<byte> buffer)

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

@ -181,7 +181,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif
/// <inheritdoc />
public bool Equals(ExifValue other)
{
if (ReferenceEquals(other, null))
if (other is null)
{
return false;
}

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

@ -125,7 +125,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public bool Equals(IccParametricCurve other)
{
if (other == null)
if (other is null)
{
return false;
}
@ -148,16 +148,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj is IccParametricCurve other && this.Equals(other);
}

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

@ -67,16 +67,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc />
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj is IccResponseCurve other && this.Equals(other);
}

4
src/ImageSharp/MetaData/Profiles/ICC/DataReader/IccDataReader.NonPrimitives.cs

@ -38,7 +38,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// Reads an ICC profile version number
/// </summary>
/// <returns>the version number</returns>
public Version ReadVersionNumber()
public IccVersion ReadVersionNumber()
{
int version = this.ReadInt32();
@ -46,7 +46,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
int minor = (version >> 20) & 0x0F;
int bugfix = (version >> 16) & 0x0F;
return new Version(major, minor, bugfix);
return new IccVersion(major, minor, bugfix);
}
/// <summary>

9
src/ImageSharp/MetaData/Profiles/ICC/DataReader/IccDataReader.Primitives.cs

@ -3,6 +3,7 @@
using System;
using System.Buffers.Binary;
using System.Runtime.CompilerServices;
using System.Text;
namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
@ -70,22 +71,22 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// Reads a float.
/// </summary>
/// <returns>the value</returns>
public unsafe float ReadSingle()
public float ReadSingle()
{
int intValue = this.ReadInt32();
return *((float*)&intValue);
return Unsafe.As<int, float>(ref intValue);
}
/// <summary>
/// Reads a double
/// </summary>
/// <returns>the value</returns>
public unsafe double ReadDouble()
public double ReadDouble()
{
long intValue = this.ReadInt64();
return *((double*)&intValue);
return Unsafe.As<long, double>(ref intValue);
}
/// <summary>

16
src/ImageSharp/MetaData/Profiles/ICC/DataWriter/IccDataWriter.NonPrimitives.cs

@ -31,11 +31,11 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// </summary>
/// <param name="value">The value to write</param>
/// <returns>the number of bytes written</returns>
public int WriteVersionNumber(Version value)
public int WriteVersionNumber(in IccVersion value)
{
int major = value.Major.Clamp(0, byte.MaxValue);
int minor = value.Minor.Clamp(0, 15);
int bugfix = value.Build.Clamp(0, 15);
int bugfix = value.Patch.Clamp(0, 15);
// TODO: This is not used?
byte mb = (byte)((minor << 4) | bugfix);
@ -61,7 +61,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// </summary>
/// <param name="value">The value to write</param>
/// <returns>the number of bytes written</returns>
public int WriteProfileId(IccProfileId value)
public int WriteProfileId(in IccProfileId value)
{
return this.WriteUInt32(value.Part1)
+ this.WriteUInt32(value.Part2)
@ -74,7 +74,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// </summary>
/// <param name="value">The value to write</param>
/// <returns>the number of bytes written</returns>
public int WritePositionNumber(IccPositionNumber value)
public int WritePositionNumber(in IccPositionNumber value)
{
return this.WriteUInt32(value.Offset)
+ this.WriteUInt32(value.Size);
@ -85,7 +85,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// </summary>
/// <param name="value">The value to write</param>
/// <returns>the number of bytes written</returns>
public int WriteResponseNumber(IccResponseNumber value)
public int WriteResponseNumber(in IccResponseNumber value)
{
return this.WriteUInt16(value.DeviceCode)
+ this.WriteFix16(value.MeasurementValue);
@ -96,7 +96,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// </summary>
/// <param name="value">The value to write</param>
/// <returns>the number of bytes written</returns>
public int WriteNamedColor(IccNamedColor value)
public int WriteNamedColor(in IccNamedColor value)
{
return this.WriteAsciiString(value.Name, 32, true)
+ this.WriteArray(value.PcsCoordinates)
@ -108,7 +108,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// </summary>
/// <param name="value">The value to write</param>
/// <returns>the number of bytes written</returns>
public int WriteProfileDescription(IccProfileDescription value)
public int WriteProfileDescription(in IccProfileDescription value)
{
return this.WriteUInt32(value.DeviceManufacturer)
+ this.WriteUInt32(value.DeviceModel)
@ -125,7 +125,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// </summary>
/// <param name="value">The value to write</param>
/// <returns>the number of bytes written</returns>
public int WriteScreeningChannel(IccScreeningChannel value)
public int WriteScreeningChannel(in IccScreeningChannel value)
{
return this.WriteFix16(value.Frequency)
+ this.WriteFix16(value.Angle)

34
src/ImageSharp/MetaData/Profiles/ICC/IccProfileHeader.cs

@ -7,42 +7,42 @@ using System.Numerics;
namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
{
/// <summary>
/// Contains all values of an ICC profile header
/// Contains all values of an ICC profile header.
/// </summary>
public sealed class IccProfileHeader
{
/// <summary>
/// Gets or sets the profile size in bytes (will be ignored when writing a profile)
/// Gets or sets the profile size in bytes (will be ignored when writing a profile).
/// </summary>
public uint Size { get; set; }
/// <summary>
/// Gets or sets the preferred CMM (Color Management Module) type
/// Gets or sets the preferred CMM (Color Management Module) type.
/// </summary>
public string CmmType { get; set; }
/// <summary>
/// Gets or sets the profiles version number
/// Gets or sets the profiles version number.
/// </summary>
public Version Version { get; set; }
public IccVersion Version { get; set; }
/// <summary>
/// Gets or sets the type of the profile
/// Gets or sets the type of the profile.
/// </summary>
public IccProfileClass Class { get; set; }
/// <summary>
/// Gets or sets the data colorspace
/// Gets or sets the data colorspace.
/// </summary>
public IccColorSpaceType DataColorSpace { get; set; }
/// <summary>
/// Gets or sets the profile connection space
/// Gets or sets the profile connection space.
/// </summary>
public IccColorSpaceType ProfileConnectionSpace { get; set; }
/// <summary>
/// Gets or sets the date and time this profile was created
/// Gets or sets the date and time this profile was created.
/// </summary>
public DateTime CreationDate { get; set; }
@ -59,42 +59,42 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <summary>
/// Gets or sets the profile flags to indicate various options for the CMM
/// such as distributed processing and caching options
/// such as distributed processing and caching options.
/// </summary>
public IccProfileFlag Flags { get; set; }
/// <summary>
/// Gets or sets the device manufacturer of the device for which this profile is created
/// Gets or sets the device manufacturer of the device for which this profile is created.
/// </summary>
public uint DeviceManufacturer { get; set; }
/// <summary>
/// Gets or sets the model of the device for which this profile is created
/// Gets or sets the model of the device for which this profile is created.
/// </summary>
public uint DeviceModel { get; set; }
/// <summary>
/// Gets or sets the device attributes unique to the particular device setup such as media type
/// Gets or sets the device attributes unique to the particular device setup such as media type.
/// </summary>
public IccDeviceAttribute DeviceAttributes { get; set; }
/// <summary>
/// Gets or sets the rendering Intent
/// Gets or sets the rendering Intent.
/// </summary>
public IccRenderingIntent RenderingIntent { get; set; }
/// <summary>
/// Gets or sets The normalized XYZ values of the illuminant of the PCS
/// Gets or sets The normalized XYZ values of the illuminant of the PCS.
/// </summary>
public Vector3 PcsIlluminant { get; set; }
/// <summary>
/// Gets or sets Profile creator signature
/// Gets or sets profile creator signature.
/// </summary>
public string CreatorSignature { get; set; }
/// <summary>
/// Gets or sets the profile ID (hash)
/// Gets or sets the profile ID (hash).
/// </summary>
public IccProfileId Id { get; set; }
}

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

@ -44,28 +44,9 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj is IccTagDataEntry entry && this.Equals(entry);
}
/// <inheritdoc/>
public override int GetHashCode()
{
unchecked
{
return (int)this.Signature * 397;
}
}
/// <inheritdoc/>
public virtual bool Equals(IccTagDataEntry other)
{
@ -81,5 +62,14 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
return this.Signature == other.Signature;
}
/// <inheritdoc/>
public override int GetHashCode()
{
unchecked
{
return (int)this.Signature * 397;
}
}
}
}

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

@ -88,7 +88,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public bool Equals(IccChromaticityTagDataEntry other)
{
if (ReferenceEquals(null, other))
if (other is null)
{
return false;
}
@ -104,17 +104,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj is IccChromaticityTagDataEntry && this.Equals((IccChromaticityTagDataEntry)obj);
return obj is IccChromaticityTagDataEntry other && this.Equals(other);
}
/// <inheritdoc/>

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

@ -65,16 +65,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj is IccColorantOrderTagDataEntry other && this.Equals(other);
}

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

@ -66,16 +66,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj is IccColorantTableTagDataEntry other && this.Equals(other);
}

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

@ -115,16 +115,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj is IccCrdInfoTagDataEntry other && this.Equals(other);
}

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

@ -113,16 +113,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj is IccCurveTagDataEntry other && this.Equals(other);
}

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

@ -89,16 +89,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj is IccDataTagDataEntry other && this.Equals(other);
}

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

@ -60,17 +60,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj is IccDateTimeTagDataEntry && this.Equals((IccDateTimeTagDataEntry)obj);
return obj is IccDateTimeTagDataEntry other && this.Equals(other);
}
/// <inheritdoc/>

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

@ -62,16 +62,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj is IccFix16ArrayTagDataEntry other && this.Equals(other);
}

12
src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLut16TagDataEntry.cs

@ -137,17 +137,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj is IccLut16TagDataEntry && this.Equals((IccLut16TagDataEntry)obj);
return obj is IccLut16TagDataEntry other && this.Equals(other);
}
/// <inheritdoc/>

12
src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLut8TagDataEntry.cs

@ -140,17 +140,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj is IccLut8TagDataEntry && this.Equals((IccLut8TagDataEntry)obj);
return obj is IccLut8TagDataEntry other && this.Equals(other);
}
/// <inheritdoc/>

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

@ -177,16 +177,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj is IccLutAToBTagDataEntry other && this.Equals(other);
}

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

@ -177,16 +177,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj is IccLutBToATagDataEntry other && this.Equals(other);
}

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

@ -100,17 +100,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj is IccMeasurementTagDataEntry && this.Equals((IccMeasurementTagDataEntry)obj);
return obj is IccMeasurementTagDataEntry other && this.Equals(other);
}
/// <inheritdoc/>

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

@ -63,17 +63,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj is IccMultiLocalizedUnicodeTagDataEntry && this.Equals((IccMultiLocalizedUnicodeTagDataEntry)obj);
return obj is IccMultiLocalizedUnicodeTagDataEntry other && this.Equals(other);
}
/// <inheritdoc />

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

@ -84,16 +84,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj is IccMultiProcessElementsTagDataEntry other && this.Equals(other);
}

12
src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccNamedColor2TagDataEntry.cs

@ -127,7 +127,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public bool Equals(IccNamedColor2TagDataEntry other)
{
if (ReferenceEquals(null, other))
if (other is null)
{
return false;
}
@ -148,16 +148,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj is IccNamedColor2TagDataEntry other && this.Equals(other);
}

12
src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccParametricCurveTagDataEntry.cs

@ -45,7 +45,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public bool Equals(IccParametricCurveTagDataEntry other)
{
if (ReferenceEquals(null, other))
if (other is null)
{
return false;
}
@ -61,16 +61,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj is IccParametricCurveTagDataEntry other && this.Equals(other);
}

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

@ -48,7 +48,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc />
public bool Equals(IccProfileSequenceDescTagDataEntry other)
{
if (ReferenceEquals(null, other))
if (other is null)
{
return false;
}
@ -64,16 +64,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj is IccProfileSequenceDescTagDataEntry other && this.Equals(other);
}

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

@ -47,7 +47,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc />
public bool Equals(IccProfileSequenceIdentifierTagDataEntry other)
{
if (ReferenceEquals(null, other))
if (other is null)
{
return false;
}
@ -63,16 +63,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc />
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj is IccProfileSequenceIdentifierTagDataEntry other && this.Equals(other);
}

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

@ -59,7 +59,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc />
public bool Equals(IccResponseCurveSet16TagDataEntry other)
{
if (ReferenceEquals(null, other))
if (other is null)
{
return false;
}
@ -77,17 +77,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc />
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj is IccResponseCurveSet16TagDataEntry && this.Equals((IccResponseCurveSet16TagDataEntry)obj);
return obj is IccResponseCurveSet16TagDataEntry other && this.Equals(other);
}
/// <inheritdoc />

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

@ -56,7 +56,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc />
public bool Equals(IccScreeningTagDataEntry other)
{
if (ReferenceEquals(null, other))
if (other is null)
{
return false;
}
@ -74,16 +74,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc />
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj is IccScreeningTagDataEntry other && this.Equals(other);
}

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

@ -46,7 +46,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc />
public bool Equals(IccSignatureTagDataEntry other)
{
if (ReferenceEquals(null, other))
if (other is null)
{
return false;
}
@ -62,16 +62,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc />
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj is IccSignatureTagDataEntry other && this.Equals(other);
}

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

@ -139,7 +139,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc />
public bool Equals(IccTextDescriptionTagDataEntry other)
{
if (ReferenceEquals(null, other))
if (other is null)
{
return false;
}
@ -160,17 +160,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc />
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj is IccTextDescriptionTagDataEntry && this.Equals((IccTextDescriptionTagDataEntry)obj);
return obj is IccTextDescriptionTagDataEntry other && this.Equals(other);
}
/// <inheritdoc />

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

@ -45,7 +45,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc />
public bool Equals(IccTextTagDataEntry other)
{
if (ReferenceEquals(null, other))
if (other is null)
{
return false;
}
@ -61,16 +61,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc />
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj is IccTextTagDataEntry other && this.Equals(other);
}

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

@ -46,7 +46,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public bool Equals(IccUFix16ArrayTagDataEntry other)
{
if (ReferenceEquals(null, other))
if (other is null)
{
return false;
}
@ -62,16 +62,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj is IccUFix16ArrayTagDataEntry other && this.Equals(other);
}

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

@ -46,7 +46,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public bool Equals(IccUInt16ArrayTagDataEntry other)
{
if (ReferenceEquals(null, other))
if (other is null)
{
return false;
}
@ -62,16 +62,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj is IccUInt16ArrayTagDataEntry other && this.Equals(other);
}

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

@ -62,17 +62,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj is IccUInt32ArrayTagDataEntry && this.Equals((IccUInt32ArrayTagDataEntry)obj);
return obj is IccUInt32ArrayTagDataEntry other && this.Equals(other);
}
/// <inheritdoc/>

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

@ -62,17 +62,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj is IccUInt64ArrayTagDataEntry && this.Equals((IccUInt64ArrayTagDataEntry)obj);
return obj is IccUInt64ArrayTagDataEntry other && this.Equals(other);
}
/// <inheritdoc/>

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

@ -62,16 +62,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj is IccUInt8ArrayTagDataEntry other && this.Equals(other);
}

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

@ -85,16 +85,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj is IccUcrBgTagDataEntry other && this.Equals(other);
}

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

@ -62,16 +62,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj is IccUnknownTagDataEntry other && this.Equals(other);
}

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

@ -61,7 +61,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public bool Equals(IccViewingConditionsTagDataEntry other)
{
if (ReferenceEquals(null, other))
if (other is null)
{
return false;
}
@ -80,17 +80,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj is IccViewingConditionsTagDataEntry && this.Equals((IccViewingConditionsTagDataEntry)obj);
return obj is IccViewingConditionsTagDataEntry other && this.Equals(other);
}
/// <inheritdoc/>

2
src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccXyzTagDataEntry.cs

@ -55,4 +55,4 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
return this.Equals((IccTagDataEntry)other);
}
}
}
}

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

@ -136,16 +136,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj is IccClut other && this.Equals(other);
}

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

@ -77,7 +77,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// <inheritdoc/>
public override bool Equals(object obj)
{
return obj is IccScreeningChannel && this.Equals((IccScreeningChannel)obj);
return obj is IccScreeningChannel other && this.Equals(other);
}
/// <inheritdoc/>

53
src/ImageSharp/MetaData/Profiles/ICC/Various/IccVersion.cs

@ -0,0 +1,53 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
{
/// <summary>
/// Represents the ICC profile version number.
/// </summary>
public readonly struct IccVersion : IEquatable<IccVersion>
{
/// <summary>
/// Initializes a new instance of the <see cref="IccVersion"/> struct.
/// </summary>
/// <param name="major">The major version number.</param>
/// <param name="minor">The minor version number.</param>
/// <param name="patch">The patch version number.</param>
public IccVersion(int major, int minor, int patch)
{
this.Major = major;
this.Minor = minor;
this.Patch = patch;
}
/// <summary>
/// Gets the major version number.
/// </summary>
public int Major { get; }
/// <summary>
/// Gets the minor version number.
/// </summary>
public int Minor { get; }
/// <summary>
/// Gets the patch number.
/// </summary>
public int Patch { get; }
/// <inheritdoc/>
public bool Equals(IccVersion other) =>
this.Major == other.Major &&
this.Minor == other.Minor &&
this.Patch == other.Patch;
/// <inheritdoc/>
public override string ToString()
{
return string.Join(".", this.Major, this.Minor, this.Patch);
}
}
}

2
src/ImageSharp/PixelFormats/Bgr565.cs

@ -206,7 +206,7 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc />
public override bool Equals(object obj)
{
return (obj is Bgr565) && this.Equals((Bgr565)obj);
return obj is Bgr565 other && this.Equals(other);
}
/// <inheritdoc />

2
src/ImageSharp/PixelFormats/HalfSingle.cs

@ -211,7 +211,7 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc />
public override bool Equals(object obj)
{
return (obj is HalfSingle) && this.Equals((HalfSingle)obj);
return obj is HalfSingle other && this.Equals(other);
}
/// <inheritdoc />

2
src/ImageSharp/PixelFormats/HalfVector2.cs

@ -239,7 +239,7 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc />
public override bool Equals(object obj)
{
return (obj is HalfVector2) && this.Equals((HalfVector2)obj);
return obj is HalfVector2 other && this.Equals(other);
}
/// <inheritdoc />

2
src/ImageSharp/PixelFormats/NormalizedShort2.cs

@ -247,7 +247,7 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc />
public override bool Equals(object obj)
{
return (obj is NormalizedShort2) && this.Equals((NormalizedShort2)obj);
return obj is NormalizedShort2 other && this.Equals(other);
}
/// <inheritdoc />

2
src/ImageSharp/PixelFormats/Rg32.cs

@ -210,7 +210,7 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc />
public override bool Equals(object obj)
{
return (obj is Rg32) && this.Equals((Rg32)obj);
return obj is Rg32 other && this.Equals(other);
}
/// <inheritdoc />

1
src/ImageSharp/Processing/Dithering/ErrorDiffusion/ErrorDiffuserBase.cs

@ -47,7 +47,6 @@ namespace SixLabors.ImageSharp.Processing.Dithering.ErrorDiffusion
/// <param name="divisor">The divisor.</param>
internal ErrorDiffuserBase(DenseMatrix<float> matrix, byte divisor)
{
Guard.NotNull(matrix, nameof(matrix));
Guard.MustBeGreaterThan(divisor, 0, nameof(divisor));
this.matrix = matrix;

1
tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj

@ -19,6 +19,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="BitMiracle.LibJpeg.NET" Version="1.4.280" />
<PackageReference Include="Magick.NET-Q16-AnyCPU" Version="7.5.0" />
<PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="Moq" Version="4.8.3" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.2" />

8
tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs

@ -30,7 +30,11 @@ namespace SixLabors.ImageSharp.Tests
using (Image<TPixel> image = provider.GetImage(new BmpDecoder()))
{
image.DebugSave(provider, "bmp");
image.CompareToOriginal(provider);
if (TestEnvironment.IsWindows)
{
image.CompareToOriginal(provider);
}
}
}
@ -52,7 +56,7 @@ namespace SixLabors.ImageSharp.Tests
[InlineData(NegHeight, 24)]
[InlineData(Bit8, 8)]
[InlineData(Bit8Inverted, 8)]
public void DetectPixelSize(string imagePath, int expectedPixelSize)
public void Identify(string imagePath, int expectedPixelSize)
{
var testFile = TestFile.Create(imagePath);
using (var stream = new MemoryStream(testFile.Bytes, false))

127
tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.Chunks.cs

@ -0,0 +1,127 @@
using System.Buffers.Binary;
using System.IO;
using System.Text;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.PixelFormats;
using Xunit;
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Tests.Formats.Png
{
public partial class PngDecoderTests
{
// Contains the png marker, IHDR and pHYs chunks of a 1x1 pixel 32bit png 1 a single black pixel.
private static readonly byte[] Raw1X1PngIhdrAndpHYs =
{
// PNG Identifier
0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
// IHDR
0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x02,
0x00, 0x00, 0x00,
// IHDR CRC
0x90, 0x77, 0x53, 0xDE,
// pHYS
0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00,
0x00, 0x0E, 0xC3, 0x00, 0x00, 0x0E, 0xC3, 0x01,
// pHYS CRC
0xC7, 0x6F, 0xA8, 0x64
};
// Contains the png marker, IDAT and IEND chunks of a 1x1 pixel 32bit png 1 a single black pixel.
private static readonly byte[] Raw1X1PngIdatAndIend =
{
// IDAT
0x00, 0x00, 0x00, 0x0C, 0x49, 0x44, 0x41, 0x54, 0x18,
0x57, 0x63, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x04,
0x00, 0x01,
// IDAT CRC
0x5C, 0xCD, 0xFF, 0x69,
// IEND
0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44,
// IEND CRC
0xAE, 0x42, 0x60, 0x82
};
[Theory]
[InlineData((uint)PngChunkType.Header)] // IHDR
[InlineData((uint)PngChunkType.Palette)] // PLTE
// [InlineData(PngChunkTypes.Data)] //TODO: Figure out how to test this
[InlineData((uint)PngChunkType.End)] // IEND
public void Decode_IncorrectCRCForCriticalChunk_ExceptionIsThrown(uint chunkType)
{
string chunkName = GetChunkTypeName(chunkType);
using (var memStream = new MemoryStream())
{
WriteHeaderChunk(memStream);
WriteChunk(memStream, chunkName);
WriteDataChunk(memStream);
var decoder = new PngDecoder();
ImageFormatException exception =
Assert.Throws<ImageFormatException>(() => decoder.Decode<Rgb24>(null, memStream));
Assert.Equal($"CRC Error. PNG {chunkName} chunk is corrupt!", exception.Message);
}
}
[Theory]
[InlineData((uint)PngChunkType.Gamma)] // gAMA
[InlineData((uint)PngChunkType.PaletteAlpha)] // tRNS
[InlineData(
(uint)PngChunkType.Physical)] // pHYs: It's ok to test physical as we don't throw for duplicate chunks.
//[InlineData(PngChunkTypes.Text)] //TODO: Figure out how to test this
public void Decode_IncorrectCRCForNonCriticalChunk_ExceptionIsThrown(uint chunkType)
{
string chunkName = GetChunkTypeName(chunkType);
using (var memStream = new MemoryStream())
{
WriteHeaderChunk(memStream);
WriteChunk(memStream, chunkName);
WriteDataChunk(memStream);
var decoder = new PngDecoder();
decoder.Decode<Rgb24>(null, memStream);
}
}
private static string GetChunkTypeName(uint value)
{
byte[] data = new byte[4];
BinaryPrimitives.WriteUInt32BigEndian(data, value);
return Encoding.ASCII.GetString(data);
}
private static void WriteHeaderChunk(MemoryStream memStream)
{
// Writes a 1x1 32bit png header chunk containing a single black pixel
memStream.Write(Raw1X1PngIhdrAndpHYs, 0, Raw1X1PngIhdrAndpHYs.Length);
}
private static void WriteChunk(MemoryStream memStream, string chunkName)
{
memStream.Write(new byte[] { 0, 0, 0, 1 }, 0, 4);
memStream.Write(Encoding.GetEncoding("ASCII").GetBytes(chunkName), 0, 4);
memStream.Write(new byte[] { 0, 0, 0, 0, 0 }, 0, 5);
}
private static void WriteDataChunk(MemoryStream memStream)
{
// Writes a 1x1 32bit png data chunk containing a single black pixel
memStream.Write(Raw1X1PngIdatAndIend, 0, Raw1X1PngIdatAndIend.Length);
memStream.Position = 0;
}
}
}

207
tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs

@ -1,63 +1,25 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
// ReSharper disable InconsistentNaming
using System.Buffers.Binary;
using System.IO;
using System.Text;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
using Xunit;
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Tests
namespace SixLabors.ImageSharp.Tests.Formats.Png
{
using System.Buffers.Binary;
using System.Linq;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
// TODO: Fix all bugs, and re enable Skipped and commented stuff !!!
public class PngDecoderTests
public partial class PngDecoderTests
{
private const PixelTypes PixelTypes = Tests.PixelTypes.Rgba32 | Tests.PixelTypes.RgbaVector | Tests.PixelTypes.Argb32;
// TODO: Cannot use exact comparer since System.Drawing doesn't preserve more than 32bits.
private static readonly ImageComparer ValidatorComparer = ImageComparer.TolerantPercentage(0.1302F, 2134);
// Contains the png marker, IHDR and pHYs chunks of a 1x1 pixel 32bit png 1 a single black pixel.
private static readonly byte[] raw1x1PngIHDRAndpHYs =
{
// PNG Identifier
0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
// IHDR
0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x02, 0x00, 0x00, 0x00,
// IHDR CRC
0x90, 0x77, 0x53, 0xDE,
// pHYS
0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0E, 0xC3, 0x00, 0x00, 0x0E, 0xC3, 0x01,
// pHYS CRC
0xC7, 0x6F, 0xA8, 0x64
};
// Contains the png marker, IDAT and IEND chunks of a 1x1 pixel 32bit png 1 a single black pixel.
private static readonly byte[] raw1x1PngIDATAndIEND =
{
// IDAT
0x00, 0x00, 0x00, 0x0C, 0x49, 0x44, 0x41, 0x54, 0x18, 0x57, 0x63, 0x60, 0x60, 0x60, 0x00, 0x00,
0x00, 0x04, 0x00, 0x01,
// IDAT CRC
0x5C, 0xCD, 0xFF, 0x69,
// IEND
0x00, 0x00, 0x00, 0x00, 0x49, 0x45,
0x4E, 0x44,
// IEND CRC
0xAE, 0x42, 0x60, 0x82
};
public static readonly string[] CommonTestImages =
{
@ -105,30 +67,6 @@ namespace SixLabors.ImageSharp.Tests
TestImages.Png.GrayTrns16BitInterlaced
};
// This is a workaround for Mono-s decoder being incompatible with ours and GDI+.
// We shouldn't mix these with the Interleaved cases (which are also failing with Mono System.Drawing). Let's go AAA!
private static readonly string[] SkipOnMono =
{
TestImages.Png.Bad.ChunkLength2,
TestImages.Png.VimImage2,
TestImages.Png.Splash,
TestImages.Png.Indexed,
TestImages.Png.Bad.ChunkLength1,
TestImages.Png.VersioningImage1,
TestImages.Png.Banner7Adam7InterlaceMode,
TestImages.Png.GrayTrns16BitInterlaced,
TestImages.Png.Rgb48BppInterlaced
};
private static bool SkipVerification(ITestImageProvider provider)
{
string fn = provider.SourceFileOrDescription;
// This is a workaround for Mono-s decoder being incompatible with ours and GDI+.
// We shouldn't mix these with the Interleaved cases (which are also failing with Mono System.Drawing). Let's go AAA!
return (TestEnvironment.IsLinux || TestEnvironment.IsMono) && SkipOnMono.Contains(fn);
}
[Theory]
[WithFileCollection(nameof(CommonTestImages), PixelTypes.Rgba32)]
public void Decode<TPixel>(TestImageProvider<TPixel> provider)
@ -137,22 +75,7 @@ namespace SixLabors.ImageSharp.Tests
using (Image<TPixel> image = provider.GetImage(new PngDecoder()))
{
image.DebugSave(provider);
if (!SkipVerification(provider))
{
image.CompareToOriginal(provider, ImageComparer.Exact);
}
}
}
[Theory]
[WithFile(TestImages.Png.Interlaced, PixelTypes.Rgba32)]
public void Decode_Interlaced_DoesNotThrow<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
using (Image<TPixel> image = provider.GetImage(new PngDecoder()))
{
image.DebugSave(provider);
image.CompareToOriginal(provider, ImageComparer.Exact);
}
}
@ -175,12 +98,8 @@ namespace SixLabors.ImageSharp.Tests
{
using (Image<TPixel> image = provider.GetImage(new PngDecoder()))
{
var encoder = new PngEncoder { ColorType = PngColorType.Rgb, BitDepth = PngBitDepth.Bit16 };
if (!SkipVerification(provider))
{
image.VerifyEncoder(provider, "png", null, encoder, customComparer: ValidatorComparer);
}
image.DebugSave(provider);
image.CompareToOriginal(provider, ImageComparer.Exact);
}
}
@ -191,12 +110,8 @@ namespace SixLabors.ImageSharp.Tests
{
using (Image<TPixel> image = provider.GetImage(new PngDecoder()))
{
var encoder = new PngEncoder { ColorType = PngColorType.RgbWithAlpha, BitDepth = PngBitDepth.Bit16 };
if (!SkipVerification(provider))
{
image.VerifyEncoder(provider, "png", null, encoder, customComparer: ValidatorComparer);
}
image.DebugSave(provider);
image.CompareToOriginal(provider, ImageComparer.Exact);
}
}
@ -207,12 +122,8 @@ namespace SixLabors.ImageSharp.Tests
{
using (Image<TPixel> image = provider.GetImage(new PngDecoder()))
{
var encoder = new PngEncoder { ColorType = PngColorType.Grayscale, BitDepth = PngBitDepth.Bit16 };
if (!SkipVerification(provider))
{
image.VerifyEncoder(provider, "png", null, encoder, customComparer: ValidatorComparer);
}
image.DebugSave(provider);
image.CompareToOriginal(provider, ImageComparer.Exact);
}
}
@ -223,12 +134,8 @@ namespace SixLabors.ImageSharp.Tests
{
using (Image<TPixel> image = provider.GetImage(new PngDecoder()))
{
var encoder = new PngEncoder { ColorType = PngColorType.GrayscaleWithAlpha, BitDepth = PngBitDepth.Bit16 };
if (!SkipVerification(provider))
{
image.VerifyEncoder(provider, "png", null, encoder, customComparer: ValidatorComparer);
}
image.DebugSave(provider);
image.CompareToOriginal(provider, ImageComparer.Exact);
}
}
@ -303,7 +210,7 @@ namespace SixLabors.ImageSharp.Tests
[InlineData(TestImages.Png.Blur, 32)]
[InlineData(TestImages.Png.Rgb48Bpp, 48)]
[InlineData(TestImages.Png.Rgb48BppInterlaced, 48)]
public void DetectPixelSize(string imagePath, int expectedPixelSize)
public void Identify(string imagePath, int expectedPixelSize)
{
var testFile = TestFile.Create(imagePath);
using (var stream = new MemoryStream(testFile.Bytes, false))
@ -311,77 +218,5 @@ namespace SixLabors.ImageSharp.Tests
Assert.Equal(expectedPixelSize, Image.Identify(stream)?.PixelType?.BitsPerPixel);
}
}
[Theory]
[InlineData((uint)PngChunkType.Header)] // IHDR
[InlineData((uint)PngChunkType.Palette)] // PLTE
// [InlineData(PngChunkTypes.Data)] //TODO: Figure out how to test this
[InlineData((uint)PngChunkType.End)] // IEND
public void Decode_IncorrectCRCForCriticalChunk_ExceptionIsThrown(uint chunkType)
{
string chunkName = GetChunkTypeName(chunkType);
using (var memStream = new MemoryStream())
{
WriteHeaderChunk(memStream);
WriteChunk(memStream, chunkName);
WriteDataChunk(memStream);
var decoder = new PngDecoder();
ImageFormatException exception = Assert.Throws<ImageFormatException>(() => decoder.Decode<Rgb24>(null, memStream));
Assert.Equal($"CRC Error. PNG {chunkName} chunk is corrupt!", exception.Message);
}
}
[Theory]
[InlineData((uint)PngChunkType.Gamma)] // gAMA
[InlineData((uint)PngChunkType.PaletteAlpha)] // tRNS
[InlineData((uint)PngChunkType.Physical)] // pHYs: It's ok to test physical as we don't throw for duplicate chunks.
//[InlineData(PngChunkTypes.Text)] //TODO: Figure out how to test this
public void Decode_IncorrectCRCForNonCriticalChunk_ExceptionIsThrown(uint chunkType)
{
string chunkName = GetChunkTypeName(chunkType);
using (var memStream = new MemoryStream())
{
WriteHeaderChunk(memStream);
WriteChunk(memStream, chunkName);
WriteDataChunk(memStream);
var decoder = new PngDecoder();
decoder.Decode<Rgb24>(null, memStream);
}
}
private static string GetChunkTypeName(uint value)
{
byte[] data = new byte[4];
BinaryPrimitives.WriteUInt32BigEndian(data, value);
return Encoding.ASCII.GetString(data);
}
private static void WriteHeaderChunk(MemoryStream memStream)
{
// Writes a 1x1 32bit png header chunk containing a single black pixel
memStream.Write(raw1x1PngIHDRAndpHYs, 0, raw1x1PngIHDRAndpHYs.Length);
}
private static void WriteChunk(MemoryStream memStream, string chunkName)
{
memStream.Write(new byte[] { 0, 0, 0, 1 }, 0, 4);
memStream.Write(Encoding.GetEncoding("ASCII").GetBytes(chunkName), 0, 4);
memStream.Write(new byte[] { 0, 0, 0, 0, 0 }, 0, 5);
}
private static void WriteDataChunk(MemoryStream memStream)
{
// Writes a 1x1 32bit png data chunk containing a single black pixel
memStream.Write(raw1x1PngIDATAndIEND, 0, raw1x1PngIDATAndIEND.Length);
memStream.Position = 0;
}
}
}

86
tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs

@ -1,22 +1,21 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
// ReSharper disable InconsistentNaming
using System.IO;
using System.Linq;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Processing.Quantization;
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
using Xunit;
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Tests
namespace SixLabors.ImageSharp.Tests.Formats.Png
{
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
public class PngEncoderTests
{
private const float ToleranceThresholdForPaletteEncoder = 0.2f / 100;
@ -70,7 +69,12 @@ namespace SixLabors.ImageSharp.Tests
public void WorksWithDifferentSizes<TPixel>(TestImageProvider<TPixel> provider, PngColorType pngColorType)
where TPixel : struct, IPixel<TPixel>
{
TestPngEncoderCore(provider, pngColorType, PngFilterMethod.Adaptive, appendPngColorType: true);
TestPngEncoderCore(
provider,
pngColorType,
PngFilterMethod.Adaptive,
PngBitDepth.Bit8,
appendPngColorType: true);
}
[Theory]
@ -78,7 +82,13 @@ namespace SixLabors.ImageSharp.Tests
public void IsNotBoundToSinglePixelType<TPixel>(TestImageProvider<TPixel> provider, PngColorType pngColorType)
where TPixel : struct, IPixel<TPixel>
{
TestPngEncoderCore(provider, pngColorType, PngFilterMethod.Adaptive, appendPixelType: true, appendPngColorType: true);
TestPngEncoderCore(
provider,
pngColorType,
PngFilterMethod.Adaptive,
PngBitDepth.Bit8,
appendPixelType: true,
appendPngColorType: true);
}
[Theory]
@ -86,7 +96,12 @@ namespace SixLabors.ImageSharp.Tests
public void WorksWithAllFilterMethods<TPixel>(TestImageProvider<TPixel> provider, PngFilterMethod pngFilterMethod)
where TPixel : struct, IPixel<TPixel>
{
TestPngEncoderCore(provider, PngColorType.RgbWithAlpha, pngFilterMethod, appendPngFilterMethod: true);
TestPngEncoderCore(
provider,
PngColorType.RgbWithAlpha,
pngFilterMethod,
PngBitDepth.Bit8,
appendPngFilterMethod: true);
}
[Theory]
@ -94,7 +109,29 @@ namespace SixLabors.ImageSharp.Tests
public void WorksWithAllCompressionLevels<TPixel>(TestImageProvider<TPixel> provider, int compressionLevel)
where TPixel : struct, IPixel<TPixel>
{
TestPngEncoderCore(provider, PngColorType.RgbWithAlpha, PngFilterMethod.Adaptive, compressionLevel, appendCompressionLevel: true);
TestPngEncoderCore(
provider,
PngColorType.RgbWithAlpha,
PngFilterMethod.Adaptive,
PngBitDepth.Bit8,
compressionLevel,
appendCompressionLevel: true);
}
[Theory]
[WithTestPatternImages(24, 24, PixelTypes.Rgba64, PngColorType.Rgb)]
[WithTestPatternImages(24, 24, PixelTypes.Rgba64, PngColorType.RgbWithAlpha)]
[WithTestPatternImages(24, 24, PixelTypes.Rgba32, PngColorType.RgbWithAlpha)]
public void WorksWithBitDepth16<TPixel>(TestImageProvider<TPixel> provider, PngColorType pngColorType)
where TPixel : struct, IPixel<TPixel>
{
TestPngEncoderCore(
provider,
pngColorType,
PngFilterMethod.Adaptive,
PngBitDepth.Bit16,
appendPngColorType: true,
appendPixelType: true);
}
[Theory]
@ -102,7 +139,13 @@ namespace SixLabors.ImageSharp.Tests
public void PaletteColorType_WuQuantizer<TPixel>(TestImageProvider<TPixel> provider, int paletteSize)
where TPixel : struct, IPixel<TPixel>
{
TestPngEncoderCore(provider, PngColorType.Palette, PngFilterMethod.Adaptive, paletteSize: paletteSize, appendPaletteSize: true);
TestPngEncoderCore(
provider,
PngColorType.Palette,
PngFilterMethod.Adaptive,
PngBitDepth.Bit8,
paletteSize: paletteSize,
appendPaletteSize: true);
}
private static bool HasAlpha(PngColorType pngColorType) =>
@ -112,6 +155,7 @@ namespace SixLabors.ImageSharp.Tests
TestImageProvider<TPixel> provider,
PngColorType pngColorType,
PngFilterMethod pngFilterMethod,
PngBitDepth bitDepth,
int compressionLevel = 6,
int paletteSize = 255,
bool appendPngColorType = false,
@ -133,6 +177,7 @@ namespace SixLabors.ImageSharp.Tests
ColorType = pngColorType,
FilterMethod = pngFilterMethod,
CompressionLevel = compressionLevel,
BitDepth = bitDepth,
Quantizer = new WuQuantizer(paletteSize)
};
@ -155,16 +200,31 @@ namespace SixLabors.ImageSharp.Tests
IImageDecoder referenceDecoder = TestEnvironment.GetReferenceDecoder(actualOutputFile);
string referenceOutputFile = ((ITestImageProvider)provider).Utility.GetReferenceOutputFileName("png", debugInfo, appendPixelType, true);
bool referenceOutputFileExists = File.Exists(referenceOutputFile);
using (var actualImage = Image.Load<TPixel>(actualOutputFile, referenceDecoder))
using (var referenceImage = Image.Load<TPixel>(referenceOutputFile, referenceDecoder))
{
// TODO: Do we still need the reference output files?
Image<TPixel> referenceImage = referenceOutputFileExists
? Image.Load<TPixel>(referenceOutputFile, referenceDecoder)
: image;
float paletteToleranceHack = 80f / paletteSize;
paletteToleranceHack = paletteToleranceHack * paletteToleranceHack;
ImageComparer comparer = pngColorType == PngColorType.Palette
? ImageComparer.Tolerant(ToleranceThresholdForPaletteEncoder * paletteToleranceHack)
: ImageComparer.Exact;
comparer.VerifySimilarity(referenceImage, actualImage);
try
{
comparer.VerifySimilarity(referenceImage, actualImage);
}
finally
{
if (referenceOutputFileExists)
{
referenceImage.Dispose();
}
}
}
}
}

8
tests/ImageSharp.Tests/Helpers/GuardTests.cs

@ -12,13 +12,17 @@ namespace SixLabors.ImageSharp.Tests.Helpers
/// </summary>
public class GuardTests
{
class Test
{
}
/// <summary>
/// Tests that the <see cref="M:Guard.NotNull"/> method throws when the argument is null.
/// </summary>
[Fact]
public void NotNullThrowsWhenArgIsNull()
{
Assert.Throws<ArgumentNullException>(() => Guard.NotNull(null, "foo"));
Assert.Throws<ArgumentNullException>(() => Guard.NotNull((Test)null, "foo"));
}
/// <summary>
@ -27,7 +31,7 @@ namespace SixLabors.ImageSharp.Tests.Helpers
[Fact]
public void NotNullThrowsWhenArgNameEmpty()
{
Assert.Throws<ArgumentNullException>(() => Guard.NotNull(null, string.Empty));
Assert.Throws<ArgumentNullException>(() => Guard.NotNull((Test)null, string.Empty));
}
/// <summary>

1
tests/ImageSharp.Tests/ImageSharp.Tests.csproj

@ -27,6 +27,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Magick.NET-Q16-AnyCPU" Version="7.5.0" />
<PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
<PackageReference Include="System.Drawing.Common" Version="4.5.0" />
<PackageReference Include="xunit" Version="2.3.1" />

3
tests/ImageSharp.Tests/Memory/BufferTestSuite.cs

@ -46,8 +46,7 @@ namespace SixLabors.ImageSharp.Tests.Memory
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
return obj is CustomStruct && this.Equals((CustomStruct)obj);
return obj is CustomStruct other && this.Equals(other);
}
public override int GetHashCode()

4
tests/ImageSharp.Tests/MetaData/Profiles/ICC/DataReader/IccDataReader.NonPrimitivesTests.cs

@ -23,11 +23,11 @@ namespace SixLabors.ImageSharp.Tests.Icc
[Theory]
[MemberData(nameof(IccTestDataNonPrimitives.VersionNumberTestData), MemberType = typeof(IccTestDataNonPrimitives))]
public void ReadVersionNumber(byte[] data, Version expected)
public void ReadVersionNumber(byte[] data, IccVersion expected)
{
IccDataReader reader = CreateReader(data);
Version output = reader.ReadVersionNumber();
IccVersion output = reader.ReadVersionNumber();
Assert.Equal(expected, output);
}

2
tests/ImageSharp.Tests/MetaData/Profiles/ICC/DataWriter/IccDataWriter.NonPrimitivesTests.cs

@ -24,7 +24,7 @@ namespace SixLabors.ImageSharp.Tests.Icc
[Theory]
[MemberData(nameof(IccTestDataNonPrimitives.VersionNumberTestData), MemberType = typeof(IccTestDataNonPrimitives))]
public void WriteVersionNumber(byte[] expected, Version data)
public void WriteVersionNumber(byte[] expected, IccVersion data)
{
IccDataWriter writer = CreateWriter();

8
tests/ImageSharp.Tests/TestDataIcc/IccTestDataNonPrimitives.cs

@ -67,10 +67,10 @@ namespace SixLabors.ImageSharp.Tests
#region VersionNumber
public static readonly Version VersionNumber_ValMin = new Version(0, 0, 0);
public static readonly Version VersionNumber_Val211 = new Version(2, 1, 1);
public static readonly Version VersionNumber_Val430 = new Version(4, 3, 0);
public static readonly Version VersionNumber_ValMax = new Version(255, 15, 15);
public static readonly IccVersion VersionNumber_ValMin = new IccVersion(0, 0, 0);
public static readonly IccVersion VersionNumber_Val211 = new IccVersion(2, 1, 1);
public static readonly IccVersion VersionNumber_Val430 = new IccVersion(4, 3, 0);
public static readonly IccVersion VersionNumber_ValMax = new IccVersion(255, 15, 15);
public static readonly byte[] VersionNumber_Min = { 0x00, 0x00, 0x00, 0x00 };
public static readonly byte[] VersionNumber_211 = { 0x02, 0x11, 0x00, 0x00 };

2
tests/ImageSharp.Tests/TestDataIcc/IccTestDataProfiles.cs

@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests
ProfileConnectionSpace = IccColorSpaceType.CieXyz,
RenderingIntent = IccRenderingIntent.AbsoluteColorimetric,
Size = size,
Version = new Version(4, 3, 0),
Version = new IccVersion(4, 3, 0),
};
}

6
tests/ImageSharp.Tests/TestUtilities/ImagingTestCaseUtility.cs

@ -146,7 +146,6 @@ namespace SixLabors.ImageSharp.Tests
appendSourceFileOrDescription);
}
/// <summary>
/// Encodes image by the format matching the required extension, than saves it to the recommended output file.
/// </summary>
@ -154,7 +153,9 @@ namespace SixLabors.ImageSharp.Tests
/// <param name="image">The image instance</param>
/// <param name="extension">The requested extension</param>
/// <param name="encoder">Optional encoder</param>
/// /// <param name="appendSourceFileOrDescription">A boolean indicating whether to append <see cref="ITestImageProvider.SourceFileOrDescription"/> to the test output file name.</param>
/// <param name="appendPixelTypeToFileName">A value indicating whether to append the pixel type to the test output file name</param>
/// <param name="appendSourceFileOrDescription">A boolean indicating whether to append <see cref="ITestImageProvider.SourceFileOrDescription"/> to the test output file name.</param>
/// <param name="testOutputDetails">Additional information to append to the test output file name</param>
public string SaveTestOutputFile<TPixel>(
Image<TPixel> image,
string extension = null,
@ -176,6 +177,7 @@ namespace SixLabors.ImageSharp.Tests
{
image.Save(stream, encoder);
}
return path;
}

53
tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs

@ -0,0 +1,53 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.IO;
using System.Runtime.InteropServices;
using ImageMagick;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs
{
public class MagickReferenceDecoder : IImageDecoder
{
public static MagickReferenceDecoder Instance { get; } = new MagickReferenceDecoder();
public Image<TPixel> Decode<TPixel>(Configuration configuration, Stream stream)
where TPixel : struct, IPixel<TPixel>
{
using (var magickImage = new MagickImage(stream))
{
var result = new Image<TPixel>(configuration, magickImage.Width, magickImage.Height);
Span<TPixel> resultPixels = result.GetPixelSpan();
using (IPixelCollection pixels = magickImage.GetPixelsUnsafe())
{
if (magickImage.Depth == 8)
{
byte[] data = pixels.ToByteArray("RGBA");
PixelOperations<TPixel>.Instance.PackFromRgba32Bytes(data, resultPixels, resultPixels.Length);
}
else if (magickImage.Depth == 16)
{
ushort[] data = pixels.ToShortArray("RGBA");
Span<byte> bytes = MemoryMarshal.Cast<ushort, byte>(data.AsSpan());
PixelOperations<TPixel>.Instance.PackFromRgba64Bytes(bytes, resultPixels, resultPixels.Length);
}
else
{
throw new InvalidOperationException();
}
}
return result;
}
}
}
}

2
tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingReferenceEncoder.cs

@ -20,6 +20,8 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs
public static SystemDrawingReferenceEncoder Png { get; } = new SystemDrawingReferenceEncoder(ImageFormat.Png);
public static SystemDrawingReferenceEncoder Bmp { get; } = new SystemDrawingReferenceEncoder(ImageFormat.Bmp);
public void Encode<TPixel>(Image<TPixel> image, Stream stream)
where TPixel : struct, IPixel<TPixel>
{

44
tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Formats.cs

@ -14,9 +14,9 @@ namespace SixLabors.ImageSharp.Tests
{
public static partial class TestEnvironment
{
private static Lazy<Configuration> configuration = new Lazy<Configuration>(CreateDefaultConfiguration);
private static readonly Lazy<Configuration> ConfigurationLazy = new Lazy<Configuration>(CreateDefaultConfiguration);
internal static Configuration Configuration => configuration.Value;
internal static Configuration Configuration => ConfigurationLazy.Value;
internal static IImageDecoder GetReferenceDecoder(string filePath)
{
@ -52,36 +52,28 @@ namespace SixLabors.ImageSharp.Tests
private static Configuration CreateDefaultConfiguration()
{
var configuration = new Configuration(
new PngConfigurationModule(),
var cfg = new Configuration(
new JpegConfigurationModule(),
new GifConfigurationModule()
);
if (!IsLinux)
{
// TODO: System.Drawing on Windows can decode 48bit and 64bit pngs but
// it doesn't preserve the accuracy we require for comparison.
// This makes CompareToOriginal method non-useful.
configuration.ConfigureCodecs(
ImageFormats.Png,
SystemDrawingReferenceDecoder.Instance,
SystemDrawingReferenceEncoder.Png,
new PngImageFormatDetector());
// Magick codecs should work on all platforms
IImageEncoder pngEncoder = IsWindows ? (IImageEncoder)SystemDrawingReferenceEncoder.Png : new PngEncoder();
IImageEncoder bmpEncoder = IsWindows ? (IImageEncoder)SystemDrawingReferenceEncoder.Bmp : new BmpEncoder();
configuration.ConfigureCodecs(
ImageFormats.Bmp,
SystemDrawingReferenceDecoder.Instance,
SystemDrawingReferenceEncoder.Png,
new PngImageFormatDetector());
}
else
{
configuration.Configure(new PngConfigurationModule());
configuration.Configure(new BmpConfigurationModule());
}
cfg.ConfigureCodecs(
ImageFormats.Png,
MagickReferenceDecoder.Instance,
pngEncoder,
new PngImageFormatDetector());
return configuration;
cfg.ConfigureCodecs(
ImageFormats.Bmp,
SystemDrawingReferenceDecoder.Instance,
bmpEncoder,
new BmpImageFormatDetector());
return cfg;
}
}
}

11
tests/ImageSharp.Tests/TestUtilities/TestEnvironment.cs

@ -21,9 +21,9 @@ namespace SixLabors.ImageSharp.Tests
private const string ToolsDirectoryRelativePath = @"tests\Images\External\tools";
private static Lazy<string> solutionDirectoryFullPath = new Lazy<string>(GetSolutionDirectoryFullPathImpl);
private static readonly Lazy<string> SolutionDirectoryFullPathLazy = new Lazy<string>(GetSolutionDirectoryFullPathImpl);
private static Lazy<bool> runsOnCi = new Lazy<bool>(
private static readonly Lazy<bool> RunsOnCiLazy = new Lazy<bool>(
() =>
{
bool isCi;
@ -41,9 +41,9 @@ namespace SixLabors.ImageSharp.Tests
/// <summary>
/// Gets a value indicating whether test execution runs on CI.
/// </summary>
internal static bool RunsOnCI => runsOnCi.Value;
internal static bool RunsOnCI => RunsOnCiLazy.Value;
internal static string SolutionDirectoryFullPath => solutionDirectoryFullPath.Value;
internal static string SolutionDirectoryFullPath => SolutionDirectoryFullPathLazy.Value;
private static string GetSolutionDirectoryFullPathImpl()
{
@ -65,6 +65,7 @@ namespace SixLabors.ImageSharp.Tests
$"Unable to find ImageSharp solution directory from {assemblyLocation} because of {ex.GetType().Name}!",
ex);
}
if (directory == null)
{
throw new Exception($"Unable to find ImageSharp solution directory from {assemblyLocation}!");
@ -116,7 +117,7 @@ namespace SixLabors.ImageSharp.Tests
/// </returns>
internal static string CreateOutputDirectory(string path, params string[] pathParts)
{
path = Path.Combine(TestEnvironment.ActualOutputDirectoryFullPath, path);
path = Path.Combine(ActualOutputDirectoryFullPath, path);
if (pathParts != null && pathParts.Length > 0)
{

25
tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs

@ -499,16 +499,18 @@ namespace SixLabors.ImageSharp.Tests
public static Image<TPixel> CompareToOriginal<TPixel>(
this Image<TPixel> image,
ITestImageProvider provider)
ITestImageProvider provider,
IImageDecoder referenceDecoder = null)
where TPixel : struct, IPixel<TPixel>
{
return CompareToOriginal(image, provider, ImageComparer.Tolerant());
return CompareToOriginal(image, provider, ImageComparer.Tolerant(), referenceDecoder);
}
public static Image<TPixel> CompareToOriginal<TPixel>(
this Image<TPixel> image,
ITestImageProvider provider,
ImageComparer comparer)
ImageComparer comparer,
IImageDecoder referenceDecoder = null)
where TPixel : struct, IPixel<TPixel>
{
string path = TestImageProvider<TPixel>.GetFilePathOrNull(provider);
@ -519,15 +521,8 @@ namespace SixLabors.ImageSharp.Tests
var testFile = TestFile.Create(path);
IImageDecoder referenceDecoder = TestEnvironment.GetReferenceDecoder(path);
IImageFormat format = TestEnvironment.GetImageFormat(path);
IImageDecoder defaultDecoder = Configuration.Default.ImageFormatsManager.FindDecoder(format);
//if (referenceDecoder.GetType() == defaultDecoder.GetType())
//{
// throw new InvalidOperationException($"Can't use CompareToOriginal(): no actual reference decoder registered for {format.Name}");
//}
referenceDecoder = referenceDecoder ?? TestEnvironment.GetReferenceDecoder(path);
using (var original = Image.Load<TPixel>(testFile.Bytes, referenceDecoder))
{
comparer.VerifySimilarity(original, image);
@ -641,7 +636,8 @@ namespace SixLabors.ImageSharp.Tests
IImageEncoder encoder,
ImageComparer customComparer = null,
bool appendPixelTypeToFileName = true,
string referenceImageExtension = null)
string referenceImageExtension = null,
IImageDecoder referenceDecoder = null)
where TPixel : struct, IPixel<TPixel>
{
string actualOutputFile = provider.Utility.SaveTestOutputFile(
@ -650,7 +646,8 @@ namespace SixLabors.ImageSharp.Tests
encoder,
testOutputDetails,
appendPixelTypeToFileName);
IImageDecoder referenceDecoder = TestEnvironment.GetReferenceDecoder(actualOutputFile);
referenceDecoder = referenceDecoder ?? TestEnvironment.GetReferenceDecoder(actualOutputFile);
using (var actualImage = Image.Load<TPixel>(actualOutputFile, referenceDecoder))
{

89
tests/ImageSharp.Tests/TestUtilities/Tests/MagickReferenceCodecTests.cs

@ -0,0 +1,89 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using Xunit;
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Tests.TestUtilities.Tests
{
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
using SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs;
using Xunit.Abstractions;
public class MagickReferenceCodecTests
{
public MagickReferenceCodecTests(ITestOutputHelper output)
{
this.Output = output;
}
private ITestOutputHelper Output { get; }
public const PixelTypes PixelTypesToTest32 = PixelTypes.Rgba32 | PixelTypes.Bgra32 | PixelTypes.Rgb24;
public const PixelTypes PixelTypesToTest64 =
PixelTypes.Rgba32 | PixelTypes.Rgb24 | PixelTypes.Rgba64 | PixelTypes.Rgb48;
public const PixelTypes PixelTypesToTest48 =
PixelTypes.Rgba32 | PixelTypes.Rgba64 | PixelTypes.Rgb48;
[Theory]
[WithBlankImages(1, 1, PixelTypesToTest32, TestImages.Png.Splash)]
[WithBlankImages(1, 1, PixelTypesToTest32, TestImages.Png.Indexed)]
public void MagickDecode_8BitDepthImage_IsEquivalentTo_SystemDrawingResult<TPixel>(TestImageProvider<TPixel> dummyProvider, string testImage)
where TPixel : struct, IPixel<TPixel>
{
string path = TestFile.GetInputFileFullPath(testImage);
var magickDecoder = new MagickReferenceDecoder();
var sdDecoder = new SystemDrawingReferenceDecoder();
ImageComparer comparer = ImageComparer.Exact;
using (var mImage = Image.Load<TPixel>(path, magickDecoder))
using (var sdImage = Image.Load<TPixel>(path, sdDecoder))
{
ImageSimilarityReport<TPixel, TPixel> report = comparer.CompareImagesOrFrames(mImage, sdImage);
mImage.DebugSave(dummyProvider);
if (TestEnvironment.IsWindows)
{
Assert.True(report.IsEmpty);
}
}
}
[Theory]
[WithBlankImages(1, 1, PixelTypesToTest64, TestImages.Png.Rgba64Bpp)]
[WithBlankImages(1, 1, PixelTypesToTest48, TestImages.Png.Rgb48Bpp)]
[WithBlankImages(1, 1, PixelTypesToTest48, TestImages.Png.Rgb48BppInterlaced)]
[WithBlankImages(1, 1, PixelTypesToTest48, TestImages.Png.Rgb48BppTrans)]
public void MagickDecode_16BitDepthImage_IsApproximatelyEquivalentTo_SystemDrawingResult<TPixel>(TestImageProvider<TPixel> dummyProvider, string testImage)
where TPixel : struct, IPixel<TPixel>
{
string path = TestFile.GetInputFileFullPath(testImage);
var magickDecoder = new MagickReferenceDecoder();
var sdDecoder = new SystemDrawingReferenceDecoder();
// 1020 == 4 * 255 (Equivalent to manhattan distance of 1+1+1+1=4 in Rgba32 space)
var comparer = ImageComparer.TolerantPercentage(1, 1020);
using (var mImage = Image.Load<TPixel>(path, magickDecoder))
using (var sdImage = Image.Load<TPixel>(path, sdDecoder))
{
ImageSimilarityReport<TPixel, TPixel> report = comparer.CompareImagesOrFrames(mImage, sdImage);
mImage.DebugSave(dummyProvider);
if (TestEnvironment.IsWindows)
{
Assert.True(report.IsEmpty);
}
}
}
}
}

96
tests/ImageSharp.Tests/TestUtilities/Tests/ReferenceDecoderBenchmarks.cs

@ -0,0 +1,96 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System.Collections.Generic;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs;
using Xunit;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests.TestUtilities.Tests
{
public class ReferenceDecoderBenchmarks
{
private ITestOutputHelper Output { get; }
public const string SkipBenchmarks =
#if false
"Benchmark, enable manually!";
#else
null;
#endif
public const int DefaultExecutionCount = 50;
public static readonly string[] PngBenchmarkFiles =
{
TestImages.Png.CalliphoraPartial,
TestImages.Png.Kaboom,
TestImages.Png.Bike,
TestImages.Png.Splash,
TestImages.Png.SplashInterlaced
};
public static readonly string[] BmpBenchmarkFiles =
{
TestImages.Bmp.NegHeight,
TestImages.Bmp.Car,
TestImages.Bmp.V5Header
};
public ReferenceDecoderBenchmarks(ITestOutputHelper output)
{
this.Output = output;
}
[Theory(Skip = SkipBenchmarks)]
[WithFile(TestImages.Png.Kaboom, PixelTypes.Rgba32)]
public void BenchmarkMagickPngDecoder<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
this.BenckmarkDecoderImpl(PngBenchmarkFiles, new MagickReferenceDecoder(), $@"Magick Decode Png");
}
[Theory(Skip = SkipBenchmarks)]
[WithFile(TestImages.Png.Kaboom, PixelTypes.Rgba32)]
public void BenchmarkSystemDrawingPngDecoder<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
this.BenckmarkDecoderImpl(PngBenchmarkFiles, new SystemDrawingReferenceDecoder(), $@"System.Drawing Decode Png");
}
[Theory(Skip = SkipBenchmarks)]
[WithFile(TestImages.Png.Kaboom, PixelTypes.Rgba32)]
public void BenchmarkMagickBmpDecoder<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
this.BenckmarkDecoderImpl(BmpBenchmarkFiles, new MagickReferenceDecoder(), $@"Magick Decode Bmp");
}
[Theory(Skip = SkipBenchmarks)]
[WithFile(TestImages.Png.Kaboom, PixelTypes.Rgba32)]
public void BenchmarkSystemDrawingBmpDecoder<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : struct, IPixel<TPixel>
{
this.BenckmarkDecoderImpl(BmpBenchmarkFiles, new SystemDrawingReferenceDecoder(), $@"System.Drawing Decode Bmp");
}
private void BenckmarkDecoderImpl(IEnumerable<string> testFiles, IImageDecoder decoder, string info, int times = DefaultExecutionCount)
{
var measure = new MeasureFixture(this.Output);
measure.Measure(times,
() =>
{
foreach (string testFile in testFiles)
{
Image<Rgba32> image = TestFile.Create(testFile).CreateImage(decoder);
image.Dispose();
}
},
info);
}
}
}

10
tests/ImageSharp.Tests/TestUtilities/Tests/ReferenceCodecTests.cs → tests/ImageSharp.Tests/TestUtilities/Tests/SystemDrawingReferenceCodecTests.cs

@ -1,4 +1,6 @@
using System.IO;
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
@ -8,13 +10,13 @@ using SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs;
using Xunit;
using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests
namespace SixLabors.ImageSharp.Tests.TestUtilities.Tests
{
public class ReferenceCodecTests
public class SystemDrawingReferenceCodecTests
{
private ITestOutputHelper Output { get; }
public ReferenceCodecTests(ITestOutputHelper output)
public SystemDrawingReferenceCodecTests(ITestOutputHelper output)
{
this.Output = output;
}

7
tests/ImageSharp.Tests/TestUtilities/Tests/TestEnvironmentTests.cs

@ -18,7 +18,6 @@ using Xunit.Abstractions;
namespace SixLabors.ImageSharp.Tests
{
public class TestEnvironmentTests
{
public TestEnvironmentTests(ITestOutputHelper output)
@ -99,7 +98,7 @@ namespace SixLabors.ImageSharp.Tests
}
[Theory]
[InlineData("lol/foo.png", typeof(SystemDrawingReferenceDecoder))]
[InlineData("lol/foo.png", typeof(MagickReferenceDecoder))]
[InlineData("lol/Rofl.bmp", typeof(SystemDrawingReferenceDecoder))]
[InlineData("lol/Baz.JPG", typeof(JpegDecoder))]
[InlineData("lol/Baz.gif", typeof(GifDecoder))]
@ -125,8 +124,8 @@ namespace SixLabors.ImageSharp.Tests
}
[Theory]
[InlineData("lol/foo.png", typeof(PngDecoder))]
[InlineData("lol/Rofl.bmp", typeof(BmpDecoder))]
[InlineData("lol/foo.png", typeof(MagickReferenceDecoder))]
[InlineData("lol/Rofl.bmp", typeof(SystemDrawingReferenceDecoder))]
[InlineData("lol/Baz.JPG", typeof(JpegDecoder))]
[InlineData("lol/Baz.gif", typeof(GifDecoder))]
public void GetReferenceDecoder_ReturnsCorrectDecoders_Linux(string fileName, Type expectedDecoderType)

6
tests/ImageSharp.Tests/TestUtilities/Tests/TestImageProviderTests.cs

@ -241,7 +241,11 @@ namespace SixLabors.ImageSharp.Tests
}
public static string[] AllBmpFiles => TestImages.Bmp.All;
public static string[] AllBmpFiles =
{
TestImages.Bmp.F,
TestImages.Bmp.Bit8
};
[Theory]
[WithFileCollection(nameof(AllBmpFiles), PixelTypes.Rgba32 | PixelTypes.Argb32)]

Loading…
Cancel
Save