Browse Source

Reduced intermediate allocations: Profiles

pull/2415/head
Günther Foidl 3 years ago
parent
commit
5d65ef0afd
  1. 33
      src/ImageSharp/Metadata/Profiles/Exif/ExifReader.cs
  2. 4
      src/ImageSharp/Metadata/Profiles/Exif/Values/ExifByteArray.cs
  3. 14
      src/ImageSharp/Metadata/Profiles/ICC/IccProfile.cs

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

@ -86,10 +86,6 @@ internal class ExifReader : BaseExifReader
/// </summary>
internal abstract class BaseExifReader
{
private readonly byte[] buf8 = new byte[8];
private readonly byte[] buf4 = new byte[4];
private readonly byte[] buf2 = new byte[2];
private readonly MemoryAllocator? allocator;
private readonly Stream data;
private List<ExifTag>? invalidTags;
@ -528,20 +524,33 @@ internal abstract class BaseExifReader
return read == length;
}
protected ulong ReadUInt64() =>
this.TryReadSpan(this.buf8)
? this.ConvertToUInt64(this.buf8)
protected ulong ReadUInt64()
{
Span<byte> buffer = stackalloc byte[8];
return this.TryReadSpan(buffer)
? this.ConvertToUInt64(buffer)
: default;
}
// Known as Long in Exif Specification.
protected uint ReadUInt32() =>
this.TryReadSpan(this.buf4)
? this.ConvertToUInt32(this.buf4)
protected uint ReadUInt32()
{
Span<byte> buffer = stackalloc byte[4];
return this.TryReadSpan(buffer)
? this.ConvertToUInt32(buffer)
: default;
}
protected ushort ReadUInt16() => this.TryReadSpan(this.buf2)
? this.ConvertToShort(this.buf2)
protected ushort ReadUInt16()
{
Span<byte> buffer = stackalloc byte[2];
return this.TryReadSpan(buffer)
? this.ConvertToShort(buffer)
: default;
}
private long ConvertToInt64(ReadOnlySpan<byte> buffer)
{

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

@ -45,12 +45,12 @@ internal sealed class ExifByteArray : ExifArrayValue<byte>
private bool TrySetSignedIntArray(int[] intArrayValue)
{
if (Array.FindIndex(intArrayValue, x => x < byte.MinValue || x > byte.MaxValue) > -1)
if (Array.FindIndex(intArrayValue, x => (uint)x > byte.MaxValue) >= 0)
{
return false;
}
var value = new byte[intArrayValue.Length];
byte[] value = new byte[intArrayValue.Length];
for (int i = 0; i < intArrayValue.Length; i++)
{
int s = intArrayValue[i];

14
src/ImageSharp/Metadata/Profiles/ICC/IccProfile.cs

@ -108,10 +108,10 @@ public sealed class IccProfile : IDeepCloneable<IccProfile>
const int profileIdPos = 84;
// need to copy some values because they need to be zero for the hashing
byte[] temp = new byte[24];
Buffer.BlockCopy(data, profileFlagPos, temp, 0, 4);
Buffer.BlockCopy(data, renderingIntentPos, temp, 4, 4);
Buffer.BlockCopy(data, profileIdPos, temp, 8, 16);
Span<byte> temp = stackalloc byte[24];
data.AsSpan(profileFlagPos, 4).CopyTo(temp);
data.AsSpan(renderingIntentPos, 4).CopyTo(temp.Slice(4));
data.AsSpan(profileIdPos, 16).CopyTo(temp.Slice(8));
try
{
@ -131,9 +131,9 @@ public sealed class IccProfile : IDeepCloneable<IccProfile>
}
finally
{
Buffer.BlockCopy(temp, 0, data, profileFlagPos, 4);
Buffer.BlockCopy(temp, 4, data, renderingIntentPos, 4);
Buffer.BlockCopy(temp, 8, data, profileIdPos, 16);
temp.Slice(0, 4).CopyTo(data.AsSpan(profileFlagPos));
temp.Slice(4, 4).CopyTo(data.AsSpan(renderingIntentPos));
temp.Slice(8, 16).CopyTo(data.AsSpan(profileIdPos));
}
}

Loading…
Cancel
Save