Browse Source

Write the BmpFileHeader directly to the output span

af/merge-core
Jason Nelson 8 years ago
parent
commit
19591271da
  1. 27
      src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs
  2. 26
      src/ImageSharp/Formats/Bmp/BmpFileHeader.cs
  3. 21
      tests/ImageSharp.Tests/Formats/Bmp/BmpFileHeaderTests.cs

27
src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs

@ -14,6 +14,11 @@ namespace SixLabors.ImageSharp.Formats.Bmp
/// </summary>
internal sealed class BmpEncoderCore
{
/// <summary>
/// A general use buffer for reading and writing data.
/// </summary>
private byte[] buffer = new byte[16];
/// <summary>
/// The amount to pad each row by.
/// </summary>
@ -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();
}
/// <summary>
/// Writes the bitmap header data to the binary stream.
/// </summary>
/// <param name="writer">
/// The <see cref="EndianBinaryWriter"/> containing the stream to write to.
/// </param>
/// <param name="fileHeader">
/// The <see cref="BmpFileHeader"/> containing the header data.
/// </param>
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);
}
/// <summary>
/// Writes the bitmap information to the binary stream.
/// </summary>

26
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
{
/// <summary>
@ -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).
/// </remarks>
[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal readonly struct BmpFileHeader
{
/// <summary>
@ -44,12 +49,31 @@ namespace SixLabors.ImageSharp.Formats.Bmp
/// Gets any reserved data; actual value depends on the application
/// that creates the image.
/// </summary>
public int Reserved { get; }
public int Reserved { get; }
/// <summary>
/// Gets the offset, i.e. starting address, of the byte where
/// the bitmap data can be found.
/// </summary>
public int Offset { get; }
public unsafe void WriteTo(Span<byte> buffer)
{
if (BitConverter.IsLittleEndian)
{
fixed (BmpFileHeader* pointer = &this)
{
MemoryMarshal.AsBytes(new ReadOnlySpan<BmpFileHeader>(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);
}
}
}
}

21
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));
}
}
}
Loading…
Cancel
Save