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); ///