diff --git a/src/ImageSharp/Formats/Tiff/Ifd/EntryReader.cs b/src/ImageSharp/Formats/Tiff/Ifd/EntryReader.cs index 4496de6fb..49e43e49c 100644 --- a/src/ImageSharp/Formats/Tiff/Ifd/EntryReader.cs +++ b/src/ImageSharp/Formats/Tiff/Ifd/EntryReader.cs @@ -14,7 +14,7 @@ internal class EntryReader : BaseExifReader : base(stream, allocator) => this.IsBigEndian = byteOrder == ByteOrder.BigEndian; - public List Values { get; } = new(); + public List Values { get; } = []; public ulong NextIfdOffset { get; private set; } @@ -31,8 +31,6 @@ internal class EntryReader : BaseExifReader { this.ReadValues64(this.Values, ifdOffset); this.NextIfdOffset = this.ReadUInt64(); - - //// this.ReadSubIfd64(this.Values); } } @@ -62,9 +60,9 @@ internal class HeaderReader : BaseExifReader { this.IsBigTiff = true; - ushort bytesize = this.ReadUInt16(); + ushort byteSize = this.ReadUInt16(); ushort reserve = this.ReadUInt16(); - if (bytesize == TiffConstants.BigTiffByteSize && reserve == 0) + if (byteSize == TiffConstants.BigTiffByteSize && reserve == 0) { this.FirstIfdOffset = this.ReadUInt64(); return; diff --git a/src/ImageSharp/Metadata/Profiles/Exif/ExifDataType.cs b/src/ImageSharp/Metadata/Profiles/Exif/ExifDataType.cs index 90a5d15b7..e0b549362 100644 --- a/src/ImageSharp/Metadata/Profiles/Exif/ExifDataType.cs +++ b/src/ImageSharp/Metadata/Profiles/Exif/ExifDataType.cs @@ -4,7 +4,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif; /// -/// Specifies exif data types. +/// Specifies Exif data types. /// public enum ExifDataType { diff --git a/src/ImageSharp/Metadata/Profiles/Exif/ExifEncodedStringHelpers.cs b/src/ImageSharp/Metadata/Profiles/Exif/ExifEncodedStringHelpers.cs index e9f46731c..d2b88cbff 100644 --- a/src/ImageSharp/Metadata/Profiles/Exif/ExifEncodedStringHelpers.cs +++ b/src/ImageSharp/Metadata/Profiles/Exif/ExifEncodedStringHelpers.cs @@ -16,13 +16,13 @@ internal static class ExifEncodedStringHelpers private const ulong UnicodeCode = 0x_45_44_4F_43_49_4E_55; private const ulong UndefinedCode = 0x_00_00_00_00_00_00_00_00; - private static ReadOnlySpan AsciiCodeBytes => new byte[] { 0x41, 0x53, 0x43, 0x49, 0x49, 0, 0, 0 }; + private static ReadOnlySpan AsciiCodeBytes => [0x41, 0x53, 0x43, 0x49, 0x49, 0, 0, 0]; - private static ReadOnlySpan JISCodeBytes => new byte[] { 0x4A, 0x49, 0x53, 0, 0, 0, 0, 0 }; + private static ReadOnlySpan JISCodeBytes => [0x4A, 0x49, 0x53, 0, 0, 0, 0, 0]; - private static ReadOnlySpan UnicodeCodeBytes => new byte[] { 0x55, 0x4E, 0x49, 0x43, 0x4F, 0x44, 0x45, 0 }; + private static ReadOnlySpan UnicodeCodeBytes => [0x55, 0x4E, 0x49, 0x43, 0x4F, 0x44, 0x45, 0]; - private static ReadOnlySpan UndefinedCodeBytes => new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }; + private static ReadOnlySpan UndefinedCodeBytes => [0, 0, 0, 0, 0, 0, 0, 0]; // 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 @@ -50,22 +50,45 @@ internal static class ExifEncodedStringHelpers _ => UndefinedCodeBytes }; - public static Encoding GetEncoding(CharacterCode code) => code switch + public static Encoding GetEncoding(CharacterCode code, ByteOrder order) => code switch { CharacterCode.ASCII => Encoding.ASCII, CharacterCode.JIS => JIS0208Encoding, - CharacterCode.Unicode => Encoding.Unicode, + CharacterCode.Unicode => order is ByteOrder.BigEndian ? Encoding.BigEndianUnicode : Encoding.Unicode, CharacterCode.Undefined => Encoding.UTF8, _ => Encoding.UTF8 }; - public static bool TryParse(ReadOnlySpan buffer, out EncodedString encodedString) + public static bool TryParse(ReadOnlySpan buffer, ByteOrder order, out EncodedString encodedString) { if (TryDetect(buffer, out CharacterCode code)) { - string text = GetEncoding(code).GetString(buffer[CharacterCodeBytesLength..]); - encodedString = new EncodedString(code, text); - return true; + ReadOnlySpan textBuffer = buffer[CharacterCodeBytesLength..]; + if (code == CharacterCode.Unicode && textBuffer.Length >= 2) + { + // Check BOM + if (textBuffer.StartsWith((ReadOnlySpan)[0xFF, 0xFE])) + { + // Little-endian BOM + string text = Encoding.Unicode.GetString(textBuffer[2..]); + encodedString = new EncodedString(code, text); + return true; + } + + if (textBuffer.StartsWith((ReadOnlySpan)[0xFE, 0xFF])) + { + // Big-endian BOM + string text = Encoding.BigEndianUnicode.GetString(textBuffer[2..]); + encodedString = new EncodedString(code, text); + return true; + } + } + + { + string text = GetEncoding(code, order).GetString(textBuffer); + encodedString = new EncodedString(code, text); + return true; + } } encodedString = default; @@ -73,14 +96,14 @@ internal static class ExifEncodedStringHelpers } public static uint GetDataLength(EncodedString encodedString) => - (uint)GetEncoding(encodedString.Code).GetByteCount(encodedString.Text) + CharacterCodeBytesLength; + (uint)GetEncoding(encodedString.Code, ByteOrder.LittleEndian).GetByteCount(encodedString.Text) + CharacterCodeBytesLength; public static int Write(EncodedString encodedString, Span destination) { GetCodeBytes(encodedString.Code).CopyTo(destination); string text = encodedString.Text; - int count = Write(GetEncoding(encodedString.Code), text, destination[CharacterCodeBytesLength..]); + int count = Write(GetEncoding(encodedString.Code, ByteOrder.LittleEndian), text, destination[CharacterCodeBytesLength..]); return CharacterCodeBytesLength + count; } @@ -92,8 +115,7 @@ internal static class ExifEncodedStringHelpers { if (buffer.Length >= CharacterCodeBytesLength) { - ulong test = BinaryPrimitives.ReadUInt64LittleEndian(buffer); - switch (test) + switch (BinaryPrimitives.ReadUInt64LittleEndian(buffer)) { case AsciiCode: code = CharacterCode.ASCII; @@ -108,7 +130,8 @@ internal static class ExifEncodedStringHelpers code = CharacterCode.Undefined; return true; default: - break; + code = default; + return false; } } diff --git a/src/ImageSharp/Metadata/Profiles/Exif/ExifProfile.cs b/src/ImageSharp/Metadata/Profiles/Exif/ExifProfile.cs index e91a69444..aa987bbe7 100644 --- a/src/ImageSharp/Metadata/Profiles/Exif/ExifProfile.cs +++ b/src/ImageSharp/Metadata/Profiles/Exif/ExifProfile.cs @@ -3,7 +3,6 @@ using System.Diagnostics.CodeAnalysis; using SixLabors.ImageSharp.PixelFormats; -using static System.Runtime.InteropServices.JavaScript.JSType; namespace SixLabors.ImageSharp.Metadata.Profiles.Exif; @@ -48,7 +47,7 @@ public sealed class ExifProfile : IDeepCloneable { this.Parts = ExifParts.All; this.data = data; - this.InvalidTags = Array.Empty(); + this.InvalidTags = []; } /// @@ -171,7 +170,7 @@ public sealed class ExifProfile : IDeepCloneable /// /// Returns the value with the specified tag. /// - /// The tag of the exif value. + /// The tag of the Exif value. /// The value with the specified tag. /// True when found, otherwise false /// The data type of the tag. @@ -215,7 +214,7 @@ public sealed class ExifProfile : IDeepCloneable /// /// Sets the value of the specified tag. /// - /// The tag of the exif value. + /// The tag of the Exif value. /// The value. /// The data type of the tag. public void SetValue(ExifTag tag, TValueType value) @@ -234,7 +233,7 @@ public sealed class ExifProfile : IDeepCloneable if (this.values.Count == 0) { - return Array.Empty(); + return []; } ExifWriter writer = new(this.values, this.Parts); @@ -247,7 +246,7 @@ public sealed class ExifProfile : IDeepCloneable /// /// Returns the value with the specified tag. /// - /// The tag of the exif value. + /// The tag of the Exif value. /// The value with the specified tag. internal IExifValue? GetValueInternal(ExifTag tag) { @@ -265,7 +264,7 @@ public sealed class ExifProfile : IDeepCloneable /// /// Sets the value of the specified tag. /// - /// The tag of the exif value. + /// The tag of the Exif value. /// The value. /// Newly created value is null. internal void SetValueInternal(ExifTag tag, object? value) @@ -279,11 +278,7 @@ public sealed class ExifProfile : IDeepCloneable } } - ExifValue? newExifValue = ExifValues.Create(tag); - if (newExifValue is null) - { - throw new NotSupportedException($"Newly created value for tag {tag} is null."); - } + ExifValue? newExifValue = ExifValues.Create(tag) ?? throw new NotSupportedException($"Newly created value for tag {tag} is null."); newExifValue.TrySetValue(value); this.values.Add(newExifValue); @@ -349,7 +344,7 @@ public sealed class ExifProfile : IDeepCloneable if (this.data is null) { - this.values = new List(); + this.values = []; return; } diff --git a/src/ImageSharp/Metadata/Profiles/Exif/ExifReader.cs b/src/ImageSharp/Metadata/Profiles/Exif/ExifReader.cs index 3af4eb3c3..4cd4b4aac 100644 --- a/src/ImageSharp/Metadata/Profiles/Exif/ExifReader.cs +++ b/src/ImageSharp/Metadata/Profiles/Exif/ExifReader.cs @@ -34,7 +34,7 @@ internal class ExifReader : BaseExifReader /// public List ReadValues() { - List values = new(); + List values = []; // II == 0x4949 this.IsBigEndian = this.ReadUInt16() != 0x4949; @@ -64,7 +64,7 @@ internal class ExifReader : BaseExifReader return; } - List values = new(); + List values = []; this.ReadValues(values, offset); for (int i = 0; i < values.Count; i++) @@ -90,8 +90,8 @@ internal abstract class BaseExifReader private readonly MemoryAllocator? allocator; private readonly Stream data; private List? invalidTags; - private List? subIfds; + private bool isBigEndian; protected BaseExifReader(Stream stream, MemoryAllocator? allocator) { @@ -104,7 +104,7 @@ internal abstract class BaseExifReader /// /// Gets the invalid tags. /// - public IReadOnlyList InvalidTags => this.invalidTags ?? (IReadOnlyList)Array.Empty(); + public IReadOnlyList InvalidTags => this.invalidTags ?? (IReadOnlyList)[]; /// /// Gets or sets the thumbnail length in the byte stream. @@ -116,9 +116,19 @@ internal abstract class BaseExifReader /// public uint ThumbnailOffset { get; protected set; } - public bool IsBigEndian { get; protected set; } + public bool IsBigEndian + { + get => this.isBigEndian; + protected set + { + this.isBigEndian = value; + this.ByteOrder = value ? ByteOrder.BigEndian : ByteOrder.LittleEndian; + } + } + + protected ByteOrder ByteOrder { get; private set; } - public List<(ulong Offset, ExifDataType DataType, ulong NumberOfComponents, ExifValue Exif)> BigValues { get; } = new(); + public List<(ulong Offset, ExifDataType DataType, ulong NumberOfComponents, ExifValue Exif)> BigValues { get; } = []; protected void ReadBigValues(List values) { @@ -486,14 +496,21 @@ internal abstract class BaseExifReader private void Add(IList values, ExifValue exif, object? value) { - if (!exif.TrySetValue(value)) + if (exif is ExifEncodedString encodedString) + { + if (!encodedString.TrySetValue(value, this.ByteOrder)) + { + return; + } + } + else if (!exif.TrySetValue(value)) { return; } foreach (IExifValue val in values) { - // to skip duplicates must be used Equals method, + // To skip duplicates must be used Equals method, // == operator not defined for ExifValue and IExifValue if (exif.Equals(val)) { @@ -517,10 +534,10 @@ internal abstract class BaseExifReader } private void AddInvalidTag(ExifTag tag) - => (this.invalidTags ??= new List()).Add(tag); + => (this.invalidTags ??= []).Add(tag); private void AddSubIfd(object? val) - => (this.subIfds ??= new List()).Add(Convert.ToUInt64(val, CultureInfo.InvariantCulture)); + => (this.subIfds ??= []).Add(Convert.ToUInt64(val, CultureInfo.InvariantCulture)); private void Seek(ulong pos) => this.data.Seek((long)pos, SeekOrigin.Begin); diff --git a/src/ImageSharp/Metadata/Profiles/Exif/ExifWriter.cs b/src/ImageSharp/Metadata/Profiles/Exif/ExifWriter.cs index cf4a421b4..732e3eab2 100644 --- a/src/ImageSharp/Metadata/Profiles/Exif/ExifWriter.cs +++ b/src/ImageSharp/Metadata/Profiles/Exif/ExifWriter.cs @@ -55,7 +55,7 @@ internal sealed class ExifWriter if (length == 0) { - return Array.Empty(); + return []; } // two bytes for the byte Order marker 'II' or 'MM', followed by the number 42 (0x2A) and a 0, making 4 bytes total @@ -197,7 +197,7 @@ internal sealed class ExifWriter private List GetPartValues(ExifParts part) { - List result = new(); + List result = []; if (!EnumUtils.HasFlag(this.allowedParts, part)) { @@ -332,7 +332,7 @@ internal sealed class ExifWriter private int WriteHeaders(List values, Span destination, int offset) { - this.dataOffsets = new List(); + this.dataOffsets = []; int newOffset = WriteUInt16((ushort)values.Count, destination, offset); diff --git a/src/ImageSharp/Metadata/Profiles/Exif/Tags/ExifTag.cs b/src/ImageSharp/Metadata/Profiles/Exif/Tags/ExifTag.cs index ea0b8060d..ec30f21cd 100644 --- a/src/ImageSharp/Metadata/Profiles/Exif/Tags/ExifTag.cs +++ b/src/ImageSharp/Metadata/Profiles/Exif/Tags/ExifTag.cs @@ -4,7 +4,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif; /// -/// Class that represents an exif tag from the Exif standard 2.31. +/// Class that represents an Exif tag from the Exif standard 2.31. /// public abstract partial class ExifTag : IEquatable { @@ -16,21 +16,21 @@ public abstract partial class ExifTag : IEquatable /// Converts the specified to a . /// /// The to convert. - public static explicit operator ushort(ExifTag tag) => tag?.value ?? (ushort)ExifTagValue.Unknown; + public static explicit operator ushort(ExifTag? tag) => tag?.value ?? (ushort)ExifTagValue.Unknown; /// /// Determines whether the specified instances are considered equal. /// /// The first to compare. /// The second to compare. - public static bool operator ==(ExifTag left, ExifTag right) => Equals(left, right); + public static bool operator ==(ExifTag? left, ExifTag? right) => left?.Equals(right) == true; /// /// Determines whether the specified instances are not considered equal. /// /// The first to compare. /// The second to compare. - public static bool operator !=(ExifTag left, ExifTag right) => !Equals(left, right); + public static bool operator !=(ExifTag? left, ExifTag? right) => !(left == right); /// public override bool Equals(object? obj) diff --git a/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifArrayValue{TValueType}.cs b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifArrayValue{TValueType}.cs index 64b8d2313..630709bec 100644 --- a/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifArrayValue{TValueType}.cs +++ b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifArrayValue{TValueType}.cs @@ -43,7 +43,7 @@ internal abstract class ExifArrayValue : ExifValue, IExifValue switch (value) { case int intValue: - if (intValue >= byte.MinValue && intValue <= byte.MaxValue) + if (intValue is >= byte.MinValue and <= byte.MaxValue) { this.Value = (byte)intValue; return true; diff --git a/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifByteArray.cs b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifByteArray.cs index 6811fc6f9..c0bbb5bee 100644 --- a/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifByteArray.cs +++ b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifByteArray.cs @@ -30,9 +30,9 @@ internal sealed class ExifByteArray : ExifArrayValue if (value is int intValue) { - if (intValue >= byte.MinValue && intValue <= byte.MaxValue) + if (intValue is >= byte.MinValue and <= byte.MaxValue) { - this.Value = new byte[] { (byte)intValue }; + this.Value = [(byte)intValue]; } return true; diff --git a/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifEncodedString.cs b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifEncodedString.cs index cce7cf3e8..14b097f81 100644 --- a/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifEncodedString.cs +++ b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifEncodedString.cs @@ -24,7 +24,7 @@ internal sealed class ExifEncodedString : ExifValue protected override string StringValue => this.Value.Text; - public override bool TrySetValue(object? value) + public bool TrySetValue(object? value, ByteOrder order) { if (base.TrySetValue(value)) { @@ -38,7 +38,7 @@ internal sealed class ExifEncodedString : ExifValue } else if (value is byte[] buffer) { - if (ExifEncodedStringHelpers.TryParse(buffer, out EncodedString encodedString)) + if (ExifEncodedStringHelpers.TryParse(buffer, order, out EncodedString encodedString)) { this.Value = encodedString; return true; @@ -48,5 +48,8 @@ internal sealed class ExifEncodedString : ExifValue return false; } + public override bool TrySetValue(object? value) + => this.TrySetValue(value, ByteOrder.LittleEndian); + public override IExifValue DeepClone() => new ExifEncodedString(this); } diff --git a/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifLong8Array.cs b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifLong8Array.cs index b7756e62b..3266e538a 100644 --- a/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifLong8Array.cs +++ b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifLong8Array.cs @@ -47,46 +47,40 @@ internal sealed class ExifLong8Array : ExifArrayValue return this.SetSingle((ulong)Numerics.Clamp(val, 0, int.MaxValue)); case uint val: - return this.SetSingle((ulong)val); + return this.SetSingle(val); case short val: return this.SetSingle((ulong)Numerics.Clamp(val, 0, short.MaxValue)); case ushort val: - return this.SetSingle((ulong)val); + return this.SetSingle(val); case long val: return this.SetSingle((ulong)Numerics.Clamp(val, 0, long.MaxValue)); case long[] array: - { if (value.GetType() == typeof(ulong[])) { return this.SetArray((ulong[])value); } return this.SetArray(array); - } case int[] array: - { if (value.GetType() == typeof(uint[])) { return this.SetArray((uint[])value); } return this.SetArray(array); - } case short[] array: - { if (value.GetType() == typeof(ushort[])) { return this.SetArray((ushort[])value); } return this.SetArray(array); - } } return false; @@ -96,13 +90,13 @@ internal sealed class ExifLong8Array : ExifArrayValue private bool SetSingle(ulong value) { - this.Value = new[] { value }; + this.Value = [value]; return true; } private bool SetArray(long[] values) { - var numbers = new ulong[values.Length]; + ulong[] numbers = new ulong[values.Length]; for (int i = 0; i < values.Length; i++) { numbers[i] = (ulong)(values[i] < 0 ? 0 : values[i]); @@ -120,7 +114,7 @@ internal sealed class ExifLong8Array : ExifArrayValue private bool SetArray(int[] values) { - var numbers = new ulong[values.Length]; + ulong[] numbers = new ulong[values.Length]; for (int i = 0; i < values.Length; i++) { numbers[i] = (ulong)Numerics.Clamp(values[i], 0, int.MaxValue); @@ -132,10 +126,10 @@ internal sealed class ExifLong8Array : ExifArrayValue private bool SetArray(uint[] values) { - var numbers = new ulong[values.Length]; + ulong[] numbers = new ulong[values.Length]; for (int i = 0; i < values.Length; i++) { - numbers[i] = (ulong)values[i]; + numbers[i] = values[i]; } this.Value = numbers; @@ -144,7 +138,7 @@ internal sealed class ExifLong8Array : ExifArrayValue private bool SetArray(short[] values) { - var numbers = new ulong[values.Length]; + ulong[] numbers = new ulong[values.Length]; for (int i = 0; i < values.Length; i++) { numbers[i] = (ulong)Numerics.Clamp(values[i], 0, short.MaxValue); @@ -156,10 +150,10 @@ internal sealed class ExifLong8Array : ExifArrayValue private bool SetArray(ushort[] values) { - var numbers = new ulong[values.Length]; + ulong[] numbers = new ulong[values.Length]; for (int i = 0; i < values.Length; i++) { - numbers[i] = (ulong)values[i]; + numbers[i] = values[i]; } this.Value = numbers; diff --git a/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifNumberArray.cs b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifNumberArray.cs index 1162c25ea..3c8e4fc33 100644 --- a/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifNumberArray.cs +++ b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifNumberArray.cs @@ -52,7 +52,6 @@ internal sealed class ExifNumberArray : ExifArrayValue case ushort val: return this.SetSingle(val); case int[] array: - { // workaround for inconsistent covariance of value-typed arrays if (value.GetType() == typeof(uint[])) { @@ -60,17 +59,14 @@ internal sealed class ExifNumberArray : ExifArrayValue } return this.SetArray(array); - } case short[] array: - { if (value.GetType() == typeof(ushort[])) { return this.SetArray((ushort[])value); } return this.SetArray(array); - } } return false; @@ -80,13 +76,13 @@ internal sealed class ExifNumberArray : ExifArrayValue private bool SetSingle(Number value) { - this.Value = new[] { value }; + this.Value = [value]; return true; } private bool SetArray(int[] values) { - var numbers = new Number[values.Length]; + Number[] numbers = new Number[values.Length]; for (int i = 0; i < values.Length; i++) { numbers[i] = values[i]; @@ -98,7 +94,7 @@ internal sealed class ExifNumberArray : ExifArrayValue private bool SetArray(uint[] values) { - var numbers = new Number[values.Length]; + Number[] numbers = new Number[values.Length]; for (int i = 0; i < values.Length; i++) { numbers[i] = values[i]; @@ -110,7 +106,7 @@ internal sealed class ExifNumberArray : ExifArrayValue private bool SetArray(short[] values) { - var numbers = new Number[values.Length]; + Number[] numbers = new Number[values.Length]; for (int i = 0; i < values.Length; i++) { numbers[i] = values[i]; @@ -122,7 +118,7 @@ internal sealed class ExifNumberArray : ExifArrayValue private bool SetArray(ushort[] values) { - var numbers = new Number[values.Length]; + Number[] numbers = new Number[values.Length]; for (int i = 0; i < values.Length; i++) { numbers[i] = values[i]; diff --git a/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifRationalArray.cs b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifRationalArray.cs index ac6453edc..e8b2006df 100644 --- a/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifRationalArray.cs +++ b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifRationalArray.cs @@ -38,7 +38,7 @@ internal sealed class ExifRationalArray : ExifArrayValue { if (signed.Numerator >= 0 && signed.Denominator >= 0) { - this.Value = new[] { new Rational((uint)signed.Numerator, (uint)signed.Denominator) }; + this.Value = [new Rational((uint)signed.Numerator, (uint)signed.Denominator)]; } return true; @@ -56,7 +56,7 @@ internal sealed class ExifRationalArray : ExifArrayValue return false; } - var unsigned = new Rational[signed.Length]; + Rational[] unsigned = new Rational[signed.Length]; for (int i = 0; i < signed.Length; i++) { SignedRational s = signed[i]; diff --git a/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifShort.cs b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifShort.cs index d35b21422..7dfd7aed1 100644 --- a/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifShort.cs +++ b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifShort.cs @@ -36,7 +36,7 @@ internal sealed class ExifShort : ExifValue switch (value) { case int intValue: - if (intValue >= ushort.MinValue && intValue <= ushort.MaxValue) + if (intValue is >= ushort.MinValue and <= ushort.MaxValue) { this.Value = (ushort)intValue; return true; diff --git a/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifShortArray.cs b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifShortArray.cs index a205e77de..18ab5a162 100644 --- a/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifShortArray.cs +++ b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifShortArray.cs @@ -41,9 +41,9 @@ internal sealed class ExifShortArray : ExifArrayValue if (value is int signedInt) { - if (signedInt >= ushort.MinValue && signedInt <= ushort.MaxValue) + if (signedInt is >= ushort.MinValue and <= ushort.MaxValue) { - this.Value = new ushort[] { (ushort)signedInt }; + this.Value = [(ushort)signedInt]; } return true; @@ -53,7 +53,7 @@ internal sealed class ExifShortArray : ExifArrayValue { if (signedShort >= ushort.MinValue) { - this.Value = new ushort[] { (ushort)signedShort }; + this.Value = [(ushort)signedShort]; } return true; @@ -66,12 +66,12 @@ internal sealed class ExifShortArray : ExifArrayValue private bool TrySetSignedIntArray(int[] signed) { - if (Array.FindIndex(signed, x => x < ushort.MinValue || x > ushort.MaxValue) > -1) + if (Array.FindIndex(signed, x => x is < ushort.MinValue or > ushort.MaxValue) > -1) { return false; } - var unsigned = new ushort[signed.Length]; + ushort[] unsigned = new ushort[signed.Length]; for (int i = 0; i < signed.Length; i++) { int s = signed[i]; @@ -89,7 +89,7 @@ internal sealed class ExifShortArray : ExifArrayValue return false; } - var unsigned = new ushort[signed.Length]; + ushort[] unsigned = new ushort[signed.Length]; for (int i = 0; i < signed.Length; i++) { short s = signed[i]; diff --git a/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifSignedByte.cs b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifSignedByte.cs index 95a239b70..206f8bd41 100644 --- a/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifSignedByte.cs +++ b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifSignedByte.cs @@ -31,7 +31,7 @@ internal sealed class ExifSignedByte : ExifValue switch (value) { case int intValue: - if (intValue >= sbyte.MinValue && intValue <= sbyte.MaxValue) + if (intValue is >= sbyte.MinValue and <= sbyte.MaxValue) { this.Value = (sbyte)intValue; return true; diff --git a/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifSignedShort.cs b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifSignedShort.cs index 6726febef..5b008ea4a 100644 --- a/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifSignedShort.cs +++ b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifSignedShort.cs @@ -31,7 +31,7 @@ internal sealed class ExifSignedShort : ExifValue switch (value) { case int intValue: - if (intValue >= short.MinValue && intValue <= short.MaxValue) + if (intValue is >= short.MinValue and <= short.MaxValue) { this.Value = (short)intValue; return true; diff --git a/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifSignedShortArray.cs b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifSignedShortArray.cs index 206417f66..d3993ac0d 100644 --- a/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifSignedShortArray.cs +++ b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifSignedShortArray.cs @@ -36,9 +36,9 @@ internal sealed class ExifSignedShortArray : ExifArrayValue if (value is int intValue) { - if (intValue >= short.MinValue && intValue <= short.MaxValue) + if (intValue is >= short.MinValue and <= short.MaxValue) { - this.Value = new short[] { (short)intValue }; + this.Value = [(short)intValue]; } return true; @@ -51,12 +51,12 @@ internal sealed class ExifSignedShortArray : ExifArrayValue private bool TrySetSignedArray(int[] intArray) { - if (Array.FindIndex(intArray, x => x < short.MinValue || x > short.MaxValue) > -1) + if (Array.FindIndex(intArray, x => x is < short.MinValue or > short.MaxValue) > -1) { return false; } - var value = new short[intArray.Length]; + short[] value = new short[intArray.Length]; for (int i = 0; i < intArray.Length; i++) { int s = intArray[i]; diff --git a/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifValues.cs b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifValues.cs index 93f67d46a..1c054fcba 100644 --- a/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifValues.cs +++ b/src/ImageSharp/Metadata/Profiles/Exif/Values/ExifValues.cs @@ -3,7 +3,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif; -internal static partial class ExifValues +internal static class ExifValues { public static ExifValue? Create(ExifTagValue tag) => (ExifValue?)CreateValue(tag); @@ -12,573 +12,281 @@ internal static partial class ExifValues 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) - { - switch (dataType) + => dataType switch { - case ExifDataType.Byte: - return isArray ? new ExifByteArray(tag, dataType) : new ExifByte(tag, dataType); - case ExifDataType.DoubleFloat: - return isArray ? new ExifDoubleArray(tag) : new ExifDouble(tag); - case ExifDataType.SingleFloat: - return isArray ? new ExifFloatArray(tag) : new ExifFloat(tag); - case ExifDataType.Long: - return isArray ? new ExifLongArray(tag) : new ExifLong(tag); - case ExifDataType.Long8: - return isArray ? new ExifLong8Array(tag) : new ExifLong8(tag); - case ExifDataType.Rational: - return isArray ? new ExifRationalArray(tag) : new ExifRational(tag); - case ExifDataType.Short: - return isArray ? new ExifShortArray(tag) : new ExifShort(tag); - case ExifDataType.SignedByte: - return isArray ? new ExifSignedByteArray(tag) : new ExifSignedByte(tag); - case ExifDataType.SignedLong: - return isArray ? new ExifSignedLongArray(tag) : new ExifSignedLong(tag); - case ExifDataType.SignedLong8: - return isArray ? new ExifSignedLong8Array(tag) : new ExifSignedLong8(tag); - case ExifDataType.SignedRational: - return isArray ? new ExifSignedRationalArray(tag) : new ExifSignedRational(tag); - case ExifDataType.SignedShort: - return isArray ? new ExifSignedShortArray(tag) : new ExifSignedShort(tag); - case ExifDataType.Ascii: - return new ExifString(tag); - case ExifDataType.Undefined: - return isArray ? new ExifByteArray(tag, dataType) : new ExifByte(tag, dataType); - default: - return null; - } - } + ExifDataType.Byte => isArray ? new ExifByteArray(tag, dataType) : new ExifByte(tag, dataType), + ExifDataType.DoubleFloat => isArray ? new ExifDoubleArray(tag) : new ExifDouble(tag), + ExifDataType.SingleFloat => isArray ? new ExifFloatArray(tag) : new ExifFloat(tag), + ExifDataType.Long => isArray ? new ExifLongArray(tag) : new ExifLong(tag), + ExifDataType.Long8 => isArray ? new ExifLong8Array(tag) : new ExifLong8(tag), + ExifDataType.Rational => isArray ? new ExifRationalArray(tag) : new ExifRational(tag), + ExifDataType.Short => isArray ? new ExifShortArray(tag) : new ExifShort(tag), + ExifDataType.SignedByte => isArray ? new ExifSignedByteArray(tag) : new ExifSignedByte(tag), + ExifDataType.SignedLong => isArray ? new ExifSignedLongArray(tag) : new ExifSignedLong(tag), + ExifDataType.SignedLong8 => isArray ? new ExifSignedLong8Array(tag) : new ExifSignedLong8(tag), + ExifDataType.SignedRational => isArray ? new ExifSignedRationalArray(tag) : new ExifSignedRational(tag), + ExifDataType.SignedShort => isArray ? new ExifSignedShortArray(tag) : new ExifSignedShort(tag), + ExifDataType.Ascii => new ExifString(tag), + ExifDataType.Undefined => isArray ? new ExifByteArray(tag, dataType) : new ExifByte(tag, dataType), + _ => null, + }; private static object? CreateValue(ExifTagValue tag) - { - switch (tag) + => tag switch { - case ExifTagValue.FaxProfile: - return new ExifByte(ExifTag.FaxProfile, ExifDataType.Byte); - case ExifTagValue.ModeNumber: - return new ExifByte(ExifTag.ModeNumber, ExifDataType.Byte); - case ExifTagValue.GPSAltitudeRef: - return new ExifByte(ExifTag.GPSAltitudeRef, ExifDataType.Byte); - - case ExifTagValue.ClipPath: - return new ExifByteArray(ExifTag.ClipPath, ExifDataType.Byte); - case ExifTagValue.VersionYear: - return new ExifByteArray(ExifTag.VersionYear, ExifDataType.Byte); - case ExifTagValue.XMP: - return new ExifByteArray(ExifTag.XMP, ExifDataType.Byte); - case ExifTagValue.CFAPattern2: - return new ExifByteArray(ExifTag.CFAPattern2, ExifDataType.Byte); - case ExifTagValue.TIFFEPStandardID: - return new ExifByteArray(ExifTag.TIFFEPStandardID, ExifDataType.Byte); - case ExifTagValue.GPSVersionID: - return new ExifByteArray(ExifTag.GPSVersionID, ExifDataType.Byte); - - case ExifTagValue.PixelScale: - return new ExifDoubleArray(ExifTag.PixelScale); - case ExifTagValue.IntergraphMatrix: - return new ExifDoubleArray(ExifTag.IntergraphMatrix); - case ExifTagValue.ModelTiePoint: - return new ExifDoubleArray(ExifTag.ModelTiePoint); - case ExifTagValue.ModelTransform: - return new ExifDoubleArray(ExifTag.ModelTransform); - - case ExifTagValue.SubfileType: - return new ExifLong(ExifTag.SubfileType); - case ExifTagValue.SubIFDOffset: - return new ExifLong(ExifTag.SubIFDOffset); - case ExifTagValue.GPSIFDOffset: - return new ExifLong(ExifTag.GPSIFDOffset); - case ExifTagValue.T4Options: - return new ExifLong(ExifTag.T4Options); - case ExifTagValue.T6Options: - return new ExifLong(ExifTag.T6Options); - case ExifTagValue.XClipPathUnits: - return new ExifLong(ExifTag.XClipPathUnits); - case ExifTagValue.YClipPathUnits: - return new ExifLong(ExifTag.YClipPathUnits); - case ExifTagValue.ProfileType: - return new ExifLong(ExifTag.ProfileType); - case ExifTagValue.CodingMethods: - return new ExifLong(ExifTag.CodingMethods); - case ExifTagValue.T82ptions: - return new ExifLong(ExifTag.T82ptions); - case ExifTagValue.JPEGInterchangeFormat: - return new ExifLong(ExifTag.JPEGInterchangeFormat); - case ExifTagValue.JPEGInterchangeFormatLength: - return new ExifLong(ExifTag.JPEGInterchangeFormatLength); - case ExifTagValue.MDFileTag: - return new ExifLong(ExifTag.MDFileTag); - case ExifTagValue.StandardOutputSensitivity: - return new ExifLong(ExifTag.StandardOutputSensitivity); - case ExifTagValue.RecommendedExposureIndex: - return new ExifLong(ExifTag.RecommendedExposureIndex); - case ExifTagValue.ISOSpeed: - return new ExifLong(ExifTag.ISOSpeed); - case ExifTagValue.ISOSpeedLatitudeyyy: - return new ExifLong(ExifTag.ISOSpeedLatitudeyyy); - case ExifTagValue.ISOSpeedLatitudezzz: - return new ExifLong(ExifTag.ISOSpeedLatitudezzz); - case ExifTagValue.FaxRecvParams: - return new ExifLong(ExifTag.FaxRecvParams); - case ExifTagValue.FaxRecvTime: - return new ExifLong(ExifTag.FaxRecvTime); - case ExifTagValue.ImageNumber: - return new ExifLong(ExifTag.ImageNumber); - - case ExifTagValue.FreeOffsets: - return new ExifLongArray(ExifTag.FreeOffsets); - case ExifTagValue.FreeByteCounts: - return new ExifLongArray(ExifTag.FreeByteCounts); - case ExifTagValue.ColorResponseUnit: - return new ExifLongArray(ExifTag.ColorResponseUnit); - case ExifTagValue.SMinSampleValue: - return new ExifLongArray(ExifTag.SMinSampleValue); - case ExifTagValue.SMaxSampleValue: - return new ExifLongArray(ExifTag.SMaxSampleValue); - case ExifTagValue.JPEGQTables: - return new ExifLongArray(ExifTag.JPEGQTables); - case ExifTagValue.JPEGDCTables: - return new ExifLongArray(ExifTag.JPEGDCTables); - case ExifTagValue.JPEGACTables: - return new ExifLongArray(ExifTag.JPEGACTables); - case ExifTagValue.StripRowCounts: - return new ExifLongArray(ExifTag.StripRowCounts); - case ExifTagValue.IntergraphRegisters: - return new ExifLongArray(ExifTag.IntergraphRegisters); - case ExifTagValue.SubIFDs: - return new ExifLongArray(ExifTag.SubIFDs); - - case ExifTagValue.ImageWidth: - return new ExifNumber(ExifTag.ImageWidth); - case ExifTagValue.ImageLength: - return new ExifNumber(ExifTag.ImageLength); - case ExifTagValue.RowsPerStrip: - return new ExifNumber(ExifTag.RowsPerStrip); - case ExifTagValue.TileWidth: - return new ExifNumber(ExifTag.TileWidth); - case ExifTagValue.TileLength: - return new ExifNumber(ExifTag.TileLength); - case ExifTagValue.BadFaxLines: - return new ExifNumber(ExifTag.BadFaxLines); - case ExifTagValue.ConsecutiveBadFaxLines: - return new ExifNumber(ExifTag.ConsecutiveBadFaxLines); - case ExifTagValue.PixelXDimension: - return new ExifNumber(ExifTag.PixelXDimension); - case ExifTagValue.PixelYDimension: - return new ExifNumber(ExifTag.PixelYDimension); - - case ExifTagValue.StripByteCounts: - return new ExifNumberArray(ExifTag.StripByteCounts); - case ExifTagValue.StripOffsets: - return new ExifNumberArray(ExifTag.StripOffsets); - case ExifTagValue.TileByteCounts: - return new ExifNumberArray(ExifTag.TileByteCounts); - case ExifTagValue.TileOffsets: - return new ExifNumberArray(ExifTag.TileOffsets); - case ExifTagValue.ImageLayer: - return new ExifNumberArray(ExifTag.ImageLayer); - - case ExifTagValue.XPosition: - return new ExifRational(ExifTag.XPosition); - case ExifTagValue.YPosition: - return new ExifRational(ExifTag.YPosition); - case ExifTagValue.XResolution: - return new ExifRational(ExifTag.XResolution); - case ExifTagValue.YResolution: - return new ExifRational(ExifTag.YResolution); - case ExifTagValue.BatteryLevel: - return new ExifRational(ExifTag.BatteryLevel); - case ExifTagValue.ExposureTime: - return new ExifRational(ExifTag.ExposureTime); - case ExifTagValue.FNumber: - return new ExifRational(ExifTag.FNumber); - case ExifTagValue.MDScalePixel: - return new ExifRational(ExifTag.MDScalePixel); - case ExifTagValue.CompressedBitsPerPixel: - return new ExifRational(ExifTag.CompressedBitsPerPixel); - case ExifTagValue.ApertureValue: - return new ExifRational(ExifTag.ApertureValue); - case ExifTagValue.MaxApertureValue: - return new ExifRational(ExifTag.MaxApertureValue); - case ExifTagValue.SubjectDistance: - return new ExifRational(ExifTag.SubjectDistance); - case ExifTagValue.FocalLength: - return new ExifRational(ExifTag.FocalLength); - case ExifTagValue.FlashEnergy2: - return new ExifRational(ExifTag.FlashEnergy2); - case ExifTagValue.FocalPlaneXResolution2: - return new ExifRational(ExifTag.FocalPlaneXResolution2); - case ExifTagValue.FocalPlaneYResolution2: - return new ExifRational(ExifTag.FocalPlaneYResolution2); - case ExifTagValue.ExposureIndex2: - return new ExifRational(ExifTag.ExposureIndex2); - case ExifTagValue.Humidity: - return new ExifRational(ExifTag.Humidity); - case ExifTagValue.Pressure: - return new ExifRational(ExifTag.Pressure); - case ExifTagValue.Acceleration: - return new ExifRational(ExifTag.Acceleration); - case ExifTagValue.FlashEnergy: - return new ExifRational(ExifTag.FlashEnergy); - case ExifTagValue.FocalPlaneXResolution: - return new ExifRational(ExifTag.FocalPlaneXResolution); - case ExifTagValue.FocalPlaneYResolution: - return new ExifRational(ExifTag.FocalPlaneYResolution); - case ExifTagValue.ExposureIndex: - return new ExifRational(ExifTag.ExposureIndex); - case ExifTagValue.DigitalZoomRatio: - return new ExifRational(ExifTag.DigitalZoomRatio); - case ExifTagValue.GPSAltitude: - return new ExifRational(ExifTag.GPSAltitude); - case ExifTagValue.GPSDOP: - return new ExifRational(ExifTag.GPSDOP); - case ExifTagValue.GPSSpeed: - return new ExifRational(ExifTag.GPSSpeed); - case ExifTagValue.GPSTrack: - return new ExifRational(ExifTag.GPSTrack); - case ExifTagValue.GPSImgDirection: - return new ExifRational(ExifTag.GPSImgDirection); - case ExifTagValue.GPSDestBearing: - return new ExifRational(ExifTag.GPSDestBearing); - case ExifTagValue.GPSDestDistance: - return new ExifRational(ExifTag.GPSDestDistance); - case ExifTagValue.GPSHPositioningError: - return new ExifRational(ExifTag.GPSHPositioningError); - - case ExifTagValue.WhitePoint: - return new ExifRationalArray(ExifTag.WhitePoint); - case ExifTagValue.PrimaryChromaticities: - return new ExifRationalArray(ExifTag.PrimaryChromaticities); - case ExifTagValue.YCbCrCoefficients: - return new ExifRationalArray(ExifTag.YCbCrCoefficients); - case ExifTagValue.ReferenceBlackWhite: - return new ExifRationalArray(ExifTag.ReferenceBlackWhite); - case ExifTagValue.GPSLatitude: - return new ExifRationalArray(ExifTag.GPSLatitude); - case ExifTagValue.GPSLongitude: - return new ExifRationalArray(ExifTag.GPSLongitude); - case ExifTagValue.GPSTimestamp: - return new ExifRationalArray(ExifTag.GPSTimestamp); - case ExifTagValue.GPSDestLatitude: - return new ExifRationalArray(ExifTag.GPSDestLatitude); - case ExifTagValue.GPSDestLongitude: - return new ExifRationalArray(ExifTag.GPSDestLongitude); - case ExifTagValue.LensSpecification: - return new ExifRationalArray(ExifTag.LensSpecification); - - case ExifTagValue.OldSubfileType: - return new ExifShort(ExifTag.OldSubfileType); - case ExifTagValue.Compression: - return new ExifShort(ExifTag.Compression); - case ExifTagValue.PhotometricInterpretation: - return new ExifShort(ExifTag.PhotometricInterpretation); - case ExifTagValue.Thresholding: - return new ExifShort(ExifTag.Thresholding); - case ExifTagValue.CellWidth: - return new ExifShort(ExifTag.CellWidth); - case ExifTagValue.CellLength: - return new ExifShort(ExifTag.CellLength); - case ExifTagValue.FillOrder: - return new ExifShort(ExifTag.FillOrder); - case ExifTagValue.Orientation: - return new ExifShort(ExifTag.Orientation); - case ExifTagValue.SamplesPerPixel: - return new ExifShort(ExifTag.SamplesPerPixel); - case ExifTagValue.PlanarConfiguration: - return new ExifShort(ExifTag.PlanarConfiguration); - case ExifTagValue.Predictor: - return new ExifShort(ExifTag.Predictor); - case ExifTagValue.GrayResponseUnit: - return new ExifShort(ExifTag.GrayResponseUnit); - case ExifTagValue.ResolutionUnit: - return new ExifShort(ExifTag.ResolutionUnit); - case ExifTagValue.CleanFaxData: - return new ExifShort(ExifTag.CleanFaxData); - case ExifTagValue.InkSet: - return new ExifShort(ExifTag.InkSet); - case ExifTagValue.NumberOfInks: - return new ExifShort(ExifTag.NumberOfInks); - case ExifTagValue.DotRange: - return new ExifShort(ExifTag.DotRange); - case ExifTagValue.Indexed: - return new ExifShort(ExifTag.Indexed); - case ExifTagValue.OPIProxy: - return new ExifShort(ExifTag.OPIProxy); - case ExifTagValue.JPEGProc: - return new ExifShort(ExifTag.JPEGProc); - case ExifTagValue.JPEGRestartInterval: - return new ExifShort(ExifTag.JPEGRestartInterval); - case ExifTagValue.YCbCrPositioning: - return new ExifShort(ExifTag.YCbCrPositioning); - case ExifTagValue.Rating: - return new ExifShort(ExifTag.Rating); - case ExifTagValue.RatingPercent: - return new ExifShort(ExifTag.RatingPercent); - case ExifTagValue.ExposureProgram: - return new ExifShort(ExifTag.ExposureProgram); - case ExifTagValue.Interlace: - return new ExifShort(ExifTag.Interlace); - case ExifTagValue.SelfTimerMode: - return new ExifShort(ExifTag.SelfTimerMode); - case ExifTagValue.SensitivityType: - return new ExifShort(ExifTag.SensitivityType); - case ExifTagValue.MeteringMode: - return new ExifShort(ExifTag.MeteringMode); - case ExifTagValue.LightSource: - return new ExifShort(ExifTag.LightSource); - case ExifTagValue.FocalPlaneResolutionUnit2: - return new ExifShort(ExifTag.FocalPlaneResolutionUnit2); - case ExifTagValue.SensingMethod2: - return new ExifShort(ExifTag.SensingMethod2); - case ExifTagValue.Flash: - return new ExifShort(ExifTag.Flash); - case ExifTagValue.ColorSpace: - return new ExifShort(ExifTag.ColorSpace); - case ExifTagValue.FocalPlaneResolutionUnit: - return new ExifShort(ExifTag.FocalPlaneResolutionUnit); - case ExifTagValue.SensingMethod: - return new ExifShort(ExifTag.SensingMethod); - case ExifTagValue.CustomRendered: - return new ExifShort(ExifTag.CustomRendered); - case ExifTagValue.ExposureMode: - return new ExifShort(ExifTag.ExposureMode); - case ExifTagValue.WhiteBalance: - return new ExifShort(ExifTag.WhiteBalance); - case ExifTagValue.FocalLengthIn35mmFilm: - return new ExifShort(ExifTag.FocalLengthIn35mmFilm); - case ExifTagValue.SceneCaptureType: - return new ExifShort(ExifTag.SceneCaptureType); - case ExifTagValue.GainControl: - return new ExifShort(ExifTag.GainControl); - case ExifTagValue.Contrast: - return new ExifShort(ExifTag.Contrast); - case ExifTagValue.Saturation: - return new ExifShort(ExifTag.Saturation); - case ExifTagValue.Sharpness: - return new ExifShort(ExifTag.Sharpness); - case ExifTagValue.SubjectDistanceRange: - return new ExifShort(ExifTag.SubjectDistanceRange); - case ExifTagValue.GPSDifferential: - return new ExifShort(ExifTag.GPSDifferential); - - case ExifTagValue.BitsPerSample: - return new ExifShortArray(ExifTag.BitsPerSample); - case ExifTagValue.MinSampleValue: - return new ExifShortArray(ExifTag.MinSampleValue); - case ExifTagValue.MaxSampleValue: - return new ExifShortArray(ExifTag.MaxSampleValue); - case ExifTagValue.GrayResponseCurve: - return new ExifShortArray(ExifTag.GrayResponseCurve); - case ExifTagValue.ColorMap: - return new ExifShortArray(ExifTag.ColorMap); - case ExifTagValue.ExtraSamples: - return new ExifShortArray(ExifTag.ExtraSamples); - case ExifTagValue.PageNumber: - return new ExifShortArray(ExifTag.PageNumber); - case ExifTagValue.TransferFunction: - return new ExifShortArray(ExifTag.TransferFunction); - case ExifTagValue.HalftoneHints: - return new ExifShortArray(ExifTag.HalftoneHints); - case ExifTagValue.SampleFormat: - return new ExifShortArray(ExifTag.SampleFormat); - case ExifTagValue.TransferRange: - return new ExifShortArray(ExifTag.TransferRange); - case ExifTagValue.DefaultImageColor: - return new ExifShortArray(ExifTag.DefaultImageColor); - case ExifTagValue.JPEGLosslessPredictors: - return new ExifShortArray(ExifTag.JPEGLosslessPredictors); - case ExifTagValue.JPEGPointTransforms: - return new ExifShortArray(ExifTag.JPEGPointTransforms); - case ExifTagValue.YCbCrSubsampling: - return new ExifShortArray(ExifTag.YCbCrSubsampling); - case ExifTagValue.CFARepeatPatternDim: - return new ExifShortArray(ExifTag.CFARepeatPatternDim); - case ExifTagValue.IntergraphPacketData: - return new ExifShortArray(ExifTag.IntergraphPacketData); - case ExifTagValue.ISOSpeedRatings: - return new ExifShortArray(ExifTag.ISOSpeedRatings); - case ExifTagValue.SubjectArea: - return new ExifShortArray(ExifTag.SubjectArea); - case ExifTagValue.SubjectLocation: - return new ExifShortArray(ExifTag.SubjectLocation); - - case ExifTagValue.ShutterSpeedValue: - return new ExifSignedRational(ExifTag.ShutterSpeedValue); - case ExifTagValue.BrightnessValue: - return new ExifSignedRational(ExifTag.BrightnessValue); - case ExifTagValue.ExposureBiasValue: - return new ExifSignedRational(ExifTag.ExposureBiasValue); - case ExifTagValue.AmbientTemperature: - return new ExifSignedRational(ExifTag.AmbientTemperature); - case ExifTagValue.WaterDepth: - return new ExifSignedRational(ExifTag.WaterDepth); - case ExifTagValue.CameraElevationAngle: - return new ExifSignedRational(ExifTag.CameraElevationAngle); - - case ExifTagValue.Decode: - return new ExifSignedRationalArray(ExifTag.Decode); - - case ExifTagValue.TimeZoneOffset: - return new ExifSignedShortArray(ExifTag.TimeZoneOffset); - - case ExifTagValue.ImageDescription: - return new ExifString(ExifTag.ImageDescription); - case ExifTagValue.Make: - return new ExifString(ExifTag.Make); - case ExifTagValue.Model: - return new ExifString(ExifTag.Model); - case ExifTagValue.Software: - return new ExifString(ExifTag.Software); - case ExifTagValue.DateTime: - return new ExifString(ExifTag.DateTime); - case ExifTagValue.Artist: - return new ExifString(ExifTag.Artist); - case ExifTagValue.HostComputer: - return new ExifString(ExifTag.HostComputer); - case ExifTagValue.Copyright: - return new ExifString(ExifTag.Copyright); - case ExifTagValue.DocumentName: - return new ExifString(ExifTag.DocumentName); - case ExifTagValue.PageName: - return new ExifString(ExifTag.PageName); - case ExifTagValue.InkNames: - return new ExifString(ExifTag.InkNames); - case ExifTagValue.TargetPrinter: - return new ExifString(ExifTag.TargetPrinter); - case ExifTagValue.ImageID: - return new ExifString(ExifTag.ImageID); - case ExifTagValue.MDLabName: - return new ExifString(ExifTag.MDLabName); - case ExifTagValue.MDSampleInfo: - return new ExifString(ExifTag.MDSampleInfo); - case ExifTagValue.MDPrepDate: - return new ExifString(ExifTag.MDPrepDate); - case ExifTagValue.MDPrepTime: - return new ExifString(ExifTag.MDPrepTime); - case ExifTagValue.MDFileUnits: - return new ExifString(ExifTag.MDFileUnits); - case ExifTagValue.SEMInfo: - return new ExifString(ExifTag.SEMInfo); - case ExifTagValue.SpectralSensitivity: - return new ExifString(ExifTag.SpectralSensitivity); - case ExifTagValue.DateTimeOriginal: - return new ExifString(ExifTag.DateTimeOriginal); - case ExifTagValue.DateTimeDigitized: - return new ExifString(ExifTag.DateTimeDigitized); - case ExifTagValue.SubsecTime: - return new ExifString(ExifTag.SubsecTime); - case ExifTagValue.SubsecTimeOriginal: - return new ExifString(ExifTag.SubsecTimeOriginal); - case ExifTagValue.SubsecTimeDigitized: - return new ExifString(ExifTag.SubsecTimeDigitized); - case ExifTagValue.RelatedSoundFile: - return new ExifString(ExifTag.RelatedSoundFile); - case ExifTagValue.FaxSubaddress: - return new ExifString(ExifTag.FaxSubaddress); - case ExifTagValue.OffsetTime: - return new ExifString(ExifTag.OffsetTime); - case ExifTagValue.OffsetTimeOriginal: - return new ExifString(ExifTag.OffsetTimeOriginal); - case ExifTagValue.OffsetTimeDigitized: - return new ExifString(ExifTag.OffsetTimeDigitized); - case ExifTagValue.SecurityClassification: - return new ExifString(ExifTag.SecurityClassification); - case ExifTagValue.ImageHistory: - return new ExifString(ExifTag.ImageHistory); - case ExifTagValue.ImageUniqueID: - return new ExifString(ExifTag.ImageUniqueID); - case ExifTagValue.OwnerName: - return new ExifString(ExifTag.OwnerName); - case ExifTagValue.SerialNumber: - return new ExifString(ExifTag.SerialNumber); - case ExifTagValue.LensMake: - return new ExifString(ExifTag.LensMake); - case ExifTagValue.LensModel: - return new ExifString(ExifTag.LensModel); - case ExifTagValue.LensSerialNumber: - return new ExifString(ExifTag.LensSerialNumber); - case ExifTagValue.GDALMetadata: - return new ExifString(ExifTag.GDALMetadata); - case ExifTagValue.GDALNoData: - return new ExifString(ExifTag.GDALNoData); - case ExifTagValue.GPSLatitudeRef: - return new ExifString(ExifTag.GPSLatitudeRef); - case ExifTagValue.GPSLongitudeRef: - return new ExifString(ExifTag.GPSLongitudeRef); - case ExifTagValue.GPSSatellites: - return new ExifString(ExifTag.GPSSatellites); - case ExifTagValue.GPSStatus: - return new ExifString(ExifTag.GPSStatus); - case ExifTagValue.GPSMeasureMode: - return new ExifString(ExifTag.GPSMeasureMode); - case ExifTagValue.GPSSpeedRef: - return new ExifString(ExifTag.GPSSpeedRef); - case ExifTagValue.GPSTrackRef: - return new ExifString(ExifTag.GPSTrackRef); - case ExifTagValue.GPSImgDirectionRef: - return new ExifString(ExifTag.GPSImgDirectionRef); - case ExifTagValue.GPSMapDatum: - return new ExifString(ExifTag.GPSMapDatum); - case ExifTagValue.GPSDestLatitudeRef: - return new ExifString(ExifTag.GPSDestLatitudeRef); - case ExifTagValue.GPSDestLongitudeRef: - return new ExifString(ExifTag.GPSDestLongitudeRef); - case ExifTagValue.GPSDestBearingRef: - return new ExifString(ExifTag.GPSDestBearingRef); - case ExifTagValue.GPSDestDistanceRef: - return new ExifString(ExifTag.GPSDestDistanceRef); - case ExifTagValue.GPSDateStamp: - return new ExifString(ExifTag.GPSDateStamp); - - case ExifTagValue.FileSource: - return new ExifByte(ExifTag.FileSource, ExifDataType.Undefined); - case ExifTagValue.SceneType: - return new ExifByte(ExifTag.SceneType, ExifDataType.Undefined); - - case ExifTagValue.JPEGTables: - return new ExifByteArray(ExifTag.JPEGTables, ExifDataType.Undefined); - case ExifTagValue.OECF: - return new ExifByteArray(ExifTag.OECF, ExifDataType.Undefined); - case ExifTagValue.ExifVersion: - return new ExifByteArray(ExifTag.ExifVersion, ExifDataType.Undefined); - case ExifTagValue.ComponentsConfiguration: - return new ExifByteArray(ExifTag.ComponentsConfiguration, ExifDataType.Undefined); - case ExifTagValue.MakerNote: - return new ExifByteArray(ExifTag.MakerNote, ExifDataType.Undefined); - case ExifTagValue.FlashpixVersion: - return new ExifByteArray(ExifTag.FlashpixVersion, ExifDataType.Undefined); - case ExifTagValue.SpatialFrequencyResponse: - return new ExifByteArray(ExifTag.SpatialFrequencyResponse, ExifDataType.Undefined); - case ExifTagValue.SpatialFrequencyResponse2: - return new ExifByteArray(ExifTag.SpatialFrequencyResponse2, ExifDataType.Undefined); - case ExifTagValue.Noise: - return new ExifByteArray(ExifTag.Noise, ExifDataType.Undefined); - case ExifTagValue.CFAPattern: - return new ExifByteArray(ExifTag.CFAPattern, ExifDataType.Undefined); - case ExifTagValue.DeviceSettingDescription: - return new ExifByteArray(ExifTag.DeviceSettingDescription, ExifDataType.Undefined); - case ExifTagValue.ImageSourceData: - return new ExifByteArray(ExifTag.ImageSourceData, ExifDataType.Undefined); - - case ExifTagValue.XPTitle: - return new ExifUcs2String(ExifTag.XPTitle); - case ExifTagValue.XPComment: - return new ExifUcs2String(ExifTag.XPComment); - case ExifTagValue.XPAuthor: - return new ExifUcs2String(ExifTag.XPAuthor); - case ExifTagValue.XPKeywords: - return new ExifUcs2String(ExifTag.XPKeywords); - case ExifTagValue.XPSubject: - return new ExifUcs2String(ExifTag.XPSubject); - - case ExifTagValue.UserComment: - return new ExifEncodedString(ExifTag.UserComment); - case ExifTagValue.GPSProcessingMethod: - return new ExifEncodedString(ExifTag.GPSProcessingMethod); - case ExifTagValue.GPSAreaInformation: - return new ExifEncodedString(ExifTag.GPSAreaInformation); - - default: - return null; - } - } + ExifTagValue.FaxProfile => new ExifByte(ExifTag.FaxProfile, ExifDataType.Byte), + ExifTagValue.ModeNumber => new ExifByte(ExifTag.ModeNumber, ExifDataType.Byte), + ExifTagValue.GPSAltitudeRef => new ExifByte(ExifTag.GPSAltitudeRef, ExifDataType.Byte), + ExifTagValue.ClipPath => new ExifByteArray(ExifTag.ClipPath, ExifDataType.Byte), + ExifTagValue.VersionYear => new ExifByteArray(ExifTag.VersionYear, ExifDataType.Byte), + ExifTagValue.XMP => new ExifByteArray(ExifTag.XMP, ExifDataType.Byte), + ExifTagValue.CFAPattern2 => new ExifByteArray(ExifTag.CFAPattern2, ExifDataType.Byte), + ExifTagValue.TIFFEPStandardID => new ExifByteArray(ExifTag.TIFFEPStandardID, ExifDataType.Byte), + ExifTagValue.GPSVersionID => new ExifByteArray(ExifTag.GPSVersionID, ExifDataType.Byte), + ExifTagValue.PixelScale => new ExifDoubleArray(ExifTag.PixelScale), + ExifTagValue.IntergraphMatrix => new ExifDoubleArray(ExifTag.IntergraphMatrix), + ExifTagValue.ModelTiePoint => new ExifDoubleArray(ExifTag.ModelTiePoint), + ExifTagValue.ModelTransform => new ExifDoubleArray(ExifTag.ModelTransform), + ExifTagValue.SubfileType => new ExifLong(ExifTag.SubfileType), + ExifTagValue.SubIFDOffset => new ExifLong(ExifTag.SubIFDOffset), + ExifTagValue.GPSIFDOffset => new ExifLong(ExifTag.GPSIFDOffset), + ExifTagValue.T4Options => new ExifLong(ExifTag.T4Options), + ExifTagValue.T6Options => new ExifLong(ExifTag.T6Options), + ExifTagValue.XClipPathUnits => new ExifLong(ExifTag.XClipPathUnits), + ExifTagValue.YClipPathUnits => new ExifLong(ExifTag.YClipPathUnits), + ExifTagValue.ProfileType => new ExifLong(ExifTag.ProfileType), + ExifTagValue.CodingMethods => new ExifLong(ExifTag.CodingMethods), + ExifTagValue.T82ptions => new ExifLong(ExifTag.T82ptions), + ExifTagValue.JPEGInterchangeFormat => new ExifLong(ExifTag.JPEGInterchangeFormat), + ExifTagValue.JPEGInterchangeFormatLength => new ExifLong(ExifTag.JPEGInterchangeFormatLength), + ExifTagValue.MDFileTag => new ExifLong(ExifTag.MDFileTag), + ExifTagValue.StandardOutputSensitivity => new ExifLong(ExifTag.StandardOutputSensitivity), + ExifTagValue.RecommendedExposureIndex => new ExifLong(ExifTag.RecommendedExposureIndex), + ExifTagValue.ISOSpeed => new ExifLong(ExifTag.ISOSpeed), + ExifTagValue.ISOSpeedLatitudeyyy => new ExifLong(ExifTag.ISOSpeedLatitudeyyy), + ExifTagValue.ISOSpeedLatitudezzz => new ExifLong(ExifTag.ISOSpeedLatitudezzz), + ExifTagValue.FaxRecvParams => new ExifLong(ExifTag.FaxRecvParams), + ExifTagValue.FaxRecvTime => new ExifLong(ExifTag.FaxRecvTime), + ExifTagValue.ImageNumber => new ExifLong(ExifTag.ImageNumber), + ExifTagValue.FreeOffsets => new ExifLongArray(ExifTag.FreeOffsets), + ExifTagValue.FreeByteCounts => new ExifLongArray(ExifTag.FreeByteCounts), + ExifTagValue.ColorResponseUnit => new ExifLongArray(ExifTag.ColorResponseUnit), + ExifTagValue.SMinSampleValue => new ExifLongArray(ExifTag.SMinSampleValue), + ExifTagValue.SMaxSampleValue => new ExifLongArray(ExifTag.SMaxSampleValue), + ExifTagValue.JPEGQTables => new ExifLongArray(ExifTag.JPEGQTables), + ExifTagValue.JPEGDCTables => new ExifLongArray(ExifTag.JPEGDCTables), + ExifTagValue.JPEGACTables => new ExifLongArray(ExifTag.JPEGACTables), + ExifTagValue.StripRowCounts => new ExifLongArray(ExifTag.StripRowCounts), + ExifTagValue.IntergraphRegisters => new ExifLongArray(ExifTag.IntergraphRegisters), + ExifTagValue.SubIFDs => new ExifLongArray(ExifTag.SubIFDs), + ExifTagValue.ImageWidth => new ExifNumber(ExifTag.ImageWidth), + ExifTagValue.ImageLength => new ExifNumber(ExifTag.ImageLength), + ExifTagValue.RowsPerStrip => new ExifNumber(ExifTag.RowsPerStrip), + ExifTagValue.TileWidth => new ExifNumber(ExifTag.TileWidth), + ExifTagValue.TileLength => new ExifNumber(ExifTag.TileLength), + ExifTagValue.BadFaxLines => new ExifNumber(ExifTag.BadFaxLines), + ExifTagValue.ConsecutiveBadFaxLines => new ExifNumber(ExifTag.ConsecutiveBadFaxLines), + ExifTagValue.PixelXDimension => new ExifNumber(ExifTag.PixelXDimension), + ExifTagValue.PixelYDimension => new ExifNumber(ExifTag.PixelYDimension), + ExifTagValue.StripByteCounts => new ExifNumberArray(ExifTag.StripByteCounts), + ExifTagValue.StripOffsets => new ExifNumberArray(ExifTag.StripOffsets), + ExifTagValue.TileByteCounts => new ExifNumberArray(ExifTag.TileByteCounts), + ExifTagValue.TileOffsets => new ExifNumberArray(ExifTag.TileOffsets), + ExifTagValue.ImageLayer => new ExifNumberArray(ExifTag.ImageLayer), + ExifTagValue.XPosition => new ExifRational(ExifTag.XPosition), + ExifTagValue.YPosition => new ExifRational(ExifTag.YPosition), + ExifTagValue.XResolution => new ExifRational(ExifTag.XResolution), + ExifTagValue.YResolution => new ExifRational(ExifTag.YResolution), + ExifTagValue.BatteryLevel => new ExifRational(ExifTag.BatteryLevel), + ExifTagValue.ExposureTime => new ExifRational(ExifTag.ExposureTime), + ExifTagValue.FNumber => new ExifRational(ExifTag.FNumber), + ExifTagValue.MDScalePixel => new ExifRational(ExifTag.MDScalePixel), + ExifTagValue.CompressedBitsPerPixel => new ExifRational(ExifTag.CompressedBitsPerPixel), + ExifTagValue.ApertureValue => new ExifRational(ExifTag.ApertureValue), + ExifTagValue.MaxApertureValue => new ExifRational(ExifTag.MaxApertureValue), + ExifTagValue.SubjectDistance => new ExifRational(ExifTag.SubjectDistance), + ExifTagValue.FocalLength => new ExifRational(ExifTag.FocalLength), + ExifTagValue.FlashEnergy2 => new ExifRational(ExifTag.FlashEnergy2), + ExifTagValue.FocalPlaneXResolution2 => new ExifRational(ExifTag.FocalPlaneXResolution2), + ExifTagValue.FocalPlaneYResolution2 => new ExifRational(ExifTag.FocalPlaneYResolution2), + ExifTagValue.ExposureIndex2 => new ExifRational(ExifTag.ExposureIndex2), + ExifTagValue.Humidity => new ExifRational(ExifTag.Humidity), + ExifTagValue.Pressure => new ExifRational(ExifTag.Pressure), + ExifTagValue.Acceleration => new ExifRational(ExifTag.Acceleration), + ExifTagValue.FlashEnergy => new ExifRational(ExifTag.FlashEnergy), + ExifTagValue.FocalPlaneXResolution => new ExifRational(ExifTag.FocalPlaneXResolution), + ExifTagValue.FocalPlaneYResolution => new ExifRational(ExifTag.FocalPlaneYResolution), + ExifTagValue.ExposureIndex => new ExifRational(ExifTag.ExposureIndex), + ExifTagValue.DigitalZoomRatio => new ExifRational(ExifTag.DigitalZoomRatio), + ExifTagValue.GPSAltitude => new ExifRational(ExifTag.GPSAltitude), + ExifTagValue.GPSDOP => new ExifRational(ExifTag.GPSDOP), + ExifTagValue.GPSSpeed => new ExifRational(ExifTag.GPSSpeed), + ExifTagValue.GPSTrack => new ExifRational(ExifTag.GPSTrack), + ExifTagValue.GPSImgDirection => new ExifRational(ExifTag.GPSImgDirection), + ExifTagValue.GPSDestBearing => new ExifRational(ExifTag.GPSDestBearing), + ExifTagValue.GPSDestDistance => new ExifRational(ExifTag.GPSDestDistance), + ExifTagValue.GPSHPositioningError => new ExifRational(ExifTag.GPSHPositioningError), + ExifTagValue.WhitePoint => new ExifRationalArray(ExifTag.WhitePoint), + ExifTagValue.PrimaryChromaticities => new ExifRationalArray(ExifTag.PrimaryChromaticities), + ExifTagValue.YCbCrCoefficients => new ExifRationalArray(ExifTag.YCbCrCoefficients), + ExifTagValue.ReferenceBlackWhite => new ExifRationalArray(ExifTag.ReferenceBlackWhite), + ExifTagValue.GPSLatitude => new ExifRationalArray(ExifTag.GPSLatitude), + ExifTagValue.GPSLongitude => new ExifRationalArray(ExifTag.GPSLongitude), + ExifTagValue.GPSTimestamp => new ExifRationalArray(ExifTag.GPSTimestamp), + ExifTagValue.GPSDestLatitude => new ExifRationalArray(ExifTag.GPSDestLatitude), + ExifTagValue.GPSDestLongitude => new ExifRationalArray(ExifTag.GPSDestLongitude), + ExifTagValue.LensSpecification => new ExifRationalArray(ExifTag.LensSpecification), + ExifTagValue.OldSubfileType => new ExifShort(ExifTag.OldSubfileType), + ExifTagValue.Compression => new ExifShort(ExifTag.Compression), + ExifTagValue.PhotometricInterpretation => new ExifShort(ExifTag.PhotometricInterpretation), + ExifTagValue.Thresholding => new ExifShort(ExifTag.Thresholding), + ExifTagValue.CellWidth => new ExifShort(ExifTag.CellWidth), + ExifTagValue.CellLength => new ExifShort(ExifTag.CellLength), + ExifTagValue.FillOrder => new ExifShort(ExifTag.FillOrder), + ExifTagValue.Orientation => new ExifShort(ExifTag.Orientation), + ExifTagValue.SamplesPerPixel => new ExifShort(ExifTag.SamplesPerPixel), + ExifTagValue.PlanarConfiguration => new ExifShort(ExifTag.PlanarConfiguration), + ExifTagValue.Predictor => new ExifShort(ExifTag.Predictor), + ExifTagValue.GrayResponseUnit => new ExifShort(ExifTag.GrayResponseUnit), + ExifTagValue.ResolutionUnit => new ExifShort(ExifTag.ResolutionUnit), + ExifTagValue.CleanFaxData => new ExifShort(ExifTag.CleanFaxData), + ExifTagValue.InkSet => new ExifShort(ExifTag.InkSet), + ExifTagValue.NumberOfInks => new ExifShort(ExifTag.NumberOfInks), + ExifTagValue.DotRange => new ExifShort(ExifTag.DotRange), + ExifTagValue.Indexed => new ExifShort(ExifTag.Indexed), + ExifTagValue.OPIProxy => new ExifShort(ExifTag.OPIProxy), + ExifTagValue.JPEGProc => new ExifShort(ExifTag.JPEGProc), + ExifTagValue.JPEGRestartInterval => new ExifShort(ExifTag.JPEGRestartInterval), + ExifTagValue.YCbCrPositioning => new ExifShort(ExifTag.YCbCrPositioning), + ExifTagValue.Rating => new ExifShort(ExifTag.Rating), + ExifTagValue.RatingPercent => new ExifShort(ExifTag.RatingPercent), + ExifTagValue.ExposureProgram => new ExifShort(ExifTag.ExposureProgram), + ExifTagValue.Interlace => new ExifShort(ExifTag.Interlace), + ExifTagValue.SelfTimerMode => new ExifShort(ExifTag.SelfTimerMode), + ExifTagValue.SensitivityType => new ExifShort(ExifTag.SensitivityType), + ExifTagValue.MeteringMode => new ExifShort(ExifTag.MeteringMode), + ExifTagValue.LightSource => new ExifShort(ExifTag.LightSource), + ExifTagValue.FocalPlaneResolutionUnit2 => new ExifShort(ExifTag.FocalPlaneResolutionUnit2), + ExifTagValue.SensingMethod2 => new ExifShort(ExifTag.SensingMethod2), + ExifTagValue.Flash => new ExifShort(ExifTag.Flash), + ExifTagValue.ColorSpace => new ExifShort(ExifTag.ColorSpace), + ExifTagValue.FocalPlaneResolutionUnit => new ExifShort(ExifTag.FocalPlaneResolutionUnit), + ExifTagValue.SensingMethod => new ExifShort(ExifTag.SensingMethod), + ExifTagValue.CustomRendered => new ExifShort(ExifTag.CustomRendered), + ExifTagValue.ExposureMode => new ExifShort(ExifTag.ExposureMode), + ExifTagValue.WhiteBalance => new ExifShort(ExifTag.WhiteBalance), + ExifTagValue.FocalLengthIn35mmFilm => new ExifShort(ExifTag.FocalLengthIn35mmFilm), + ExifTagValue.SceneCaptureType => new ExifShort(ExifTag.SceneCaptureType), + ExifTagValue.GainControl => new ExifShort(ExifTag.GainControl), + ExifTagValue.Contrast => new ExifShort(ExifTag.Contrast), + ExifTagValue.Saturation => new ExifShort(ExifTag.Saturation), + ExifTagValue.Sharpness => new ExifShort(ExifTag.Sharpness), + ExifTagValue.SubjectDistanceRange => new ExifShort(ExifTag.SubjectDistanceRange), + ExifTagValue.GPSDifferential => new ExifShort(ExifTag.GPSDifferential), + ExifTagValue.BitsPerSample => new ExifShortArray(ExifTag.BitsPerSample), + ExifTagValue.MinSampleValue => new ExifShortArray(ExifTag.MinSampleValue), + ExifTagValue.MaxSampleValue => new ExifShortArray(ExifTag.MaxSampleValue), + ExifTagValue.GrayResponseCurve => new ExifShortArray(ExifTag.GrayResponseCurve), + ExifTagValue.ColorMap => new ExifShortArray(ExifTag.ColorMap), + ExifTagValue.ExtraSamples => new ExifShortArray(ExifTag.ExtraSamples), + ExifTagValue.PageNumber => new ExifShortArray(ExifTag.PageNumber), + ExifTagValue.TransferFunction => new ExifShortArray(ExifTag.TransferFunction), + ExifTagValue.HalftoneHints => new ExifShortArray(ExifTag.HalftoneHints), + ExifTagValue.SampleFormat => new ExifShortArray(ExifTag.SampleFormat), + ExifTagValue.TransferRange => new ExifShortArray(ExifTag.TransferRange), + ExifTagValue.DefaultImageColor => new ExifShortArray(ExifTag.DefaultImageColor), + ExifTagValue.JPEGLosslessPredictors => new ExifShortArray(ExifTag.JPEGLosslessPredictors), + ExifTagValue.JPEGPointTransforms => new ExifShortArray(ExifTag.JPEGPointTransforms), + ExifTagValue.YCbCrSubsampling => new ExifShortArray(ExifTag.YCbCrSubsampling), + ExifTagValue.CFARepeatPatternDim => new ExifShortArray(ExifTag.CFARepeatPatternDim), + ExifTagValue.IntergraphPacketData => new ExifShortArray(ExifTag.IntergraphPacketData), + ExifTagValue.ISOSpeedRatings => new ExifShortArray(ExifTag.ISOSpeedRatings), + ExifTagValue.SubjectArea => new ExifShortArray(ExifTag.SubjectArea), + ExifTagValue.SubjectLocation => new ExifShortArray(ExifTag.SubjectLocation), + ExifTagValue.ShutterSpeedValue => new ExifSignedRational(ExifTag.ShutterSpeedValue), + ExifTagValue.BrightnessValue => new ExifSignedRational(ExifTag.BrightnessValue), + ExifTagValue.ExposureBiasValue => new ExifSignedRational(ExifTag.ExposureBiasValue), + ExifTagValue.AmbientTemperature => new ExifSignedRational(ExifTag.AmbientTemperature), + ExifTagValue.WaterDepth => new ExifSignedRational(ExifTag.WaterDepth), + ExifTagValue.CameraElevationAngle => new ExifSignedRational(ExifTag.CameraElevationAngle), + ExifTagValue.Decode => new ExifSignedRationalArray(ExifTag.Decode), + ExifTagValue.TimeZoneOffset => new ExifSignedShortArray(ExifTag.TimeZoneOffset), + ExifTagValue.ImageDescription => new ExifString(ExifTag.ImageDescription), + ExifTagValue.Make => new ExifString(ExifTag.Make), + ExifTagValue.Model => new ExifString(ExifTag.Model), + ExifTagValue.Software => new ExifString(ExifTag.Software), + ExifTagValue.DateTime => new ExifString(ExifTag.DateTime), + ExifTagValue.Artist => new ExifString(ExifTag.Artist), + ExifTagValue.HostComputer => new ExifString(ExifTag.HostComputer), + ExifTagValue.Copyright => new ExifString(ExifTag.Copyright), + ExifTagValue.DocumentName => new ExifString(ExifTag.DocumentName), + ExifTagValue.PageName => new ExifString(ExifTag.PageName), + ExifTagValue.InkNames => new ExifString(ExifTag.InkNames), + ExifTagValue.TargetPrinter => new ExifString(ExifTag.TargetPrinter), + ExifTagValue.ImageID => new ExifString(ExifTag.ImageID), + ExifTagValue.MDLabName => new ExifString(ExifTag.MDLabName), + ExifTagValue.MDSampleInfo => new ExifString(ExifTag.MDSampleInfo), + ExifTagValue.MDPrepDate => new ExifString(ExifTag.MDPrepDate), + ExifTagValue.MDPrepTime => new ExifString(ExifTag.MDPrepTime), + ExifTagValue.MDFileUnits => new ExifString(ExifTag.MDFileUnits), + ExifTagValue.SEMInfo => new ExifString(ExifTag.SEMInfo), + ExifTagValue.SpectralSensitivity => new ExifString(ExifTag.SpectralSensitivity), + ExifTagValue.DateTimeOriginal => new ExifString(ExifTag.DateTimeOriginal), + ExifTagValue.DateTimeDigitized => new ExifString(ExifTag.DateTimeDigitized), + ExifTagValue.SubsecTime => new ExifString(ExifTag.SubsecTime), + ExifTagValue.SubsecTimeOriginal => new ExifString(ExifTag.SubsecTimeOriginal), + ExifTagValue.SubsecTimeDigitized => new ExifString(ExifTag.SubsecTimeDigitized), + ExifTagValue.RelatedSoundFile => new ExifString(ExifTag.RelatedSoundFile), + ExifTagValue.FaxSubaddress => new ExifString(ExifTag.FaxSubaddress), + ExifTagValue.OffsetTime => new ExifString(ExifTag.OffsetTime), + ExifTagValue.OffsetTimeOriginal => new ExifString(ExifTag.OffsetTimeOriginal), + ExifTagValue.OffsetTimeDigitized => new ExifString(ExifTag.OffsetTimeDigitized), + ExifTagValue.SecurityClassification => new ExifString(ExifTag.SecurityClassification), + ExifTagValue.ImageHistory => new ExifString(ExifTag.ImageHistory), + ExifTagValue.ImageUniqueID => new ExifString(ExifTag.ImageUniqueID), + ExifTagValue.OwnerName => new ExifString(ExifTag.OwnerName), + ExifTagValue.SerialNumber => new ExifString(ExifTag.SerialNumber), + ExifTagValue.LensMake => new ExifString(ExifTag.LensMake), + ExifTagValue.LensModel => new ExifString(ExifTag.LensModel), + ExifTagValue.LensSerialNumber => new ExifString(ExifTag.LensSerialNumber), + ExifTagValue.GDALMetadata => new ExifString(ExifTag.GDALMetadata), + ExifTagValue.GDALNoData => new ExifString(ExifTag.GDALNoData), + ExifTagValue.GPSLatitudeRef => new ExifString(ExifTag.GPSLatitudeRef), + ExifTagValue.GPSLongitudeRef => new ExifString(ExifTag.GPSLongitudeRef), + ExifTagValue.GPSSatellites => new ExifString(ExifTag.GPSSatellites), + ExifTagValue.GPSStatus => new ExifString(ExifTag.GPSStatus), + ExifTagValue.GPSMeasureMode => new ExifString(ExifTag.GPSMeasureMode), + ExifTagValue.GPSSpeedRef => new ExifString(ExifTag.GPSSpeedRef), + ExifTagValue.GPSTrackRef => new ExifString(ExifTag.GPSTrackRef), + ExifTagValue.GPSImgDirectionRef => new ExifString(ExifTag.GPSImgDirectionRef), + ExifTagValue.GPSMapDatum => new ExifString(ExifTag.GPSMapDatum), + ExifTagValue.GPSDestLatitudeRef => new ExifString(ExifTag.GPSDestLatitudeRef), + ExifTagValue.GPSDestLongitudeRef => new ExifString(ExifTag.GPSDestLongitudeRef), + ExifTagValue.GPSDestBearingRef => new ExifString(ExifTag.GPSDestBearingRef), + ExifTagValue.GPSDestDistanceRef => new ExifString(ExifTag.GPSDestDistanceRef), + ExifTagValue.GPSDateStamp => new ExifString(ExifTag.GPSDateStamp), + ExifTagValue.FileSource => new ExifByte(ExifTag.FileSource, ExifDataType.Undefined), + ExifTagValue.SceneType => new ExifByte(ExifTag.SceneType, ExifDataType.Undefined), + ExifTagValue.JPEGTables => new ExifByteArray(ExifTag.JPEGTables, ExifDataType.Undefined), + ExifTagValue.OECF => new ExifByteArray(ExifTag.OECF, ExifDataType.Undefined), + ExifTagValue.ExifVersion => new ExifByteArray(ExifTag.ExifVersion, ExifDataType.Undefined), + ExifTagValue.ComponentsConfiguration => new ExifByteArray(ExifTag.ComponentsConfiguration, ExifDataType.Undefined), + ExifTagValue.MakerNote => new ExifByteArray(ExifTag.MakerNote, ExifDataType.Undefined), + ExifTagValue.FlashpixVersion => new ExifByteArray(ExifTag.FlashpixVersion, ExifDataType.Undefined), + ExifTagValue.SpatialFrequencyResponse => new ExifByteArray(ExifTag.SpatialFrequencyResponse, ExifDataType.Undefined), + ExifTagValue.SpatialFrequencyResponse2 => new ExifByteArray(ExifTag.SpatialFrequencyResponse2, ExifDataType.Undefined), + ExifTagValue.Noise => new ExifByteArray(ExifTag.Noise, ExifDataType.Undefined), + ExifTagValue.CFAPattern => new ExifByteArray(ExifTag.CFAPattern, ExifDataType.Undefined), + ExifTagValue.DeviceSettingDescription => new ExifByteArray(ExifTag.DeviceSettingDescription, ExifDataType.Undefined), + ExifTagValue.ImageSourceData => new ExifByteArray(ExifTag.ImageSourceData, ExifDataType.Undefined), + ExifTagValue.XPTitle => new ExifUcs2String(ExifTag.XPTitle), + ExifTagValue.XPComment => new ExifUcs2String(ExifTag.XPComment), + ExifTagValue.XPAuthor => new ExifUcs2String(ExifTag.XPAuthor), + ExifTagValue.XPKeywords => new ExifUcs2String(ExifTag.XPKeywords), + ExifTagValue.XPSubject => new ExifUcs2String(ExifTag.XPSubject), + ExifTagValue.UserComment => new ExifEncodedString(ExifTag.UserComment), + ExifTagValue.GPSProcessingMethod => new ExifEncodedString(ExifTag.GPSProcessingMethod), + ExifTagValue.GPSAreaInformation => new ExifEncodedString(ExifTag.GPSAreaInformation), + _ => null, + }; } diff --git a/src/ImageSharp/Metadata/Profiles/Exif/Values/IExifValue.cs b/src/ImageSharp/Metadata/Profiles/Exif/Values/IExifValue.cs index c5b1574f3..3bb555192 100644 --- a/src/ImageSharp/Metadata/Profiles/Exif/Values/IExifValue.cs +++ b/src/ImageSharp/Metadata/Profiles/Exif/Values/IExifValue.cs @@ -4,35 +4,35 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif; /// -/// A value of the exif profile. +/// A value of the Exif profile. /// public interface IExifValue : IDeepCloneable { /// - /// Gets the data type of the exif value. + /// Gets the data type of the Exif value. /// - ExifDataType DataType { get; } + public ExifDataType DataType { get; } /// /// Gets a value indicating whether the value is an array. /// - bool IsArray { get; } + public bool IsArray { get; } /// - /// Gets the tag of the exif value. + /// Gets the tag of the Exif value. /// - ExifTag Tag { get; } + public ExifTag Tag { get; } /// - /// Gets the value of this exif value. + /// Gets the value of this Exif value. /// - /// The value of this exif value. - object? GetValue(); + /// The value of this Exif value. + public object? GetValue(); /// - /// Sets the value of this exif value. + /// Sets the value of this Exif value. /// - /// The value of this exif value. + /// The value of this Exif value. /// A value indicating whether the value could be set. - bool TrySetValue(object? value); + public bool TrySetValue(object? value); } diff --git a/tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs b/tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs index 660ab2e66..1ffbd9f55 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs @@ -5,6 +5,7 @@ using System.Runtime.Intrinsics.X86; using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.Formats.Webp; using SixLabors.ImageSharp.Metadata; +using SixLabors.ImageSharp.Metadata.Profiles.Exif; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Tests.TestUtilities; using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; @@ -559,4 +560,22 @@ public class WebpDecoderTests image.DebugSave(provider); image.CompareToOriginal(provider, ReferenceDecoder); } + + [Theory] + [WithFile(Lossy.Issue2906, PixelTypes.Rgba32)] + public void WebpDecoder_CanDecode_Issue2906(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using Image image = provider.GetImage(WebpDecoder.Instance); + + ExifProfile exifProfile = image.Metadata.ExifProfile; + IExifValue comment = exifProfile.GetValue(ExifTag.UserComment); + + Assert.NotNull(comment); + Assert.Equal(EncodedString.CharacterCode.Unicode, comment.Value.Code); + Assert.StartsWith("1girl, pariya, ", comment.Value.Text); + + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); + } } diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index 9b73e60cf..406283b97 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -875,6 +875,7 @@ public static class TestImages public const string Issue2801 = "Webp/issues/Issue2801.webp"; public const string Issue2866 = "Webp/issues/Issue2866.webp"; public const string Issue2925 = "Webp/issues/Issue2925.webp"; + public const string Issue2906 = "Webp/issues/Issue2906.webp"; } public const string AlphaBlend = "Webp/alpha-blend.webp"; diff --git a/tests/Images/Input/Webp/issues/Issue2906.webp b/tests/Images/Input/Webp/issues/Issue2906.webp new file mode 100644 index 000000000..0911da047 --- /dev/null +++ b/tests/Images/Input/Webp/issues/Issue2906.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:56fe6a91feb9545c0a15966e0f6bc560890b193073c96ae9e39bf387c7e0cbca +size 157092