Browse Source

Bug fixes of reading and writing (UCS2 and EncodedString)

pull/1935/head
Ildar Khayrutdinov 4 years ago
parent
commit
cda6b24b63
  1. 1
      src/ImageSharp/ImageSharp.csproj
  2. 36
      src/ImageSharp/Metadata/Profiles/Exif/ExifEncodedStringHelpers.cs
  3. 27
      src/ImageSharp/Metadata/Profiles/Exif/ExifReader.cs
  4. 19
      src/ImageSharp/Metadata/Profiles/Exif/ExifUcs2StringHelpers.cs
  5. 41
      src/ImageSharp/Metadata/Profiles/Exif/ExifWriter.cs
  6. 25
      src/ImageSharp/Metadata/Profiles/Exif/Tags/ExifTag.String.cs
  7. 34
      src/ImageSharp/Metadata/Profiles/Exif/Tags/ExifTag.Ucs2String.cs
  8. 12
      src/ImageSharp/Metadata/Profiles/Exif/Values/EncodedString.cs
  9. 8
      src/ImageSharp/Metadata/Profiles/Exif/Values/ExifEncodedString.cs
  10. 47
      src/ImageSharp/Metadata/Profiles/Exif/Values/ExifUcs2String.cs
  11. 11
      src/ImageSharp/Metadata/Profiles/Exif/Values/ExifValues.cs
  12. 40
      tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Metadata.cs
  13. 2
      tests/ImageSharp.Tests/Metadata/Profiles/Exif/ExifProfileTests.cs
  14. 45
      tests/ImageSharp.Tests/Metadata/Profiles/Exif/Values/ExifValuesTests.cs

1
src/ImageSharp/ImageSharp.csproj

@ -49,6 +49,7 @@
<ItemGroup>
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="5.0.0" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="5.0.0" />
</ItemGroup>
<ItemGroup Condition=" $(TargetFramework.StartsWith('netstandard')) OR '$(TargetFramework)' == 'net472'">

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

@ -12,9 +12,9 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
{
public const int CharacterCodeBytesLength = 8;
private const ulong AsciiCode = 0x_41_53_43_49_49_00_00_00;
private const ulong JISCode = 0x_4A_49_53_00_00_00_00_00;
private const ulong UnicodeCode = 0x_55_4E_49_43_4F_44_45_00;
private const ulong AsciiCode = 0x_00_00_00_49_49_43_53_41;
private const ulong JISCode = 0x_00_00_00_00_00_53_49_4A;
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<byte> AsciiCodeBytes => new byte[] { 0x41, 0x53, 0x43, 0x49, 0x49, 0, 0, 0 };
@ -25,7 +25,13 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
private static ReadOnlySpan<byte> UndefinedCodeBytes => new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 };
private static Encoding JIS0208Encoding => Encoding.GetEncoding(932);
private static Encoding JIS0208Encoding => CodePagesEncodingProvider.Instance.GetEncoding(932);
public static bool IsEncodedString(ExifTagValue tag) => tag switch
{
ExifTagValue.UserComment or ExifTagValue.GPSProcessingMethod or ExifTagValue.GPSAreaInformation => true,
_ => false
};
public static ReadOnlySpan<byte> GetCodeBytes(CharacterCode code) => code switch
{
@ -45,7 +51,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
_ => Encoding.UTF8
};
public static bool TryCreate(ReadOnlySpan<byte> buffer, out EncodedString encodedString)
public static bool TryParse(ReadOnlySpan<byte> buffer, out EncodedString encodedString)
{
if (TryDetect(buffer, out CharacterCode code))
{
@ -61,17 +67,17 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
public static uint GetDataLength(EncodedString encodedString) =>
(uint)GetEncoding(encodedString.Code).GetByteCount(encodedString.Text) + CharacterCodeBytesLength;
public static bool IsEncodedString(ExifTagValue tag)
public static byte[] GetData(EncodedString encodedString)
{
switch (tag)
{
case ExifTagValue.UserComment:
case ExifTagValue.GPSProcessingMethod:
case ExifTagValue.GPSAreaInformation:
return true;
default:
return false;
}
int length = (int)GetDataLength(encodedString);
byte[] buffer = new byte[length];
GetCodeBytes(encodedString.Code).CopyTo(buffer);
string text = encodedString.Text;
GetEncoding(encodedString.Code).GetBytes(text, 0, text.Length, buffer, CharacterCodeBytesLength);
return buffer;
}
private static bool TryDetect(ReadOnlySpan<byte> buffer, out CharacterCode code)

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

@ -220,10 +220,6 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
if (this.TryReadSpan(buffer))
{
object value = this.ConvertValue(tag.Exif, tag.DataType, buffer, tag.NumberOfComponents > 1 || tag.Exif.IsArray);
if (value is EncodedString)
{
// Console.WriteLine("EncodedString tag: " + (ushort)tag.Exif.Tag);
}
this.Add(values, tag.Exif, value);
}
@ -248,7 +244,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
private byte ConvertToByte(ReadOnlySpan<byte> buffer) => buffer[0];
private string ConvertToString(ReadOnlySpan<byte> buffer)
private string ConvertToString(Encoding encoding, ReadOnlySpan<byte> buffer)
{
int nullCharIndex = buffer.IndexOf((byte)0);
@ -257,7 +253,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
buffer = buffer.Slice(0, nullCharIndex);
}
return ExifConstants.DefaultEncoding.GetString(buffer);
return encoding.GetString(buffer);
}
private object ConvertValue(ExifValue exifValue, ExifDataType dataType, ReadOnlySpan<byte> buffer, bool isArray)
@ -267,35 +263,20 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
return null;
}
var tagValue = (ExifTagValue)(ushort)exifValue.Tag;
if (ExifUcs2StringHelpers.IsUcs2Tag(tagValue))
{
return ExifUcs2StringHelpers.ConvertToString(buffer);
}
else if (ExifEncodedStringHelpers.IsEncodedString(tagValue))
{
if (ExifEncodedStringHelpers.TryCreate(buffer, out EncodedString encodedString))
{
return encodedString;
}
}
switch (dataType)
{
case ExifDataType.Unknown:
return null;
case ExifDataType.Ascii:
return this.ConvertToString(buffer);
return this.ConvertToString(ExifConstants.DefaultEncoding, buffer);
case ExifDataType.Byte:
case ExifDataType.Undefined:
{
if (!isArray)
{
return this.ConvertToByte(buffer);
}
return ExifEncodedStringHelpers.TryCreate(buffer, out EncodedString encodedString) ? encodedString : buffer.ToArray();
}
return buffer.ToArray();
case ExifDataType.DoubleFloat:
if (!isArray)

19
src/ImageSharp/Metadata/Profiles/Exif/ExifUcs2StringHelpers.cs

@ -10,21 +10,10 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
{
public static Encoding Ucs2Encoding => Encoding.GetEncoding("UCS-2");
public static bool IsUcs2Tag(ExifTagValue tag)
public static bool IsUcs2Tag(ExifTagValue tag) => tag switch
{
switch (tag)
{
case ExifTagValue.XPAuthor:
case ExifTagValue.XPComment:
case ExifTagValue.XPKeywords:
case ExifTagValue.XPSubject:
case ExifTagValue.XPTitle:
return true;
default:
return false;
}
}
public static string ConvertToString(ReadOnlySpan<byte> buffer) => Ucs2Encoding.GetString(buffer);
ExifTagValue.XPAuthor or ExifTagValue.XPComment or ExifTagValue.XPKeywords or ExifTagValue.XPSubject or ExifTagValue.XPTitle => true,
_ => false,
};
}
}

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

@ -274,9 +274,9 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
{
object value = exifValue.GetValue();
if (exifValue.DataType == ExifDataType.Ascii)
if (ExifUcs2StringHelpers.IsUcs2Tag((ExifTagValue)(ushort)exifValue.Tag))
{
return (uint)(ExifUcs2StringHelpers.IsUcs2Tag((ExifTagValue)(ushort)exifValue.Tag) ? ExifUcs2StringHelpers.Ucs2Encoding : ExifConstants.DefaultEncoding).GetByteCount((string)value) + 1;
return (uint)ExifUcs2StringHelpers.Ucs2Encoding.GetByteCount((string)value);
}
if (value is EncodedString encodedString)
@ -284,6 +284,11 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
return ExifEncodedStringHelpers.GetDataLength(encodedString);
}
if (exifValue.DataType == ExifDataType.Ascii)
{
return (uint)ExifConstants.DefaultEncoding.GetByteCount((string)value) + 1;
}
if (value is Array arrayValue)
{
return (uint)arrayValue.Length;
@ -378,21 +383,14 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
switch (dataType)
{
case ExifDataType.Ascii:
offset = Write((ExifUcs2StringHelpers.IsUcs2Tag((ExifTagValue)(ushort)exifValue.Tag) ? ExifUcs2StringHelpers.Ucs2Encoding : ExifConstants.DefaultEncoding).GetBytes((string)value), destination, offset);
offset = Write(ExifConstants.DefaultEncoding.GetBytes((string)value), destination, offset);
destination[offset] = 0;
return offset + 1;
case ExifDataType.Byte:
case ExifDataType.Undefined:
if (value is EncodedString encodedString)
if (value is byte[] array)
{
ReadOnlySpan<byte> codeBytes = ExifEncodedStringHelpers.GetCodeBytes(encodedString.Code);
codeBytes.CopyTo(destination.Slice(offset));
offset += codeBytes.Length;
ReadOnlySpan<byte> dataBytes = ExifEncodedStringHelpers.GetEncoding(encodedString.Code).GetBytes(encodedString.Text);
dataBytes.CopyTo(destination.Slice(offset));
offset += dataBytes.Length;
offset = Write(array, destination, offset);
return offset;
}
else
@ -441,14 +439,25 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
}
}
internal static int WriteValue(IExifValue value, Span<byte> destination, int offset)
internal static int WriteValue(IExifValue exifValue, Span<byte> destination, int offset)
{
if (value.IsArray)
object value = exifValue.GetValue();
if (ExifUcs2StringHelpers.IsUcs2Tag((ExifTagValue)(ushort)exifValue.Tag))
{
value = ExifUcs2StringHelpers.Ucs2Encoding.GetBytes((string)value);
}
else if (value is EncodedString encodedString)
{
value = ExifEncodedStringHelpers.GetData(encodedString);
}
if (exifValue.IsArray)
{
return WriteArray(value, destination, offset);
return WriteArray(exifValue, destination, offset);
}
return WriteValue(value, value.DataType, value.GetValue(), destination, offset);
return WriteValue(exifValue, exifValue.DataType, value, destination, offset);
}
}
}

25
src/ImageSharp/Metadata/Profiles/Exif/Tags/ExifTag.String.cs

@ -275,30 +275,5 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
/// Gets the GPSDateStamp exif tag.
/// </summary>
public static ExifTag<string> GPSDateStamp { get; } = new ExifTag<string>(ExifTagValue.GPSDateStamp);
/// <summary>
/// Gets the title tag used by Windows (encoded in UCS2).
/// </summary>
public static ExifTag<string> XPTitle => new ExifTag<string>(ExifTagValue.XPTitle);
/// <summary>
/// Gets the comment tag used by Windows (encoded in UCS2).
/// </summary>
public static ExifTag<string> XPComment => new ExifTag<string>(ExifTagValue.XPComment);
/// <summary>
/// Gets the author tag used by Windows (encoded in UCS2).
/// </summary>
public static ExifTag<string> XPAuthor => new ExifTag<string>(ExifTagValue.XPAuthor);
/// <summary>
/// Gets the keywords tag used by Windows (encoded in UCS2).
/// </summary>
public static ExifTag<string> XPKeywords => new ExifTag<string>(ExifTagValue.XPKeywords);
/// <summary>
/// Gets the subject tag used by Windows (encoded in UCS2).
/// </summary>
public static ExifTag<string> XPSubject => new ExifTag<string>(ExifTagValue.XPSubject);
}
}

34
src/ImageSharp/Metadata/Profiles/Exif/Tags/ExifTag.Ucs2String.cs

@ -0,0 +1,34 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
{
/// <content/>
public abstract partial class ExifTag
{
/// <summary>
/// Gets the title tag used by Windows (encoded in UCS2).
/// </summary>
public static ExifTag<string> XPTitle => new ExifTag<string>(ExifTagValue.XPTitle);
/// <summary>
/// Gets the comment tag used by Windows (encoded in UCS2).
/// </summary>
public static ExifTag<string> XPComment => new ExifTag<string>(ExifTagValue.XPComment);
/// <summary>
/// Gets the author tag used by Windows (encoded in UCS2).
/// </summary>
public static ExifTag<string> XPAuthor => new ExifTag<string>(ExifTagValue.XPAuthor);
/// <summary>
/// Gets the keywords tag used by Windows (encoded in UCS2).
/// </summary>
public static ExifTag<string> XPKeywords => new ExifTag<string>(ExifTagValue.XPKeywords);
/// <summary>
/// Gets the subject tag used by Windows (encoded in UCS2).
/// </summary>
public static ExifTag<string> XPSubject => new ExifTag<string>(ExifTagValue.XPSubject);
}
}

12
src/ImageSharp/Metadata/Profiles/Exif/Values/EncodedString.cs

@ -66,6 +66,18 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
/// </summary>
public string Text { get; }
/// <summary>
/// Converts the specified <see cref="string"/> to an instance of this type.
/// </summary>
/// <param name="text">The text value.</param>
public static implicit operator EncodedString(string text) => new(text);
/// <summary>
/// Converts the specified <see cref="EncodedString"/> to a <see cref="string"/>.
/// </summary>
/// <param name="encodedString">The <see cref="EncodedString"/> to convert.</param>
public static explicit operator string(EncodedString encodedString) => encodedString.Text;
/// <inheritdoc/>
public override bool Equals(object obj) => obj is EncodedString other && this.Equals(other);

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

@ -38,6 +38,14 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
this.Value = new EncodedString(stringValue);
return true;
}
else if (value is byte[] buffer)
{
if (ExifEncodedStringHelpers.TryParse(buffer, out EncodedString encodedString))
{
this.Value = encodedString;
return true;
}
}
return false;
}

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

@ -0,0 +1,47 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
{
internal sealed class ExifUcs2String : ExifValue<string>
{
public ExifUcs2String(ExifTag<string> tag)
: base(tag)
{
}
public ExifUcs2String(ExifTagValue tag)
: base(tag)
{
}
private ExifUcs2String(ExifUcs2String value)
: base(value)
{
}
public override ExifDataType DataType => ExifDataType.Byte;
protected override string StringValue => this.Value;
public override object GetValue() => this.Value;
public override bool TrySetValue(object value)
{
if (base.TrySetValue(value))
{
return true;
}
if (value is byte[] buffer)
{
this.Value = ExifUcs2StringHelpers.Ucs2Encoding.GetString(buffer);
return true;
}
return false;
}
public override IExifValue DeepClone() => new ExifUcs2String(this);
}
}

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

@ -280,11 +280,6 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
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.XPTitle: return new ExifString(ExifTag.XPTitle);
case ExifTagValue.XPComment: return new ExifString(ExifTag.XPComment);
case ExifTagValue.XPAuthor: return new ExifString(ExifTag.XPAuthor);
case ExifTagValue.XPKeywords: return new ExifString(ExifTag.XPKeywords);
case ExifTagValue.XPSubject: return new ExifString(ExifTag.XPSubject);
case ExifTagValue.FileSource: return new ExifByte(ExifTag.FileSource, ExifDataType.Undefined);
case ExifTagValue.SceneType: return new ExifByte(ExifTag.SceneType, ExifDataType.Undefined);
@ -302,6 +297,12 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
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);

40
tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Metadata.cs

@ -303,32 +303,56 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
}
[Fact]
public void ExifIfdStructure()
public void EncodedStringTags()
{
byte[] exifBytes;
using var memoryStream = new MemoryStream();
using (var image = Image.Load(TestFile.GetInputFileFullPath(TestImages.Jpeg.Baseline.Calliphora)))
{
var exif = new ExifProfile();
exif.SetValue(ExifTag.XPAuthor, "Dan Petitt");
exif.SetValue(ExifTag.XPTitle, "A bit of test metadata for image title");
exif.SetValue(ExifTag.UserComment, new EncodedString(EncodedString.CharacterCode.ASCII, "A bit of normal comment text"));
exif.SetValue(ExifTag.GPSDateStamp, "2022-01-06");
exif.SetValue(ExifTag.XPKeywords, "Keywords");
image.Metadata.ExifProfile = exif;
exif.SetValue(ExifTag.XPTitle, "A bit of test metadata for image title");
exif.SetValue(ExifTag.XPComment, "A bit of test metadata for image comment");
exif.SetValue(ExifTag.XPAuthor, "Dan Petitt");
exif.SetValue(ExifTag.XPKeywords, "Keyword1;Keyword2");
exif.SetValue(ExifTag.XPSubject, "This is a subject");
exif.SetValue(ExifTag.UserComment, new EncodedString(EncodedString.CharacterCode.ASCII, "user comment (ASCII)"));
exif.SetValue(ExifTag.GPSProcessingMethod, new EncodedString(EncodedString.CharacterCode.JIS, "GPS processing method (JIS)"));
exif.SetValue(ExifTag.GPSAreaInformation, new EncodedString(EncodedString.CharacterCode.Unicode, "GPS area info (Unicode)"));
exifBytes = exif.ToByteArray();
image.Metadata.ExifProfile = exif;
image.Save(@"c:\\temp\1.jpeg");
image.Save(memoryStream, new JpegEncoder());
}
memoryStream.Seek(0, SeekOrigin.Begin);
using (var image = Image.Load(memoryStream))
{
Assert.NotNull(image.Metadata.ExifProfile);
ExifProfile exif = image.Metadata.ExifProfile;
Assert.NotNull(exif);
Assert.Equal("2022-01-06", exif.GetValue(ExifTag.GPSDateStamp).Value);
Assert.Equal("A bit of test metadata for image title", exif.GetValue(ExifTag.XPTitle).Value);
Assert.Equal("A bit of test metadata for image comment", exif.GetValue(ExifTag.XPComment).Value);
Assert.Equal("Dan Petitt", exif.GetValue(ExifTag.XPAuthor).Value);
Assert.Equal("Keyword1;Keyword2", exif.GetValue(ExifTag.XPKeywords).Value);
Assert.Equal("This is a subject", exif.GetValue(ExifTag.XPSubject).Value);
Assert.Equal("user comment (ASCII)", exif.GetValue(ExifTag.UserComment).Value.Text);
Assert.Equal(EncodedString.CharacterCode.ASCII, exif.GetValue(ExifTag.UserComment).Value.Code);
Assert.Equal("GPS processing method (JIS)", exif.GetValue(ExifTag.GPSProcessingMethod).Value.Text);
Assert.Equal(EncodedString.CharacterCode.JIS, exif.GetValue(ExifTag.GPSProcessingMethod).Value.Code);
Assert.Equal("GPS area info (Unicode)", exif.GetValue(ExifTag.GPSAreaInformation).Value.Text);
Assert.Equal(EncodedString.CharacterCode.Unicode, exif.GetValue(ExifTag.GPSAreaInformation).Value.Code);
}
}
}

2
tests/ImageSharp.Tests/Metadata/Profiles/Exif/ExifProfileTests.cs

@ -591,7 +591,7 @@ namespace SixLabors.ImageSharp.Tests.Metadata.Profiles.Exif
foreach (IExifValue value in profile.Values)
{
Assert.NotNull(value.GetValue());
}
}
IExifValue<string> software = profile.GetValue(ExifTag.Software);
Assert.Equal("Windows Photo Editor 10.0.10011.16384", software.Value);

45
tests/ImageSharp.Tests/Metadata/Profiles/Exif/Values/ExifValuesTests.cs

@ -1,6 +1,8 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Text;
using SixLabors.ImageSharp.Metadata.Profiles.Exif;
using Xunit;
@ -291,11 +293,6 @@ namespace SixLabors.ImageSharp.Tests.Metadata.Profiles.Exif.Values
{ ExifTag.GPSDestBearingRef },
{ ExifTag.GPSDestDistanceRef },
{ ExifTag.GPSDateStamp },
{ ExifTag.XPTitle },
{ ExifTag.XPComment },
{ ExifTag.XPAuthor },
{ ExifTag.XPKeywords },
{ ExifTag.XPSubject },
};
public static TheoryData<ExifTag> UndefinedTags => new TheoryData<ExifTag>
@ -327,6 +324,15 @@ namespace SixLabors.ImageSharp.Tests.Metadata.Profiles.Exif.Values
{ ExifTag.GPSAreaInformation }
};
public static TheoryData<ExifTag> Ucs2StringTags => new TheoryData<ExifTag>
{
{ ExifTag.XPTitle },
{ ExifTag.XPComment },
{ ExifTag.XPAuthor },
{ ExifTag.XPKeywords },
{ ExifTag.XPSubject },
};
[Theory]
[MemberData(nameof(ByteTags))]
public void ExifByteTests(ExifTag tag)
@ -602,13 +608,38 @@ namespace SixLabors.ImageSharp.Tests.Metadata.Profiles.Exif.Values
[MemberData(nameof(EncodedStringTags))]
public void ExifEncodedStringTests(ExifTag tag)
{
var expected = new EncodedString(EncodedString.CharacterCode.JIS, "test string");
foreach (object code in Enum.GetValues(typeof(EncodedString.CharacterCode)))
{
var charCode = (EncodedString.CharacterCode)code;
const string expectedText = "test string";
var expected = new EncodedString(charCode, expectedText);
ExifValue value = ExifValues.Create(tag);
Assert.False(value.TrySetValue(123));
Assert.True(value.TrySetValue(expected));
var typed = (ExifEncodedString)value;
Assert.Equal(expected, typed.Value);
Assert.Equal(expectedText, (string)typed.Value);
Assert.Equal(charCode, typed.Value.Code);
}
}
[Theory]
[MemberData(nameof(Ucs2StringTags))]
public void ExifUcs2StringTests(ExifTag tag)
{
const string expected = "Dan Petitt";
ExifValue value = ExifValues.Create(tag);
Assert.False(value.TrySetValue(123));
Assert.True(value.TrySetValue(expected));
var typed = (ExifEncodedString)value;
var typed = (ExifUcs2String)value;
Assert.Equal(expected, typed.Value);
Assert.True(value.TrySetValue(Encoding.GetEncoding("UCS-2").GetBytes(expected)));
Assert.Equal(expected, typed.Value);
}
}

Loading…
Cancel
Save