diff --git a/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs
index be7c1d2e55..aa8f2b8a5e 100644
--- a/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs
+++ b/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs
@@ -14,6 +14,11 @@ namespace SixLabors.ImageSharp.Formats.Bmp
///
internal sealed class BmpEncoderCore
{
+ ///
+ /// A general use buffer for reading and writing data.
+ ///
+ private byte[] buffer = new byte[16];
+
///
/// The amount to pad each row by.
///
@@ -75,30 +80,16 @@ namespace SixLabors.ImageSharp.Formats.Bmp
reserved: 0,
fileSize: 54 + infoHeader.ImageSize);
- WriteHeader(writer, fileHeader);
+ fileHeader.WriteTo(this.buffer);
+
+ stream.Write(this.buffer, 0, BmpFileHeader.Size);
+
this.WriteInfo(writer, infoHeader);
this.WriteImage(writer, image.Frames.RootFrame);
writer.Flush();
}
- ///
- /// Writes the bitmap header data to the binary stream.
- ///
- ///
- /// The containing the stream to write to.
- ///
- ///
- /// The containing the header data.
- ///
- private static void WriteHeader(EndianBinaryWriter writer, in BmpFileHeader fileHeader)
- {
- writer.Write(fileHeader.Type);
- writer.Write(fileHeader.FileSize);
- writer.Write(fileHeader.Reserved);
- writer.Write(fileHeader.Offset);
- }
-
///
/// Writes the bitmap information to the binary stream.
///
diff --git a/src/ImageSharp/Formats/Bmp/BmpFileHeader.cs b/src/ImageSharp/Formats/Bmp/BmpFileHeader.cs
index ed17164a22..113dc0d479 100644
--- a/src/ImageSharp/Formats/Bmp/BmpFileHeader.cs
+++ b/src/ImageSharp/Formats/Bmp/BmpFileHeader.cs
@@ -1,6 +1,10 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
+using System;
+using System.Buffers.Binary;
+using System.Runtime.InteropServices;
+
namespace SixLabors.ImageSharp.Formats.Bmp
{
///
@@ -13,6 +17,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
/// All of the other integer values are stored in little-endian format
/// (i.e. least-significant byte first).
///
+ [StructLayout(LayoutKind.Sequential, Pack = 1)]
internal readonly struct BmpFileHeader
{
///
@@ -44,12 +49,31 @@ namespace SixLabors.ImageSharp.Formats.Bmp
/// Gets any reserved data; actual value depends on the application
/// that creates the image.
///
- public int Reserved { get; }
+ public int Reserved { get; }
///
/// Gets the offset, i.e. starting address, of the byte where
/// the bitmap data can be found.
///
public int Offset { get; }
+
+ public unsafe void WriteTo(Span buffer)
+ {
+ if (BitConverter.IsLittleEndian)
+ {
+ fixed (BmpFileHeader* pointer = &this)
+ {
+ MemoryMarshal.AsBytes(new ReadOnlySpan(pointer, 1)).CopyTo(buffer);
+ }
+ }
+ else
+ {
+ // Big Endian Platform
+ BinaryPrimitives.WriteInt16LittleEndian(buffer.Slice(0, 2), this.Type);
+ BinaryPrimitives.WriteInt32LittleEndian(buffer.Slice(2, 4), this.FileSize);
+ BinaryPrimitives.WriteInt32LittleEndian(buffer.Slice(6, 4), this.Reserved);
+ BinaryPrimitives.WriteInt32LittleEndian(buffer.Slice(10, 4), this.Offset);
+ }
+ }
}
}
\ No newline at end of file
diff --git a/tests/ImageSharp.Tests/Formats/Bmp/BmpFileHeaderTests.cs b/tests/ImageSharp.Tests/Formats/Bmp/BmpFileHeaderTests.cs
new file mode 100644
index 0000000000..8ad227cfdc
--- /dev/null
+++ b/tests/ImageSharp.Tests/Formats/Bmp/BmpFileHeaderTests.cs
@@ -0,0 +1,21 @@
+using System;
+using SixLabors.ImageSharp.Formats.Bmp;
+using Xunit;
+
+namespace SixLabors.ImageSharp.Tests.Formats.Bmp
+{
+ public class BmpFileHeaderTests
+ {
+ [Fact]
+ public void TestWrite()
+ {
+ var header = new BmpFileHeader(1, 2, 3, 4);
+
+ byte[] buffer = new byte[14];
+
+ header.WriteTo(buffer);
+
+ Assert.Equal("AQACAAAAAwAAAAQAAAA=", Convert.ToBase64String(buffer));
+ }
+ }
+}
\ No newline at end of file