From 5078f1e1df1d0a91a0bf61af12ca26aad602d56c Mon Sep 17 00:00:00 2001 From: Stefan Nikolei Date: Thu, 26 Jan 2023 09:26:19 +0100 Subject: [PATCH 1/3] Remove Nullable disable from MetaData.Profiles #2231 --- .../Formats/Gif/MetadataExtensions.cs | 3 ++- src/ImageSharp/Metadata/ImageFrameMetadata.cs | 15 +++++++------- .../Metadata/Profiles/IPTC/IptcProfile.cs | 20 +++++++++---------- .../Metadata/Profiles/IPTC/IptcValue.cs | 10 +++------- .../Metadata/Profiles/XMP/XmpProfile.cs | 13 ++++++------ 5 files changed, 28 insertions(+), 33 deletions(-) diff --git a/src/ImageSharp/Formats/Gif/MetadataExtensions.cs b/src/ImageSharp/Formats/Gif/MetadataExtensions.cs index 7280024e2..e20b9dd17 100644 --- a/src/ImageSharp/Formats/Gif/MetadataExtensions.cs +++ b/src/ImageSharp/Formats/Gif/MetadataExtensions.cs @@ -1,6 +1,7 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. +using System.Diagnostics.CodeAnalysis; using SixLabors.ImageSharp.Formats.Gif; using SixLabors.ImageSharp.Metadata; @@ -37,5 +38,5 @@ public static partial class MetadataExtensions /// /// if the gif frame metadata exists; otherwise, . /// - public static bool TryGetGifMetadata(this ImageFrameMetadata source, out GifFrameMetadata metadata) => source.TryGetFormatMetadata(GifFormat.Instance, out metadata); + public static bool TryGetGifMetadata(this ImageFrameMetadata source, [NotNullWhen(true)] out GifFrameMetadata? metadata) => source.TryGetFormatMetadata(GifFormat.Instance, out metadata); } diff --git a/src/ImageSharp/Metadata/ImageFrameMetadata.cs b/src/ImageSharp/Metadata/ImageFrameMetadata.cs index 08a3dc74d..03f628afa 100644 --- a/src/ImageSharp/Metadata/ImageFrameMetadata.cs +++ b/src/ImageSharp/Metadata/ImageFrameMetadata.cs @@ -1,6 +1,5 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#nullable disable using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.Metadata.Profiles.Exif; @@ -49,22 +48,22 @@ public sealed class ImageFrameMetadata : IDeepCloneable /// /// Gets or sets the Exif profile. /// - public ExifProfile ExifProfile { get; set; } + public ExifProfile? ExifProfile { get; set; } /// /// Gets or sets the XMP profile. /// - public XmpProfile XmpProfile { get; set; } + public XmpProfile? XmpProfile { get; set; } /// /// Gets or sets the ICC profile. /// - public IccProfile IccProfile { get; set; } + public IccProfile? IccProfile { get; set; } /// /// Gets or sets the iptc profile. /// - public IptcProfile IptcProfile { get; set; } + public IptcProfile? IptcProfile { get; set; } /// public ImageFrameMetadata DeepClone() => new(this); @@ -83,7 +82,7 @@ public sealed class ImageFrameMetadata : IDeepCloneable where TFormatMetadata : class where TFormatFrameMetadata : class, IDeepCloneable { - if (this.formatMetadata.TryGetValue(key, out IDeepCloneable meta)) + if (this.formatMetadata.TryGetValue(key, out IDeepCloneable? meta)) { return (TFormatFrameMetadata)meta; } @@ -107,11 +106,11 @@ public sealed class ImageFrameMetadata : IDeepCloneable /// /// if the frame metadata exists for the specified key; otherwise, . /// - public bool TryGetFormatMetadata(IImageFormat key, out TFormatFrameMetadata metadata) + public bool TryGetFormatMetadata(IImageFormat key, out TFormatFrameMetadata? metadata) where TFormatMetadata : class where TFormatFrameMetadata : class, IDeepCloneable { - if (this.formatMetadata.TryGetValue(key, out IDeepCloneable meta)) + if (this.formatMetadata.TryGetValue(key, out IDeepCloneable? meta)) { metadata = (TFormatFrameMetadata)meta; return true; diff --git a/src/ImageSharp/Metadata/Profiles/IPTC/IptcProfile.cs b/src/ImageSharp/Metadata/Profiles/IPTC/IptcProfile.cs index 1aff9cc5d..4c20f6c15 100644 --- a/src/ImageSharp/Metadata/Profiles/IPTC/IptcProfile.cs +++ b/src/ImageSharp/Metadata/Profiles/IPTC/IptcProfile.cs @@ -1,9 +1,9 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#nullable disable using System.Buffers.Binary; using System.Collections.ObjectModel; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Text; using SixLabors.ImageSharp.Metadata.Profiles.IPTC; @@ -30,7 +30,7 @@ public sealed class IptcProfile : IDeepCloneable /// Initializes a new instance of the class. /// public IptcProfile() - : this((byte[])null) + : this((byte[]?)null) { } @@ -38,7 +38,7 @@ public sealed class IptcProfile : IDeepCloneable /// Initializes a new instance of the class. /// /// The byte array to read the iptc profile from. - public IptcProfile(byte[] data) + public IptcProfile(byte[]? data) { this.Data = data; this.Initialize(); @@ -53,14 +53,11 @@ public sealed class IptcProfile : IDeepCloneable { Guard.NotNull(other, nameof(other)); - if (other.values != null) - { - this.values = new Collection(); + this.values = new Collection(); - foreach (IptcValue value in other.Values) - { - this.values.Add(value.DeepClone()); - } + foreach (IptcValue value in other.Values) + { + this.values.Add(value.DeepClone()); } if (other.Data != null) @@ -78,7 +75,7 @@ public sealed class IptcProfile : IDeepCloneable /// /// Gets the byte data of the IPTC profile. /// - public byte[] Data { get; private set; } + public byte[]? Data { get; private set; } /// /// Gets the values of this iptc profile. @@ -310,6 +307,7 @@ public sealed class IptcProfile : IDeepCloneable return offset; } + [MemberNotNull(nameof(values))] private void Initialize() { if (this.values != null) diff --git a/src/ImageSharp/Metadata/Profiles/IPTC/IptcValue.cs b/src/ImageSharp/Metadata/Profiles/IPTC/IptcValue.cs index d39697e89..1a75ecba2 100644 --- a/src/ImageSharp/Metadata/Profiles/IPTC/IptcValue.cs +++ b/src/ImageSharp/Metadata/Profiles/IPTC/IptcValue.cs @@ -1,6 +1,5 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#nullable disable using System.Text; @@ -22,10 +21,7 @@ public sealed class IptcValue : IDeepCloneable other.data.AsSpan().CopyTo(this.data); } - if (other.Encoding != null) - { - this.Encoding = (Encoding)other.Encoding.Clone(); - } + this.encoding = (Encoding)other.Encoding.Clone(); this.Tag = other.Tag; this.Strict = other.Strict; @@ -133,7 +129,7 @@ public sealed class IptcValue : IDeepCloneable /// /// The object to compare this with. /// True when the specified object is equal to the current . - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (ReferenceEquals(this, obj)) { @@ -148,7 +144,7 @@ public sealed class IptcValue : IDeepCloneable /// /// The iptc value to compare this with. /// True when the specified iptc value is equal to the current . - public bool Equals(IptcValue other) + public bool Equals(IptcValue? other) { if (other is null) { diff --git a/src/ImageSharp/Metadata/Profiles/XMP/XmpProfile.cs b/src/ImageSharp/Metadata/Profiles/XMP/XmpProfile.cs index 5e9024cf0..77ff35df0 100644 --- a/src/ImageSharp/Metadata/Profiles/XMP/XmpProfile.cs +++ b/src/ImageSharp/Metadata/Profiles/XMP/XmpProfile.cs @@ -1,7 +1,7 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -#nullable disable +using System.Diagnostics; using System.Text; using System.Xml.Linq; @@ -17,7 +17,7 @@ public sealed class XmpProfile : IDeepCloneable /// Initializes a new instance of the class. /// public XmpProfile() - : this((byte[])null) + : this((byte[]?)null) { } @@ -25,7 +25,7 @@ public sealed class XmpProfile : IDeepCloneable /// Initializes a new instance of the class. /// /// The UTF8 encoded byte array to read the XMP profile from. - public XmpProfile(byte[] data) => this.Data = data; + public XmpProfile(byte[]? data) => this.Data = data; /// /// Initializes a new instance of the class @@ -42,15 +42,15 @@ public sealed class XmpProfile : IDeepCloneable /// /// Gets the XMP raw data byte array. /// - internal byte[] Data { get; private set; } + internal byte[]? Data { get; private set; } /// /// Gets the raw XML document containing the XMP profile. /// /// The - public XDocument GetDocument() + public XDocument? GetDocument() { - byte[] byteArray = this.Data; + byte[]? byteArray = this.Data; if (byteArray is null) { return null; @@ -77,6 +77,7 @@ public sealed class XmpProfile : IDeepCloneable /// The public byte[] ToByteArray() { + Guard.NotNull(this.Data); byte[] result = new byte[this.Data.Length]; this.Data.AsSpan().CopyTo(result); return result; From 6eec48de54dfacd0df1a93fe465e3368833d4fd6 Mon Sep 17 00:00:00 2001 From: Stefan Nikolei Date: Fri, 3 Feb 2023 16:39:58 +0100 Subject: [PATCH 2/3] Initialize values during declaration --- src/ImageSharp/Metadata/Profiles/IPTC/IptcProfile.cs | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/ImageSharp/Metadata/Profiles/IPTC/IptcProfile.cs b/src/ImageSharp/Metadata/Profiles/IPTC/IptcProfile.cs index 4c20f6c15..d7bd09758 100644 --- a/src/ImageSharp/Metadata/Profiles/IPTC/IptcProfile.cs +++ b/src/ImageSharp/Metadata/Profiles/IPTC/IptcProfile.cs @@ -15,7 +15,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Iptc; /// public sealed class IptcProfile : IDeepCloneable { - private Collection values; + private readonly Collection values = new(); private const byte IptcTagMarkerByte = 0x1c; @@ -53,8 +53,6 @@ public sealed class IptcProfile : IDeepCloneable { Guard.NotNull(other, nameof(other)); - this.values = new Collection(); - foreach (IptcValue value in other.Values) { this.values.Add(value.DeepClone()); @@ -307,16 +305,8 @@ public sealed class IptcProfile : IDeepCloneable return offset; } - [MemberNotNull(nameof(values))] private void Initialize() { - if (this.values != null) - { - return; - } - - this.values = new Collection(); - if (this.Data == null || this.Data[0] != IptcTagMarkerByte) { return; From 2d6c1746063a19a5f0b1ca2871035ad7c4d75dc3 Mon Sep 17 00:00:00 2001 From: Stefan Nikolei Date: Fri, 3 Feb 2023 16:49:13 +0100 Subject: [PATCH 3/3] Initialize is only needed in the constructor. It would just return on the other invocations --- .../Metadata/Profiles/IPTC/IptcProfile.cs | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/ImageSharp/Metadata/Profiles/IPTC/IptcProfile.cs b/src/ImageSharp/Metadata/Profiles/IPTC/IptcProfile.cs index d7bd09758..162fae96b 100644 --- a/src/ImageSharp/Metadata/Profiles/IPTC/IptcProfile.cs +++ b/src/ImageSharp/Metadata/Profiles/IPTC/IptcProfile.cs @@ -78,14 +78,7 @@ public sealed class IptcProfile : IDeepCloneable /// /// Gets the values of this iptc profile. /// - public IEnumerable Values - { - get - { - this.Initialize(); - return this.values; - } - } + public IEnumerable Values => this.values; /// public IptcProfile DeepClone() => new(this); @@ -116,8 +109,6 @@ public sealed class IptcProfile : IDeepCloneable /// True when the value was found and removed. public bool RemoveValue(IptcTag tag) { - this.Initialize(); - bool removed = false; for (int i = this.values.Count - 1; i >= 0; i--) { @@ -139,8 +130,6 @@ public sealed class IptcProfile : IDeepCloneable /// True when the value was found and removed. public bool RemoveValue(IptcTag tag, string value) { - this.Initialize(); - bool removed = false; for (int i = this.values.Count - 1; i >= 0; i--) {