Browse Source

Improve behavior and add comments

pull/3047/head
James Jackson-South 2 weeks ago
parent
commit
81d533b320
  1. 32
      src/ImageSharp/Metadata/Profiles/XMP/XmpProfile.cs
  2. 2
      tests/ImageSharp.Tests/Metadata/Profiles/XMP/XmpProfileTests.cs

32
src/ImageSharp/Metadata/Profiles/XMP/XmpProfile.cs

@ -46,7 +46,7 @@ public sealed class XmpProfile : IDeepCloneable<XmpProfile>
/// <summary>
/// Convert the content of this <see cref="XmpProfile"/> into an <see cref="XDocument"/>.
/// </summary>
/// <returns>The <see cref="XDocument"/></returns>
/// <returns>The <see cref="XDocument"/> instance, or <see langword="null"/> if no XMP data is present.</returns>
public XDocument? ToXDocument()
{
byte[]? data = this.Data;
@ -74,8 +74,14 @@ public sealed class XmpProfile : IDeepCloneable<XmpProfile>
/// <returns>The <see cref="T:Byte[]"/></returns>
public byte[] ToByteArray()
{
Guard.NotNull(this.Data);
byte[] result = new byte[this.Data.Length];
byte[]? data = this.Data;
if (data is null)
{
return [];
}
byte[] result = new byte[data.Length];
this.Data.AsSpan().CopyTo(result);
return result;
}
@ -83,10 +89,15 @@ public sealed class XmpProfile : IDeepCloneable<XmpProfile>
/// <inheritdoc/>
public XmpProfile DeepClone()
{
Guard.NotNull(this.Data);
byte[]? data = this.Data;
if (data is null)
{
// Preserve the semantics of an "empty" profile when cloning.
return new XmpProfile();
}
byte[] clone = new byte[this.Data.Length];
this.Data.AsSpan().CopyTo(clone);
byte[] clone = new byte[data.Length];
data.AsSpan().CopyTo(clone);
return new XmpProfile(clone);
}
@ -118,7 +129,14 @@ public sealed class XmpProfile : IDeepCloneable<XmpProfile>
}
// Allocation-free fast path for the normal case.
// Check for UTF-8 BOM (0xEF,0xBB,0xBF)
bool hasBom = data.Length >= 3 && data[0] == 0xEF && data[1] == 0xBB && data[2] == 0xBF;
// XMP metadata is commonly stored in fixed-size container blocks (e.g. TIFF tag 700).
// Producers often pad unused space so the packet can be updated in-place without
// rewriting the file. In practice this padding is either NUL (0x00) from the container
// or 0x0F used by Adobe XMP writers. Both are invalid XML and must be trimmed.
bool hasTrailingPad = data[^1] is 0 or 0x0F;
if (!hasBom && !hasTrailingPad)
@ -146,7 +164,7 @@ public sealed class XmpProfile : IDeepCloneable<XmpProfile>
int length = end - start;
if (length <= 0)
{
return [];
return null;
}
byte[] normalized = new byte[length];

2
tests/ImageSharp.Tests/Metadata/Profiles/XMP/XmpProfileTests.cs

@ -79,7 +79,7 @@ public class XmpProfileTests
}
[Fact]
public void XmlProfile_CtorFromXDocument_Works()
public void XmpProfile_CtorFromXDocument_Works()
{
// arrange
XDocument document = CreateMinimalXDocument();

Loading…
Cancel
Save