Browse Source

Remove Nullable Disable from ICC Code

Removed the nullable disable from the icc Code (And one Tiff).
Most parts could be solved relative easily. There are also some parts were the bang operator had to be used.
pull/3023/head
Stefan Nikolei 3 months ago
parent
commit
30a2dfaaa9
  1. 5
      src/ImageSharp/ColorProfiles/Icc/Calculators/CurveCalculator.cs
  2. 4
      src/ImageSharp/ColorProfiles/Icc/Calculators/GrayTrcCalculator.cs
  3. 1
      src/ImageSharp/ColorProfiles/Icc/Calculators/LutABCalculator.CalculationType.cs
  4. 73
      src/ImageSharp/ColorProfiles/Icc/Calculators/LutABCalculator.cs
  5. 3
      src/ImageSharp/ColorProfiles/Icc/Calculators/LutEntryCalculator.cs
  6. 2
      src/ImageSharp/ColorProfiles/Icc/Calculators/TrcCalculator.cs
  7. 5
      src/ImageSharp/ColorProfiles/Icc/IccConverterBase.Checks.cs
  8. 16
      src/ImageSharp/ColorProfiles/Icc/IccConverterbase.Conversions.cs
  9. 3
      src/ImageSharp/ColorProfiles/Icc/IccConverterbase.cs
  10. 21
      src/ImageSharp/Formats/Tiff/TiffDecoderMetadataCreator.cs
  11. 2
      src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.NonPrimitives.cs
  12. 31
      src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.TagDataEntry.cs
  13. 2
      src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.Primitives.cs
  14. 3
      src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.TagDataEntry.cs
  15. 14
      src/ImageSharp/Metadata/Profiles/ICC/IccProfile.cs
  16. 7
      src/ImageSharp/Metadata/Profiles/ICC/IccProfileHeader.cs
  17. 73
      src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccLutAToBTagDataEntry.cs
  18. 115
      src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccLutBToATagDataEntry.cs
  19. 23
      src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccTextDescriptionTagDataEntry.cs

5
src/ImageSharp/ColorProfiles/Icc/Calculators/CurveCalculator.cs

@ -1,6 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
#nullable disable
using SixLabors.ImageSharp.ColorProfiles.Icc.Calculators;
using SixLabors.ImageSharp.Metadata.Profiles.Icc;
@ -9,7 +8,7 @@ namespace SixLabors.ImageSharp.ColorProfiles.Conversion.Icc;
internal partial class CurveCalculator : ISingleCalculator
{
private readonly LutCalculator lutCalculator;
private readonly LutCalculator? lutCalculator;
private readonly float gamma;
private readonly CalculationType type;
@ -41,7 +40,7 @@ internal partial class CurveCalculator : ISingleCalculator
{
CalculationType.Identity => value,
CalculationType.Gamma => MathF.Pow(value, this.gamma), // TODO: This could be optimized using a LUT. See SrgbCompanding
CalculationType.Lut => this.lutCalculator.Calculate(value),
CalculationType.Lut => this.lutCalculator!.Calculate(value),
_ => throw new InvalidOperationException("Invalid calculation type"),
};
}

4
src/ImageSharp/ColorProfiles/Icc/Calculators/GrayTrcCalculator.cs

@ -11,8 +11,8 @@ internal class GrayTrcCalculator : IVector4Calculator
{
private readonly TrcCalculator calculator;
public GrayTrcCalculator(IccTagDataEntry grayTrc, bool toPcs)
=> this.calculator = new TrcCalculator(new IccTagDataEntry[] { grayTrc }, !toPcs);
public GrayTrcCalculator(IccTagDataEntry? grayTrc, bool toPcs)
=> this.calculator = new TrcCalculator([grayTrc], !toPcs);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector4 Calculate(Vector4 value) => this.calculator.Calculate(value);

1
src/ImageSharp/ColorProfiles/Icc/Calculators/LutABCalculator.CalculationType.cs

@ -5,6 +5,7 @@ namespace SixLabors.ImageSharp.ColorProfiles.Conversion.Icc;
internal partial class LutABCalculator
{
[Flags]
private enum CalculationType
{
AtoB = 1 << 3,

73
src/ImageSharp/ColorProfiles/Icc/Calculators/LutABCalculator.cs

@ -1,6 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
#nullable disable
using System.Numerics;
using SixLabors.ImageSharp.ColorProfiles.Icc.Calculators;
@ -11,22 +10,22 @@ namespace SixLabors.ImageSharp.ColorProfiles.Conversion.Icc;
internal partial class LutABCalculator : IVector4Calculator
{
private CalculationType type;
private TrcCalculator curveACalculator;
private TrcCalculator curveBCalculator;
private TrcCalculator curveMCalculator;
private MatrixCalculator matrixCalculator;
private ClutCalculator clutCalculator;
private TrcCalculator? curveACalculator;
private TrcCalculator? curveBCalculator;
private TrcCalculator? curveMCalculator;
private MatrixCalculator? matrixCalculator;
private ClutCalculator? clutCalculator;
public LutABCalculator(IccLutAToBTagDataEntry entry)
{
Guard.NotNull(entry, nameof(entry));
Guard.NotNull(entry);
this.Init(entry.CurveA, entry.CurveB, entry.CurveM, entry.Matrix3x1, entry.Matrix3x3, entry.ClutValues);
this.type |= CalculationType.AtoB;
}
public LutABCalculator(IccLutBToATagDataEntry entry)
{
Guard.NotNull(entry, nameof(entry));
Guard.NotNull(entry);
this.Init(entry.CurveA, entry.CurveB, entry.CurveM, entry.Matrix3x1, entry.Matrix3x3, entry.ClutValues);
this.type |= CalculationType.BtoA;
}
@ -36,49 +35,49 @@ internal partial class LutABCalculator : IVector4Calculator
switch (this.type)
{
case CalculationType.Full | CalculationType.AtoB:
value = this.curveACalculator.Calculate(value);
value = this.clutCalculator.Calculate(value);
value = this.curveMCalculator.Calculate(value);
value = this.matrixCalculator.Calculate(value);
return this.curveBCalculator.Calculate(value);
value = this.curveACalculator!.Calculate(value);
value = this.clutCalculator!.Calculate(value);
value = this.curveMCalculator!.Calculate(value);
value = this.matrixCalculator!.Calculate(value);
return this.curveBCalculator!.Calculate(value);
case CalculationType.Full | CalculationType.BtoA:
value = this.curveBCalculator.Calculate(value);
value = this.matrixCalculator.Calculate(value);
value = this.curveMCalculator.Calculate(value);
value = this.clutCalculator.Calculate(value);
return this.curveACalculator.Calculate(value);
value = this.curveBCalculator!.Calculate(value);
value = this.matrixCalculator!.Calculate(value);
value = this.curveMCalculator!.Calculate(value);
value = this.clutCalculator!.Calculate(value);
return this.curveACalculator!.Calculate(value);
case CalculationType.CurveClut | CalculationType.AtoB:
value = this.curveACalculator.Calculate(value);
value = this.clutCalculator.Calculate(value);
return this.curveBCalculator.Calculate(value);
value = this.curveACalculator!.Calculate(value);
value = this.clutCalculator!.Calculate(value);
return this.curveBCalculator!.Calculate(value);
case CalculationType.CurveClut | CalculationType.BtoA:
value = this.curveBCalculator.Calculate(value);
value = this.clutCalculator.Calculate(value);
return this.curveACalculator.Calculate(value);
value = this.curveBCalculator!.Calculate(value);
value = this.clutCalculator!.Calculate(value);
return this.curveACalculator!.Calculate(value);
case CalculationType.CurveMatrix | CalculationType.AtoB:
value = this.curveMCalculator.Calculate(value);
value = this.matrixCalculator.Calculate(value);
return this.curveBCalculator.Calculate(value);
value = this.curveMCalculator!.Calculate(value);
value = this.matrixCalculator!.Calculate(value);
return this.curveBCalculator!.Calculate(value);
case CalculationType.CurveMatrix | CalculationType.BtoA:
value = this.curveBCalculator.Calculate(value);
value = this.matrixCalculator.Calculate(value);
return this.curveMCalculator.Calculate(value);
value = this.curveBCalculator!.Calculate(value);
value = this.matrixCalculator!.Calculate(value);
return this.curveMCalculator!.Calculate(value);
case CalculationType.SingleCurve | CalculationType.AtoB:
case CalculationType.SingleCurve | CalculationType.BtoA:
return this.curveBCalculator.Calculate(value);
return this.curveBCalculator!.Calculate(value);
default:
throw new InvalidOperationException("Invalid calculation type");
}
}
private void Init(IccTagDataEntry[] curveA, IccTagDataEntry[] curveB, IccTagDataEntry[] curveM, Vector3? matrix3x1, Matrix4x4? matrix3x3, IccClut clut)
private void Init(IccTagDataEntry[]? curveA, IccTagDataEntry[]? curveB, IccTagDataEntry[]? curveM, Vector3? matrix3x1, Matrix4x4? matrix3x3, IccClut? clut)
{
bool hasACurve = curveA != null;
bool hasBCurve = curveB != null;
@ -109,27 +108,27 @@ internal partial class LutABCalculator : IVector4Calculator
if (hasACurve)
{
this.curveACalculator = new TrcCalculator(curveA, false);
this.curveACalculator = new TrcCalculator(curveA!, false);
}
if (hasBCurve)
{
this.curveBCalculator = new TrcCalculator(curveB, false);
this.curveBCalculator = new TrcCalculator(curveB!, false);
}
if (hasMCurve)
{
this.curveMCalculator = new TrcCalculator(curveM, false);
this.curveMCalculator = new TrcCalculator(curveM!, false);
}
if (hasMatrix)
{
this.matrixCalculator = new MatrixCalculator(matrix3x3.Value, matrix3x1.Value);
this.matrixCalculator = new MatrixCalculator(matrix3x3!.Value, matrix3x1!.Value);
}
if (hasClut)
{
this.clutCalculator = new ClutCalculator(clut);
this.clutCalculator = new ClutCalculator(clut!);
}
}
}

3
src/ImageSharp/ColorProfiles/Icc/Calculators/LutEntryCalculator.cs

@ -1,7 +1,7 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
#nullable disable
using System.Diagnostics.CodeAnalysis;
using System.Numerics;
using System.Runtime.CompilerServices;
using SixLabors.ImageSharp.Metadata.Profiles.Icc;
@ -57,6 +57,7 @@ internal class LutEntryCalculator : IVector4Calculator
return value;
}
[MemberNotNull(nameof(this.inputCurve), nameof(this.outputCurve), nameof(this.clutCalculator), nameof(this.matrix))]
private void Init(IccLut[] inputCurve, IccLut[] outputCurve, IccClut clut, Matrix4x4 matrix)
{
this.inputCurve = InitLut(inputCurve);

2
src/ImageSharp/ColorProfiles/Icc/Calculators/TrcCalculator.cs

@ -12,7 +12,7 @@ internal class TrcCalculator : IVector4Calculator
{
private readonly ISingleCalculator[] calculators;
public TrcCalculator(IccTagDataEntry[] entries, bool inverted)
public TrcCalculator(IccTagDataEntry?[] entries, bool inverted)
{
Guard.NotNull(entries, nameof(entries));

5
src/ImageSharp/ColorProfiles/Icc/IccConverterBase.Checks.cs

@ -1,6 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
#nullable disable
using SixLabors.ImageSharp.Metadata.Profiles.Icc;
@ -146,10 +145,10 @@ internal abstract partial class IccConverterBase
private static bool HasTag(IccProfile profile, IccProfileTag tag)
=> profile.Entries.Any(t => t.TagSignature == tag);
private static IccTagDataEntry GetTag(IccProfile profile, IccProfileTag tag)
private static IccTagDataEntry? GetTag(IccProfile profile, IccProfileTag tag)
=> Array.Find(profile.Entries, t => t.TagSignature == tag);
private static T GetTag<T>(IccProfile profile, IccProfileTag tag)
private static T? GetTag<T>(IccProfile profile, IccProfileTag tag)
where T : IccTagDataEntry
=> profile.Entries.OfType<T>().FirstOrDefault(t => t.TagSignature == tag);
}

16
src/ImageSharp/ColorProfiles/Icc/IccConverterbase.Conversions.cs

@ -1,6 +1,7 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Diagnostics.CodeAnalysis;
using SixLabors.ImageSharp.ColorProfiles.Icc.Calculators;
using SixLabors.ImageSharp.Metadata.Profiles.Icc;
@ -24,6 +25,7 @@ internal abstract partial class IccConverterBase
/// <param name="toPcs">True if the conversion is to the Profile Connection Space.</param>
/// <param name="renderingIntent">The wanted rendering intent. Can be ignored if not available.</param>
/// <exception cref="InvalidIccProfileException">Invalid conversion method.</exception>
[MemberNotNull(nameof(this.calculator))]
protected void Init(IccProfile profile, bool toPcs, IccRenderingIntent renderingIntent)
=> this.calculator = GetConversionMethod(profile, renderingIntent) switch
{
@ -73,13 +75,13 @@ internal abstract partial class IccConverterBase
private static ColorTrcCalculator InitColorTrc(IccProfile profile, bool toPcs)
{
IccXyzTagDataEntry redMatrixColumn = GetTag<IccXyzTagDataEntry>(profile, IccProfileTag.RedMatrixColumn);
IccXyzTagDataEntry greenMatrixColumn = GetTag<IccXyzTagDataEntry>(profile, IccProfileTag.GreenMatrixColumn);
IccXyzTagDataEntry blueMatrixColumn = GetTag<IccXyzTagDataEntry>(profile, IccProfileTag.BlueMatrixColumn);
IccXyzTagDataEntry? redMatrixColumn = GetTag<IccXyzTagDataEntry>(profile, IccProfileTag.RedMatrixColumn);
IccXyzTagDataEntry? greenMatrixColumn = GetTag<IccXyzTagDataEntry>(profile, IccProfileTag.GreenMatrixColumn);
IccXyzTagDataEntry? blueMatrixColumn = GetTag<IccXyzTagDataEntry>(profile, IccProfileTag.BlueMatrixColumn);
IccTagDataEntry redTrc = GetTag(profile, IccProfileTag.RedTrc);
IccTagDataEntry greenTrc = GetTag(profile, IccProfileTag.GreenTrc);
IccTagDataEntry blueTrc = GetTag(profile, IccProfileTag.BlueTrc);
IccTagDataEntry? redTrc = GetTag(profile, IccProfileTag.RedTrc);
IccTagDataEntry? greenTrc = GetTag(profile, IccProfileTag.GreenTrc);
IccTagDataEntry? blueTrc = GetTag(profile, IccProfileTag.BlueTrc);
if (redMatrixColumn == null ||
greenMatrixColumn == null ||
@ -103,7 +105,7 @@ internal abstract partial class IccConverterBase
private static GrayTrcCalculator InitGrayTrc(IccProfile profile, bool toPcs)
{
IccTagDataEntry entry = GetTag(profile, IccProfileTag.GrayTrc);
IccTagDataEntry? entry = GetTag(profile, IccProfileTag.GrayTrc);
return new GrayTrcCalculator(entry, toPcs);
}
}

3
src/ImageSharp/ColorProfiles/Icc/IccConverterbase.cs

@ -1,6 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
#nullable disable
using System.Numerics;
using System.Runtime.CompilerServices;
@ -18,7 +17,7 @@ internal abstract partial class IccConverterBase
/// </summary>
/// <param name="profile">The ICC profile to use for the conversions</param>
/// <param name="toPcs">True if the conversion is to the profile connection space (PCS); False if the conversion is to the data space</param>
protected IccConverterBase(IccProfile profile, bool toPcs)
protected IccConverterBase(IccProfile? profile, bool toPcs)
{
Guard.NotNull(profile, nameof(profile));
this.Init(profile, toPcs, profile.Header.RenderingIntent);

21
src/ImageSharp/Formats/Tiff/TiffDecoderMetadataCreator.cs

@ -1,6 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
#nullable disable
using SixLabors.ImageSharp.Common.Helpers;
using SixLabors.ImageSharp.Metadata;
@ -31,12 +30,14 @@ internal static class TiffDecoderMetadataCreator
// ICC profile data has already been resolved in the frame metadata,
// as it is required for color conversion.
ImageFrameMetadata frameMetaData = frames[i];
if (TryGetIptc(frameMetaData.ExifProfile.Values, out byte[] iptcBytes))
DebugGuard.NotNull(frameMetaData.ExifProfile);
if (TryGetIptc(frameMetaData.ExifProfile.Values, out byte[]? iptcBytes))
{
frameMetaData.IptcProfile = new IptcProfile(iptcBytes);
}
if (frameMetaData.ExifProfile.TryGetValue(ExifTag.XMP, out IExifValue<byte[]> xmpProfileBytes))
if (frameMetaData.ExifProfile.TryGetValue(ExifTag.XMP, out IExifValue<byte[]>? xmpProfileBytes))
{
frameMetaData.XmpProfile = new XmpProfile(xmpProfileBytes.Value);
}
@ -65,7 +66,7 @@ internal static class TiffDecoderMetadataCreator
return imageMetaData;
}
private static void SetResolution(ImageMetadata imageMetaData, ExifProfile exifProfile)
private static void SetResolution(ImageMetadata imageMetaData, ExifProfile? exifProfile)
{
imageMetaData.ResolutionUnits = exifProfile != null ? UnitConverter.ExifProfileToResolutionUnit(exifProfile) : PixelResolutionUnit.PixelsPerInch;
@ -74,34 +75,34 @@ internal static class TiffDecoderMetadataCreator
return;
}
if (exifProfile.TryGetValue(ExifTag.XResolution, out IExifValue<Rational> horizontalResolution))
if (exifProfile.TryGetValue(ExifTag.XResolution, out IExifValue<Rational>? horizontalResolution))
{
imageMetaData.HorizontalResolution = horizontalResolution.Value.ToDouble();
}
if (exifProfile.TryGetValue(ExifTag.YResolution, out IExifValue<Rational> verticalResolution))
if (exifProfile.TryGetValue(ExifTag.YResolution, out IExifValue<Rational>? verticalResolution))
{
imageMetaData.VerticalResolution = verticalResolution.Value.ToDouble();
}
}
private static bool TryGetIptc(IReadOnlyList<IExifValue> exifValues, out byte[] iptcBytes)
private static bool TryGetIptc(IReadOnlyList<IExifValue> exifValues, out byte[]? iptcBytes)
{
iptcBytes = null;
IExifValue iptc = exifValues.FirstOrDefault(f => f.Tag == ExifTag.IPTC);
IExifValue? iptc = exifValues.FirstOrDefault(f => f.Tag == ExifTag.IPTC);
if (iptc != null)
{
if (iptc.DataType is ExifDataType.Byte or ExifDataType.Undefined)
{
iptcBytes = (byte[])iptc.GetValue();
iptcBytes = (byte[]?)iptc.GetValue();
return true;
}
// Some Encoders write the data type of IPTC as long.
if (iptc.DataType == ExifDataType.Long)
{
uint[] iptcValues = (uint[])iptc.GetValue();
uint[] iptcValues = (uint[])iptc.GetValue()!;
iptcBytes = new byte[iptcValues.Length * 4];
Buffer.BlockCopy(iptcValues, 0, iptcBytes, 0, iptcValues.Length * 4);
if (iptcBytes[0] == 0x1c)

2
src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.NonPrimitives.cs

@ -144,7 +144,7 @@ internal sealed partial class IccDataReader
case IccTypeSignature.MultiLocalizedUnicode:
return this.ReadMultiLocalizedUnicodeTagDataEntry();
case IccTypeSignature.TextDescription:
return (IccMultiLocalizedUnicodeTagDataEntry)this.ReadTextDescriptionTagDataEntry();
return ((IccMultiLocalizedUnicodeTagDataEntry)this.ReadTextDescriptionTagDataEntry())!;
default:
throw new InvalidIccProfileException("Profile description can only have multi-localized Unicode or text description entries");

31
src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.TagDataEntry.cs

@ -1,6 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
#nullable disable
using System.Globalization;
using System.Numerics;
@ -332,12 +331,12 @@ internal sealed partial class IccDataReader
uint clutOffset = this.ReadUInt32();
uint aCurveOffset = this.ReadUInt32();
IccTagDataEntry[] bCurve = null;
IccTagDataEntry[] mCurve = null;
IccTagDataEntry[] aCurve = null;
IccClut clut = null;
float[,] matrix3x3 = null;
float[] matrix3x1 = null;
IccTagDataEntry[]? bCurve = null;
IccTagDataEntry[]? mCurve = null;
IccTagDataEntry[]? aCurve = null;
IccClut? clut = null;
float[,]? matrix3x3 = null;
float[]? matrix3x1 = null;
if (bCurveOffset != 0)
{
@ -391,12 +390,12 @@ internal sealed partial class IccDataReader
uint clutOffset = this.ReadUInt32();
uint aCurveOffset = this.ReadUInt32();
IccTagDataEntry[] bCurve = null;
IccTagDataEntry[] mCurve = null;
IccTagDataEntry[] aCurve = null;
IccClut clut = null;
float[,] matrix3x3 = null;
float[] matrix3x1 = null;
IccTagDataEntry[]? bCurve = null;
IccTagDataEntry[]? mCurve = null;
IccTagDataEntry[]? aCurve = null;
IccClut? clut = null;
float[,]? matrix3x3 = null;
float[]? matrix3x1 = null;
if (bCurveOffset != 0)
{
@ -477,7 +476,7 @@ internal sealed partial class IccDataReader
return new IccMultiLocalizedUnicodeTagDataEntry(text);
CultureInfo ReadCulture(string language, string country)
CultureInfo ReadCulture(string language, string? country)
{
if (string.IsNullOrWhiteSpace(language))
{
@ -775,8 +774,8 @@ internal sealed partial class IccDataReader
/// <returns>The read entry.</returns>
public IccTextDescriptionTagDataEntry ReadTextDescriptionTagDataEntry()
{
string unicodeValue, scriptcodeValue;
string asciiValue = unicodeValue = scriptcodeValue = null;
string? unicodeValue, scriptcodeValue;
string? asciiValue = unicodeValue = scriptcodeValue = null;
int asciiCount = (int)this.ReadUInt32();
if (asciiCount > 0)

2
src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.Primitives.cs

@ -189,7 +189,7 @@ internal sealed partial class IccDataWriter
/// <param name="length">The desired length of the string (including potential null terminator)</param>
/// <param name="ensureNullTerminator">If True, there will be a \0 added at the end</param>
/// <returns>the number of bytes written</returns>
public int WriteAsciiString(string value, int length, bool ensureNullTerminator)
public int WriteAsciiString(string? value, int length, bool ensureNullTerminator)
{
if (length == 0)
{

3
src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.TagDataEntry.cs

@ -1,6 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
#nullable disable
namespace SixLabors.ImageSharp.Metadata.Profiles.Icc;
@ -71,7 +70,7 @@ internal sealed partial class IccDataWriter
IccTypeSignature.UcrBg => this.WriteUcrBgTagDataEntry((IccUcrBgTagDataEntry)entry),
// Unsupported or unknown
_ => this.WriteUnknownTagDataEntry(entry as IccUnknownTagDataEntry),
_ => this.WriteUnknownTagDataEntry((entry as IccUnknownTagDataEntry)!),
};
return count;
}

14
src/ImageSharp/Metadata/Profiles/ICC/IccProfile.cs

@ -1,7 +1,7 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
#nullable disable
using System.Diagnostics.CodeAnalysis;
using System.Security.Cryptography;
namespace SixLabors.ImageSharp.Metadata.Profiles.Icc;
@ -14,23 +14,23 @@ public sealed partial class IccProfile : IDeepCloneable<IccProfile>
/// <summary>
/// The byte array to read the ICC profile from
/// </summary>
private readonly byte[] data;
private readonly byte[]? data;
/// <summary>
/// The backing file for the <see cref="Entries"/> property
/// </summary>
private IccTagDataEntry[] entries;
private IccTagDataEntry[]? entries;
/// <summary>
/// ICC profile header
/// </summary>
private IccProfileHeader header;
private IccProfileHeader? header;
/// <summary>
/// Initializes a new instance of the <see cref="IccProfile"/> class.
/// </summary>
public IccProfile()
: this((byte[])null)
: this((byte[]?)null)
{
}
@ -38,7 +38,7 @@ public sealed partial class IccProfile : IDeepCloneable<IccProfile>
/// Initializes a new instance of the <see cref="IccProfile"/> class.
/// </summary>
/// <param name="data">The raw ICC profile data</param>
public IccProfile(byte[] data) => this.data = data;
public IccProfile(byte[]? data) => this.data = data;
/// <summary>
/// Initializes a new instance of the <see cref="IccProfile"/> class.
@ -177,6 +177,7 @@ public sealed partial class IccProfile : IDeepCloneable<IccProfile>
return IccWriter.Write(this);
}
[MemberNotNull(nameof(this.header))]
private void InitializeHeader()
{
if (this.header != null)
@ -193,6 +194,7 @@ public sealed partial class IccProfile : IDeepCloneable<IccProfile>
this.header = IccReader.ReadHeader(this.data);
}
[MemberNotNull(nameof(this.entries))]
private void InitializeEntries()
{
if (this.entries != null)

7
src/ImageSharp/Metadata/Profiles/ICC/IccProfileHeader.cs

@ -1,6 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
#nullable disable
using System.Numerics;
@ -19,7 +18,7 @@ public sealed class IccProfileHeader
/// <summary>
/// Gets or sets the preferred CMM (Color Management Module) type.
/// </summary>
public string CmmType { get; set; }
public string? CmmType { get; set; }
/// <summary>
/// Gets or sets the profiles version number.
@ -50,7 +49,7 @@ public sealed class IccProfileHeader
/// Gets or sets the file signature. Should always be "acsp".
/// Value will be ignored when writing a profile.
/// </summary>
public string FileSignature { get; set; }
public string? FileSignature { get; set; }
/// <summary>
/// Gets or sets the primary platform this profile as created for
@ -91,7 +90,7 @@ public sealed class IccProfileHeader
/// <summary>
/// Gets or sets profile creator signature.
/// </summary>
public string CreatorSignature { get; set; }
public string? CreatorSignature { get; set; }
/// <summary>
/// Gets or sets the profile ID (hash).

73
src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccLutAToBTagDataEntry.cs

@ -1,7 +1,7 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
#nullable disable
using System.Diagnostics.CodeAnalysis;
using System.Numerics;
// TODO: Review the use of base IccTagDataEntry comparison.
@ -22,12 +22,12 @@ internal sealed class IccLutAToBTagDataEntry : IccTagDataEntry, IEquatable<IccLu
/// <param name="clutValues">CLUT</param>
/// <param name="curveA">A Curve</param>
public IccLutAToBTagDataEntry(
IccTagDataEntry[] curveB,
float[,] matrix3x3,
float[] matrix3x1,
IccTagDataEntry[] curveM,
IccClut clutValues,
IccTagDataEntry[] curveA)
IccTagDataEntry[]? curveB,
float[,]? matrix3x3,
float[]? matrix3x1,
IccTagDataEntry[]? curveM,
IccClut? clutValues,
IccTagDataEntry[]? curveA)
: this(curveB, matrix3x3, matrix3x1, curveM, clutValues, curveA, IccProfileTag.Unknown)
{
}
@ -43,12 +43,12 @@ internal sealed class IccLutAToBTagDataEntry : IccTagDataEntry, IEquatable<IccLu
/// <param name="curveA">A Curve</param>
/// <param name="tagSignature">Tag Signature</param>
public IccLutAToBTagDataEntry(
IccTagDataEntry[] curveB,
float[,] matrix3x3,
float[] matrix3x1,
IccTagDataEntry[] curveM,
IccClut clutValues,
IccTagDataEntry[] curveA,
IccTagDataEntry[]? curveB,
float[,]? matrix3x3,
float[]? matrix3x1,
IccTagDataEntry[]? curveM,
IccClut? clutValues,
IccTagDataEntry[]? curveA,
IccProfileTag tagSignature)
: base(IccTypeSignature.LutAToB, tagSignature)
{
@ -70,11 +70,11 @@ internal sealed class IccLutAToBTagDataEntry : IccTagDataEntry, IEquatable<IccLu
Guard.IsTrue(this.CurveM.Length == 3, nameof(this.CurveM), $"{nameof(this.CurveM)} must have a length of three");
Guard.MustBeBetweenOrEqualTo(this.CurveA.Length, 1, 15, nameof(this.CurveA));
this.InputChannelCount = curveA.Length;
this.InputChannelCount = this.CurveA.Length;
this.OutputChannelCount = 3;
Guard.IsTrue(this.InputChannelCount == clutValues.InputChannelCount, nameof(clutValues), "Input channel count does not match the CLUT size");
Guard.IsTrue(this.OutputChannelCount == clutValues.OutputChannelCount, nameof(clutValues), "Output channel count does not match the CLUT size");
Guard.IsTrue(this.InputChannelCount == this.ClutValues.InputChannelCount, nameof(clutValues), "Input channel count does not match the CLUT size");
Guard.IsTrue(this.OutputChannelCount == this.ClutValues.OutputChannelCount, nameof(clutValues), "Output channel count does not match the CLUT size");
}
else if (this.IsMMatrixB())
{
@ -88,11 +88,11 @@ internal sealed class IccLutAToBTagDataEntry : IccTagDataEntry, IEquatable<IccLu
Guard.MustBeBetweenOrEqualTo(this.CurveA.Length, 1, 15, nameof(this.CurveA));
Guard.MustBeBetweenOrEqualTo(this.CurveB.Length, 1, 15, nameof(this.CurveB));
this.InputChannelCount = curveA.Length;
this.OutputChannelCount = curveB.Length;
this.InputChannelCount = this.CurveA.Length;
this.OutputChannelCount = this.CurveB.Length;
Guard.IsTrue(this.InputChannelCount == clutValues.InputChannelCount, nameof(clutValues), "Input channel count does not match the CLUT size");
Guard.IsTrue(this.OutputChannelCount == clutValues.OutputChannelCount, nameof(clutValues), "Output channel count does not match the CLUT size");
Guard.IsTrue(this.InputChannelCount == this.ClutValues.InputChannelCount, nameof(clutValues), "Input channel count does not match the CLUT size");
Guard.IsTrue(this.OutputChannelCount == this.ClutValues.OutputChannelCount, nameof(clutValues), "Output channel count does not match the CLUT size");
}
else if (this.IsB())
{
@ -127,28 +127,28 @@ internal sealed class IccLutAToBTagDataEntry : IccTagDataEntry, IEquatable<IccLu
/// <summary>
/// Gets the color lookup table
/// </summary>
public IccClut ClutValues { get; }
public IccClut? ClutValues { get; }
/// <summary>
/// Gets the B Curve
/// </summary>
public IccTagDataEntry[] CurveB { get; }
public IccTagDataEntry[]? CurveB { get; }
/// <summary>
/// Gets the M Curve
/// </summary>
public IccTagDataEntry[] CurveM { get; }
public IccTagDataEntry[]? CurveM { get; }
/// <summary>
/// Gets the A Curve
/// </summary>
public IccTagDataEntry[] CurveA { get; }
public IccTagDataEntry[]? CurveA { get; }
/// <inheritdoc/>
public override bool Equals(IccTagDataEntry other) => 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)
public bool Equals(IccLutAToBTagDataEntry? other)
{
if (other is null)
{
@ -165,14 +165,14 @@ internal sealed class IccLutAToBTagDataEntry : IccTagDataEntry, IEquatable<IccLu
&& this.OutputChannelCount == other.OutputChannelCount
&& this.Matrix3x3.Equals(other.Matrix3x3)
&& this.Matrix3x1.Equals(other.Matrix3x1)
&& this.ClutValues.Equals(other.ClutValues)
&& this.ClutValues!.Equals(other.ClutValues)
&& EqualsCurve(this.CurveB, other.CurveB)
&& EqualsCurve(this.CurveM, other.CurveM)
&& EqualsCurve(this.CurveA, other.CurveA);
}
/// <inheritdoc/>
public override bool Equals(object obj) => 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()
@ -192,7 +192,7 @@ internal sealed class IccLutAToBTagDataEntry : IccTagDataEntry, IEquatable<IccLu
return hashCode.ToHashCode();
}
private static bool EqualsCurve(IccTagDataEntry[] thisCurves, IccTagDataEntry[] entryCurves)
private static bool EqualsCurve(IccTagDataEntry[]? thisCurves, IccTagDataEntry[]? entryCurves)
{
bool thisNull = thisCurves is null;
bool entryNull = entryCurves is null;
@ -207,9 +207,13 @@ internal sealed class IccLutAToBTagDataEntry : IccTagDataEntry, IEquatable<IccLu
return false;
}
DebugGuard.NotNull(thisCurves);
DebugGuard.NotNull(entryCurves);
return thisCurves.SequenceEqual(entryCurves);
}
[MemberNotNullWhen(true, nameof(this.CurveB), nameof(Matrix3x3), nameof(this.Matrix3x1), nameof(this.CurveM), nameof(this.ClutValues), nameof(this.CurveA))]
private bool IsAClutMMatrixB()
=> this.CurveB != null
&& this.Matrix3x3 != null
@ -218,20 +222,23 @@ internal sealed class IccLutAToBTagDataEntry : IccTagDataEntry, IEquatable<IccLu
&& this.ClutValues != null
&& this.CurveA != null;
[MemberNotNullWhen(true, nameof(this.CurveB), nameof(Matrix3x3), nameof(this.Matrix3x1), nameof(this.CurveM))]
private bool IsMMatrixB()
=> this.CurveB != null
&& this.Matrix3x3 != null
&& this.Matrix3x1 != null
&& this.CurveM != null;
[MemberNotNullWhen(true, nameof(this.CurveB), nameof(this.ClutValues), nameof(this.CurveA))]
private bool IsAClutB()
=> this.CurveB != null
&& this.ClutValues != null
&& this.CurveA != null;
[MemberNotNullWhen(true, nameof(this.CurveB))]
private bool IsB() => this.CurveB != null;
private void VerifyCurve(IccTagDataEntry[] curves, string name)
private void VerifyCurve(IccTagDataEntry[]? curves, string name)
{
if (curves != null)
{
@ -240,7 +247,7 @@ internal sealed class IccLutAToBTagDataEntry : IccTagDataEntry, IEquatable<IccLu
}
}
private static void VerifyMatrix(float[,] matrix3x3, float[] matrix3x1)
private static void VerifyMatrix(float[,]? matrix3x3, float[]? matrix3x1)
{
if (matrix3x1 != null)
{
@ -254,7 +261,7 @@ internal sealed class IccLutAToBTagDataEntry : IccTagDataEntry, IEquatable<IccLu
}
}
private static Vector3? CreateMatrix3x1(float[] matrix)
private static Vector3? CreateMatrix3x1(float[]? matrix)
{
if (matrix is null)
{
@ -264,7 +271,7 @@ internal sealed class IccLutAToBTagDataEntry : IccTagDataEntry, IEquatable<IccLu
return new Vector3(matrix[0], matrix[1], matrix[2]);
}
private static Matrix4x4? CreateMatrix3x3(float[,] matrix)
private static Matrix4x4? CreateMatrix3x3(float[,]? matrix)
{
if (matrix is null)
{

115
src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccLutBToATagDataEntry.cs

@ -1,7 +1,7 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
#nullable disable
using System.Diagnostics.CodeAnalysis;
using System.Numerics;
// TODO: Review the use of base IccTagDataEntry comparison.
@ -15,19 +15,19 @@ internal sealed class IccLutBToATagDataEntry : IccTagDataEntry, IEquatable<IccLu
/// <summary>
/// Initializes a new instance of the <see cref="IccLutBToATagDataEntry"/> class.
/// </summary>
/// <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="curveM">M Curve</param>
/// <param name="clutValues">CLUT</param>
/// <param name="curveA">A 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="curveM">M Curve.</param>
/// <param name="clutValues">CLUT.</param>
/// <param name="curveA">A Curve.</param>
public IccLutBToATagDataEntry(
IccTagDataEntry[] curveB,
float[,] matrix3x3,
float[] matrix3x1,
IccTagDataEntry[] curveM,
IccClut clutValues,
IccTagDataEntry[] curveA)
IccTagDataEntry[]? curveB,
float[,]? matrix3x3,
float[]? matrix3x1,
IccTagDataEntry[]? curveM,
IccClut? clutValues,
IccTagDataEntry[]? curveA)
: this(curveB, matrix3x3, matrix3x1, curveM, clutValues, curveA, IccProfileTag.Unknown)
{
}
@ -35,20 +35,20 @@ internal sealed class IccLutBToATagDataEntry : IccTagDataEntry, IEquatable<IccLu
/// <summary>
/// Initializes a new instance of the <see cref="IccLutBToATagDataEntry"/> class.
/// </summary>
/// <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="curveM">M Curve</param>
/// <param name="clutValues">CLUT</param>
/// <param name="curveA">A Curve</param>
/// <param name="tagSignature">Tag Signature</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="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,
float[,] matrix3x3,
float[] matrix3x1,
IccTagDataEntry[] curveM,
IccClut clutValues,
IccTagDataEntry[] curveA,
IccTagDataEntry[]? curveB,
float[,]? matrix3x3,
float[]? matrix3x1,
IccTagDataEntry[]? curveM,
IccClut? clutValues,
IccTagDataEntry[]? curveA,
IccProfileTag tagSignature)
: base(IccTypeSignature.LutBToA, tagSignature)
{
@ -71,10 +71,10 @@ internal sealed class IccLutBToATagDataEntry : IccTagDataEntry, IEquatable<IccLu
Guard.MustBeBetweenOrEqualTo(this.CurveA.Length, 1, 15, nameof(this.CurveA));
this.InputChannelCount = 3;
this.OutputChannelCount = curveA.Length;
this.OutputChannelCount = this.CurveA.Length;
Guard.IsTrue(this.InputChannelCount == clutValues.InputChannelCount, nameof(clutValues), "Input channel count does not match the CLUT size");
Guard.IsTrue(this.OutputChannelCount == clutValues.OutputChannelCount, nameof(clutValues), "Output channel count does not match the CLUT size");
Guard.IsTrue(this.InputChannelCount == this.ClutValues.InputChannelCount, nameof(clutValues), "Input channel count does not match the CLUT size");
Guard.IsTrue(this.OutputChannelCount == this.ClutValues.OutputChannelCount, nameof(clutValues), "Output channel count does not match the CLUT size");
}
else if (this.IsBMatrixM())
{
@ -88,11 +88,11 @@ internal sealed class IccLutBToATagDataEntry : IccTagDataEntry, IEquatable<IccLu
Guard.MustBeBetweenOrEqualTo(this.CurveA.Length, 1, 15, nameof(this.CurveA));
Guard.MustBeBetweenOrEqualTo(this.CurveB.Length, 1, 15, nameof(this.CurveB));
this.InputChannelCount = curveB.Length;
this.OutputChannelCount = curveA.Length;
this.InputChannelCount = this.CurveB.Length;
this.OutputChannelCount = this.CurveA.Length;
Guard.IsTrue(this.InputChannelCount == clutValues.InputChannelCount, nameof(clutValues), "Input channel count does not match the CLUT size");
Guard.IsTrue(this.OutputChannelCount == clutValues.OutputChannelCount, nameof(clutValues), "Output channel count does not match the CLUT size");
Guard.IsTrue(this.InputChannelCount == this.ClutValues.InputChannelCount, nameof(clutValues), "Input channel count does not match the CLUT size");
Guard.IsTrue(this.OutputChannelCount == this.ClutValues.OutputChannelCount, nameof(clutValues), "Output channel count does not match the CLUT size");
}
else if (this.IsB())
{
@ -105,50 +105,50 @@ internal sealed class IccLutBToATagDataEntry : IccTagDataEntry, IEquatable<IccLu
}
/// <summary>
/// Gets the number of input channels
/// Gets the number of input channels.
/// </summary>
public int InputChannelCount { get; }
/// <summary>
/// Gets the number of output channels
/// Gets the number of output channels.
/// </summary>
public int OutputChannelCount { get; }
/// <summary>
/// Gets the two dimensional conversion matrix (3x3)
/// Gets the two dimensional conversion matrix (3x3).
/// </summary>
public Matrix4x4? Matrix3x3 { get; }
/// <summary>
/// Gets the one dimensional conversion matrix (3x1)
/// Gets the one dimensional conversion matrix (3x1).
/// </summary>
public Vector3? Matrix3x1 { get; }
/// <summary>
/// Gets the color lookup table
/// Gets the color lookup table.
/// </summary>
public IccClut ClutValues { get; }
public IccClut? ClutValues { get; }
/// <summary>
/// Gets the B Curve
/// Gets the B Curve.
/// </summary>
public IccTagDataEntry[] CurveB { get; }
public IccTagDataEntry[]? CurveB { get; }
/// <summary>
/// Gets the M Curve
/// Gets the M Curve.
/// </summary>
public IccTagDataEntry[] CurveM { get; }
public IccTagDataEntry[]? CurveM { get; }
/// <summary>
/// Gets the A Curve
/// Gets the A Curve.
/// </summary>
public IccTagDataEntry[] CurveA { get; }
public IccTagDataEntry[]? CurveA { get; }
/// <inheritdoc/>
public override bool Equals(IccTagDataEntry other) => 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)
public bool Equals(IccLutBToATagDataEntry? other)
{
if (other is null)
{
@ -165,14 +165,14 @@ internal sealed class IccLutBToATagDataEntry : IccTagDataEntry, IEquatable<IccLu
&& this.OutputChannelCount == other.OutputChannelCount
&& this.Matrix3x3.Equals(other.Matrix3x3)
&& this.Matrix3x1.Equals(other.Matrix3x1)
&& this.ClutValues.Equals(other.ClutValues)
&& this.ClutValues!.Equals(other.ClutValues)
&& EqualsCurve(this.CurveB, other.CurveB)
&& EqualsCurve(this.CurveM, other.CurveM)
&& EqualsCurve(this.CurveA, other.CurveA);
}
/// <inheritdoc/>
public override bool Equals(object obj) => 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()
@ -191,7 +191,7 @@ internal sealed class IccLutBToATagDataEntry : IccTagDataEntry, IEquatable<IccLu
return hashCode.ToHashCode();
}
private static bool EqualsCurve(IccTagDataEntry[] thisCurves, IccTagDataEntry[] entryCurves)
private static bool EqualsCurve(IccTagDataEntry[]? thisCurves, IccTagDataEntry[]? entryCurves)
{
bool thisNull = thisCurves is null;
bool entryNull = entryCurves is null;
@ -206,21 +206,28 @@ internal sealed class IccLutBToATagDataEntry : IccTagDataEntry, IEquatable<IccLu
return false;
}
DebugGuard.NotNull(thisCurves);
DebugGuard.NotNull(entryCurves);
return thisCurves.SequenceEqual(entryCurves);
}
[MemberNotNullWhen(true, nameof(this.CurveB), nameof(Matrix3x3), nameof(Matrix3x1), nameof(CurveM), nameof(ClutValues), nameof(CurveA))]
private bool IsBMatrixMClutA()
=> this.CurveB != null && this.Matrix3x3 != null && this.Matrix3x1 != null && this.CurveM != null && this.ClutValues != null && this.CurveA != null;
[MemberNotNullWhen(true, nameof(this.CurveB), nameof(this.Matrix3x3), nameof(this.Matrix3x1), nameof(this.CurveM))]
private bool IsBMatrixM()
=> this.CurveB != null && this.Matrix3x3 != null && this.Matrix3x1 != null && this.CurveM != null;
[MemberNotNullWhen(true, nameof(this.CurveB), nameof(this.ClutValues), nameof(this.CurveA))]
private bool IsBClutA()
=> this.CurveB != null && this.ClutValues != null && this.CurveA != null;
[MemberNotNullWhen(true, nameof(this.CurveB))]
private bool IsB() => this.CurveB != null;
private void VerifyCurve(IccTagDataEntry[] curves, string name)
private void VerifyCurve(IccTagDataEntry[]? curves, string name)
{
if (curves != null)
{
@ -229,7 +236,7 @@ internal sealed class IccLutBToATagDataEntry : IccTagDataEntry, IEquatable<IccLu
}
}
private static void VerifyMatrix(float[,] matrix3x3, float[] matrix3x1)
private static void VerifyMatrix(float[,]? matrix3x3, float[]? matrix3x1)
{
if (matrix3x1 != null)
{
@ -243,7 +250,7 @@ internal sealed class IccLutBToATagDataEntry : IccTagDataEntry, IEquatable<IccLu
}
}
private static Vector3? CreateMatrix3x1(float[] matrix)
private static Vector3? CreateMatrix3x1(float[]? matrix)
{
if (matrix is null)
{
@ -253,7 +260,7 @@ internal sealed class IccLutBToATagDataEntry : IccTagDataEntry, IEquatable<IccLu
return new Vector3(matrix[0], matrix[1], matrix[2]);
}
private static Matrix4x4? CreateMatrix3x3(float[,] matrix)
private static Matrix4x4? CreateMatrix3x3(float[,]? matrix)
{
if (matrix is null)
{

23
src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccTextDescriptionTagDataEntry.cs

@ -1,6 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
#nullable disable
using System.Globalization;
@ -19,7 +18,7 @@ internal sealed class IccTextDescriptionTagDataEntry : IccTagDataEntry, IEquatab
/// <param name="scriptCode">ScriptCode text</param>
/// <param name="unicodeLanguageCode">Unicode Language-Code</param>
/// <param name="scriptCodeCode">ScriptCode Code</param>
public IccTextDescriptionTagDataEntry(string ascii, string unicode, string scriptCode, uint unicodeLanguageCode, ushort scriptCodeCode)
public IccTextDescriptionTagDataEntry(string? ascii, string? unicode, string? scriptCode, uint unicodeLanguageCode, ushort scriptCodeCode)
: this(ascii, unicode, scriptCode, unicodeLanguageCode, scriptCodeCode, IccProfileTag.Unknown)
{
}
@ -33,7 +32,7 @@ internal sealed class IccTextDescriptionTagDataEntry : IccTagDataEntry, IEquatab
/// <param name="unicodeLanguageCode">Unicode Language-Code</param>
/// <param name="scriptCodeCode">ScriptCode Code</param>
/// <param name="tagSignature">Tag Signature</param>
public IccTextDescriptionTagDataEntry(string ascii, string unicode, string scriptCode, uint unicodeLanguageCode, ushort scriptCodeCode, IccProfileTag tagSignature)
public IccTextDescriptionTagDataEntry(string? ascii, string? unicode, string? scriptCode, uint unicodeLanguageCode, ushort scriptCodeCode, IccProfileTag tagSignature)
: base(IccTypeSignature.TextDescription, tagSignature)
{
this.Ascii = ascii;
@ -46,17 +45,17 @@ internal sealed class IccTextDescriptionTagDataEntry : IccTagDataEntry, IEquatab
/// <summary>
/// Gets the ASCII text
/// </summary>
public string Ascii { get; }
public string? Ascii { get; }
/// <summary>
/// Gets the Unicode text
/// </summary>
public string Unicode { get; }
public string? Unicode { get; }
/// <summary>
/// Gets the ScriptCode text
/// </summary>
public string ScriptCode { get; }
public string? ScriptCode { get; }
/// <summary>
/// Gets the Unicode Language-Code
@ -74,7 +73,7 @@ internal sealed class IccTextDescriptionTagDataEntry : IccTagDataEntry, IEquatab
/// </summary>
/// <param name="textEntry">The entry to convert</param>
/// <returns>The converted entry</returns>
public static explicit operator IccMultiLocalizedUnicodeTagDataEntry(IccTextDescriptionTagDataEntry textEntry)
public static explicit operator IccMultiLocalizedUnicodeTagDataEntry?(IccTextDescriptionTagDataEntry? textEntry)
{
if (textEntry is null)
{
@ -84,7 +83,7 @@ internal sealed class IccTextDescriptionTagDataEntry : IccTagDataEntry, IEquatab
IccLocalizedString localString;
if (!string.IsNullOrEmpty(textEntry.Unicode))
{
CultureInfo culture = GetCulture(textEntry.UnicodeLanguageCode);
CultureInfo? culture = GetCulture(textEntry.UnicodeLanguageCode);
localString = culture != null
? new IccLocalizedString(culture, textEntry.Unicode)
: new IccLocalizedString(textEntry.Unicode);
@ -104,7 +103,7 @@ internal sealed class IccTextDescriptionTagDataEntry : IccTagDataEntry, IEquatab
return new IccMultiLocalizedUnicodeTagDataEntry(new[] { localString }, textEntry.TagSignature);
static CultureInfo GetCulture(uint value)
static CultureInfo? GetCulture(uint value)
{
if (value == 0)
{
@ -131,11 +130,11 @@ internal sealed class IccTextDescriptionTagDataEntry : IccTagDataEntry, IEquatab
}
/// <inheritdoc/>
public override bool Equals(IccTagDataEntry other)
public override bool Equals(IccTagDataEntry? other)
=> other is IccTextDescriptionTagDataEntry entry && this.Equals(entry);
/// <inheritdoc />
public bool Equals(IccTextDescriptionTagDataEntry other)
public bool Equals(IccTextDescriptionTagDataEntry? other)
{
if (other is null)
{
@ -156,7 +155,7 @@ internal sealed class IccTextDescriptionTagDataEntry : IccTagDataEntry, IEquatab
}
/// <inheritdoc />
public override bool Equals(object obj)
public override bool Equals(object? obj)
=> obj is IccTextDescriptionTagDataEntry other && this.Equals(other);
/// <inheritdoc />

Loading…
Cancel
Save