From 602c359fc2dd54fca7e7f2863cb894d8f526d817 Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Sat, 14 Apr 2018 21:00:02 -0700 Subject: [PATCH] Remove EndianBinaryWriter from BmpEncoderCore --- src/ImageSharp/Formats/Bmp/BmpCompression.cs | 2 +- src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs | 66 ++++++-------------- src/ImageSharp/Formats/Bmp/BmpFileHeader.cs | 17 ++--- src/ImageSharp/Formats/Bmp/BmpInfoHeader.cs | 20 +++++- 4 files changed, 42 insertions(+), 63 deletions(-) diff --git a/src/ImageSharp/Formats/Bmp/BmpCompression.cs b/src/ImageSharp/Formats/Bmp/BmpCompression.cs index 22b12346f..ef063f010 100644 --- a/src/ImageSharp/Formats/Bmp/BmpCompression.cs +++ b/src/ImageSharp/Formats/Bmp/BmpCompression.cs @@ -7,7 +7,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp /// Defines how the compression type of the image data /// in the bitmap file. /// - internal enum BmpCompression + internal enum BmpCompression : int { /// /// Each image row has a multiple of four elements. If the diff --git a/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs index aa8f2b8a5..1e0ecd3b1 100644 --- a/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs +++ b/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs @@ -3,7 +3,6 @@ using System; using System.IO; -using SixLabors.ImageSharp.IO; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; @@ -14,11 +13,6 @@ 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. /// @@ -59,9 +53,6 @@ namespace SixLabors.ImageSharp.Formats.Bmp int bytesPerLine = 4 * (((image.Width * bpp) + 31) / 32); this.padding = bytesPerLine - (image.Width * (int)this.bitsPerPixel); - // Do not use IDisposable pattern here as we want to preserve the stream. - var writer = new EndianBinaryWriter(Endianness.LittleEndian, stream); - var infoHeader = new BmpInfoHeader { HeaderSize = BmpInfoHeader.BitmapInfoHeaderSize, @@ -80,49 +71,30 @@ namespace SixLabors.ImageSharp.Formats.Bmp reserved: 0, fileSize: 54 + infoHeader.ImageSize); - fileHeader.WriteTo(this.buffer); + byte[] buffer = new byte[40]; // TODO: stackalloc - stream.Write(this.buffer, 0, BmpFileHeader.Size); + fileHeader.WriteTo(buffer); - this.WriteInfo(writer, infoHeader); - this.WriteImage(writer, image.Frames.RootFrame); + stream.Write(buffer, 0, BmpFileHeader.Size); - writer.Flush(); - } + infoHeader.WriteTo(buffer); - /// - /// Writes the bitmap information to the binary stream. - /// - /// - /// The containing the stream to write to. - /// - /// - /// The containing the detailed information about the image. - /// - private void WriteInfo(EndianBinaryWriter writer, BmpInfoHeader infoHeader) - { - writer.Write(infoHeader.HeaderSize); - writer.Write(infoHeader.Width); - writer.Write(infoHeader.Height); - writer.Write(infoHeader.Planes); - writer.Write(infoHeader.BitsPerPixel); - writer.Write((int)infoHeader.Compression); - writer.Write(infoHeader.ImageSize); - writer.Write(infoHeader.XPelsPerMeter); - writer.Write(infoHeader.YPelsPerMeter); - writer.Write(infoHeader.ClrUsed); - writer.Write(infoHeader.ClrImportant); + stream.Write(buffer, 0, 40); + + this.WriteImage(stream, image.Frames.RootFrame); + + stream.Flush(); } /// /// Writes the pixel data to the binary stream. /// /// The pixel format. - /// The containing the stream to write to. + /// The to write to. /// /// The containing pixel data. /// - private void WriteImage(EndianBinaryWriter writer, ImageFrame image) + private void WriteImage(Stream stream, ImageFrame image) where TPixel : struct, IPixel { using (PixelAccessor pixels = image.Lock()) @@ -130,11 +102,11 @@ namespace SixLabors.ImageSharp.Formats.Bmp switch (this.bitsPerPixel) { case BmpBitsPerPixel.Pixel32: - this.Write32Bit(writer, pixels); + this.Write32Bit(stream, pixels); break; case BmpBitsPerPixel.Pixel24: - this.Write24Bit(writer, pixels); + this.Write24Bit(stream, pixels); break; } } @@ -149,9 +121,9 @@ namespace SixLabors.ImageSharp.Formats.Bmp /// Writes the 32bit color palette to the stream. /// /// The pixel format. - /// The containing the stream to write to. + /// The to write to. /// The containing pixel data. - private void Write32Bit(EndianBinaryWriter writer, PixelAccessor pixels) + private void Write32Bit(Stream stream, PixelAccessor pixels) where TPixel : struct, IPixel { using (IManagedByteBuffer row = this.AllocateRow(pixels.Width, 4)) @@ -160,7 +132,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp { Span pixelSpan = pixels.GetRowSpan(y); PixelOperations.Instance.ToBgra32Bytes(pixelSpan, row.Span, pixelSpan.Length); - writer.Write(row.Array, 0, row.Length()); + stream.Write(row.Array, 0, row.Length()); } } } @@ -169,9 +141,9 @@ namespace SixLabors.ImageSharp.Formats.Bmp /// Writes the 24bit color palette to the stream. /// /// The pixel format. - /// The containing the stream to write to. + /// The to write to. /// The containing pixel data. - private void Write24Bit(EndianBinaryWriter writer, PixelAccessor pixels) + private void Write24Bit(Stream stream, PixelAccessor pixels) where TPixel : struct, IPixel { using (IManagedByteBuffer row = this.AllocateRow(pixels.Width, 3)) @@ -180,7 +152,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp { Span pixelSpan = pixels.GetRowSpan(y); PixelOperations.Instance.ToBgr24Bytes(pixelSpan, row.Span, pixelSpan.Length); - writer.Write(row.Array, 0, row.Length()); + stream.Write(row.Array, 0, row.Length()); } } } diff --git a/src/ImageSharp/Formats/Bmp/BmpFileHeader.cs b/src/ImageSharp/Formats/Bmp/BmpFileHeader.cs index 113dc0d47..64474ad90 100644 --- a/src/ImageSharp/Formats/Bmp/BmpFileHeader.cs +++ b/src/ImageSharp/Formats/Bmp/BmpFileHeader.cs @@ -59,21 +59,12 @@ namespace SixLabors.ImageSharp.Formats.Bmp public unsafe void WriteTo(Span buffer) { - if (BitConverter.IsLittleEndian) + fixed (BmpFileHeader* pointer = &this) { - 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); + MemoryMarshal.AsBytes(new ReadOnlySpan(pointer, 1)).CopyTo(buffer); } + + // TODO: Big Endian Platforms } } } \ No newline at end of file diff --git a/src/ImageSharp/Formats/Bmp/BmpInfoHeader.cs b/src/ImageSharp/Formats/Bmp/BmpInfoHeader.cs index b24404cac..b38cfd450 100644 --- a/src/ImageSharp/Formats/Bmp/BmpInfoHeader.cs +++ b/src/ImageSharp/Formats/Bmp/BmpInfoHeader.cs @@ -1,5 +1,8 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using System; +using System.Runtime.InteropServices; + namespace SixLabors.ImageSharp.Formats.Bmp { /// @@ -8,8 +11,11 @@ namespace SixLabors.ImageSharp.Formats.Bmp /// the screen. /// /// - internal sealed class BmpInfoHeader + [StructLayout(LayoutKind.Sequential, Pack = 1)] + internal struct BmpInfoHeader { + // TODO: Make readonly + /// /// Defines the size of the BITMAPINFOHEADER data structure in the bitmap file. /// @@ -91,5 +97,15 @@ namespace SixLabors.ImageSharp.Formats.Bmp /// or 0 when every color is important{ get; set; } generally ignored. /// public int ClrImportant { get; set; } + + public unsafe void WriteTo(Span buffer) + { + fixed (BmpInfoHeader* pointer = &this) + { + MemoryMarshal.AsBytes(new ReadOnlySpan(pointer, 1)).CopyTo(buffer); + } + + // TODO: Big Endian Platforms + } } -} +} \ No newline at end of file