Browse Source

Remove #nullable disable from ExifProfile

pull/2320/head
Stefan Nikolei 4 years ago
parent
commit
07d116d8d1
  1. 2
      src/ImageSharp/Common/Helpers/UnitConverter.cs
  2. 4
      src/ImageSharp/Metadata/Profiles/Exif/ExifEncodedStringHelpers.cs
  3. 31
      src/ImageSharp/Metadata/Profiles/Exif/ExifProfile.cs
  4. 27
      src/ImageSharp/Metadata/Profiles/Exif/ExifReader.cs
  5. 9
      src/ImageSharp/Metadata/Profiles/Exif/ExifTagDescriptionAttribute.cs
  6. 28
      src/ImageSharp/Metadata/Profiles/Exif/ExifWriter.cs
  7. 7
      src/ImageSharp/Metadata/Profiles/Exif/Values/ExifArrayValue{TValueType}.cs
  8. 2
      src/ImageSharp/Metadata/Profiles/Exif/Values/ExifByte.cs
  9. 2
      src/ImageSharp/Metadata/Profiles/Exif/Values/ExifByteArray.cs
  10. 2
      src/ImageSharp/Metadata/Profiles/Exif/Values/ExifDouble.cs
  11. 2
      src/ImageSharp/Metadata/Profiles/Exif/Values/ExifEncodedString.cs
  12. 2
      src/ImageSharp/Metadata/Profiles/Exif/Values/ExifFloat.cs
  13. 2
      src/ImageSharp/Metadata/Profiles/Exif/Values/ExifLong.cs
  14. 2
      src/ImageSharp/Metadata/Profiles/Exif/Values/ExifLong8.cs
  15. 2
      src/ImageSharp/Metadata/Profiles/Exif/Values/ExifLong8Array.cs
  16. 2
      src/ImageSharp/Metadata/Profiles/Exif/Values/ExifNumber.cs
  17. 2
      src/ImageSharp/Metadata/Profiles/Exif/Values/ExifNumberArray.cs
  18. 2
      src/ImageSharp/Metadata/Profiles/Exif/Values/ExifRational.cs
  19. 2
      src/ImageSharp/Metadata/Profiles/Exif/Values/ExifRationalArray.cs
  20. 2
      src/ImageSharp/Metadata/Profiles/Exif/Values/ExifShort.cs
  21. 2
      src/ImageSharp/Metadata/Profiles/Exif/Values/ExifShortArray.cs
  22. 2
      src/ImageSharp/Metadata/Profiles/Exif/Values/ExifSignedByte.cs
  23. 2
      src/ImageSharp/Metadata/Profiles/Exif/Values/ExifSignedShort.cs
  24. 2
      src/ImageSharp/Metadata/Profiles/Exif/Values/ExifSignedShortArray.cs
  25. 4
      src/ImageSharp/Metadata/Profiles/Exif/Values/ExifString.cs
  26. 6
      src/ImageSharp/Metadata/Profiles/Exif/Values/ExifUcs2String.cs
  27. 11
      src/ImageSharp/Metadata/Profiles/Exif/Values/ExifValue.cs
  28. 11
      src/ImageSharp/Metadata/Profiles/Exif/Values/ExifValues.cs
  29. 18
      src/ImageSharp/Metadata/Profiles/Exif/Values/ExifValue{TValueType}.cs
  30. 4
      src/ImageSharp/Metadata/Profiles/Exif/Values/IExifValue.cs
  31. 2
      src/ImageSharp/Metadata/Profiles/Exif/Values/IExifValue{TValueType}.cs
  32. 2
      src/ImageSharp/Processing/Processors/Transforms/Linear/AutoOrientProcessor{TPixel}.cs

2
src/ImageSharp/Common/Helpers/UnitConverter.cs

@ -91,7 +91,7 @@ internal static class UnitConverter
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public static PixelResolutionUnit ExifProfileToResolutionUnit(ExifProfile profile) public static PixelResolutionUnit ExifProfileToResolutionUnit(ExifProfile profile)
{ {
IExifValue<ushort> resolution = profile.GetValue(ExifTag.ResolutionUnit); IExifValue<ushort>? resolution = profile.GetValue(ExifTag.ResolutionUnit);
// EXIF is 1, 2, 3 so we minus "1" off the result. // EXIF is 1, 2, 3 so we minus "1" off the result.
return resolution is null ? DefaultResolutionUnit : (PixelResolutionUnit)(byte)(resolution.Value - 1); return resolution is null ? DefaultResolutionUnit : (PixelResolutionUnit)(byte)(resolution.Value - 1);

4
src/ImageSharp/Metadata/Profiles/Exif/ExifEncodedStringHelpers.cs

@ -1,6 +1,5 @@
// Copyright (c) Six Labors. // Copyright (c) Six Labors.
// Licensed under the Six Labors Split License. // Licensed under the Six Labors Split License.
#nullable disable
using System.Buffers.Binary; using System.Buffers.Binary;
using System.Text; using System.Text;
@ -27,7 +26,8 @@ internal static class ExifEncodedStringHelpers
// 20932 EUC-JP Japanese (JIS 0208-1990 and 0212-1990) // 20932 EUC-JP Japanese (JIS 0208-1990 and 0212-1990)
// https://docs.microsoft.com/en-us/dotnet/api/system.text.encoding?view=net-6.0 // https://docs.microsoft.com/en-us/dotnet/api/system.text.encoding?view=net-6.0
private static Encoding JIS0208Encoding => CodePagesEncodingProvider.Instance.GetEncoding(20932); private static Encoding JIS0208Encoding => CodePagesEncodingProvider.Instance.GetEncoding(20932) ??
throw new InvalidOperationException();
public static bool IsEncodedString(ExifTagValue tag) => tag switch public static bool IsEncodedString(ExifTagValue tag) => tag switch
{ {

31
src/ImageSharp/Metadata/Profiles/Exif/ExifProfile.cs

@ -1,7 +1,8 @@
// Copyright (c) Six Labors. // Copyright (c) Six Labors.
// Licensed under the Six Labors Split License. // Licensed under the Six Labors Split License.
#nullable disable
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.Metadata.Profiles.Exif; namespace SixLabors.ImageSharp.Metadata.Profiles.Exif;
@ -14,12 +15,12 @@ public sealed class ExifProfile : IDeepCloneable<ExifProfile>
/// <summary> /// <summary>
/// The byte array to read the EXIF profile from. /// The byte array to read the EXIF profile from.
/// </summary> /// </summary>
private readonly byte[] data; private readonly byte[]? data;
/// <summary> /// <summary>
/// The collection of EXIF values /// The collection of EXIF values
/// </summary> /// </summary>
private List<IExifValue> values; private List<IExifValue>? values;
/// <summary> /// <summary>
/// The thumbnail offset position in the byte stream /// The thumbnail offset position in the byte stream
@ -35,7 +36,7 @@ public sealed class ExifProfile : IDeepCloneable<ExifProfile>
/// Initializes a new instance of the <see cref="ExifProfile"/> class. /// Initializes a new instance of the <see cref="ExifProfile"/> class.
/// </summary> /// </summary>
public ExifProfile() public ExifProfile()
: this((byte[])null) : this((byte[]?)null)
{ {
} }
@ -43,7 +44,7 @@ public sealed class ExifProfile : IDeepCloneable<ExifProfile>
/// Initializes a new instance of the <see cref="ExifProfile"/> class. /// Initializes a new instance of the <see cref="ExifProfile"/> class.
/// </summary> /// </summary>
/// <param name="data">The byte array to read the EXIF profile from.</param> /// <param name="data">The byte array to read the EXIF profile from.</param>
public ExifProfile(byte[] data) public ExifProfile(byte[]? data)
{ {
this.Parts = ExifParts.All; this.Parts = ExifParts.All;
this.data = data; this.data = data;
@ -110,6 +111,7 @@ public sealed class ExifProfile : IDeepCloneable<ExifProfile>
/// <summary> /// <summary>
/// Gets the values of this EXIF profile. /// Gets the values of this EXIF profile.
/// </summary> /// </summary>
[MemberNotNull(nameof(values))]
public IReadOnlyList<IExifValue> Values public IReadOnlyList<IExifValue> Values
{ {
get get
@ -125,7 +127,7 @@ public sealed class ExifProfile : IDeepCloneable<ExifProfile>
/// <returns> /// <returns>
/// The <see cref="Image"/>. /// The <see cref="Image"/>.
/// </returns> /// </returns>
public Image CreateThumbnail() => this.CreateThumbnail<Rgba32>(); public Image? CreateThumbnail() => this.CreateThumbnail<Rgba32>();
/// <summary> /// <summary>
/// Returns the thumbnail in the EXIF profile when available. /// Returns the thumbnail in the EXIF profile when available.
@ -134,7 +136,7 @@ public sealed class ExifProfile : IDeepCloneable<ExifProfile>
/// <returns> /// <returns>
/// The <see cref="Image{TPixel}"/>. /// The <see cref="Image{TPixel}"/>.
/// </returns> /// </returns>
public Image<TPixel> CreateThumbnail<TPixel>() public Image<TPixel>? CreateThumbnail<TPixel>()
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
{ {
this.InitializeValues(); this.InitializeValues();
@ -161,9 +163,9 @@ public sealed class ExifProfile : IDeepCloneable<ExifProfile>
/// <param name="tag">The tag of the exif value.</param> /// <param name="tag">The tag of the exif value.</param>
/// <returns>The value with the specified tag.</returns> /// <returns>The value with the specified tag.</returns>
/// <typeparam name="TValueType">The data type of the tag.</typeparam> /// <typeparam name="TValueType">The data type of the tag.</typeparam>
public IExifValue<TValueType> GetValue<TValueType>(ExifTag<TValueType> tag) public IExifValue<TValueType>? GetValue<TValueType>(ExifTag<TValueType> tag)
{ {
IExifValue value = this.GetValueInternal(tag); IExifValue? value = this.GetValueInternal(tag);
return value is null ? null : (IExifValue<TValueType>)value; return value is null ? null : (IExifValue<TValueType>)value;
} }
@ -203,7 +205,7 @@ public sealed class ExifProfile : IDeepCloneable<ExifProfile>
/// Converts this instance to a byte array. /// Converts this instance to a byte array.
/// </summary> /// </summary>
/// <returns>The <see cref="T:byte[]"/></returns> /// <returns>The <see cref="T:byte[]"/></returns>
public byte[] ToByteArray() public byte[]? ToByteArray()
{ {
if (this.values is null) if (this.values is null)
{ {
@ -227,7 +229,7 @@ public sealed class ExifProfile : IDeepCloneable<ExifProfile>
/// </summary> /// </summary>
/// <param name="tag">The tag of the exif value.</param> /// <param name="tag">The tag of the exif value.</param>
/// <returns>The value with the specified tag.</returns> /// <returns>The value with the specified tag.</returns>
internal IExifValue GetValueInternal(ExifTag tag) internal IExifValue? GetValueInternal(ExifTag tag)
{ {
foreach (IExifValue exifValue in this.Values) foreach (IExifValue exifValue in this.Values)
{ {
@ -245,7 +247,7 @@ public sealed class ExifProfile : IDeepCloneable<ExifProfile>
/// </summary> /// </summary>
/// <param name="tag">The tag of the exif value.</param> /// <param name="tag">The tag of the exif value.</param>
/// <param name="value">The value.</param> /// <param name="value">The value.</param>
internal void SetValueInternal(ExifTag tag, object value) internal void SetValueInternal(ExifTag tag, object? value)
{ {
foreach (IExifValue exifValue in this.Values) foreach (IExifValue exifValue in this.Values)
{ {
@ -256,7 +258,7 @@ public sealed class ExifProfile : IDeepCloneable<ExifProfile>
} }
} }
ExifValue newExifValue = ExifValues.Create(tag); ExifValue? newExifValue = ExifValues.Create(tag);
if (newExifValue is null) if (newExifValue is null)
{ {
throw new NotSupportedException(); throw new NotSupportedException();
@ -278,7 +280,7 @@ public sealed class ExifProfile : IDeepCloneable<ExifProfile>
private void SyncResolution(ExifTag<Rational> tag, double resolution) private void SyncResolution(ExifTag<Rational> tag, double resolution)
{ {
IExifValue<Rational> value = this.GetValue(tag); IExifValue<Rational>? value = this.GetValue(tag);
if (value is null) if (value is null)
{ {
@ -294,6 +296,7 @@ public sealed class ExifProfile : IDeepCloneable<ExifProfile>
this.SetValue(tag, newResolution); this.SetValue(tag, newResolution);
} }
[MemberNotNull(nameof(values))]
private void InitializeValues() private void InitializeValues()
{ {
if (this.values != null) if (this.values != null)

27
src/ImageSharp/Metadata/Profiles/Exif/ExifReader.cs

@ -1,6 +1,5 @@
// Copyright (c) Six Labors. // Copyright (c) Six Labors.
// Licensed under the Six Labors Split License. // Licensed under the Six Labors Split License.
#nullable disable
using System.Buffers; using System.Buffers;
using System.Buffers.Binary; using System.Buffers.Binary;
@ -20,7 +19,7 @@ internal class ExifReader : BaseExifReader
{ {
} }
public ExifReader(byte[] exifData, MemoryAllocator allocator) public ExifReader(byte[] exifData, MemoryAllocator? allocator)
: base(new MemoryStream(exifData ?? throw new ArgumentNullException(nameof(exifData))), allocator) : base(new MemoryStream(exifData ?? throw new ArgumentNullException(nameof(exifData))), allocator)
{ {
} }
@ -90,13 +89,13 @@ internal abstract class BaseExifReader
private readonly byte[] buf4 = new byte[4]; private readonly byte[] buf4 = new byte[4];
private readonly byte[] buf2 = new byte[2]; private readonly byte[] buf2 = new byte[2];
private readonly MemoryAllocator allocator; private readonly MemoryAllocator? allocator;
private readonly Stream data; private readonly Stream data;
private List<ExifTag> invalidTags; private List<ExifTag>? invalidTags;
private List<ulong> subIfds; private List<ulong>? subIfds;
protected BaseExifReader(Stream stream, MemoryAllocator allocator) protected BaseExifReader(Stream stream, MemoryAllocator? allocator)
{ {
this.data = stream ?? throw new ArgumentNullException(nameof(stream)); this.data = stream ?? throw new ArgumentNullException(nameof(stream));
this.allocator = allocator; this.allocator = allocator;
@ -219,7 +218,7 @@ internal abstract class BaseExifReader
this.Seek(tag.Offset); this.Seek(tag.Offset);
if (this.TryReadSpan(buffer)) if (this.TryReadSpan(buffer))
{ {
object value = this.ConvertValue(tag.DataType, buffer, tag.NumberOfComponents > 1 || tag.Exif.IsArray); object? value = this.ConvertValue(tag.DataType, buffer, tag.NumberOfComponents > 1 || tag.Exif.IsArray);
this.Add(values, tag.Exif, value); this.Add(values, tag.Exif, value);
} }
} }
@ -255,7 +254,7 @@ internal abstract class BaseExifReader
private static byte ConvertToByte(ReadOnlySpan<byte> buffer) => buffer[0]; private static byte ConvertToByte(ReadOnlySpan<byte> buffer) => buffer[0];
private object ConvertValue(ExifDataType dataType, ReadOnlySpan<byte> buffer, bool isArray) private object? ConvertValue(ExifDataType dataType, ReadOnlySpan<byte> buffer, bool isArray)
{ {
if (buffer.Length == 0) if (buffer.Length == 0)
{ {
@ -390,7 +389,7 @@ internal abstract class BaseExifReader
numberOfComponents = 4 / ExifDataTypes.GetSize(dataType); numberOfComponents = 4 / ExifDataTypes.GetSize(dataType);
} }
ExifValue exifValue = ExifValues.Create(tag) ?? ExifValues.Create(tag, dataType, numberOfComponents); ExifValue? exifValue = ExifValues.Create(tag) ?? ExifValues.Create(tag, dataType, numberOfComponents);
if (exifValue is null) if (exifValue is null)
{ {
@ -414,7 +413,7 @@ internal abstract class BaseExifReader
} }
else else
{ {
object value = this.ConvertValue(dataType, offsetBuffer[..(int)size], numberOfComponents > 1 || exifValue.IsArray); object? value = this.ConvertValue(dataType, offsetBuffer[..(int)size], numberOfComponents > 1 || exifValue.IsArray);
this.Add(values, exifValue, value); this.Add(values, exifValue, value);
} }
} }
@ -443,7 +442,7 @@ internal abstract class BaseExifReader
numberOfComponents = 8 / ExifDataTypes.GetSize(dataType); numberOfComponents = 8 / ExifDataTypes.GetSize(dataType);
} }
ExifValue exifValue = tag switch ExifValue? exifValue = tag switch
{ {
ExifTagValue.StripOffsets => new ExifLong8Array(ExifTagValue.StripOffsets), ExifTagValue.StripOffsets => new ExifLong8Array(ExifTagValue.StripOffsets),
ExifTagValue.StripByteCounts => new ExifLong8Array(ExifTagValue.StripByteCounts), ExifTagValue.StripByteCounts => new ExifLong8Array(ExifTagValue.StripByteCounts),
@ -471,12 +470,12 @@ internal abstract class BaseExifReader
} }
else else
{ {
object value = this.ConvertValue(dataType, offsetBuffer[..(int)size], numberOfComponents > 1 || exifValue.IsArray); object? value = this.ConvertValue(dataType, offsetBuffer[..(int)size], numberOfComponents > 1 || exifValue.IsArray);
this.Add(values, exifValue, value); this.Add(values, exifValue, value);
} }
} }
private void Add(IList<IExifValue> values, IExifValue exif, object value) private void Add(IList<IExifValue> values, IExifValue exif, object? value)
{ {
if (!exif.TrySetValue(value)) if (!exif.TrySetValue(value))
{ {
@ -510,7 +509,7 @@ internal abstract class BaseExifReader
private void AddInvalidTag(ExifTag tag) private void AddInvalidTag(ExifTag tag)
=> (this.invalidTags ??= new List<ExifTag>()).Add(tag); => (this.invalidTags ??= new List<ExifTag>()).Add(tag);
private void AddSubIfd(object val) private void AddSubIfd(object? val)
=> (this.subIfds ??= new List<ulong>()).Add(Convert.ToUInt64(val, CultureInfo.InvariantCulture)); => (this.subIfds ??= new List<ulong>()).Add(Convert.ToUInt64(val, CultureInfo.InvariantCulture));
private void Seek(ulong pos) private void Seek(ulong pos)

9
src/ImageSharp/Metadata/Profiles/Exif/ExifTagDescriptionAttribute.cs

@ -1,6 +1,5 @@
// Copyright (c) Six Labors. // Copyright (c) Six Labors.
// Licensed under the Six Labors Split License. // Licensed under the Six Labors Split License.
#nullable disable
using System.Reflection; using System.Reflection;
@ -29,10 +28,10 @@ internal sealed class ExifTagDescriptionAttribute : Attribute
/// <returns> /// <returns>
/// The <see cref="string"/>. /// The <see cref="string"/>.
/// </returns> /// </returns>
public static string GetDescription(ExifTag tag, object value) public static string? GetDescription(ExifTag tag, object? value)
{ {
var tagValue = (ExifTagValue)(ushort)tag; var tagValue = (ExifTagValue)(ushort)tag;
FieldInfo field = typeof(ExifTagValue).GetField(tagValue.ToString(), BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); FieldInfo? field = typeof(ExifTagValue).GetField(tagValue.ToString(), BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
if (field is null) if (field is null)
{ {
@ -41,11 +40,11 @@ internal sealed class ExifTagDescriptionAttribute : Attribute
foreach (CustomAttributeData customAttribute in field.CustomAttributes) foreach (CustomAttributeData customAttribute in field.CustomAttributes)
{ {
object attributeValue = customAttribute.ConstructorArguments[0].Value; object? attributeValue = customAttribute.ConstructorArguments[0].Value;
if (Equals(attributeValue, value)) if (Equals(attributeValue, value))
{ {
return (string)customAttribute.ConstructorArguments[1].Value; return (string?)customAttribute.ConstructorArguments[1].Value;
} }
} }

28
src/ImageSharp/Metadata/Profiles/Exif/ExifWriter.cs

@ -1,6 +1,5 @@
// Copyright (c) Six Labors. // Copyright (c) Six Labors.
// Licensed under the Six Labors Split License. // Licensed under the Six Labors Split License.
#nullable disable
using System.Buffers.Binary; using System.Buffers.Binary;
@ -16,7 +15,7 @@ internal sealed class ExifWriter
/// </summary> /// </summary>
private readonly ExifParts allowedParts; private readonly ExifParts allowedParts;
private readonly IList<IExifValue> values; private readonly IList<IExifValue> values;
private List<int> dataOffsets; private List<int>? dataOffsets;
private readonly List<IExifValue> ifdValues; private readonly List<IExifValue> ifdValues;
private readonly List<IExifValue> exifValues; private readonly List<IExifValue> exifValues;
private readonly List<IExifValue> gpsValues; private readonly List<IExifValue> gpsValues;
@ -45,8 +44,8 @@ internal sealed class ExifWriter
{ {
const uint startIndex = 0; const uint startIndex = 0;
IExifValue exifOffset = GetOffsetValue(this.ifdValues, this.exifValues, ExifTag.SubIFDOffset); IExifValue? exifOffset = GetOffsetValue(this.ifdValues, this.exifValues, ExifTag.SubIFDOffset);
IExifValue gpsOffset = GetOffsetValue(this.ifdValues, this.gpsValues, ExifTag.GPSIFDOffset); IExifValue? gpsOffset = GetOffsetValue(this.ifdValues, this.gpsValues, ExifTag.GPSIFDOffset);
uint ifdLength = GetLength(this.ifdValues); uint ifdLength = GetLength(this.ifdValues);
uint exifLength = GetLength(this.exifValues); uint exifLength = GetLength(this.exifValues);
@ -160,7 +159,7 @@ internal sealed class ExifWriter
return offset + 4; return offset + 4;
} }
private static IExifValue GetOffsetValue(List<IExifValue> ifdValues, List<IExifValue> values, ExifTag offset) private static IExifValue? GetOffsetValue(List<IExifValue> ifdValues, List<IExifValue> values, ExifTag offset)
{ {
int index = -1; int index = -1;
@ -179,7 +178,9 @@ internal sealed class ExifWriter
return ifdValues[index]; return ifdValues[index];
} }
ExifValue result = ExifValues.Create(offset); ExifValue? result = ExifValues.Create(offset);
Guard.NotNull(result);
ifdValues.Add(result); ifdValues.Add(result);
return result; return result;
@ -219,7 +220,7 @@ internal sealed class ExifWriter
private static bool HasValue(IExifValue exifValue) private static bool HasValue(IExifValue exifValue)
{ {
object value = exifValue.GetValue(); object? value = exifValue.GetValue();
if (value is null) if (value is null)
{ {
return false; return false;
@ -270,11 +271,11 @@ internal sealed class ExifWriter
internal static uint GetNumberOfComponents(IExifValue exifValue) internal static uint GetNumberOfComponents(IExifValue exifValue)
{ {
object value = exifValue.GetValue(); object? value = exifValue.GetValue();
if (ExifUcs2StringHelpers.IsUcs2Tag((ExifTagValue)(ushort)exifValue.Tag)) if (ExifUcs2StringHelpers.IsUcs2Tag((ExifTagValue)(ushort)exifValue.Tag))
{ {
return (uint)ExifUcs2StringHelpers.Ucs2Encoding.GetByteCount((string)value); return (uint)ExifUcs2StringHelpers.Ucs2Encoding.GetByteCount((string?)value!);
} }
if (value is EncodedString encodedString) if (value is EncodedString encodedString)
@ -284,7 +285,7 @@ internal sealed class ExifWriter
if (exifValue.DataType == ExifDataType.Ascii) if (exifValue.DataType == ExifDataType.Ascii)
{ {
return (uint)ExifConstants.DefaultEncoding.GetByteCount((string)value) + 1; return (uint)ExifConstants.DefaultEncoding.GetByteCount((string?)value!) + 1;
} }
if (value is Array arrayValue) if (value is Array arrayValue)
@ -298,7 +299,7 @@ internal sealed class ExifWriter
private static int WriteArray(IExifValue value, Span<byte> destination, int offset) private static int WriteArray(IExifValue value, Span<byte> destination, int offset)
{ {
int newOffset = offset; int newOffset = offset;
foreach (object obj in (Array)value.GetValue()) foreach (object obj in (Array)value.GetValue()!)
{ {
newOffset = WriteValue(value.DataType, obj, destination, newOffset); newOffset = WriteValue(value.DataType, obj, destination, newOffset);
} }
@ -308,7 +309,7 @@ internal sealed class ExifWriter
private int WriteData(uint startIndex, List<IExifValue> values, Span<byte> destination, int offset) private int WriteData(uint startIndex, List<IExifValue> values, Span<byte> destination, int offset)
{ {
if (this.dataOffsets.Count == 0) if (this.dataOffsets is null || this.dataOffsets.Count == 0)
{ {
return offset; return offset;
} }
@ -428,7 +429,8 @@ internal sealed class ExifWriter
internal static int WriteValue(IExifValue exifValue, Span<byte> destination, int offset) internal static int WriteValue(IExifValue exifValue, Span<byte> destination, int offset)
{ {
object value = exifValue.GetValue(); object? value = exifValue.GetValue();
Guard.NotNull(value);
if (ExifUcs2StringHelpers.IsUcs2Tag((ExifTagValue)(ushort)exifValue.Tag)) if (ExifUcs2StringHelpers.IsUcs2Tag((ExifTagValue)(ushort)exifValue.Tag))
{ {

7
src/ImageSharp/Metadata/Profiles/Exif/Values/ExifArrayValue{TValueType}.cs

@ -1,6 +1,5 @@
// Copyright (c) Six Labors. // Copyright (c) Six Labors.
// Licensed under the Six Labors Split License. // Licensed under the Six Labors Split License.
#nullable disable
namespace SixLabors.ImageSharp.Metadata.Profiles.Exif; namespace SixLabors.ImageSharp.Metadata.Profiles.Exif;
@ -23,11 +22,11 @@ internal abstract class ExifArrayValue<TValueType> : ExifValue, IExifValue<TValu
public override bool IsArray => true; public override bool IsArray => true;
public TValueType[] Value { get; set; } public TValueType[]? Value { get; set; }
public override object GetValue() => this.Value; public override object? GetValue() => this.Value;
public override bool TrySetValue(object value) public override bool TrySetValue(object? value)
{ {
if (value is null) if (value is null)
{ {

2
src/ImageSharp/Metadata/Profiles/Exif/Values/ExifByte.cs

@ -20,7 +20,7 @@ internal sealed class ExifByte : ExifValue<byte>
protected override string StringValue => this.Value.ToString("X2", CultureInfo.InvariantCulture); protected override string StringValue => this.Value.ToString("X2", CultureInfo.InvariantCulture);
public override bool TrySetValue(object value) public override bool TrySetValue(object? value)
{ {
if (base.TrySetValue(value)) if (base.TrySetValue(value))
{ {

2
src/ImageSharp/Metadata/Profiles/Exif/Values/ExifByteArray.cs

@ -16,7 +16,7 @@ internal sealed class ExifByteArray : ExifArrayValue<byte>
public override ExifDataType DataType { get; } public override ExifDataType DataType { get; }
public override bool TrySetValue(object value) public override bool TrySetValue(object? value)
{ {
if (base.TrySetValue(value)) if (base.TrySetValue(value))
{ {

2
src/ImageSharp/Metadata/Profiles/Exif/Values/ExifDouble.cs

@ -26,7 +26,7 @@ internal sealed class ExifDouble : ExifValue<double>
protected override string StringValue => this.Value.ToString(CultureInfo.InvariantCulture); protected override string StringValue => this.Value.ToString(CultureInfo.InvariantCulture);
public override bool TrySetValue(object value) public override bool TrySetValue(object? value)
{ {
if (base.TrySetValue(value)) if (base.TrySetValue(value))
{ {

2
src/ImageSharp/Metadata/Profiles/Exif/Values/ExifEncodedString.cs

@ -24,7 +24,7 @@ internal sealed class ExifEncodedString : ExifValue<EncodedString>
protected override string StringValue => this.Value.Text; protected override string StringValue => this.Value.Text;
public override bool TrySetValue(object value) public override bool TrySetValue(object? value)
{ {
if (base.TrySetValue(value)) if (base.TrySetValue(value))
{ {

2
src/ImageSharp/Metadata/Profiles/Exif/Values/ExifFloat.cs

@ -21,7 +21,7 @@ internal sealed class ExifFloat : ExifValue<float>
protected override string StringValue => this.Value.ToString(CultureInfo.InvariantCulture); protected override string StringValue => this.Value.ToString(CultureInfo.InvariantCulture);
public override bool TrySetValue(object value) public override bool TrySetValue(object? value)
{ {
if (base.TrySetValue(value)) if (base.TrySetValue(value))
{ {

2
src/ImageSharp/Metadata/Profiles/Exif/Values/ExifLong.cs

@ -26,7 +26,7 @@ internal sealed class ExifLong : ExifValue<uint>
protected override string StringValue => this.Value.ToString(CultureInfo.InvariantCulture); protected override string StringValue => this.Value.ToString(CultureInfo.InvariantCulture);
public override bool TrySetValue(object value) public override bool TrySetValue(object? value)
{ {
if (base.TrySetValue(value)) if (base.TrySetValue(value))
{ {

2
src/ImageSharp/Metadata/Profiles/Exif/Values/ExifLong8.cs

@ -26,7 +26,7 @@ internal sealed class ExifLong8 : ExifValue<ulong>
protected override string StringValue => this.Value.ToString(CultureInfo.InvariantCulture); protected override string StringValue => this.Value.ToString(CultureInfo.InvariantCulture);
public override bool TrySetValue(object value) public override bool TrySetValue(object? value)
{ {
if (base.TrySetValue(value)) if (base.TrySetValue(value))
{ {

2
src/ImageSharp/Metadata/Profiles/Exif/Values/ExifLong8Array.cs

@ -34,7 +34,7 @@ internal sealed class ExifLong8Array : ExifArrayValue<ulong>
} }
} }
public override bool TrySetValue(object value) public override bool TrySetValue(object? value)
{ {
if (base.TrySetValue(value)) if (base.TrySetValue(value))
{ {

2
src/ImageSharp/Metadata/Profiles/Exif/Values/ExifNumber.cs

@ -32,7 +32,7 @@ internal sealed class ExifNumber : ExifValue<Number>
protected override string StringValue => this.Value.ToString(CultureInfo.InvariantCulture); protected override string StringValue => this.Value.ToString(CultureInfo.InvariantCulture);
public override bool TrySetValue(object value) public override bool TrySetValue(object? value)
{ {
if (base.TrySetValue(value)) if (base.TrySetValue(value))
{ {

2
src/ImageSharp/Metadata/Profiles/Exif/Values/ExifNumberArray.cs

@ -34,7 +34,7 @@ internal sealed class ExifNumberArray : ExifArrayValue<Number>
} }
} }
public override bool TrySetValue(object value) public override bool TrySetValue(object? value)
{ {
if (base.TrySetValue(value)) if (base.TrySetValue(value))
{ {

2
src/ImageSharp/Metadata/Profiles/Exif/Values/ExifRational.cs

@ -26,7 +26,7 @@ internal sealed class ExifRational : ExifValue<Rational>
protected override string StringValue => this.Value.ToString(CultureInfo.InvariantCulture); protected override string StringValue => this.Value.ToString(CultureInfo.InvariantCulture);
public override bool TrySetValue(object value) public override bool TrySetValue(object? value)
{ {
if (base.TrySetValue(value)) if (base.TrySetValue(value))
{ {

2
src/ImageSharp/Metadata/Profiles/Exif/Values/ExifRationalArray.cs

@ -22,7 +22,7 @@ internal sealed class ExifRationalArray : ExifArrayValue<Rational>
public override ExifDataType DataType => ExifDataType.Rational; public override ExifDataType DataType => ExifDataType.Rational;
public override bool TrySetValue(object value) public override bool TrySetValue(object? value)
{ {
if (base.TrySetValue(value)) if (base.TrySetValue(value))
{ {

2
src/ImageSharp/Metadata/Profiles/Exif/Values/ExifShort.cs

@ -26,7 +26,7 @@ internal sealed class ExifShort : ExifValue<ushort>
protected override string StringValue => this.Value.ToString(CultureInfo.InvariantCulture); protected override string StringValue => this.Value.ToString(CultureInfo.InvariantCulture);
public override bool TrySetValue(object value) public override bool TrySetValue(object? value)
{ {
if (base.TrySetValue(value)) if (base.TrySetValue(value))
{ {

2
src/ImageSharp/Metadata/Profiles/Exif/Values/ExifShortArray.cs

@ -22,7 +22,7 @@ internal sealed class ExifShortArray : ExifArrayValue<ushort>
public override ExifDataType DataType => ExifDataType.Short; public override ExifDataType DataType => ExifDataType.Short;
public override bool TrySetValue(object value) public override bool TrySetValue(object? value)
{ {
if (base.TrySetValue(value)) if (base.TrySetValue(value))
{ {

2
src/ImageSharp/Metadata/Profiles/Exif/Values/ExifSignedByte.cs

@ -21,7 +21,7 @@ internal sealed class ExifSignedByte : ExifValue<sbyte>
protected override string StringValue => this.Value.ToString("X2", CultureInfo.InvariantCulture); protected override string StringValue => this.Value.ToString("X2", CultureInfo.InvariantCulture);
public override bool TrySetValue(object value) public override bool TrySetValue(object? value)
{ {
if (base.TrySetValue(value)) if (base.TrySetValue(value))
{ {

2
src/ImageSharp/Metadata/Profiles/Exif/Values/ExifSignedShort.cs

@ -21,7 +21,7 @@ internal sealed class ExifSignedShort : ExifValue<short>
protected override string StringValue => this.Value.ToString(CultureInfo.InvariantCulture); protected override string StringValue => this.Value.ToString(CultureInfo.InvariantCulture);
public override bool TrySetValue(object value) public override bool TrySetValue(object? value)
{ {
if (base.TrySetValue(value)) if (base.TrySetValue(value))
{ {

2
src/ImageSharp/Metadata/Profiles/Exif/Values/ExifSignedShortArray.cs

@ -17,7 +17,7 @@ internal sealed class ExifSignedShortArray : ExifArrayValue<short>
public override ExifDataType DataType => ExifDataType.SignedShort; public override ExifDataType DataType => ExifDataType.SignedShort;
public override bool TrySetValue(object value) public override bool TrySetValue(object? value)
{ {
if (base.TrySetValue(value)) if (base.TrySetValue(value))
{ {

4
src/ImageSharp/Metadata/Profiles/Exif/Values/ExifString.cs

@ -24,9 +24,9 @@ internal sealed class ExifString : ExifValue<string>
public override ExifDataType DataType => ExifDataType.Ascii; public override ExifDataType DataType => ExifDataType.Ascii;
protected override string StringValue => this.Value; protected override string? StringValue => this.Value;
public override bool TrySetValue(object value) public override bool TrySetValue(object? value)
{ {
if (base.TrySetValue(value)) if (base.TrySetValue(value))
{ {

6
src/ImageSharp/Metadata/Profiles/Exif/Values/ExifUcs2String.cs

@ -22,11 +22,11 @@ internal sealed class ExifUcs2String : ExifValue<string>
public override ExifDataType DataType => ExifDataType.Byte; public override ExifDataType DataType => ExifDataType.Byte;
protected override string StringValue => this.Value; protected override string? StringValue => this.Value;
public override object GetValue() => this.Value; public override object? GetValue() => this.Value;
public override bool TrySetValue(object value) public override bool TrySetValue(object? value)
{ {
if (base.TrySetValue(value)) if (base.TrySetValue(value))
{ {

11
src/ImageSharp/Metadata/Profiles/Exif/Values/ExifValue.cs

@ -1,6 +1,5 @@
// Copyright (c) Six Labors. // Copyright (c) Six Labors.
// Licensed under the Six Labors Split License. // Licensed under the Six Labors Split License.
#nullable disable
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
@ -28,7 +27,7 @@ internal abstract class ExifValue : IExifValue, IEquatable<ExifTag>
else else
{ {
// All array types are value types so Clone() is sufficient here. // All array types are value types so Clone() is sufficient here.
var array = (Array)other.GetValue(); Array? array = (Array?)other.GetValue();
this.TrySetValue(array?.Clone()); this.TrySetValue(array?.Clone());
} }
} }
@ -43,7 +42,7 @@ internal abstract class ExifValue : IExifValue, IEquatable<ExifTag>
public static bool operator !=(ExifValue left, ExifTag right) => !Equals(left, right); public static bool operator !=(ExifValue left, ExifTag right) => !Equals(left, right);
public override bool Equals(object obj) public override bool Equals(object? obj)
{ {
if (obj is null) if (obj is null)
{ {
@ -69,14 +68,14 @@ internal abstract class ExifValue : IExifValue, IEquatable<ExifTag>
} }
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public bool Equals(ExifTag other) => this.Tag.Equals(other); public bool Equals(ExifTag? other) => this.Tag.Equals(other);
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
public override int GetHashCode() => HashCode.Combine(this.Tag, this.GetValue()); public override int GetHashCode() => HashCode.Combine(this.Tag, this.GetValue());
public abstract object GetValue(); public abstract object? GetValue();
public abstract bool TrySetValue(object value); public abstract bool TrySetValue(object? value);
public abstract IExifValue DeepClone(); public abstract IExifValue DeepClone();
} }

11
src/ImageSharp/Metadata/Profiles/Exif/Values/ExifValues.cs

@ -1,18 +1,17 @@
// Copyright (c) Six Labors. // Copyright (c) Six Labors.
// Licensed under the Six Labors Split License. // Licensed under the Six Labors Split License.
#nullable disable
namespace SixLabors.ImageSharp.Metadata.Profiles.Exif; namespace SixLabors.ImageSharp.Metadata.Profiles.Exif;
internal static partial class ExifValues internal static partial class ExifValues
{ {
public static ExifValue Create(ExifTagValue tag) => (ExifValue)CreateValue(tag); public static ExifValue? Create(ExifTagValue tag) => (ExifValue?)CreateValue(tag);
public static ExifValue Create(ExifTag tag) => (ExifValue)CreateValue((ExifTagValue)(ushort)tag); public static ExifValue? Create(ExifTag tag) => (ExifValue?)CreateValue((ExifTagValue)(ushort)tag);
public static ExifValue Create(ExifTagValue tag, ExifDataType dataType, ulong numberOfComponents) => Create(tag, dataType, numberOfComponents != 1); public static ExifValue? Create(ExifTagValue tag, ExifDataType dataType, ulong numberOfComponents) => Create(tag, dataType, numberOfComponents != 1);
public static ExifValue Create(ExifTagValue tag, ExifDataType dataType, bool isArray) public static ExifValue? Create(ExifTagValue tag, ExifDataType dataType, bool isArray)
{ {
switch (dataType) switch (dataType)
{ {
@ -49,7 +48,7 @@ internal static partial class ExifValues
} }
} }
private static object CreateValue(ExifTagValue tag) private static object? CreateValue(ExifTagValue tag)
{ {
switch (tag) switch (tag)
{ {

18
src/ImageSharp/Metadata/Profiles/Exif/Values/ExifValue{TValueType}.cs

@ -1,6 +1,5 @@
// Copyright (c) Six Labors. // Copyright (c) Six Labors.
// Licensed under the Six Labors Split License. // Licensed under the Six Labors Split License.
#nullable disable
namespace SixLabors.ImageSharp.Metadata.Profiles.Exif; namespace SixLabors.ImageSharp.Metadata.Profiles.Exif;
@ -21,16 +20,16 @@ internal abstract class ExifValue<TValueType> : ExifValue, IExifValue<TValueType
{ {
} }
public TValueType Value { get; set; } public TValueType? Value { get; set; }
/// <summary> /// <summary>
/// Gets the value of the current instance as a string. /// Gets the value of the current instance as a string.
/// </summary> /// </summary>
protected abstract string StringValue { get; } protected abstract string? StringValue { get; }
public override object GetValue() => this.Value; public override object? GetValue() => this.Value;
public override bool TrySetValue(object value) public override bool TrySetValue(object? value)
{ {
if (value is null) if (value is null)
{ {
@ -49,14 +48,9 @@ internal abstract class ExifValue<TValueType> : ExifValue, IExifValue<TValueType
return false; return false;
} }
public override string ToString() public override string? ToString()
{ {
if (this.Value == null) string? description = ExifTagDescriptionAttribute.GetDescription(this.Tag, this.Value);
{
return null;
}
string description = ExifTagDescriptionAttribute.GetDescription(this.Tag, this.Value);
return description ?? this.StringValue; return description ?? this.StringValue;
} }
} }

4
src/ImageSharp/Metadata/Profiles/Exif/Values/IExifValue.cs

@ -27,12 +27,12 @@ public interface IExifValue : IDeepCloneable<IExifValue>
/// Gets the value of this exif value. /// Gets the value of this exif value.
/// </summary> /// </summary>
/// <returns>The value of this exif value.</returns> /// <returns>The value of this exif value.</returns>
object GetValue(); object? GetValue();
/// <summary> /// <summary>
/// Sets the value of this exif value. /// Sets the value of this exif value.
/// </summary> /// </summary>
/// <param name="value">The value of this exif value.</param> /// <param name="value">The value of this exif value.</param>
/// <returns>A value indicating whether the value could be set.</returns> /// <returns>A value indicating whether the value could be set.</returns>
bool TrySetValue(object value); bool TrySetValue(object? value);
} }

2
src/ImageSharp/Metadata/Profiles/Exif/Values/IExifValue{TValueType}.cs

@ -12,5 +12,5 @@ public interface IExifValue<TValueType> : IExifValue
/// <summary> /// <summary>
/// Gets or sets the value. /// Gets or sets the value.
/// </summary> /// </summary>
TValueType Value { get; set; } TValueType? Value { get; set; }
} }

2
src/ImageSharp/Processing/Processors/Transforms/Linear/AutoOrientProcessor{TPixel}.cs

@ -88,7 +88,7 @@ internal class AutoOrientProcessor<TPixel> : ImageProcessor<TPixel>
return ExifOrientationMode.Unknown; return ExifOrientationMode.Unknown;
} }
IExifValue<ushort> value = source.Metadata.ExifProfile.GetValue(ExifTag.Orientation); IExifValue<ushort>? value = source.Metadata.ExifProfile.GetValue(ExifTag.Orientation);
if (value is null) if (value is null)
{ {
return ExifOrientationMode.Unknown; return ExifOrientationMode.Unknown;

Loading…
Cancel
Save