diff --git a/src/ImageSharp/ColorProfiles/Icc/Calculators/CurveCalculator.cs b/src/ImageSharp/ColorProfiles/Icc/Calculators/CurveCalculator.cs index c39eaf958f..1544276e64 100644 --- a/src/ImageSharp/ColorProfiles/Icc/Calculators/CurveCalculator.cs +++ b/src/ImageSharp/ColorProfiles/Icc/Calculators/CurveCalculator.cs @@ -1,7 +1,7 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#nullable disable +using System.Diagnostics.CodeAnalysis; using SixLabors.ImageSharp.ColorProfiles.Icc.Calculators; using SixLabors.ImageSharp.Metadata.Profiles.Icc; @@ -9,7 +9,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; @@ -36,12 +36,26 @@ public CurveCalculator(IccCurveTagDataEntry entry, bool inverted) } } + [MemberNotNullWhen(true, nameof(lutCalculator))] + private bool IsLut => this.type == CalculationType.Lut; + public float Calculate(float value) - => this.type switch + { + if (this.IsLut) + { + return this.lutCalculator.Calculate(value); + } + + if (this.type == CalculationType.Gamma) { - 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), - _ => throw new InvalidOperationException("Invalid calculation type"), - }; + return MathF.Pow(value, this.gamma); + } + + if (this.type == CalculationType.Identity) + { + return value; + } + + throw new InvalidOperationException("Invalid calculation type"); + } } diff --git a/src/ImageSharp/ColorProfiles/Icc/Calculators/GrayTrcCalculator.cs b/src/ImageSharp/ColorProfiles/Icc/Calculators/GrayTrcCalculator.cs index 8d823c1e95..1016f829be 100644 --- a/src/ImageSharp/ColorProfiles/Icc/Calculators/GrayTrcCalculator.cs +++ b/src/ImageSharp/ColorProfiles/Icc/Calculators/GrayTrcCalculator.cs @@ -12,7 +12,7 @@ internal class GrayTrcCalculator : IVector4Calculator private readonly TrcCalculator calculator; public GrayTrcCalculator(IccTagDataEntry grayTrc, bool toPcs) - => this.calculator = new TrcCalculator(new IccTagDataEntry[] { grayTrc }, !toPcs); + => this.calculator = new TrcCalculator([grayTrc], !toPcs); [MethodImpl(MethodImplOptions.AggressiveInlining)] public Vector4 Calculate(Vector4 value) => this.calculator.Calculate(value); diff --git a/src/ImageSharp/ColorProfiles/Icc/Calculators/LutABCalculator.CalculationType.cs b/src/ImageSharp/ColorProfiles/Icc/Calculators/LutABCalculator.CalculationType.cs index 253239cb79..2e6338de65 100644 --- a/src/ImageSharp/ColorProfiles/Icc/Calculators/LutABCalculator.CalculationType.cs +++ b/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, diff --git a/src/ImageSharp/ColorProfiles/Icc/Calculators/LutABCalculator.cs b/src/ImageSharp/ColorProfiles/Icc/Calculators/LutABCalculator.cs index 172d806394..7ac21309da 100644 --- a/src/ImageSharp/ColorProfiles/Icc/Calculators/LutABCalculator.cs +++ b/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 @@ public Vector4 Calculate(Vector4 value) 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 @@ private void Init(IccTagDataEntry[] curveA, IccTagDataEntry[] curveB, IccTagData 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!); } } } diff --git a/src/ImageSharp/ColorProfiles/Icc/Calculators/LutEntryCalculator.cs b/src/ImageSharp/ColorProfiles/Icc/Calculators/LutEntryCalculator.cs index c97578ee3f..5cd934d2d6 100644 --- a/src/ImageSharp/ColorProfiles/Icc/Calculators/LutEntryCalculator.cs +++ b/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 @@ private static Vector4 CalculateLut(LutCalculator[] lut, Vector4 value) 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); diff --git a/src/ImageSharp/ColorProfiles/Icc/IccConverterBase.Checks.cs b/src/ImageSharp/ColorProfiles/Icc/IccConverterBase.Checks.cs index 94f906709a..c108ac7758 100644 --- a/src/ImageSharp/ColorProfiles/Icc/IccConverterBase.Checks.cs +++ b/src/ImageSharp/ColorProfiles/Icc/IccConverterBase.Checks.cs @@ -1,7 +1,7 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#nullable disable +using System.Diagnostics.CodeAnalysis; using SixLabors.ImageSharp.Metadata.Profiles.Icc; namespace SixLabors.ImageSharp.ColorProfiles.Conversion.Icc; @@ -146,10 +146,17 @@ private static ConversionMethod CheckMethod2(IccProfile profile) 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 bool TryGetTag(IccProfile profile, IccProfileTag tag, [NotNullWhen(true)] out IccTagDataEntry? entry) + { + entry = GetTag(profile, tag); + + return entry is not null; + } + + private static IccTagDataEntry? GetTag(IccProfile profile, IccProfileTag tag) => Array.Find(profile.Entries, t => t.TagSignature == tag); - private static T GetTag(IccProfile profile, IccProfileTag tag) + private static T? GetTag(IccProfile profile, IccProfileTag tag) where T : IccTagDataEntry => profile.Entries.OfType().FirstOrDefault(t => t.TagSignature == tag); } diff --git a/src/ImageSharp/ColorProfiles/Icc/IccConverterbase.Conversions.cs b/src/ImageSharp/ColorProfiles/Icc/IccConverterbase.Conversions.cs index 20df08e378..4bbd961ab2 100644 --- a/src/ImageSharp/ColorProfiles/Icc/IccConverterbase.Conversions.cs +++ b/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 /// True if the conversion is to the Profile Connection Space. /// The wanted rendering intent. Can be ignored if not available. /// Invalid conversion method. + [MemberNotNull(nameof(this.calculator))] protected void Init(IccProfile profile, bool toPcs, IccRenderingIntent renderingIntent) => this.calculator = GetConversionMethod(profile, renderingIntent) switch { @@ -73,13 +75,13 @@ private static IVector4Calculator InitD(IccProfile profile, IccProfileTag tag) private static ColorTrcCalculator InitColorTrc(IccProfile profile, bool toPcs) { - IccXyzTagDataEntry redMatrixColumn = GetTag(profile, IccProfileTag.RedMatrixColumn); - IccXyzTagDataEntry greenMatrixColumn = GetTag(profile, IccProfileTag.GreenMatrixColumn); - IccXyzTagDataEntry blueMatrixColumn = GetTag(profile, IccProfileTag.BlueMatrixColumn); + IccXyzTagDataEntry? redMatrixColumn = GetTag(profile, IccProfileTag.RedMatrixColumn); + IccXyzTagDataEntry? greenMatrixColumn = GetTag(profile, IccProfileTag.GreenMatrixColumn); + IccXyzTagDataEntry? blueMatrixColumn = GetTag(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,11 @@ private static ColorTrcCalculator InitColorTrc(IccProfile profile, bool toPcs) private static GrayTrcCalculator InitGrayTrc(IccProfile profile, bool toPcs) { - IccTagDataEntry entry = GetTag(profile, IccProfileTag.GrayTrc); - return new GrayTrcCalculator(entry, toPcs); + if (TryGetTag(profile, IccProfileTag.GrayTrc, out IccTagDataEntry? entry)) + { + return new GrayTrcCalculator(entry, toPcs); + } + + throw new InvalidIccProfileException("Missing GrayTRC entry."); } } diff --git a/src/ImageSharp/ColorProfiles/Icc/IccConverterbase.cs b/src/ImageSharp/ColorProfiles/Icc/IccConverterbase.cs index d9976dc2ac..70562a3092 100644 --- a/src/ImageSharp/ColorProfiles/Icc/IccConverterbase.cs +++ b/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 /// /// The ICC profile to use for the conversions /// True if the conversion is to the profile connection space (PCS); False if the conversion is to the data space - protected IccConverterBase(IccProfile profile, bool toPcs) + protected IccConverterBase(IccProfile? profile, bool toPcs) { Guard.NotNull(profile, nameof(profile)); this.Init(profile, toPcs, profile.Header.RenderingIntent); diff --git a/src/ImageSharp/Formats/Tiff/TiffDecoderMetadataCreator.cs b/src/ImageSharp/Formats/Tiff/TiffDecoderMetadataCreator.cs index ebf407f9b5..51e984c646 100644 --- a/src/ImageSharp/Formats/Tiff/TiffDecoderMetadataCreator.cs +++ b/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 @@ public static ImageMetadata Create(List frames, bool ignoreM // 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 xmpProfileBytes)) + if (frameMetaData.ExifProfile.TryGetValue(ExifTag.XMP, out IExifValue? xmpProfileBytes)) { frameMetaData.XmpProfile = new XmpProfile(xmpProfileBytes.Value); } @@ -65,7 +66,7 @@ private static ImageMetadata Create(ByteOrder byteOrder, bool isBigTiff, ImageFr 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 @@ private static void SetResolution(ImageMetadata imageMetaData, ExifProfile exifP return; } - if (exifProfile.TryGetValue(ExifTag.XResolution, out IExifValue horizontalResolution)) + if (exifProfile.TryGetValue(ExifTag.XResolution, out IExifValue? horizontalResolution)) { imageMetaData.HorizontalResolution = horizontalResolution.Value.ToDouble(); } - if (exifProfile.TryGetValue(ExifTag.YResolution, out IExifValue verticalResolution)) + if (exifProfile.TryGetValue(ExifTag.YResolution, out IExifValue? verticalResolution)) { imageMetaData.VerticalResolution = verticalResolution.Value.ToDouble(); } } - private static bool TryGetIptc(IReadOnlyList exifValues, out byte[] iptcBytes) + private static bool TryGetIptc(IReadOnlyList 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) diff --git a/src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.NonPrimitives.cs b/src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.NonPrimitives.cs index 219e785590..ffe47df7cc 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.NonPrimitives.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.NonPrimitives.cs @@ -144,7 +144,7 @@ IccMultiLocalizedUnicodeTagDataEntry ReadText() 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"); diff --git a/src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.TagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.TagDataEntry.cs index 9e89d24ff4..5c6f1e85af 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.TagDataEntry.cs +++ b/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 @@ public IccLutAToBTagDataEntry ReadLutAtoBTagDataEntry() 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 @@ public IccLutBToATagDataEntry ReadLutBtoATagDataEntry() 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 @@ public IccMultiLocalizedUnicodeTagDataEntry ReadMultiLocalizedUnicodeTagDataEntr return new IccMultiLocalizedUnicodeTagDataEntry(text); - CultureInfo ReadCulture(string language, string country) + CultureInfo ReadCulture(string language, string? country) { if (string.IsNullOrWhiteSpace(language)) { @@ -775,8 +774,8 @@ public IccXyzTagDataEntry ReadXyzTagDataEntry(uint size) /// The read entry. 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) diff --git a/src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.Primitives.cs b/src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.Primitives.cs index e1eebb749b..a668c61207 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.Primitives.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.Primitives.cs @@ -189,7 +189,7 @@ public int WriteAsciiString(string value) /// The desired length of the string (including potential null terminator) /// If True, there will be a \0 added at the end /// the number of bytes written - public int WriteAsciiString(string value, int length, bool ensureNullTerminator) + public int WriteAsciiString(string? value, int length, bool ensureNullTerminator) { if (length == 0) { diff --git a/src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.TagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.TagDataEntry.cs index 6019a0bff7..15e53a2b46 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/DataWriter/IccDataWriter.TagDataEntry.cs +++ b/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 @@ public int WriteTagDataEntry(IccTagDataEntry entry) IccTypeSignature.UcrBg => this.WriteUcrBgTagDataEntry((IccUcrBgTagDataEntry)entry), // Unsupported or unknown - _ => this.WriteUnknownTagDataEntry(entry as IccUnknownTagDataEntry), + _ => this.WriteUnknownTagDataEntry((entry as IccUnknownTagDataEntry)!), }; return count; } diff --git a/src/ImageSharp/Metadata/Profiles/ICC/IccProfile.cs b/src/ImageSharp/Metadata/Profiles/ICC/IccProfile.cs index 05be3eb5dd..b93d5e9fa6 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/IccProfile.cs +++ b/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 /// /// The byte array to read the ICC profile from /// - private readonly byte[] data; + private readonly byte[]? data; /// /// The backing file for the property /// - private IccTagDataEntry[] entries; + private IccTagDataEntry[]? entries; /// /// ICC profile header /// - private IccProfileHeader header; + private IccProfileHeader? header; /// /// Initializes a new instance of the class. /// public IccProfile() - : this((byte[])null) + : this((byte[]?)null) { } @@ -38,7 +38,7 @@ public IccProfile() /// Initializes a new instance of the class. /// /// The raw ICC profile data - public IccProfile(byte[] data) => this.data = data; + public IccProfile(byte[]? data) => this.data = data; /// /// Initializes a new instance of the class. @@ -177,6 +177,7 @@ public byte[] ToByteArray() return IccWriter.Write(this); } + [MemberNotNull(nameof(this.header))] private void InitializeHeader() { if (this.header != null) @@ -193,6 +194,7 @@ private void InitializeHeader() this.header = IccReader.ReadHeader(this.data); } + [MemberNotNull(nameof(this.entries))] private void InitializeEntries() { if (this.entries != null) diff --git a/src/ImageSharp/Metadata/Profiles/ICC/IccProfileHeader.cs b/src/ImageSharp/Metadata/Profiles/ICC/IccProfileHeader.cs index 959668aaf9..cea2a6cc23 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/IccProfileHeader.cs +++ b/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 /// /// Gets or sets the preferred CMM (Color Management Module) type. /// - public string CmmType { get; set; } + public string? CmmType { get; set; } /// /// 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. /// - public string FileSignature { get; set; } + public string? FileSignature { get; set; } /// /// Gets or sets the primary platform this profile as created for @@ -91,7 +90,7 @@ public sealed class IccProfileHeader /// /// Gets or sets profile creator signature. /// - public string CreatorSignature { get; set; } + public string? CreatorSignature { get; set; } /// /// Gets or sets the profile ID (hash). diff --git a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccLutAToBTagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccLutAToBTagDataEntry.cs index 9bf3232633..9d404ddb1d 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccLutAToBTagDataEntry.cs +++ b/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, IEquatableCLUT /// A Curve 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 @@ public IccLutAToBTagDataEntry( /// A Curve /// Tag Signature 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 @@ public IccLutAToBTagDataEntry( 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 @@ public IccLutAToBTagDataEntry( 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 @@ public IccLutAToBTagDataEntry( /// /// Gets the color lookup table /// - public IccClut ClutValues { get; } + public IccClut? ClutValues { get; } /// /// Gets the B Curve /// - public IccTagDataEntry[] CurveB { get; } + public IccTagDataEntry[]? CurveB { get; } /// /// Gets the M Curve /// - public IccTagDataEntry[] CurveM { get; } + public IccTagDataEntry[]? CurveM { get; } /// /// Gets the A Curve /// - public IccTagDataEntry[] CurveA { get; } + public IccTagDataEntry[]? CurveA { get; } /// - 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); /// - public bool Equals(IccLutAToBTagDataEntry other) + public bool Equals(IccLutAToBTagDataEntry? other) { if (other is null) { @@ -165,14 +165,14 @@ public bool Equals(IccLutAToBTagDataEntry other) && 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); } /// - 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); /// public override int GetHashCode() @@ -192,7 +192,7 @@ public override int GetHashCode() 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 @@ private static bool EqualsCurve(IccTagDataEntry[] thisCurves, IccTagDataEntry[] 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 @@ private bool IsAClutMMatrixB() && 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 @@ private void VerifyCurve(IccTagDataEntry[] curves, string name) } } - private static void VerifyMatrix(float[,] matrix3x3, float[] matrix3x1) + private static void VerifyMatrix(float[,]? matrix3x3, float[]? matrix3x1) { if (matrix3x1 != null) { @@ -254,7 +261,7 @@ private static void VerifyMatrix(float[,] matrix3x3, float[] matrix3x1) } } - private static Vector3? CreateMatrix3x1(float[] matrix) + private static Vector3? CreateMatrix3x1(float[]? matrix) { if (matrix is null) { @@ -264,7 +271,7 @@ private static void VerifyMatrix(float[,] matrix3x3, float[] matrix3x1) 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) { diff --git a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccLutBToATagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccLutBToATagDataEntry.cs index 033b809894..73b884c67f 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccLutBToATagDataEntry.cs +++ b/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 /// Initializes a new instance of the class. /// - /// B Curve - /// Two dimensional conversion matrix (3x3) - /// One dimensional conversion matrix (3x1) - /// M Curve - /// CLUT - /// A Curve + /// B Curve. + /// Two dimensional conversion matrix (3x3). + /// One dimensional conversion matrix (3x1). + /// M Curve. + /// CLUT. + /// A Curve. 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 @@ public IccLutBToATagDataEntry( /// /// Initializes a new instance of the class. /// - /// B Curve - /// Two dimensional conversion matrix (3x3) - /// One dimensional conversion matrix (3x1) - /// M Curve - /// CLUT - /// A Curve - /// Tag Signature + /// B Curve. + /// Two dimensional conversion matrix (3x3). + /// One dimensional conversion matrix (3x1). + /// M Curve. + /// CLUT. + /// A Curve. + /// Tag Signature. 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 @@ public IccLutBToATagDataEntry( 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 @@ public IccLutBToATagDataEntry( 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 @@ public IccLutBToATagDataEntry( } /// - /// Gets the number of input channels + /// Gets the number of input channels. /// public int InputChannelCount { get; } /// - /// Gets the number of output channels + /// Gets the number of output channels. /// public int OutputChannelCount { get; } /// - /// Gets the two dimensional conversion matrix (3x3) + /// Gets the two dimensional conversion matrix (3x3). /// public Matrix4x4? Matrix3x3 { get; } /// - /// Gets the one dimensional conversion matrix (3x1) + /// Gets the one dimensional conversion matrix (3x1). /// public Vector3? Matrix3x1 { get; } /// - /// Gets the color lookup table + /// Gets the color lookup table. /// - public IccClut ClutValues { get; } + public IccClut? ClutValues { get; } /// - /// Gets the B Curve + /// Gets the B Curve. /// - public IccTagDataEntry[] CurveB { get; } + public IccTagDataEntry[]? CurveB { get; } /// - /// Gets the M Curve + /// Gets the M Curve. /// - public IccTagDataEntry[] CurveM { get; } + public IccTagDataEntry[]? CurveM { get; } /// - /// Gets the A Curve + /// Gets the A Curve. /// - public IccTagDataEntry[] CurveA { get; } + public IccTagDataEntry[]? CurveA { get; } /// - 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); /// - public bool Equals(IccLutBToATagDataEntry other) + public bool Equals(IccLutBToATagDataEntry? other) { if (other is null) { @@ -165,14 +165,14 @@ public bool Equals(IccLutBToATagDataEntry other) && 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); } /// - 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); /// public override int GetHashCode() @@ -191,7 +191,7 @@ public override int GetHashCode() 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 @@ private static bool EqualsCurve(IccTagDataEntry[] thisCurves, IccTagDataEntry[] 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 @@ private void VerifyCurve(IccTagDataEntry[] curves, string name) } } - private static void VerifyMatrix(float[,] matrix3x3, float[] matrix3x1) + private static void VerifyMatrix(float[,]? matrix3x3, float[]? matrix3x1) { if (matrix3x1 != null) { @@ -243,7 +250,7 @@ private static void VerifyMatrix(float[,] matrix3x3, float[] matrix3x1) } } - private static Vector3? CreateMatrix3x1(float[] matrix) + private static Vector3? CreateMatrix3x1(float[]? matrix) { if (matrix is null) { @@ -253,7 +260,7 @@ private static void VerifyMatrix(float[,] matrix3x3, float[] matrix3x1) 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) { diff --git a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccTextDescriptionTagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccTextDescriptionTagDataEntry.cs index 7db26e5c58..6d21fe93b0 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccTextDescriptionTagDataEntry.cs +++ b/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 /// ScriptCode text /// Unicode Language-Code /// ScriptCode Code - 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 @@ public IccTextDescriptionTagDataEntry(string ascii, string unicode, string scrip /// Unicode Language-Code /// ScriptCode Code /// Tag Signature - 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 @@ public IccTextDescriptionTagDataEntry(string ascii, string unicode, string scrip /// /// Gets the ASCII text /// - public string Ascii { get; } + public string? Ascii { get; } /// /// Gets the Unicode text /// - public string Unicode { get; } + public string? Unicode { get; } /// /// Gets the ScriptCode text /// - public string ScriptCode { get; } + public string? ScriptCode { get; } /// /// Gets the Unicode Language-Code @@ -74,7 +73,7 @@ public IccTextDescriptionTagDataEntry(string ascii, string unicode, string scrip /// /// The entry to convert /// The converted entry - public static explicit operator IccMultiLocalizedUnicodeTagDataEntry(IccTextDescriptionTagDataEntry textEntry) + public static explicit operator IccMultiLocalizedUnicodeTagDataEntry?(IccTextDescriptionTagDataEntry? textEntry) { if (textEntry is null) { @@ -84,7 +83,7 @@ public static explicit operator IccMultiLocalizedUnicodeTagDataEntry(IccTextDesc 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 @@ public static explicit operator IccMultiLocalizedUnicodeTagDataEntry(IccTextDesc return new IccMultiLocalizedUnicodeTagDataEntry(new[] { localString }, textEntry.TagSignature); - static CultureInfo GetCulture(uint value) + static CultureInfo? GetCulture(uint value) { if (value == 0) { @@ -131,11 +130,11 @@ static CultureInfo GetCulture(uint value) } /// - public override bool Equals(IccTagDataEntry other) + public override bool Equals(IccTagDataEntry? other) => other is IccTextDescriptionTagDataEntry entry && this.Equals(entry); /// - public bool Equals(IccTextDescriptionTagDataEntry other) + public bool Equals(IccTextDescriptionTagDataEntry? other) { if (other is null) { @@ -156,7 +155,7 @@ public bool Equals(IccTextDescriptionTagDataEntry other) } /// - public override bool Equals(object obj) + public override bool Equals(object? obj) => obj is IccTextDescriptionTagDataEntry other && this.Equals(other); ///