From 30a2dfaaa920f41baf422b4037f7123c86033912 Mon Sep 17 00:00:00 2001 From: Stefan Nikolei Date: Fri, 21 Nov 2025 23:43:42 +0100 Subject: [PATCH] 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. --- .../Icc/Calculators/CurveCalculator.cs | 5 +- .../Icc/Calculators/GrayTrcCalculator.cs | 4 +- .../LutABCalculator.CalculationType.cs | 1 + .../Icc/Calculators/LutABCalculator.cs | 73 ++++++----- .../Icc/Calculators/LutEntryCalculator.cs | 3 +- .../Icc/Calculators/TrcCalculator.cs | 2 +- .../Icc/IccConverterBase.Checks.cs | 5 +- .../Icc/IccConverterbase.Conversions.cs | 16 +-- .../ColorProfiles/Icc/IccConverterbase.cs | 3 +- .../Tiff/TiffDecoderMetadataCreator.cs | 21 ++-- .../DataReader/IccDataReader.NonPrimitives.cs | 2 +- .../DataReader/IccDataReader.TagDataEntry.cs | 31 +++-- .../DataWriter/IccDataWriter.Primitives.cs | 2 +- .../DataWriter/IccDataWriter.TagDataEntry.cs | 3 +- .../Metadata/Profiles/ICC/IccProfile.cs | 14 ++- .../Metadata/Profiles/ICC/IccProfileHeader.cs | 7 +- .../TagDataEntries/IccLutAToBTagDataEntry.cs | 73 ++++++----- .../TagDataEntries/IccLutBToATagDataEntry.cs | 115 ++++++++++-------- .../IccTextDescriptionTagDataEntry.cs | 23 ++-- 19 files changed, 208 insertions(+), 195 deletions(-) diff --git a/src/ImageSharp/ColorProfiles/Icc/Calculators/CurveCalculator.cs b/src/ImageSharp/ColorProfiles/Icc/Calculators/CurveCalculator.cs index c39eaf958..476b8188f 100644 --- a/src/ImageSharp/ColorProfiles/Icc/Calculators/CurveCalculator.cs +++ b/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"), }; } diff --git a/src/ImageSharp/ColorProfiles/Icc/Calculators/GrayTrcCalculator.cs b/src/ImageSharp/ColorProfiles/Icc/Calculators/GrayTrcCalculator.cs index 8d823c1e9..dffbd8055 100644 --- a/src/ImageSharp/ColorProfiles/Icc/Calculators/GrayTrcCalculator.cs +++ b/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); diff --git a/src/ImageSharp/ColorProfiles/Icc/Calculators/LutABCalculator.CalculationType.cs b/src/ImageSharp/ColorProfiles/Icc/Calculators/LutABCalculator.CalculationType.cs index 253239cb7..2e6338de6 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 172d80639..7ac21309d 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 @@ 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!); } } } diff --git a/src/ImageSharp/ColorProfiles/Icc/Calculators/LutEntryCalculator.cs b/src/ImageSharp/ColorProfiles/Icc/Calculators/LutEntryCalculator.cs index c97578ee3..5cd934d2d 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 @@ 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); diff --git a/src/ImageSharp/ColorProfiles/Icc/Calculators/TrcCalculator.cs b/src/ImageSharp/ColorProfiles/Icc/Calculators/TrcCalculator.cs index d2fc5d9b5..3eb8d2e00 100644 --- a/src/ImageSharp/ColorProfiles/Icc/Calculators/TrcCalculator.cs +++ b/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)); diff --git a/src/ImageSharp/ColorProfiles/Icc/IccConverterBase.Checks.cs b/src/ImageSharp/ColorProfiles/Icc/IccConverterBase.Checks.cs index 94f906709..7495f9ace 100644 --- a/src/ImageSharp/ColorProfiles/Icc/IccConverterBase.Checks.cs +++ b/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(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 20df08e37..a25b15152 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 @@ internal abstract partial class IccConverterBase 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,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); } } diff --git a/src/ImageSharp/ColorProfiles/Icc/IccConverterbase.cs b/src/ImageSharp/ColorProfiles/Icc/IccConverterbase.cs index d9976dc2a..70562a309 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 ebf407f9b..51e984c64 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 @@ 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 xmpProfileBytes)) + if (frameMetaData.ExifProfile.TryGetValue(ExifTag.XMP, out IExifValue? 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 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 219e78559..ffe47df7c 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 @@ 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"); diff --git a/src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.TagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/DataReader/IccDataReader.TagDataEntry.cs index 9e89d24ff..5c6f1e85a 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 @@ 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 /// 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 e1eebb749..a668c6120 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 @@ internal sealed partial class IccDataWriter /// 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 6019a0bff..15e53a2b4 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 @@ 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; } diff --git a/src/ImageSharp/Metadata/Profiles/ICC/IccProfile.cs b/src/ImageSharp/Metadata/Profiles/ICC/IccProfile.cs index 05be3eb5d..b93d5e9fa 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 sealed partial class IccProfile : IDeepCloneable /// 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 sealed partial class IccProfile : IDeepCloneable 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 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 959668aaf..cea2a6cc2 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 9bf323263..9d404ddb1 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 @@ internal sealed class IccLutAToBTagDataEntry : IccTagDataEntry, IEquatableA 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 @@ internal sealed class IccLutAToBTagDataEntry : IccTagDataEntry, IEquatable /// 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 @@ internal sealed class IccLutAToBTagDataEntry : IccTagDataEntry, IEquatable - 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 @@ internal sealed class IccLutAToBTagDataEntry : IccTagDataEntry, IEquatable this.CurveB != null && this.Matrix3x3 != null @@ -218,20 +222,23 @@ internal sealed class IccLutAToBTagDataEntry : IccTagDataEntry, IEquatable 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 /// 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 @@ 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 - /// 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 @@ internal sealed class IccLutBToATagDataEntry : IccTagDataEntry, IEquatable - /// 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 @@ internal sealed class IccLutBToATagDataEntry : IccTagDataEntry, IEquatable - 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 @@ internal sealed class IccLutBToATagDataEntry : IccTagDataEntry, IEquatable 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, IEquatableScriptCode 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 @@ internal sealed class IccTextDescriptionTagDataEntry : IccTagDataEntry, IEquatab /// 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 @@ internal sealed class IccTextDescriptionTagDataEntry : IccTagDataEntry, IEquatab /// /// 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 @@ internal sealed class IccTextDescriptionTagDataEntry : IccTagDataEntry, IEquatab /// /// 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 @@ 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 } /// - 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 @@ internal sealed class IccTextDescriptionTagDataEntry : IccTagDataEntry, IEquatab } /// - public override bool Equals(object obj) + public override bool Equals(object? obj) => obj is IccTextDescriptionTagDataEntry other && this.Equals(other); ///