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
{
/// <summary>
/// Describes the EXIF specific markers.
/// Describes the JFIF specific markers.
/// </summary>
public static readonly byte[] JFifMarker = Encoding.ASCII.GetBytes("JFIF\0");
/// <summary>
/// Describes the EXIF specific markers.
/// Describes the ICC specific markers.
/// </summary>
public static readonly byte[] IccMarker = Encoding.ASCII.GetBytes("ICC_PROFILE\0");
/// <summary>
/// Describes the ICC specific markers.
/// Describes the EXIF specific markers.
/// </summary>
public static readonly byte[] ExifMarker = Encoding.ASCII.GetBytes("Exif\0\0");
@ -36,7 +36,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
/// </summary>
/// <param name="bytesToCheck">The bytes to check.</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)
{
return bytesToCheck.Length >= profileIdentifier.Length

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

@ -4,7 +4,6 @@
using System;
using System.Buffers.Binary;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Common.Helpers;
@ -726,7 +725,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
this.InputStream.Read(this.temp, 0, length);
// 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.");
}

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

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

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

@ -6,7 +6,6 @@ using System.Buffers;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Advanced;
@ -231,7 +230,7 @@ namespace SixLabors.ImageSharp.Formats.Png
if (this.pngColorType == PngColorType.Palette)
{
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.");
}
@ -268,7 +267,7 @@ namespace SixLabors.ImageSharp.Formats.Png
else
{
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.");
}

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

@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0.
using System;
using System.Linq;
namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
{
@ -52,7 +51,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
}
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.
using System;
using System.Linq;
using System.Numerics;
namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
@ -65,10 +64,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
}
/// <inheritdoc />
public override bool Equals(object obj)
{
return obj is IccResponseCurve other && this.Equals(other);
}
public override bool Equals(object obj) => obj is IccResponseCurve other && this.Equals(other);
/// <inheritdoc />
public override int GetHashCode()
@ -88,7 +84,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
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;
}

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

@ -163,10 +163,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
/// </summary>
/// <param name="value">The entry to write</param>
/// <returns>The number of bytes written</returns>
public int WriteUnknownTagDataEntry(IccUnknownTagDataEntry value)
{
return this.WriteArray(value.Data);
}
public int WriteUnknownTagDataEntry(IccUnknownTagDataEntry value) => this.WriteArray(value.Data);
/// <summary>
/// Writes a <see cref="IccChromaticityTagDataEntry"/>
@ -269,10 +266,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
/// </summary>
/// <param name="value">The entry to write</param>
/// <returns>The number of bytes written</returns>
public int WriteDateTimeTagDataEntry(IccDateTimeTagDataEntry value)
{
return this.WriteDateTime(value.Value);
}
public int WriteDateTimeTagDataEntry(IccDateTimeTagDataEntry value) => this.WriteDateTime(value.Value);
/// <summary>
/// Writes a <see cref="IccLut16TagDataEntry"/>
@ -563,6 +557,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
long tpos = this.dataStream.Position;
this.dataStream.Position += cultureCount * 12;
// TODO: Investigate cost of Linq GroupBy
IGrouping<string, IccLocalizedString>[] texts = value.Texts.GroupBy(t => t.Text).ToArray();
uint[] offset = new uint[texts.Length];
@ -625,7 +620,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
long tpos = this.dataStream.Position;
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++)
{
uint offset = (uint)(this.dataStream.Position - start);
@ -673,10 +668,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
/// </summary>
/// <param name="value">The entry to write</param>
/// <returns>The number of bytes written</returns>
public int WriteParametricCurveTagDataEntry(IccParametricCurveTagDataEntry value)
{
return this.WriteParametricCurve(value.Curve);
}
public int WriteParametricCurveTagDataEntry(IccParametricCurveTagDataEntry value) => this.WriteParametricCurve(value.Curve);
/// <summary>
/// Writes a <see cref="IccProfileSequenceDescTagDataEntry"/>
@ -793,20 +785,14 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
/// </summary>
/// <param name="value">The entry to write</param>
/// <returns>The number of bytes written</returns>
public int WriteSignatureTagDataEntry(IccSignatureTagDataEntry value)
{
return this.WriteAsciiString(value.SignatureData, 4, false);
}
public int WriteSignatureTagDataEntry(IccSignatureTagDataEntry value) => this.WriteAsciiString(value.SignatureData, 4, false);
/// <summary>
/// Writes a <see cref="IccTextTagDataEntry"/>
/// </summary>
/// <param name="value">The entry to write</param>
/// <returns>The number of bytes written</returns>
public int WriteTextTagDataEntry(IccTextTagDataEntry value)
{
return this.WriteAsciiString(value.Text);
}
public int WriteTextTagDataEntry(IccTextTagDataEntry value) => this.WriteAsciiString(value.Text);
/// <summary>
/// Writes a <see cref="IccUFix16ArrayTagDataEntry"/>
@ -829,40 +815,28 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
/// </summary>
/// <param name="value">The entry to write</param>
/// <returns>The number of bytes written</returns>
public int WriteUInt16ArrayTagDataEntry(IccUInt16ArrayTagDataEntry value)
{
return this.WriteArray(value.Data);
}
public int WriteUInt16ArrayTagDataEntry(IccUInt16ArrayTagDataEntry value) => this.WriteArray(value.Data);
/// <summary>
/// Writes a <see cref="IccUInt32ArrayTagDataEntry"/>
/// </summary>
/// <param name="value">The entry to write</param>
/// <returns>The number of bytes written</returns>
public int WriteUInt32ArrayTagDataEntry(IccUInt32ArrayTagDataEntry value)
{
return this.WriteArray(value.Data);
}
public int WriteUInt32ArrayTagDataEntry(IccUInt32ArrayTagDataEntry value) => this.WriteArray(value.Data);
/// <summary>
/// Writes a <see cref="IccUInt64ArrayTagDataEntry"/>
/// </summary>
/// <param name="value">The entry to write</param>
/// <returns>The number of bytes written</returns>
public int WriteUInt64ArrayTagDataEntry(IccUInt64ArrayTagDataEntry value)
{
return this.WriteArray(value.Data);
}
public int WriteUInt64ArrayTagDataEntry(IccUInt64ArrayTagDataEntry value) => this.WriteArray(value.Data);
/// <summary>
/// Writes a <see cref="IccUInt8ArrayTagDataEntry"/>
/// </summary>
/// <param name="value">The entry to write</param>
/// <returns>The number of bytes written</returns>
public int WriteUInt8ArrayTagDataEntry(IccUInt8ArrayTagDataEntry value)
{
return this.WriteArray(value.Data);
}
public int WriteUInt8ArrayTagDataEntry(IccUInt8ArrayTagDataEntry value) => this.WriteArray(value.Data);
/// <summary>
/// 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)
{
// TODO: Investigate cost of Linq GroupBy
IEnumerable<IGrouping<IccTagDataEntry, IccTagDataEntry>> grouped = entries.GroupBy(t => t);
// (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.
using System;
using System.Linq;
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>
public IccCurveSetProcessElement(IccOneDimensionalCurve[] curves)
: 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>
/// 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)
{
return this.Curves.SequenceEqual(element.Curves);
return this.Curves.AsSpan().SequenceEqual(element.Curves);
}
return false;
}
/// <inheritdoc />
public bool Equals(IccCurveSetProcessElement other)
{
return this.Equals((IccMultiProcessElement)other);
}
public bool Equals(IccCurveSetProcessElement other) => 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; }
/// <inheritdoc/>
public override bool Equals(IccTagDataEntry other)
{
return other is IccChromaticityTagDataEntry entry && this.Equals(entry);
}
public override bool Equals(IccTagDataEntry other) => other is IccChromaticityTagDataEntry entry && this.Equals(entry);
/// <inheritdoc/>
public bool Equals(IccChromaticityTagDataEntry other)
@ -102,10 +99,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
}
/// <inheritdoc/>
public override bool Equals(object obj)
{
return obj is IccChromaticityTagDataEntry other && this.Equals(other);
}
public override bool Equals(object obj) => obj is IccChromaticityTagDataEntry other && this.Equals(other);
/// <inheritdoc/>
public override int GetHashCode()
@ -162,7 +156,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
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;
}

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

@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0.
using System;
using System.Linq;
namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
{
@ -42,10 +41,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
public IccColorantTableEntry[] ColorantData { get; }
/// <inheritdoc/>
public override bool Equals(IccTagDataEntry other)
{
return other is IccColorantTableTagDataEntry entry && this.Equals(entry);
}
public override bool Equals(IccTagDataEntry other) => other is IccColorantTableTagDataEntry entry && this.Equals(entry);
/// <inheritdoc/>
public bool Equals(IccColorantTableTagDataEntry other)
@ -60,19 +56,13 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
return true;
}
return base.Equals(other) && this.ColorantData.SequenceEqual(other.ColorantData);
return base.Equals(other) && this.ColorantData.AsSpan().SequenceEqual(other.ColorantData);
}
/// <inheritdoc/>
public override bool Equals(object obj)
{
return obj is IccColorantTableTagDataEntry other && this.Equals(other);
}
public override bool Equals(object obj) => obj is IccColorantTableTagDataEntry other && this.Equals(other);
/// <inheritdoc/>
public override int GetHashCode()
{
return HashCode.Combine(this.Signature, this.ColorantData);
}
public override int GetHashCode() => 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.
using System;
using System.Linq;
using System.Numerics;
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;
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.ClutValues = clutValues ?? throw new ArgumentNullException(nameof(clutValues));
this.OutputValues = outputValues ?? throw new ArgumentNullException(nameof(outputValues));
@ -111,10 +110,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
public IccLut[] OutputValues { get; }
/// <inheritdoc/>
public override bool Equals(IccTagDataEntry other)
{
return other is IccLut16TagDataEntry entry && this.Equals(entry);
}
public override bool Equals(IccTagDataEntry other) => other is IccLut16TagDataEntry entry && this.Equals(entry);
/// <inheritdoc/>
public bool Equals(IccLut16TagDataEntry other)
@ -131,16 +127,13 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
return base.Equals(other)
&& this.Matrix.Equals(other.Matrix)
&& this.InputValues.SequenceEqual(other.InputValues)
&& this.InputValues.AsSpan().SequenceEqual(other.InputValues)
&& this.ClutValues.Equals(other.ClutValues)
&& this.OutputValues.SequenceEqual(other.OutputValues);
&& this.OutputValues.AsSpan().SequenceEqual(other.OutputValues);
}
/// <inheritdoc/>
public override bool Equals(object obj)
{
return obj is IccLut16TagDataEntry other && this.Equals(other);
}
public override bool Equals(object obj) => obj is IccLut16TagDataEntry other && this.Equals(other);
/// <inheritdoc/>
public override int GetHashCode()
@ -153,7 +146,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
this.OutputValues);
}
private Matrix4x4 CreateMatrix(float[,] matrix)
private static Matrix4x4 CreateMatrix(float[,] matrix)
{
return new Matrix4x4(
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; }
/// <inheritdoc/>
public override bool Equals(IccTagDataEntry other)
{
return other is IccLut8TagDataEntry entry && this.Equals(entry);
}
public override bool Equals(IccTagDataEntry other) => other is IccLut8TagDataEntry entry && this.Equals(entry);
/// <inheritdoc/>
public bool Equals(IccLut8TagDataEntry other)
@ -134,16 +131,13 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
return base.Equals(other)
&& this.Matrix.Equals(other.Matrix)
&& this.InputValues.SequenceEqual(other.InputValues)
&& this.InputValues.AsSpan().SequenceEqual(other.InputValues)
&& this.ClutValues.Equals(other.ClutValues)
&& this.OutputValues.SequenceEqual(other.OutputValues);
&& this.OutputValues.AsSpan().SequenceEqual(other.OutputValues);
}
/// <inheritdoc/>
public override bool Equals(object obj)
{
return obj is IccLut8TagDataEntry other && this.Equals(other);
}
public override bool Equals(object obj) => obj is IccLut8TagDataEntry other && this.Equals(other);
/// <inheritdoc/>
public override int GetHashCode()

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

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

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

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

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

@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0.
using System;
using System.Linq;
namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
{
@ -29,9 +28,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
/// <param name="tagSignature">Tag Signature</param>
public IccProfileSequenceDescTagDataEntry(IccProfileDescription[] descriptions, IccProfileTag tagSignature)
: base(IccTypeSignature.ProfileSequenceDesc, tagSignature)
{
this.Descriptions = descriptions ?? throw new ArgumentNullException(nameof(descriptions));
}
=> this.Descriptions = descriptions ?? throw new ArgumentNullException(nameof(descriptions));
/// <summary>
/// Gets the profile descriptions
@ -40,9 +37,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
/// <inheritdoc/>
public override bool Equals(IccTagDataEntry other)
{
return other is IccProfileSequenceDescTagDataEntry entry && this.Equals(entry);
}
=> other is IccProfileSequenceDescTagDataEntry entry && this.Equals(entry);
/// <inheritdoc />
public bool Equals(IccProfileSequenceDescTagDataEntry other)
@ -57,14 +52,12 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
return true;
}
return base.Equals(other) && this.Descriptions.SequenceEqual(other.Descriptions);
return base.Equals(other) && this.Descriptions.AsSpan().SequenceEqual(other.Descriptions);
}
/// <inheritdoc/>
public override bool Equals(object obj)
{
return obj is IccProfileSequenceDescTagDataEntry other && this.Equals(other);
}
=> obj is IccProfileSequenceDescTagDataEntry other && this.Equals(other);
/// <inheritdoc />
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; }
/// <inheritdoc/>
public override bool Equals(IccTagDataEntry other)
{
return other is IccResponseCurveSet16TagDataEntry entry && this.Equals(entry);
}
public override bool Equals(IccTagDataEntry other) => other is IccResponseCurveSet16TagDataEntry entry && this.Equals(entry);
/// <inheritdoc />
public bool Equals(IccResponseCurveSet16TagDataEntry other)
@ -71,14 +68,11 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
return base.Equals(other)
&& this.ChannelCount == other.ChannelCount
&& this.Curves.SequenceEqual(other.Curves);
&& this.Curves.AsSpan().SequenceEqual(other.Curves);
}
/// <inheritdoc />
public override bool Equals(object obj)
{
return obj is IccResponseCurveSet16TagDataEntry other && this.Equals(other);
}
public override bool Equals(object obj) => obj is IccResponseCurveSet16TagDataEntry other && this.Equals(other);
/// <inheritdoc />
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.
using System;
using System.Linq;
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="tagSignature">Tag Signature</param>
public IccUInt64ArrayTagDataEntry(ulong[] data, IccProfileTag tagSignature)
: base(IccTypeSignature.UInt64Array, tagSignature)
{
this.Data = data ?? throw new ArgumentNullException(nameof(data));
}
: base(IccTypeSignature.UInt64Array, tagSignature) => this.Data = data ?? throw new ArgumentNullException(nameof(data));
/// <summary>
/// Gets the array data
@ -37,10 +33,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
public ulong[] Data { get; }
/// <inheritdoc/>
public override bool Equals(IccTagDataEntry other)
{
return other is IccUInt64ArrayTagDataEntry entry && this.Equals(entry);
}
public override bool Equals(IccTagDataEntry other) => other is IccUInt64ArrayTagDataEntry entry && this.Equals(entry);
/// <inheritdoc/>
public bool Equals(IccUInt64ArrayTagDataEntry other)
@ -59,10 +52,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
}
/// <inheritdoc/>
public override bool Equals(object obj)
{
return obj is IccUInt64ArrayTagDataEntry other && this.Equals(other);
}
public override bool Equals(object obj) => obj is IccUInt64ArrayTagDataEntry other && this.Equals(other);
/// <inheritdoc/>
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/>
public override bool Equals(object obj)
{
return obj is IccClut other && this.Equals(other);
}
public override bool Equals(object obj) => obj is IccClut other && this.Equals(other);
/// <inheritdoc/>
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.
using System;
using System.Linq;
namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
{
@ -55,10 +54,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
/// <returns>
/// True if the <paramref name="left"/> parameter is equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
public static bool operator ==(IccNamedColor left, IccNamedColor right)
{
return left.Equals(right);
}
public static bool operator ==(IccNamedColor left, IccNamedColor right) => left.Equals(right);
/// <summary>
/// Compares two <see cref="IccNamedColor"/> objects for equality.
@ -68,23 +64,17 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
/// <returns>
/// True if the <paramref name="left"/> parameter is not equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns>
public static bool operator !=(IccNamedColor left, IccNamedColor right)
{
return !left.Equals(right);
}
public static bool operator !=(IccNamedColor left, IccNamedColor right) => !left.Equals(right);
/// <inheritdoc/>
public override bool Equals(object obj)
{
return obj is IccNamedColor other && this.Equals(other);
}
public override bool Equals(object obj) => obj is IccNamedColor other && this.Equals(other);
/// <inheritdoc/>
public bool Equals(IccNamedColor other)
{
return this.Name.Equals(other.Name)
&& this.PcsCoordinates.SequenceEqual(other.PcsCoordinates)
&& this.DeviceCoordinates.SequenceEqual(other.DeviceCoordinates);
&& this.PcsCoordinates.AsSpan().SequenceEqual(other.PcsCoordinates)
&& this.DeviceCoordinates.AsSpan().SequenceEqual(other.DeviceCoordinates);
}
/// <inheritdoc/>

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

@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0.
using System;
using System.Linq;
namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
{
@ -68,18 +67,15 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
/// <inheritdoc/>
public bool Equals(IccProfileDescription other) =>
this.DeviceManufacturer == other.DeviceManufacturer &&
this.DeviceModel == other.DeviceModel &&
this.DeviceAttributes == other.DeviceAttributes &&
this.TechnologyInformation == other.TechnologyInformation &&
this.DeviceManufacturerInfo.SequenceEqual(other.DeviceManufacturerInfo) &&
this.DeviceModelInfo.SequenceEqual(other.DeviceModelInfo);
this.DeviceManufacturer == other.DeviceManufacturer
&& this.DeviceModel == other.DeviceModel
&& this.DeviceAttributes == other.DeviceAttributes
&& this.TechnologyInformation == other.TechnologyInformation
&& this.DeviceManufacturerInfo.AsSpan().SequenceEqual(other.DeviceManufacturerInfo)
&& this.DeviceModelInfo.AsSpan().SequenceEqual(other.DeviceModelInfo);
/// <inheritdoc />
public override bool Equals(object obj)
{
return obj is IccProfileDescription other && this.Equals(other);
}
public override bool Equals(object obj) => obj is IccProfileDescription other && this.Equals(other);
/// <inheritdoc />
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.
using System;
using System.Linq;
namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
{
@ -34,14 +33,11 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc
/// <inheritdoc />
public bool Equals(IccProfileSequenceIdentifier other) =>
this.Id.Equals(other.Id) &&
this.Description.SequenceEqual(other.Description);
this.Id.Equals(other.Id)
&& this.Description.AsSpan().SequenceEqual(other.Description);
/// <inheritdoc />
public override bool Equals(object obj)
{
return obj is IccProfileSequenceIdentifier other && this.Equals(other);
}
public override bool Equals(object obj) => obj is IccProfileSequenceIdentifier other && this.Equals(other);
/// <inheritdoc />
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.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Collections.Generic;
using System.Linq;
using SixLabors.ImageSharp.Processing.Processors.Transforms;
using SixLabors.Primitives;
@ -26,7 +26,7 @@ namespace SixLabors.ImageSharp.Processing
/// <summary>
/// Gets or sets the center coordinates.
/// </summary>
public IEnumerable<float> CenterCoordinates { get; set; } = Enumerable.Empty<float>();
public IEnumerable<float> CenterCoordinates { get; set; } = Array.Empty<float>();
/// <summary>
/// Gets or sets the target size.

Loading…
Cancel
Save