Browse Source

Handle ulong values for EXIF Long writes

Fixes EXIF serialization when `ExifLong8Array` downgrades to `ExifDataType.Long` but still stores values as `ulong`. `ExifWriter.WriteValue` now handles `ulong` inputs in the `Long` branch by writing 32-bit values, and a BigTIFF metadata test verifies mixed in-range values are written correctly as two little-endian `uint`s.
pull/3159/head
James Jackson-South 3 weeks ago
parent
commit
e2b43407cc
  1. 7
      src/ImageSharp/Metadata/Profiles/Exif/ExifWriter.cs
  2. 15
      tests/ImageSharp.Tests/Formats/Tiff/BigTiffMetadataTests.cs

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

@ -403,6 +403,13 @@ internal sealed class ExifWriter
return WriteUInt32((uint)longNumber, destination, offset);
}
// ExifLong8Array retains ulong storage but reports Long when every value fits
// in 32 bits, allowing BigTIFF offsets to be serialized by classic EXIF writers.
if (value is ulong long8Value)
{
return WriteUInt32((uint)long8Value, destination, offset);
}
return WriteUInt32((uint)value, destination, offset);
case ExifDataType.Long8:
return WriteUInt64((ulong)value, destination, offset);

15
tests/ImageSharp.Tests/Formats/Tiff/BigTiffMetadataTests.cs

@ -88,6 +88,21 @@ public class BigTiffMetadataTests
Assert.Equal(ExifDataType.Long8, long8.DataType);
}
[Fact]
public void ExifLong8Array_CanWriteValuesAsLong()
{
ExifLong8Array long8 = new(ExifTagValue.StripOffsets);
Assert.True(long8.TrySetValue(new long[] { 1, uint.MaxValue }));
Assert.Equal(ExifDataType.Long, long8.DataType);
byte[] buffer = new byte[8];
int written = ExifWriter.WriteValue(long8, buffer, 0);
Assert.Equal(buffer.Length, written);
Assert.Equal(1U, BinaryPrimitives.ReadUInt32LittleEndian(buffer));
Assert.Equal(uint.MaxValue, BinaryPrimitives.ReadUInt32LittleEndian(buffer.AsSpan(4)));
}
[Fact]
public void ExifSignedLong8Array()
{

Loading…
Cancel
Save