diff --git a/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs b/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs
index 300814421..52a367645 100644
--- a/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs
+++ b/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs
@@ -36,6 +36,11 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
///
private readonly MemoryAllocator memoryAllocator;
+ ///
+ /// A scratch buffer to reduce allocations.
+ ///
+ private readonly byte[] buffer = new byte[4];
+
///
/// The global configuration.
///
@@ -238,15 +243,17 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
writer.Write(ExifWriter.GetNumberOfComponents(entry));
uint length = ExifWriter.GetLength(entry);
- var raw = new byte[length];
- int sz = ExifWriter.WriteValue(entry, raw, 0);
- DebugGuard.IsTrue(sz == raw.Length, "Incorrect number of bytes written");
- if (raw.Length <= 4)
+ if (length <= 4)
{
- writer.WritePadded(raw);
+ int sz = ExifWriter.WriteValue(entry, this.buffer, 0);
+ DebugGuard.IsTrue(sz == length, "Incorrect number of bytes written");
+ writer.WritePadded(this.buffer.AsSpan(0, sz));
}
else
{
+ var raw = new byte[length];
+ int sz = ExifWriter.WriteValue(entry, raw, 0);
+ DebugGuard.IsTrue(sz == raw.Length, "Incorrect number of bytes written");
largeDataBlocks.Add(raw);
writer.Write(dataOffset);
dataOffset += (uint)(raw.Length + (raw.Length % 2));
diff --git a/src/ImageSharp/Formats/Tiff/Writers/TiffStreamWriter.cs b/src/ImageSharp/Formats/Tiff/Writers/TiffStreamWriter.cs
index 39d46c878..7a49d4b82 100644
--- a/src/ImageSharp/Formats/Tiff/Writers/TiffStreamWriter.cs
+++ b/src/ImageSharp/Formats/Tiff/Writers/TiffStreamWriter.cs
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0.
using System;
+using System.Buffers.Binary;
using System.IO;
namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Writers
@@ -13,6 +14,11 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Writers
{
private static readonly byte[] PaddingBytes = new byte[4];
+ ///
+ /// A scratch buffer to reduce allocations.
+ ///
+ private readonly byte[] buffer = new byte[4];
+
///
/// Initializes a new instance of the class.
///
@@ -37,7 +43,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Writers
///
/// Writes an empty four bytes to the stream, returning the offset to be written later.
///
- /// The offset to be written later
+ /// The offset to be written later.
public long PlaceMarker()
{
long offset = this.BaseStream.Position;
@@ -69,8 +75,16 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Writers
/// The two-byte unsigned integer to write.
public void Write(ushort value)
{
- byte[] bytes = BitConverter.GetBytes(value);
- this.BaseStream.Write(bytes, 0, 2);
+ if (this.IsLittleEndian)
+ {
+ BinaryPrimitives.WriteUInt16LittleEndian(this.buffer, value);
+ }
+ else
+ {
+ BinaryPrimitives.WriteUInt16BigEndian(this.buffer, value);
+ }
+
+ this.BaseStream.Write(this.buffer.AsSpan(0, 2));
}
///
@@ -79,21 +93,29 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Writers
/// The four-byte unsigned integer to write.
public void Write(uint value)
{
- byte[] bytes = BitConverter.GetBytes(value);
- this.BaseStream.Write(bytes, 0, 4);
+ if (this.IsLittleEndian)
+ {
+ BinaryPrimitives.WriteUInt32LittleEndian(this.buffer, value);
+ }
+ else
+ {
+ BinaryPrimitives.WriteUInt32BigEndian(this.buffer, value);
+ }
+
+ this.BaseStream.Write(this.buffer.AsSpan(0, 4));
}
///
/// Writes an array of bytes to the current stream, padded to four-bytes.
///
/// The bytes to write.
- public void WritePadded(byte[] value)
+ public void WritePadded(Span value)
{
- this.BaseStream.Write(value, 0, value.Length);
+ this.BaseStream.Write(value);
- if (value.Length < 4)
+ if (value.Length % 4 != 0)
{
- this.BaseStream.Write(PaddingBytes, 0, 4 - value.Length);
+ this.BaseStream.Write(PaddingBytes, 0, 4 - (value.Length % 4));
}
}
diff --git a/tests/ImageSharp.Tests/Formats/Tiff/Utils/TiffWriterTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/Utils/TiffWriterTests.cs
index 7ea2e4cc4..b1389cec5 100644
--- a/tests/ImageSharp.Tests/Formats/Tiff/Utils/TiffWriterTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Tiff/Utils/TiffWriterTests.cs
@@ -76,12 +76,13 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff.Utils
}
[Theory]
- [InlineData(new byte[] { }, new byte[] { 0, 0, 0, 0 })]
+ [InlineData(new byte[] { }, new byte[] { })]
[InlineData(new byte[] { 2 }, new byte[] { 2, 0, 0, 0 })]
[InlineData(new byte[] { 2, 4 }, new byte[] { 2, 4, 0, 0 })]
[InlineData(new byte[] { 2, 4, 6 }, new byte[] { 2, 4, 6, 0 })]
[InlineData(new byte[] { 2, 4, 6, 8 }, new byte[] { 2, 4, 6, 8 })]
- [InlineData(new byte[] { 2, 4, 6, 8, 10, 12 }, new byte[] { 2, 4, 6, 8, 10, 12 })]
+ [InlineData(new byte[] { 2, 4, 6, 8, 10, 12 }, new byte[] { 2, 4, 6, 8, 10, 12, 0, 0 })]
+
public void WritePadded_WritesByteArray(byte[] bytes, byte[] expectedResult)
{
using var stream = new MemoryStream();