Browse Source

Removes usage of linq in several critical paths (#918)

* Remove linq usage from jpeg + formatting

* png

* ICC + formattiing

* Resize

* Fix base class comparison.
pull/923/head
James Jackson-South 7 years ago
committed by GitHub
parent
commit
07ec651190
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      src/ImageSharp/Formats/Jpeg/Components/Decoder/ProfileResolver.cs
  2. 3
      src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
  3. 36
      src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs
  4. 5
      src/ImageSharp/Formats/Png/PngEncoderCore.cs
  5. 3
      src/ImageSharp/MetaData/Profiles/ICC/Curves/IccOneDimensionalCurve.cs
  6. 8
      src/ImageSharp/MetaData/Profiles/ICC/Curves/IccResponseCurve.cs
  7. 48
      src/ImageSharp/MetaData/Profiles/ICC/DataWriter/IccDataWriter.TagDataEntry.cs
  8. 1
      src/ImageSharp/MetaData/Profiles/ICC/IccWriter.cs
  9. 12
      src/ImageSharp/MetaData/Profiles/ICC/MultiProcessElements/IccCurveSetProcessElement.cs
  10. 12
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccChromaticityTagDataEntry.cs
  11. 18
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccColorantTableTagDataEntry.cs
  12. 19
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLut16TagDataEntry.cs
  13. 14
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLut8TagDataEntry.cs
  14. 44
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLutAToBTagDataEntry.cs
  15. 37
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccLutBToATagDataEntry.cs
  16. 3
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccMultiLocalizedUnicodeTagDataEntry.cs
  17. 12
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccMultiProcessElementsTagDataEntry.cs
  18. 2
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccNamedColor2TagDataEntry.cs
  19. 15
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccProfileSequenceDescTagDataEntry.cs
  20. 12
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccResponseCurveSet16TagDataEntry.cs
  21. 16
      src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccUInt64ArrayTagDataEntry.cs
  22. 5
      src/ImageSharp/MetaData/Profiles/ICC/Various/IccClut.cs
  23. 20
      src/ImageSharp/MetaData/Profiles/ICC/Various/IccNamedColor.cs
  24. 18
      src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileDescription.cs
  25. 10
      src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileSequenceIdentifier.cs
  26. 4
      src/ImageSharp/Processing/ResizeOptions.cs

8
src/ImageSharp/Formats/Jpeg/Components/Decoder/ProfileResolver.cs

@ -12,17 +12,17 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
internal static class ProfileResolver internal static class ProfileResolver
{ {
/// <summary> /// <summary>
/// Describes the EXIF specific markers. /// Describes the JFIF specific markers.
/// </summary> /// </summary>
public static readonly byte[] JFifMarker = Encoding.ASCII.GetBytes("JFIF\0"); public static readonly byte[] JFifMarker = Encoding.ASCII.GetBytes("JFIF\0");
/// <summary> /// <summary>
/// Describes the EXIF specific markers. /// Describes the ICC specific markers.
/// </summary> /// </summary>
public static readonly byte[] IccMarker = Encoding.ASCII.GetBytes("ICC_PROFILE\0"); public static readonly byte[] IccMarker = Encoding.ASCII.GetBytes("ICC_PROFILE\0");
/// <summary> /// <summary>
/// Describes the ICC specific markers. /// Describes the EXIF specific markers.
/// </summary> /// </summary>
public static readonly byte[] ExifMarker = Encoding.ASCII.GetBytes("Exif\0\0"); public static readonly byte[] ExifMarker = Encoding.ASCII.GetBytes("Exif\0\0");
@ -36,7 +36,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
/// </summary> /// </summary>
/// <param name="bytesToCheck">The bytes to check.</param> /// <param name="bytesToCheck">The bytes to check.</param>
/// <param name="profileIdentifier">The profile identifier.</param> /// <param name="profileIdentifier">The profile identifier.</param>
/// <returns>The <see cref="bool"/></returns> /// <returns>The <see cref="bool"/>.</returns>
public static bool IsProfile(ReadOnlySpan<byte> bytesToCheck, ReadOnlySpan<byte> profileIdentifier) public static bool IsProfile(ReadOnlySpan<byte> bytesToCheck, ReadOnlySpan<byte> profileIdentifier)
{ {
return bytesToCheck.Length >= profileIdentifier.Length return bytesToCheck.Length >= profileIdentifier.Length

3
src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs

@ -4,7 +4,6 @@
using System; using System;
using System.Buffers.Binary; using System.Buffers.Binary;
using System.IO; using System.IO;
using System.Linq;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Common.Helpers; using SixLabors.ImageSharp.Common.Helpers;
@ -726,7 +725,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
this.InputStream.Read(this.temp, 0, length); this.InputStream.Read(this.temp, 0, length);
// We only support 8-bit and 12-bit precision. // We only support 8-bit and 12-bit precision.
if (!this.supportedPrecisions.Contains(this.temp[0])) if (Array.IndexOf(this.supportedPrecisions, this.temp[0]) == -1)
{ {
JpegThrowHelper.ThrowImageFormatException("Only 8-Bit and 12-Bit precision supported."); JpegThrowHelper.ThrowImageFormatException("Only 8-Bit and 12-Bit precision supported.");
} }

36
src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs

@ -4,7 +4,6 @@
using System; using System;
using System.Buffers.Binary; using System.Buffers.Binary;
using System.IO; using System.IO;
using System.Linq;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using SixLabors.ImageSharp.Common.Helpers; using SixLabors.ImageSharp.Common.Helpers;
using SixLabors.ImageSharp.Formats.Jpeg.Components; using SixLabors.ImageSharp.Formats.Jpeg.Components;
@ -197,7 +196,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
Guard.NotNull(image, nameof(image)); Guard.NotNull(image, nameof(image));
Guard.NotNull(stream, nameof(stream)); Guard.NotNull(stream, nameof(stream));
ushort max = JpegConstants.MaxLength; const ushort max = JpegConstants.MaxLength;
if (image.Width >= max || image.Height >= max) if (image.Width >= max || image.Height >= max)
{ {
throw new ImageFormatException($"Image is too large to encode at {image.Width}x{image.Height}."); throw new ImageFormatException($"Image is too large to encode at {image.Width}x{image.Height}.");
@ -226,7 +225,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
InitQuantizationTable(1, scale, ref this.chrominanceQuantTable); InitQuantizationTable(1, scale, ref this.chrominanceQuantTable);
// Compute number of components based on input image type. // Compute number of components based on input image type.
int componentCount = 3; const int componentCount = 3;
// Write the Start Of Image marker. // Write the Start Of Image marker.
this.WriteApplicationHeader(metadata); this.WriteApplicationHeader(metadata);
@ -278,7 +277,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
private static void InitQuantizationTable(int i, int scale, ref Block8x8F quant) private static void InitQuantizationTable(int i, int scale, ref Block8x8F quant)
{ {
DebugGuard.MustBeBetweenOrEqualTo(i, 0, 1, nameof(i)); DebugGuard.MustBeBetweenOrEqualTo(i, 0, 1, nameof(i));
var unscaledQuant = (i == 0) ? UnscaledQuant_Luminance : UnscaledQuant_Chrominance; ReadOnlySpan<byte> unscaledQuant = (i == 0) ? UnscaledQuant_Luminance : UnscaledQuant_Chrominance;
for (int j = 0; j < Block8x8F.Size; j++) for (int j = 0; j < Block8x8F.Size; j++)
{ {
@ -653,8 +652,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
return; return;
} }
const int MaxBytesApp1 = 65533; const int MaxBytesApp1 = 65533; // 64k - 2 padding bytes
const int MaxBytesWithExifId = 65527; const int MaxBytesWithExifId = 65527; // Max - 6 bytes for EXIF header.
byte[] data = exifProfile?.ToByteArray(); byte[] data = exifProfile?.ToByteArray();
@ -663,31 +662,30 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
return; return;
} }
data = ProfileResolver.ExifMarker.Concat(data).ToArray(); // We can write up to a maximum of 64 data to the initial marker so calculate boundaries.
int exifMarkerLength = ProfileResolver.ExifMarker.Length;
int remaining = data.Length; int remaining = exifMarkerLength + data.Length;
int bytesToWrite = remaining > MaxBytesApp1 ? MaxBytesApp1 : remaining; int bytesToWrite = remaining > MaxBytesApp1 ? MaxBytesApp1 : remaining;
int app1Length = bytesToWrite + 2; int app1Length = bytesToWrite + 2;
// Write the app marker, EXIF marker, and data
this.WriteApp1Header(app1Length); this.WriteApp1Header(app1Length);
this.outputStream.Write(ProfileResolver.ExifMarker);
// write the exif data this.outputStream.Write(data, 0, bytesToWrite - exifMarkerLength);
this.outputStream.Write(data, 0, bytesToWrite);
remaining -= bytesToWrite; remaining -= bytesToWrite;
// if the exif data exceeds 64K, write it in multiple APP1 Markers // If the exif data exceeds 64K, write it in multiple APP1 Markers
for (int idx = MaxBytesApp1; idx < data.Length; idx += MaxBytesWithExifId) for (int idx = MaxBytesWithExifId; idx < data.Length; idx += MaxBytesWithExifId)
{ {
bytesToWrite = remaining > MaxBytesWithExifId ? MaxBytesWithExifId : remaining; bytesToWrite = remaining > MaxBytesWithExifId ? MaxBytesWithExifId : remaining;
app1Length = bytesToWrite + 2 + 6; app1Length = bytesToWrite + 2 + exifMarkerLength;
this.WriteApp1Header(app1Length); this.WriteApp1Header(app1Length);
// write Exif00 marker // Write Exif00 marker
ProfileResolver.ExifMarker.AsSpan().CopyTo(this.buffer.AsSpan()); this.outputStream.Write(ProfileResolver.ExifMarker);
this.outputStream.Write(this.buffer, 0, 6);
// write the exif data // Write the exif data
this.outputStream.Write(data, idx, bytesToWrite); this.outputStream.Write(data, idx, bytesToWrite);
remaining -= bytesToWrite; remaining -= bytesToWrite;

5
src/ImageSharp/Formats/Png/PngEncoderCore.cs

@ -6,7 +6,6 @@ using System.Buffers;
using System.Buffers.Binary; using System.Buffers.Binary;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Advanced;
@ -231,7 +230,7 @@ namespace SixLabors.ImageSharp.Formats.Png
if (this.pngColorType == PngColorType.Palette) if (this.pngColorType == PngColorType.Palette)
{ {
byte bits = (byte)this.pngBitDepth; byte bits = (byte)this.pngBitDepth;
if (!ColorTypes[this.pngColorType.Value].Contains(bits)) if (Array.IndexOf(ColorTypes[this.pngColorType.Value], bits) == -1)
{ {
throw new NotSupportedException("Bit depth is not supported or not valid."); throw new NotSupportedException("Bit depth is not supported or not valid.");
} }
@ -268,7 +267,7 @@ namespace SixLabors.ImageSharp.Formats.Png
else else
{ {
this.bitDepth = (byte)this.pngBitDepth; this.bitDepth = (byte)this.pngBitDepth;
if (!ColorTypes[this.pngColorType.Value].Contains(this.bitDepth)) if (Array.IndexOf(ColorTypes[this.pngColorType.Value], this.bitDepth) == -1)
{ {
throw new NotSupportedException("Bit depth is not supported or not valid."); throw new NotSupportedException("Bit depth is not supported or not valid.");
} }

3
src/ImageSharp/MetaData/Profiles/ICC/Curves/IccOneDimensionalCurve.cs

@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
using System; using System;
using System.Linq;
namespace SixLabors.ImageSharp.Metadata.Profiles.Icc namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
{ {
@ -52,7 +51,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
} }
return this.BreakPoints.AsSpan().SequenceEqual(other.BreakPoints) return this.BreakPoints.AsSpan().SequenceEqual(other.BreakPoints)
&& this.Segments.SequenceEqual(other.Segments); && this.Segments.AsSpan().SequenceEqual(other.Segments);
} }
} }
} }

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

@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
using System; using System;
using System.Linq;
using System.Numerics; using System.Numerics;
namespace SixLabors.ImageSharp.Metadata.Profiles.Icc namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
@ -65,10 +64,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
} }
/// <inheritdoc /> /// <inheritdoc />
public override bool Equals(object obj) public override bool Equals(object obj) => obj is IccResponseCurve other && this.Equals(other);
{
return obj is IccResponseCurve other && this.Equals(other);
}
/// <inheritdoc /> /// <inheritdoc />
public override int GetHashCode() public override int GetHashCode()
@ -88,7 +84,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
for (int i = 0; i < this.ResponseArrays.Length; i++) for (int i = 0; i < this.ResponseArrays.Length; i++)
{ {
if (!this.ResponseArrays[i].SequenceEqual(other.ResponseArrays[i])) if (!this.ResponseArrays[i].AsSpan().SequenceEqual(other.ResponseArrays[i]))
{ {
return false; return false;
} }

48
src/ImageSharp/MetaData/Profiles/ICC/DataWriter/IccDataWriter.TagDataEntry.cs

@ -163,10 +163,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
/// </summary> /// </summary>
/// <param name="value">The entry to write</param> /// <param name="value">The entry to write</param>
/// <returns>The number of bytes written</returns> /// <returns>The number of bytes written</returns>
public int WriteUnknownTagDataEntry(IccUnknownTagDataEntry value) public int WriteUnknownTagDataEntry(IccUnknownTagDataEntry value) => this.WriteArray(value.Data);
{
return this.WriteArray(value.Data);
}
/// <summary> /// <summary>
/// Writes a <see cref="IccChromaticityTagDataEntry"/> /// Writes a <see cref="IccChromaticityTagDataEntry"/>
@ -269,10 +266,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
/// </summary> /// </summary>
/// <param name="value">The entry to write</param> /// <param name="value">The entry to write</param>
/// <returns>The number of bytes written</returns> /// <returns>The number of bytes written</returns>
public int WriteDateTimeTagDataEntry(IccDateTimeTagDataEntry value) public int WriteDateTimeTagDataEntry(IccDateTimeTagDataEntry value) => this.WriteDateTime(value.Value);
{
return this.WriteDateTime(value.Value);
}
/// <summary> /// <summary>
/// Writes a <see cref="IccLut16TagDataEntry"/> /// Writes a <see cref="IccLut16TagDataEntry"/>
@ -563,6 +557,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
long tpos = this.dataStream.Position; long tpos = this.dataStream.Position;
this.dataStream.Position += cultureCount * 12; this.dataStream.Position += cultureCount * 12;
// TODO: Investigate cost of Linq GroupBy
IGrouping<string, IccLocalizedString>[] texts = value.Texts.GroupBy(t => t.Text).ToArray(); IGrouping<string, IccLocalizedString>[] texts = value.Texts.GroupBy(t => t.Text).ToArray();
uint[] offset = new uint[texts.Length]; uint[] offset = new uint[texts.Length];
@ -625,7 +620,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
long tpos = this.dataStream.Position; long tpos = this.dataStream.Position;
this.dataStream.Position += value.Data.Length * 8; this.dataStream.Position += value.Data.Length * 8;
IccPositionNumber[] posTable = new IccPositionNumber[value.Data.Length]; var posTable = new IccPositionNumber[value.Data.Length];
for (int i = 0; i < value.Data.Length; i++) for (int i = 0; i < value.Data.Length; i++)
{ {
uint offset = (uint)(this.dataStream.Position - start); uint offset = (uint)(this.dataStream.Position - start);
@ -673,10 +668,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
/// </summary> /// </summary>
/// <param name="value">The entry to write</param> /// <param name="value">The entry to write</param>
/// <returns>The number of bytes written</returns> /// <returns>The number of bytes written</returns>
public int WriteParametricCurveTagDataEntry(IccParametricCurveTagDataEntry value) public int WriteParametricCurveTagDataEntry(IccParametricCurveTagDataEntry value) => this.WriteParametricCurve(value.Curve);
{
return this.WriteParametricCurve(value.Curve);
}
/// <summary> /// <summary>
/// Writes a <see cref="IccProfileSequenceDescTagDataEntry"/> /// Writes a <see cref="IccProfileSequenceDescTagDataEntry"/>
@ -793,20 +785,14 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
/// </summary> /// </summary>
/// <param name="value">The entry to write</param> /// <param name="value">The entry to write</param>
/// <returns>The number of bytes written</returns> /// <returns>The number of bytes written</returns>
public int WriteSignatureTagDataEntry(IccSignatureTagDataEntry value) public int WriteSignatureTagDataEntry(IccSignatureTagDataEntry value) => this.WriteAsciiString(value.SignatureData, 4, false);
{
return this.WriteAsciiString(value.SignatureData, 4, false);
}
/// <summary> /// <summary>
/// Writes a <see cref="IccTextTagDataEntry"/> /// Writes a <see cref="IccTextTagDataEntry"/>
/// </summary> /// </summary>
/// <param name="value">The entry to write</param> /// <param name="value">The entry to write</param>
/// <returns>The number of bytes written</returns> /// <returns>The number of bytes written</returns>
public int WriteTextTagDataEntry(IccTextTagDataEntry value) public int WriteTextTagDataEntry(IccTextTagDataEntry value) => this.WriteAsciiString(value.Text);
{
return this.WriteAsciiString(value.Text);
}
/// <summary> /// <summary>
/// Writes a <see cref="IccUFix16ArrayTagDataEntry"/> /// Writes a <see cref="IccUFix16ArrayTagDataEntry"/>
@ -829,40 +815,28 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
/// </summary> /// </summary>
/// <param name="value">The entry to write</param> /// <param name="value">The entry to write</param>
/// <returns>The number of bytes written</returns> /// <returns>The number of bytes written</returns>
public int WriteUInt16ArrayTagDataEntry(IccUInt16ArrayTagDataEntry value) public int WriteUInt16ArrayTagDataEntry(IccUInt16ArrayTagDataEntry value) => this.WriteArray(value.Data);
{
return this.WriteArray(value.Data);
}
/// <summary> /// <summary>
/// Writes a <see cref="IccUInt32ArrayTagDataEntry"/> /// Writes a <see cref="IccUInt32ArrayTagDataEntry"/>
/// </summary> /// </summary>
/// <param name="value">The entry to write</param> /// <param name="value">The entry to write</param>
/// <returns>The number of bytes written</returns> /// <returns>The number of bytes written</returns>
public int WriteUInt32ArrayTagDataEntry(IccUInt32ArrayTagDataEntry value) public int WriteUInt32ArrayTagDataEntry(IccUInt32ArrayTagDataEntry value) => this.WriteArray(value.Data);
{
return this.WriteArray(value.Data);
}
/// <summary> /// <summary>
/// Writes a <see cref="IccUInt64ArrayTagDataEntry"/> /// Writes a <see cref="IccUInt64ArrayTagDataEntry"/>
/// </summary> /// </summary>
/// <param name="value">The entry to write</param> /// <param name="value">The entry to write</param>
/// <returns>The number of bytes written</returns> /// <returns>The number of bytes written</returns>
public int WriteUInt64ArrayTagDataEntry(IccUInt64ArrayTagDataEntry value) public int WriteUInt64ArrayTagDataEntry(IccUInt64ArrayTagDataEntry value) => this.WriteArray(value.Data);
{
return this.WriteArray(value.Data);
}
/// <summary> /// <summary>
/// Writes a <see cref="IccUInt8ArrayTagDataEntry"/> /// Writes a <see cref="IccUInt8ArrayTagDataEntry"/>
/// </summary> /// </summary>
/// <param name="value">The entry to write</param> /// <param name="value">The entry to write</param>
/// <returns>The number of bytes written</returns> /// <returns>The number of bytes written</returns>
public int WriteUInt8ArrayTagDataEntry(IccUInt8ArrayTagDataEntry value) public int WriteUInt8ArrayTagDataEntry(IccUInt8ArrayTagDataEntry value) => this.WriteArray(value.Data);
{
return this.WriteArray(value.Data);
}
/// <summary> /// <summary>
/// Writes a <see cref="IccViewingConditionsTagDataEntry"/> /// Writes a <see cref="IccViewingConditionsTagDataEntry"/>

1
src/ImageSharp/MetaData/Profiles/ICC/IccWriter.cs

@ -70,6 +70,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
private IccTagTableEntry[] WriteTagData(IccDataWriter writer, IccTagDataEntry[] entries) private IccTagTableEntry[] WriteTagData(IccDataWriter writer, IccTagDataEntry[] entries)
{ {
// TODO: Investigate cost of Linq GroupBy
IEnumerable<IGrouping<IccTagDataEntry, IccTagDataEntry>> grouped = entries.GroupBy(t => t); IEnumerable<IGrouping<IccTagDataEntry, IccTagDataEntry>> grouped = entries.GroupBy(t => t);
// (Header size) + (entry count) + (nr of entries) * (size of table entry) // (Header size) + (entry count) + (nr of entries) * (size of table entry)

12
src/ImageSharp/MetaData/Profiles/ICC/MultiProcessElements/IccCurveSetProcessElement.cs

@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
using System; using System;
using System.Linq;
namespace SixLabors.ImageSharp.Metadata.Profiles.Icc namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
{ {
@ -17,9 +16,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
/// <param name="curves">An array with one dimensional curves</param> /// <param name="curves">An array with one dimensional curves</param>
public IccCurveSetProcessElement(IccOneDimensionalCurve[] curves) public IccCurveSetProcessElement(IccOneDimensionalCurve[] curves)
: base(IccMultiProcessElementSignature.CurveSet, curves?.Length ?? 1, curves?.Length ?? 1) : base(IccMultiProcessElementSignature.CurveSet, curves?.Length ?? 1, curves?.Length ?? 1)
{ => this.Curves = curves ?? throw new ArgumentNullException(nameof(curves));
this.Curves = curves ?? throw new ArgumentNullException(nameof(curves));
}
/// <summary> /// <summary>
/// Gets an array of one dimensional curves /// Gets an array of one dimensional curves
@ -31,16 +28,13 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
{ {
if (base.Equals(other) && other is IccCurveSetProcessElement element) if (base.Equals(other) && other is IccCurveSetProcessElement element)
{ {
return this.Curves.SequenceEqual(element.Curves); return this.Curves.AsSpan().SequenceEqual(element.Curves);
} }
return false; return false;
} }
/// <inheritdoc /> /// <inheritdoc />
public bool Equals(IccCurveSetProcessElement other) public bool Equals(IccCurveSetProcessElement other) => this.Equals((IccMultiProcessElement)other);
{
return this.Equals((IccMultiProcessElement)other);
}
} }
} }

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

@ -80,10 +80,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
public double[][] ChannelValues { get; } public double[][] ChannelValues { get; }
/// <inheritdoc/> /// <inheritdoc/>
public override bool Equals(IccTagDataEntry other) public override bool Equals(IccTagDataEntry other) => other is IccChromaticityTagDataEntry entry && this.Equals(entry);
{
return other is IccChromaticityTagDataEntry entry && this.Equals(entry);
}
/// <inheritdoc/> /// <inheritdoc/>
public bool Equals(IccChromaticityTagDataEntry other) public bool Equals(IccChromaticityTagDataEntry other)
@ -102,10 +99,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
} }
/// <inheritdoc/> /// <inheritdoc/>
public override bool Equals(object obj) public override bool Equals(object obj) => obj is IccChromaticityTagDataEntry other && this.Equals(other);
{
return obj is IccChromaticityTagDataEntry other && this.Equals(other);
}
/// <inheritdoc/> /// <inheritdoc/>
public override int GetHashCode() public override int GetHashCode()
@ -162,7 +156,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
for (int i = 0; i < this.ChannelValues.Length; i++) for (int i = 0; i < this.ChannelValues.Length; i++)
{ {
if (!this.ChannelValues[i].SequenceEqual(entry.ChannelValues[i])) if (!this.ChannelValues[i].AsSpan().SequenceEqual(entry.ChannelValues[i]))
{ {
return false; return false;
} }

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

@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
using System; using System;
using System.Linq;
namespace SixLabors.ImageSharp.Metadata.Profiles.Icc namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
{ {
@ -42,10 +41,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
public IccColorantTableEntry[] ColorantData { get; } public IccColorantTableEntry[] ColorantData { get; }
/// <inheritdoc/> /// <inheritdoc/>
public override bool Equals(IccTagDataEntry other) public override bool Equals(IccTagDataEntry other) => other is IccColorantTableTagDataEntry entry && this.Equals(entry);
{
return other is IccColorantTableTagDataEntry entry && this.Equals(entry);
}
/// <inheritdoc/> /// <inheritdoc/>
public bool Equals(IccColorantTableTagDataEntry other) public bool Equals(IccColorantTableTagDataEntry other)
@ -60,19 +56,13 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
return true; return true;
} }
return base.Equals(other) && this.ColorantData.SequenceEqual(other.ColorantData); return base.Equals(other) && this.ColorantData.AsSpan().SequenceEqual(other.ColorantData);
} }
/// <inheritdoc/> /// <inheritdoc/>
public override bool Equals(object obj) public override bool Equals(object obj) => obj is IccColorantTableTagDataEntry other && this.Equals(other);
{
return obj is IccColorantTableTagDataEntry other && this.Equals(other);
}
/// <inheritdoc/> /// <inheritdoc/>
public override int GetHashCode() public override int GetHashCode() => HashCode.Combine(this.Signature, this.ColorantData);
{
return HashCode.Combine(this.Signature, this.ColorantData);
}
} }
} }

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

@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
using System; using System;
using System.Linq;
using System.Numerics; using System.Numerics;
namespace SixLabors.ImageSharp.Metadata.Profiles.Icc namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
@ -71,7 +70,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
bool is3By3 = matrix.GetLength(0) == 3 && matrix.GetLength(1) == 3; bool is3By3 = matrix.GetLength(0) == 3 && matrix.GetLength(1) == 3;
Guard.IsTrue(is3By3, nameof(matrix), "Matrix must have a size of three by three"); Guard.IsTrue(is3By3, nameof(matrix), "Matrix must have a size of three by three");
this.Matrix = this.CreateMatrix(matrix); this.Matrix = CreateMatrix(matrix);
this.InputValues = inputValues ?? throw new ArgumentNullException(nameof(inputValues)); this.InputValues = inputValues ?? throw new ArgumentNullException(nameof(inputValues));
this.ClutValues = clutValues ?? throw new ArgumentNullException(nameof(clutValues)); this.ClutValues = clutValues ?? throw new ArgumentNullException(nameof(clutValues));
this.OutputValues = outputValues ?? throw new ArgumentNullException(nameof(outputValues)); this.OutputValues = outputValues ?? throw new ArgumentNullException(nameof(outputValues));
@ -111,10 +110,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
public IccLut[] OutputValues { get; } public IccLut[] OutputValues { get; }
/// <inheritdoc/> /// <inheritdoc/>
public override bool Equals(IccTagDataEntry other) public override bool Equals(IccTagDataEntry other) => other is IccLut16TagDataEntry entry && this.Equals(entry);
{
return other is IccLut16TagDataEntry entry && this.Equals(entry);
}
/// <inheritdoc/> /// <inheritdoc/>
public bool Equals(IccLut16TagDataEntry other) public bool Equals(IccLut16TagDataEntry other)
@ -131,16 +127,13 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
return base.Equals(other) return base.Equals(other)
&& this.Matrix.Equals(other.Matrix) && this.Matrix.Equals(other.Matrix)
&& this.InputValues.SequenceEqual(other.InputValues) && this.InputValues.AsSpan().SequenceEqual(other.InputValues)
&& this.ClutValues.Equals(other.ClutValues) && this.ClutValues.Equals(other.ClutValues)
&& this.OutputValues.SequenceEqual(other.OutputValues); && this.OutputValues.AsSpan().SequenceEqual(other.OutputValues);
} }
/// <inheritdoc/> /// <inheritdoc/>
public override bool Equals(object obj) public override bool Equals(object obj) => obj is IccLut16TagDataEntry other && this.Equals(other);
{
return obj is IccLut16TagDataEntry other && this.Equals(other);
}
/// <inheritdoc/> /// <inheritdoc/>
public override int GetHashCode() public override int GetHashCode()
@ -153,7 +146,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
this.OutputValues); this.OutputValues);
} }
private Matrix4x4 CreateMatrix(float[,] matrix) private static Matrix4x4 CreateMatrix(float[,] matrix)
{ {
return new Matrix4x4( return new Matrix4x4(
matrix[0, 0], matrix[0, 0],

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

@ -114,10 +114,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
public IccLut[] OutputValues { get; } public IccLut[] OutputValues { get; }
/// <inheritdoc/> /// <inheritdoc/>
public override bool Equals(IccTagDataEntry other) public override bool Equals(IccTagDataEntry other) => other is IccLut8TagDataEntry entry && this.Equals(entry);
{
return other is IccLut8TagDataEntry entry && this.Equals(entry);
}
/// <inheritdoc/> /// <inheritdoc/>
public bool Equals(IccLut8TagDataEntry other) public bool Equals(IccLut8TagDataEntry other)
@ -134,16 +131,13 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
return base.Equals(other) return base.Equals(other)
&& this.Matrix.Equals(other.Matrix) && this.Matrix.Equals(other.Matrix)
&& this.InputValues.SequenceEqual(other.InputValues) && this.InputValues.AsSpan().SequenceEqual(other.InputValues)
&& this.ClutValues.Equals(other.ClutValues) && this.ClutValues.Equals(other.ClutValues)
&& this.OutputValues.SequenceEqual(other.OutputValues); && this.OutputValues.AsSpan().SequenceEqual(other.OutputValues);
} }
/// <inheritdoc/> /// <inheritdoc/>
public override bool Equals(object obj) public override bool Equals(object obj) => obj is IccLut8TagDataEntry other && this.Equals(other);
{
return obj is IccLut8TagDataEntry other && this.Equals(other);
}
/// <inheritdoc/> /// <inheritdoc/>
public override int GetHashCode() public override int GetHashCode()

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

@ -5,6 +5,7 @@ using System;
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
// TODO: Review the use of base IccTagDataEntry comparison.
namespace SixLabors.ImageSharp.Metadata.Profiles.Icc namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
{ {
/// <summary> /// <summary>
@ -15,12 +16,12 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="IccLutAToBTagDataEntry"/> class. /// Initializes a new instance of the <see cref="IccLutAToBTagDataEntry"/> class.
/// </summary> /// </summary>
/// <param name="curveA">A Curve</param> /// <param name="curveB">B Curve</param>
/// <param name="clutValues">CLUT</param>
/// <param name="curveM">M Curve</param>
/// <param name="matrix3x3">Two dimensional conversion matrix (3x3)</param> /// <param name="matrix3x3">Two dimensional conversion matrix (3x3)</param>
/// <param name="matrix3x1">One dimensional conversion matrix (3x1)</param> /// <param name="matrix3x1">One dimensional conversion matrix (3x1)</param>
/// <param name="curveB">B Curve</param> /// <param name="curveM">M Curve</param>
/// <param name="clutValues">CLUT</param>
/// <param name="curveA">A Curve</param>
public IccLutAToBTagDataEntry( public IccLutAToBTagDataEntry(
IccTagDataEntry[] curveB, IccTagDataEntry[] curveB,
float[,] matrix3x3, float[,] matrix3x3,
@ -35,12 +36,12 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="IccLutAToBTagDataEntry"/> class. /// Initializes a new instance of the <see cref="IccLutAToBTagDataEntry"/> class.
/// </summary> /// </summary>
/// <param name="curveA">A Curve</param> /// <param name="curveB">B Curve</param>
/// <param name="clutValues">CLUT</param>
/// <param name="curveM">M Curve</param>
/// <param name="matrix3x3">Two dimensional conversion matrix (3x3)</param> /// <param name="matrix3x3">Two dimensional conversion matrix (3x3)</param>
/// <param name="matrix3x1">One dimensional conversion matrix (3x1)</param> /// <param name="matrix3x1">One dimensional conversion matrix (3x1)</param>
/// <param name="curveB">B Curve</param> /// <param name="curveM">M Curve</param>
/// <param name="clutValues">CLUT</param>
/// <param name="curveA">A Curve</param>
/// <param name="tagSignature">Tag Signature</param> /// <param name="tagSignature">Tag Signature</param>
public IccLutAToBTagDataEntry( public IccLutAToBTagDataEntry(
IccTagDataEntry[] curveB, IccTagDataEntry[] curveB,
@ -145,10 +146,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
public IccTagDataEntry[] CurveA { get; } public IccTagDataEntry[] CurveA { get; }
/// <inheritdoc/> /// <inheritdoc/>
public override bool Equals(IccTagDataEntry other) public override bool Equals(IccTagDataEntry other) => other is IccLutAToBTagDataEntry entry && this.Equals(entry);
{
return other is IccLutAToBTagDataEntry entry && this.Equals(entry);
}
/// <inheritdoc/> /// <inheritdoc/>
public bool Equals(IccLutAToBTagDataEntry other) public bool Equals(IccLutAToBTagDataEntry other)
@ -169,23 +167,18 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
&& this.Matrix3x3.Equals(other.Matrix3x3) && this.Matrix3x3.Equals(other.Matrix3x3)
&& this.Matrix3x1.Equals(other.Matrix3x1) && this.Matrix3x1.Equals(other.Matrix3x1)
&& this.ClutValues.Equals(other.ClutValues) && this.ClutValues.Equals(other.ClutValues)
&& this.EqualsCurve(this.CurveB, other.CurveB) && EqualsCurve(this.CurveB, other.CurveB)
&& this.EqualsCurve(this.CurveM, other.CurveM) && EqualsCurve(this.CurveM, other.CurveM)
&& this.EqualsCurve(this.CurveA, other.CurveA); && EqualsCurve(this.CurveA, other.CurveA);
} }
/// <inheritdoc/> /// <inheritdoc/>
public override bool Equals(object obj) public override bool Equals(object obj) => obj is IccLutAToBTagDataEntry other && this.Equals(other);
{
return obj is IccLutAToBTagDataEntry other && this.Equals(other);
}
/// <inheritdoc/> /// <inheritdoc/>
public override int GetHashCode() public override int GetHashCode()
{ {
#pragma warning disable SA1129 // Do not use default value type constructor HashCode hashCode = default;
var hashCode = new HashCode();
#pragma warning restore SA1129 // Do not use default value type constructor
hashCode.Add(this.Signature); hashCode.Add(this.Signature);
hashCode.Add(this.InputChannelCount); hashCode.Add(this.InputChannelCount);
@ -200,7 +193,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
return hashCode.ToHashCode(); return hashCode.ToHashCode();
} }
private bool EqualsCurve(IccTagDataEntry[] thisCurves, IccTagDataEntry[] entryCurves) private static bool EqualsCurve(IccTagDataEntry[] thisCurves, IccTagDataEntry[] entryCurves)
{ {
bool thisNull = thisCurves is null; bool thisNull = thisCurves is null;
bool entryNull = entryCurves is null; bool entryNull = entryCurves is null;
@ -243,10 +236,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
&& this.CurveA != null; && this.CurveA != null;
} }
private bool IsB() private bool IsB() => this.CurveB != null;
{
return this.CurveB != null;
}
private void VerifyCurve(IccTagDataEntry[] curves, string name) private void VerifyCurve(IccTagDataEntry[] curves, string name)
{ {

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

@ -5,6 +5,7 @@ using System;
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
// TODO: Review the use of base IccTagDataEntry comparison.
namespace SixLabors.ImageSharp.Metadata.Profiles.Icc namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
{ {
/// <summary> /// <summary>
@ -15,12 +16,12 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="IccLutBToATagDataEntry"/> class. /// Initializes a new instance of the <see cref="IccLutBToATagDataEntry"/> class.
/// </summary> /// </summary>
/// <param name="curveA">A Curve</param> /// <param name="curveB">B Curve</param>
/// <param name="clutValues">CLUT</param>
/// <param name="curveM">M Curve</param>
/// <param name="matrix3x3">Two dimensional conversion matrix (3x3)</param> /// <param name="matrix3x3">Two dimensional conversion matrix (3x3)</param>
/// <param name="matrix3x1">One dimensional conversion matrix (3x1)</param> /// <param name="matrix3x1">One dimensional conversion matrix (3x1)</param>
/// <param name="curveB">B Curve</param> /// <param name="curveM">M Curve</param>
/// <param name="clutValues">CLUT</param>
/// <param name="curveA">A Curve</param>
public IccLutBToATagDataEntry( public IccLutBToATagDataEntry(
IccTagDataEntry[] curveB, IccTagDataEntry[] curveB,
float[,] matrix3x3, float[,] matrix3x3,
@ -35,12 +36,12 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="IccLutBToATagDataEntry"/> class. /// Initializes a new instance of the <see cref="IccLutBToATagDataEntry"/> class.
/// </summary> /// </summary>
/// <param name="curveA">A Curve</param> /// <param name="curveB">B Curve</param>
/// <param name="clutValues">CLUT</param>
/// <param name="curveM">M Curve</param>
/// <param name="matrix3x3">Two dimensional conversion matrix (3x3)</param> /// <param name="matrix3x3">Two dimensional conversion matrix (3x3)</param>
/// <param name="matrix3x1">One dimensional conversion matrix (3x1)</param> /// <param name="matrix3x1">One dimensional conversion matrix (3x1)</param>
/// <param name="curveB">B Curve</param> /// <param name="curveM">M Curve</param>
/// <param name="clutValues">CLUT</param>
/// <param name="curveA">A Curve</param>
/// <param name="tagSignature">Tag Signature</param> /// <param name="tagSignature">Tag Signature</param>
public IccLutBToATagDataEntry( public IccLutBToATagDataEntry(
IccTagDataEntry[] curveB, IccTagDataEntry[] curveB,
@ -145,10 +146,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
public IccTagDataEntry[] CurveA { get; } public IccTagDataEntry[] CurveA { get; }
/// <inheritdoc/> /// <inheritdoc/>
public override bool Equals(IccTagDataEntry other) public override bool Equals(IccTagDataEntry other) => other is IccLutBToATagDataEntry entry && this.Equals(entry);
{
return other is IccLutBToATagDataEntry entry && this.Equals(entry);
}
/// <inheritdoc/> /// <inheritdoc/>
public bool Equals(IccLutBToATagDataEntry other) public bool Equals(IccLutBToATagDataEntry other)
@ -175,18 +173,12 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
} }
/// <inheritdoc/> /// <inheritdoc/>
public override bool Equals(object obj) public override bool Equals(object obj) => obj is IccLutBToATagDataEntry other && this.Equals(other);
{
return obj is IccLutBToATagDataEntry other && this.Equals(other);
}
/// <inheritdoc/> /// <inheritdoc/>
public override int GetHashCode() public override int GetHashCode()
{ {
#pragma warning disable SA1129 // Do not use default value type constructor HashCode hashCode = default;
var hashCode = new HashCode();
#pragma warning restore SA1129 // Do not use default value type constructor
hashCode.Add(this.Signature); hashCode.Add(this.Signature);
hashCode.Add(this.InputChannelCount); hashCode.Add(this.InputChannelCount);
hashCode.Add(this.OutputChannelCount); hashCode.Add(this.OutputChannelCount);
@ -243,10 +235,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
&& this.CurveA != null; && this.CurveA != null;
} }
private bool IsB() private bool IsB() => this.CurveB != null;
{
return this.CurveB != null;
}
private void VerifyCurve(IccTagDataEntry[] curves, string name) private void VerifyCurve(IccTagDataEntry[] curves, string name)
{ {

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

@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
using System; using System;
using System.Linq;
namespace SixLabors.ImageSharp.Metadata.Profiles.Icc namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
{ {
@ -56,7 +55,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
return true; return true;
} }
return base.Equals(other) && this.Texts.SequenceEqual(other.Texts); return base.Equals(other) && this.Texts.AsSpan().SequenceEqual(other.Texts);
} }
/// <inheritdoc/> /// <inheritdoc/>

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

@ -57,10 +57,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
/// <inheritdoc/> /// <inheritdoc/>
public override bool Equals(IccTagDataEntry other) public override bool Equals(IccTagDataEntry other)
{ => other is IccMultiProcessElementsTagDataEntry entry && this.Equals(entry);
var entry = other as IccMultiProcessElementsTagDataEntry;
return entry != null && this.Equals(entry);
}
/// <inheritdoc/> /// <inheritdoc/>
public bool Equals(IccMultiProcessElementsTagDataEntry other) public bool Equals(IccMultiProcessElementsTagDataEntry other)
@ -78,14 +75,11 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
return base.Equals(other) return base.Equals(other)
&& this.InputChannelCount == other.InputChannelCount && this.InputChannelCount == other.InputChannelCount
&& this.OutputChannelCount == other.OutputChannelCount && this.OutputChannelCount == other.OutputChannelCount
&& this.Data.SequenceEqual(other.Data); && this.Data.AsSpan().SequenceEqual(other.Data);
} }
/// <inheritdoc/> /// <inheritdoc/>
public override bool Equals(object obj) public override bool Equals(object obj) => obj is IccMultiProcessElementsTagDataEntry other && this.Equals(other);
{
return obj is IccMultiProcessElementsTagDataEntry other && this.Equals(other);
}
/// <inheritdoc/> /// <inheritdoc/>
public override int GetHashCode() public override int GetHashCode()

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

@ -143,7 +143,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
&& string.Equals(this.Prefix, other.Prefix) && string.Equals(this.Prefix, other.Prefix)
&& string.Equals(this.Suffix, other.Suffix) && string.Equals(this.Suffix, other.Suffix)
&& this.VendorFlags == other.VendorFlags && this.VendorFlags == other.VendorFlags
&& this.Colors.SequenceEqual(other.Colors); && this.Colors.AsSpan().SequenceEqual(other.Colors);
} }
/// <inheritdoc/> /// <inheritdoc/>

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

@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
using System; using System;
using System.Linq;
namespace SixLabors.ImageSharp.Metadata.Profiles.Icc namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
{ {
@ -29,9 +28,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
/// <param name="tagSignature">Tag Signature</param> /// <param name="tagSignature">Tag Signature</param>
public IccProfileSequenceDescTagDataEntry(IccProfileDescription[] descriptions, IccProfileTag tagSignature) public IccProfileSequenceDescTagDataEntry(IccProfileDescription[] descriptions, IccProfileTag tagSignature)
: base(IccTypeSignature.ProfileSequenceDesc, tagSignature) : base(IccTypeSignature.ProfileSequenceDesc, tagSignature)
{ => this.Descriptions = descriptions ?? throw new ArgumentNullException(nameof(descriptions));
this.Descriptions = descriptions ?? throw new ArgumentNullException(nameof(descriptions));
}
/// <summary> /// <summary>
/// Gets the profile descriptions /// Gets the profile descriptions
@ -40,9 +37,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
/// <inheritdoc/> /// <inheritdoc/>
public override bool Equals(IccTagDataEntry other) public override bool Equals(IccTagDataEntry other)
{ => other is IccProfileSequenceDescTagDataEntry entry && this.Equals(entry);
return other is IccProfileSequenceDescTagDataEntry entry && this.Equals(entry);
}
/// <inheritdoc /> /// <inheritdoc />
public bool Equals(IccProfileSequenceDescTagDataEntry other) public bool Equals(IccProfileSequenceDescTagDataEntry other)
@ -57,14 +52,12 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
return true; return true;
} }
return base.Equals(other) && this.Descriptions.SequenceEqual(other.Descriptions); return base.Equals(other) && this.Descriptions.AsSpan().SequenceEqual(other.Descriptions);
} }
/// <inheritdoc/> /// <inheritdoc/>
public override bool Equals(object obj) public override bool Equals(object obj)
{ => obj is IccProfileSequenceDescTagDataEntry other && this.Equals(other);
return obj is IccProfileSequenceDescTagDataEntry other && this.Equals(other);
}
/// <inheritdoc /> /// <inheritdoc />
public override int GetHashCode() => HashCode.Combine(this.Signature, this.Descriptions); public override int GetHashCode() => HashCode.Combine(this.Signature, this.Descriptions);

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

@ -51,10 +51,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
public IccResponseCurve[] Curves { get; } public IccResponseCurve[] Curves { get; }
/// <inheritdoc/> /// <inheritdoc/>
public override bool Equals(IccTagDataEntry other) public override bool Equals(IccTagDataEntry other) => other is IccResponseCurveSet16TagDataEntry entry && this.Equals(entry);
{
return other is IccResponseCurveSet16TagDataEntry entry && this.Equals(entry);
}
/// <inheritdoc /> /// <inheritdoc />
public bool Equals(IccResponseCurveSet16TagDataEntry other) public bool Equals(IccResponseCurveSet16TagDataEntry other)
@ -71,14 +68,11 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
return base.Equals(other) return base.Equals(other)
&& this.ChannelCount == other.ChannelCount && this.ChannelCount == other.ChannelCount
&& this.Curves.SequenceEqual(other.Curves); && this.Curves.AsSpan().SequenceEqual(other.Curves);
} }
/// <inheritdoc /> /// <inheritdoc />
public override bool Equals(object obj) public override bool Equals(object obj) => obj is IccResponseCurveSet16TagDataEntry other && this.Equals(other);
{
return obj is IccResponseCurveSet16TagDataEntry other && this.Equals(other);
}
/// <inheritdoc /> /// <inheritdoc />
public override int GetHashCode() public override int GetHashCode()

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

@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
using System; using System;
using System.Linq;
namespace SixLabors.ImageSharp.Metadata.Profiles.Icc namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
{ {
@ -26,10 +25,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
/// <param name="data">The array data</param> /// <param name="data">The array data</param>
/// <param name="tagSignature">Tag Signature</param> /// <param name="tagSignature">Tag Signature</param>
public IccUInt64ArrayTagDataEntry(ulong[] data, IccProfileTag tagSignature) public IccUInt64ArrayTagDataEntry(ulong[] data, IccProfileTag tagSignature)
: base(IccTypeSignature.UInt64Array, tagSignature) : base(IccTypeSignature.UInt64Array, tagSignature) => this.Data = data ?? throw new ArgumentNullException(nameof(data));
{
this.Data = data ?? throw new ArgumentNullException(nameof(data));
}
/// <summary> /// <summary>
/// Gets the array data /// Gets the array data
@ -37,10 +33,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
public ulong[] Data { get; } public ulong[] Data { get; }
/// <inheritdoc/> /// <inheritdoc/>
public override bool Equals(IccTagDataEntry other) public override bool Equals(IccTagDataEntry other) => other is IccUInt64ArrayTagDataEntry entry && this.Equals(entry);
{
return other is IccUInt64ArrayTagDataEntry entry && this.Equals(entry);
}
/// <inheritdoc/> /// <inheritdoc/>
public bool Equals(IccUInt64ArrayTagDataEntry other) public bool Equals(IccUInt64ArrayTagDataEntry other)
@ -59,10 +52,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
} }
/// <inheritdoc/> /// <inheritdoc/>
public override bool Equals(object obj) public override bool Equals(object obj) => obj is IccUInt64ArrayTagDataEntry other && this.Equals(other);
{
return obj is IccUInt64ArrayTagDataEntry other && this.Equals(other);
}
/// <inheritdoc/> /// <inheritdoc/>
public override int GetHashCode() => HashCode.Combine(this.Signature, this.Data); public override int GetHashCode() => HashCode.Combine(this.Signature, this.Data);

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

@ -134,10 +134,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
} }
/// <inheritdoc/> /// <inheritdoc/>
public override bool Equals(object obj) public override bool Equals(object obj) => obj is IccClut other && this.Equals(other);
{
return obj is IccClut other && this.Equals(other);
}
/// <inheritdoc/> /// <inheritdoc/>
public override int GetHashCode() public override int GetHashCode()

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

@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
using System; using System;
using System.Linq;
namespace SixLabors.ImageSharp.Metadata.Profiles.Icc namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
{ {
@ -55,10 +54,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
/// <returns> /// <returns>
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false. /// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns> /// </returns>
public static bool operator ==(IccNamedColor left, IccNamedColor right) public static bool operator ==(IccNamedColor left, IccNamedColor right) => left.Equals(right);
{
return left.Equals(right);
}
/// <summary> /// <summary>
/// Compares two <see cref="IccNamedColor"/> objects for equality. /// Compares two <see cref="IccNamedColor"/> objects for equality.
@ -68,23 +64,17 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
/// <returns> /// <returns>
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false. /// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns> /// </returns>
public static bool operator !=(IccNamedColor left, IccNamedColor right) public static bool operator !=(IccNamedColor left, IccNamedColor right) => !left.Equals(right);
{
return !left.Equals(right);
}
/// <inheritdoc/> /// <inheritdoc/>
public override bool Equals(object obj) public override bool Equals(object obj) => obj is IccNamedColor other && this.Equals(other);
{
return obj is IccNamedColor other && this.Equals(other);
}
/// <inheritdoc/> /// <inheritdoc/>
public bool Equals(IccNamedColor other) public bool Equals(IccNamedColor other)
{ {
return this.Name.Equals(other.Name) return this.Name.Equals(other.Name)
&& this.PcsCoordinates.SequenceEqual(other.PcsCoordinates) && this.PcsCoordinates.AsSpan().SequenceEqual(other.PcsCoordinates)
&& this.DeviceCoordinates.SequenceEqual(other.DeviceCoordinates); && this.DeviceCoordinates.AsSpan().SequenceEqual(other.DeviceCoordinates);
} }
/// <inheritdoc/> /// <inheritdoc/>

18
src/ImageSharp/MetaData/Profiles/ICC/Various/IccProfileDescription.cs

@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
using System; using System;
using System.Linq;
namespace SixLabors.ImageSharp.Metadata.Profiles.Icc namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
{ {
@ -68,18 +67,15 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
/// <inheritdoc/> /// <inheritdoc/>
public bool Equals(IccProfileDescription other) => public bool Equals(IccProfileDescription other) =>
this.DeviceManufacturer == other.DeviceManufacturer && this.DeviceManufacturer == other.DeviceManufacturer
this.DeviceModel == other.DeviceModel && && this.DeviceModel == other.DeviceModel
this.DeviceAttributes == other.DeviceAttributes && && this.DeviceAttributes == other.DeviceAttributes
this.TechnologyInformation == other.TechnologyInformation && && this.TechnologyInformation == other.TechnologyInformation
this.DeviceManufacturerInfo.SequenceEqual(other.DeviceManufacturerInfo) && && this.DeviceManufacturerInfo.AsSpan().SequenceEqual(other.DeviceManufacturerInfo)
this.DeviceModelInfo.SequenceEqual(other.DeviceModelInfo); && this.DeviceModelInfo.AsSpan().SequenceEqual(other.DeviceModelInfo);
/// <inheritdoc /> /// <inheritdoc />
public override bool Equals(object obj) public override bool Equals(object obj) => obj is IccProfileDescription other && this.Equals(other);
{
return obj is IccProfileDescription other && this.Equals(other);
}
/// <inheritdoc /> /// <inheritdoc />
public override int GetHashCode() public override int GetHashCode()

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

@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
using System; using System;
using System.Linq;
namespace SixLabors.ImageSharp.Metadata.Profiles.Icc namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
{ {
@ -34,14 +33,11 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
/// <inheritdoc /> /// <inheritdoc />
public bool Equals(IccProfileSequenceIdentifier other) => public bool Equals(IccProfileSequenceIdentifier other) =>
this.Id.Equals(other.Id) && this.Id.Equals(other.Id)
this.Description.SequenceEqual(other.Description); && this.Description.AsSpan().SequenceEqual(other.Description);
/// <inheritdoc /> /// <inheritdoc />
public override bool Equals(object obj) public override bool Equals(object obj) => obj is IccProfileSequenceIdentifier other && this.Equals(other);
{
return obj is IccProfileSequenceIdentifier other && this.Equals(other);
}
/// <inheritdoc /> /// <inheritdoc />
public override int GetHashCode() => HashCode.Combine(this.Id, this.Description); public override int GetHashCode() => HashCode.Combine(this.Id, this.Description);

4
src/ImageSharp/Processing/ResizeOptions.cs

@ -1,8 +1,8 @@
// Copyright (c) Six Labors and contributors. // Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using SixLabors.ImageSharp.Processing.Processors.Transforms; using SixLabors.ImageSharp.Processing.Processors.Transforms;
using SixLabors.Primitives; using SixLabors.Primitives;
@ -26,7 +26,7 @@ namespace SixLabors.ImageSharp.Processing
/// <summary> /// <summary>
/// Gets or sets the center coordinates. /// Gets or sets the center coordinates.
/// </summary> /// </summary>
public IEnumerable<float> CenterCoordinates { get; set; } = Enumerable.Empty<float>(); public IEnumerable<float> CenterCoordinates { get; set; } = Array.Empty<float>();
/// <summary> /// <summary>
/// Gets or sets the target size. /// Gets or sets the target size.

Loading…
Cancel
Save